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-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux