Re: [PATCH 2/2] Add UAS driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2010-09-28 at 06:14 -0400, Matthew Wilcox wrote:
> +static int uas_queuecommand(struct scsi_cmnd *cmnd,
> +					void (*done)(struct scsi_cmnd *))
> +{
> +	struct scsi_device *sdev = cmnd->device;
> +	struct uas_dev_info *devinfo = sdev->hostdata;
> +	struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
> +	int err;
> +
> +	BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer));
> +
> +	if (!cmdinfo->sense_urb && sdev->current_cmnd)
> +		return SCSI_MLQUEUE_DEVICE_BUSY;
> +
> +	if (blk_rq_tagged(cmnd->request)) {
> +		cmdinfo->stream = cmnd->request->tag + 1;
> +	} else {
> +		sdev->current_cmnd = cmnd;
> +		cmdinfo->stream = 1;
> +	}
> +
> +	cmnd->scsi_done = done;
> +
> +	cmdinfo->state = ALLOC_SENSE_URB | SUBMIT_SENSE_URB |
> +			ALLOC_CMD_URB | SUBMIT_CMD_URB;
> +
> +	switch (cmnd->sc_data_direction) {
> +	case DMA_FROM_DEVICE:
> +		cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
> +		break;
> +	case DMA_BIDIRECTIONAL:
> +		cmdinfo->state |= ALLOC_DATA_IN_URB | SUBMIT_DATA_IN_URB;
> +	case DMA_TO_DEVICE:
> +		cmdinfo->state |= ALLOC_DATA_OUT_URB | SUBMIT_DATA_OUT_URB;
> +	case DMA_NONE:
> +		break;
> +	}
> +
> +	if (!devinfo->use_streams) {
> +		cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB);
> +		cmdinfo->stream = 0;
> +	}
> +
> +	err = uas_submit_urbs(cmnd, devinfo, GFP_ATOMIC);
> +	if (err) {
> +		/* If we did nothing, give up now */
> +		if (cmdinfo->state & SUBMIT_SENSE_URB) {
> +			usb_free_urb(cmdinfo->sense_urb);
> +			return SCSI_MLQUEUE_DEVICE_BUSY;
> +		}
> +		spin_lock(&uas_work_lock);
> +		list_add_tail(&cmdinfo->list, &uas_work_list);
> +		spin_unlock(&uas_work_lock);
> +		schedule_work(&uas_work);

So, as I read this, you defer to a workqueue if allocation fails?  You
can't do that in all cases because the system will lock up if we do this
on a dirty page clearing path.  In order to avoid this lockup, you have
to guarantee at least some forward progress.  That usually (for SCSI)
means that we guarantee at least one command can be issued per device,
so we use mempools to guarantee this single free command.

James

> +	}
> +
> +	return 0;
> +}
> +

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux