> +void intel_alsa_reset_ssp_status(void)
> +{
> +       s_stream_status.ssp_handle = NULL;
> +       s_stream_status.stream_info = 0;
> +       spin_lock_init(&s_stream_status.lock);
> +}

It looks like a lot of these can be static ?


> +       spin_lock_bh(&s_stream_status.lock);

Take the lock

> +       if (s_stream_status.stream_info == 0) {
> +               open_ssp = true;
> +       } else if ((((str_info->stream_index == 0)) && (test_bit(1,
> &s_stream_status.stream_info))) ||
> +                       ((str_info->stream_index == 1) &&
> (test_bit(0, &s_stream_status.stream_info)))) {
> +               /*
> +                * do nothing be cause already Open by sibling
> substream
> +                */
> +               pr_debug("ALSA SSP: Open DO NOTHING\n");
> +
> +       } else {
> +               WARN(1, "ALSA SSP: Open unsupported Config\n");

Return with the lock held

So you've not actually tested this ?

>
> +       /* Algorithm that detects conflicting call of open /close*/
> +       spin_lock_bh(&s_stream_status.lock);
> +
> +       if (s_stream_status.stream_info == 0) {
> +               WARN(1, "ALSA SSP: Close before Open\n");

Ditto

> +               return -EBUSY;
> +       }
> +       clear_bit(str_info->stream_index,
> &s_stream_status.stream_info); +
> +       if (s_stream_status.stream_info == 0)
> +               close_ssp = true;

What guarantees the right thing occurs if the other user opens first,
closes first ?

> +
> +       spin_unlock_bh(&s_stream_status.lock);
> +
> +       /*
> +        * the Close SSP is performed out of lock
> +        */
> +       if (close_ssp) {
> +               intel_mid_i2s_close(s_stream_status.ssp_handle);
> +               s_stream_status.ssp_handle = NULL;
> +       }
> +
> +       return 0;
> +} /* intel_alsa_ssp_close */
> +
> +/*
> + * intel_alsa_ssp_control - Set Control params
> + *
> + * Input parameters
> + *             command : command to execute
> + *             value: pointer to a structure

If you've gone to the trouble of documenting the arguments (which is
nice) you might as well put them into kernel-doc format so the doc tools
can extract them.

> + * Output parameters
> + *             ret_val : status
> + */
> +int intel_alsa_ssp_control(int command, struct
> intel_alsa_ssp_stream_info *str_info) +{
> +       int retval = 0;
> +
> +       switch (command) {
> +       case INTEL_ALSA_SSP_CTRL_SND_OPEN:
> +               retval = intel_alsa_ssp_open(str_info);
> +               break;
> +       /*
> +        * SND_PAUSE & SND_RESUME not supported in this version
> +        */
> +       case INTEL_ALSA_SSP_CTRL_SND_PAUSE:
> +       case INTEL_ALSA_SSP_CTRL_SND_RESUME:
> +               break;
> +
> +       case INTEL_ALSA_SSP_CTRL_SND_CLOSE:
> +               intel_alsa_ssp_close(str_info);
> +         break;
> +
> +       default:
> +               /* Illegal case */
> +               WARN(1, "ALSA_SSP: intel_alsa_ssp_control Error: Bad
> Control ID\n");

Not sure this should be warning - it's user triggerable ?



> +       p_stream_info = (struct intel_alsa_ssp_stream_info *)
> info_substream; +

Its void * anyway so you don't need the casts, and Linux generally
omits them for such cases




> +       /*
> +        * Allocates the DMA buffer for the substream
> +        * This callback could be called several time
> +        * snd_pcm_lib_malloc_pages allows to avoid memory leak
> +        * as it release already allocated memory when already
> allocated
> +        */
> +       ret_val = snd_pcm_lib_malloc_pages(substream,
> +                       params_buffer_bytes(hw_params));
> +
> +       memset(substream->runtime->dma_area, 0,
> params_buffer_bytes(hw_params)); +

And if the allocation failed ....



_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to