📄 scsiglue.c
字号:
/* Driver for USB Mass Storage compliant devices * SCSI layer glue code * * $Id: scsiglue.c,v 1.26 2002/04/22 03:39:43 mdharm Exp $ * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * * Developed with the assistance of: * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) * (c) 2000 Stephen J. Gowdy (SGowdy@lbl.gov) * * Initial work by: * (c) 1999 Michael Gee (michael@linuxspecific.com) * * This driver is based on the 'USB Mass Storage Class' document. This * describes in detail the protocol used to communicate with such * devices. Clearly, the designers had SCSI and ATAPI commands in * mind when they created this document. The commands are all very * similar to commands in the SCSI-II and ATAPI specifications. * * It is important to note that in a number of cases this class * exhibits class-specific exemptions from the USB specification. * Notably the usage of NAK, STALL and ACK differs from the norm, in * that they are used to communicate wait, failed and OK on commands. * * Also, for certain devices, the interrupt endpoint is used to convey * status of a command. * * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more * information about this driver. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/slab.h>#include <linux/module.h>#include <linux/mutex.h>#include <scsi/scsi.h>#include <scsi/scsi_cmnd.h>#include <scsi/scsi_devinfo.h>#include <scsi/scsi_device.h>#include <scsi/scsi_eh.h>#include "usb.h"#include "scsiglue.h"#include "debug.h"#include "transport.h"#include "protocol.h"/*********************************************************************** * Host functions ***********************************************************************/static const char* host_info(struct Scsi_Host *host){ return "SCSI emulation for USB Mass Storage devices";}static int slave_alloc (struct scsi_device *sdev){ struct us_data *us = host_to_us(sdev->host); /* * Set the INQUIRY transfer length to 36. We don't use any of * the extra data and many devices choke if asked for more or * less than 36 bytes. */ sdev->inquiry_len = 36; /* * The UFI spec treates the Peripheral Qualifier bits in an * INQUIRY result as reserved and requires devices to set them * to 0. However the SCSI spec requires these bits to be set * to 3 to indicate when a LUN is not present. * * Let the scanning code know if this target merely sets * Peripheral Device Type to 0x1f to indicate no LUN. */ if (us->subclass == US_SC_UFI) sdev->sdev_target->pdt_1f_for_no_lun = 1; return 0;}static int slave_configure(struct scsi_device *sdev){ struct us_data *us = host_to_us(sdev->host); /* Scatter-gather buffers (all but the last) must have a length * divisible by the bulk maxpacket size. Otherwise a data packet * would end up being short, causing a premature end to the data * transfer. Since high-speed bulk pipes have a maxpacket size * of 512, we'll use that as the scsi device queue's DMA alignment * mask. Guaranteeing proper alignment of the first buffer will * have the desired effect because, except at the beginning and * the end, scatter-gather buffers follow page boundaries. */ blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); /* Many devices have trouble transfering more than 32KB at a time, * while others have trouble with more than 64K. At this time we * are limiting both to 32K (64 sectores). */ if ((us->flags & US_FL_MAX_SECTORS_64) && sdev->request_queue->max_sectors > 64) blk_queue_max_sectors(sdev->request_queue, 64); /* We can't put these settings in slave_alloc() because that gets * called before the device type is known. Consequently these * settings can't be overridden via the scsi devinfo mechanism. */ if (sdev->type == TYPE_DISK) { /* Disk-type devices use MODE SENSE(6) if the protocol * (SubClass) is Transparent SCSI, otherwise they use * MODE SENSE(10). */ if (us->subclass != US_SC_SCSI) sdev->use_10_for_ms = 1; /* Many disks only accept MODE SENSE transfer lengths of * 192 bytes (that's what Windows uses). */ sdev->use_192_bytes_for_3f = 1; /* Some devices don't like MODE SENSE with page=0x3f, * which is the command used for checking if a device * is write-protected. Now that we tell the sd driver * to do a 192-byte transfer with this command the * majority of devices work fine, but a few still can't * handle it. The sd driver will simply assume those * devices are write-enabled. */ if (us->flags & US_FL_NO_WP_DETECT) sdev->skip_ms_page_3f = 1; /* A number of devices have problems with MODE SENSE for * page x08, so we will skip it. */ sdev->skip_ms_page_8 = 1; /* Some disks return the total number of blocks in response * to READ CAPACITY rather than the highest block number. * If this device makes that mistake, tell the sd driver. */ if (us->flags & US_FL_FIX_CAPACITY) sdev->fix_capacity = 1; /* A few disks have two indistinguishable version, one of * which reports the correct capacity and the other does not. * The sd driver has to guess which is the case. */ if (us->flags & US_FL_CAPACITY_HEURISTICS) sdev->guess_capacity = 1; /* Some devices report a SCSI revision level above 2 but are * unable to handle the REPORT LUNS command (for which * support is mandatory at level 3). Since we already have * a Get-Max-LUN request, we won't lose much by setting the * revision level down to 2. The only devices that would be * affected are those with sparse LUNs. */ if (sdev->scsi_level > SCSI_2) sdev->sdev_target->scsi_level = sdev->scsi_level = SCSI_2; /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable * Hardware Error) when any low-level error occurs, * recoverable or not. Setting this flag tells the SCSI * midlayer to retry such commands, which frequently will * succeed and fix the error. The worst this can lead to * is an occasional series of retries that will all fail. */ sdev->retry_hwerror = 1; } else { /* Non-disk-type devices don't need to blacklist any pages * or to force 192-byte transfer lengths for MODE SENSE. * But they do need to use MODE SENSE(10). */ sdev->use_10_for_ms = 1; } /* The CB and CBI transports have no way to pass LUN values * other than the bits in the second byte of a CDB. But those * bits don't get set to the LUN value if the device reports * scsi_level == 0 (UNKNOWN). Hence such devices must necessarily * be single-LUN. */ if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) && sdev->scsi_level == SCSI_UNKNOWN) us->max_lun = 0; /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM * REMOVAL command, so suppress those commands. */ if (us->flags & US_FL_NOT_LOCKABLE) sdev->lockable = 0; /* this is to satisfy the compiler, tho I don't think the * return code is ever checked anywhere. */ return 0;}/* queue a command *//* This is always called with scsi_lock(host) held */static int queuecommand(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *)){ struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__); /* check for state-transition errors */ if (us->srb != NULL) { printk(KERN_ERR USB_STORAGE "Error in %s: us->srb = %p\n", __FUNCTION__, us->srb); return SCSI_MLQUEUE_HOST_BUSY; } /* fail the command if we are disconnecting */ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); return 0; } /* enqueue the command and wake up the control thread */ srb->scsi_done = done; us->srb = srb; up(&(us->sema)); return 0;}/*********************************************************************** * Error handling functions ***********************************************************************//* Command timeout and abort */static int command_abort(struct scsi_cmnd *srb){ struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -