diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-23 14:10:23 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-23 14:10:23 -0300 |
commit | a4e0d9af403d099e751797f6cc69e4a8e2d78ef1 (patch) | |
tree | 6f4afdffe5dbaad7529be987b8c3259a07395031 /drivers/usb/storage | |
parent | c60f2b5c1defb6b1345968e1c65c2008c221d57d (diff) | |
parent | c010b2f76c3032e48097a6eef291d8593d5d79a6 (diff) |
Merge ../linux-2.6
Diffstat (limited to 'drivers/usb/storage')
26 files changed, 145 insertions, 187 deletions
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 579e9f52053..17f1ae23291 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -1,7 +1,5 @@ /* Driver for Datafab USB Compact Flash reader * - * $Id: datafab.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $ - * * datafab driver v0.1: * * First release diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index 01e430654a1..a2b5526c9fa 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Debugging Functions Source Code File * - * $Id: debug.c,v 1.9 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index 77e244a8c37..dbb985d5242 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Debugging Functions Header File * - * $Id: debug.h,v 1.6 2001/01/12 23:51:04 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c index 9a410b5a6e5..939923471af 100644 --- a/drivers/usb/storage/dpcm.c +++ b/drivers/usb/storage/dpcm.c @@ -1,7 +1,5 @@ /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader * - * $Id: dpcm.c,v 1.4 2001/06/11 02:54:25 mdharm Exp $ - * * DPCM driver v0.1: * * First release diff --git a/drivers/usb/storage/dpcm.h b/drivers/usb/storage/dpcm.h index 81b464cfcc1..e7b7b0f120d 100644 --- a/drivers/usb/storage/dpcm.h +++ b/drivers/usb/storage/dpcm.h @@ -1,7 +1,5 @@ /* Driver for Microtech DPCM-USB CompactFlash/SmartMedia reader * - * $Id: dpcm.h,v 1.2 2000/08/25 00:13:51 mdharm Exp $ - * * DPCM driver v0.1: * * First release diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index f5a4e8d6a3b..7a4d4567722 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -1,7 +1,5 @@ /* Driver for Freecom USB/IDE adaptor * - * $Id: freecom.c,v 1.22 2002/04/22 03:39:43 mdharm Exp $ - * * Freecom v0.1: * * First release diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/freecom.h index 1b012d62d0a..20d0fe6ba0c 100644 --- a/drivers/usb/storage/freecom.h +++ b/drivers/usb/storage/freecom.h @@ -1,7 +1,5 @@ /* Driver for Freecom USB/IDE adaptor * - * $Id: freecom.h,v 1.4 2000/08/29 14:49:15 dlbrown Exp $ - * * Freecom v0.1: * * First release diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 187dd1e0109..4995bb595ae 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -1,7 +1,5 @@ /* Special Initializers for certain USB Mass Storage devices * - * $Id: initializers.c,v 1.2 2000/09/06 22:35:57 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index ad3ffd4236c..529327fbb06 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -1,7 +1,5 @@ /* Header file for Special Initializers for certain USB Mass Storage devices * - * $Id: initializers.h,v 1.1 2000/08/29 23:07:02 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 3addcd8f827..383abf2516a 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1,7 +1,5 @@ /* Transport & Protocol Driver for In-System Design, Inc. ISD200 ASIC * - * $Id: isd200.c,v 1.16 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance: * (C) 2001-2002 Björn Stenberg (bjorn@haxx.se) * @@ -586,7 +584,7 @@ static void isd200_invoke_transport( struct us_data *us, /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing */ - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { US_DEBUGP("-- command was aborted\n"); goto Handle_Abort; } @@ -633,7 +631,7 @@ static void isd200_invoke_transport( struct us_data *us, if (need_auto_sense) { result = isd200_read_regs(us); - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { US_DEBUGP("-- auto-sense aborted\n"); goto Handle_Abort; } @@ -663,7 +661,7 @@ static void isd200_invoke_transport( struct us_data *us, srb->result = DID_ABORT << 16; /* permit the reset transfer to take place */ - clear_bit(US_FLIDX_ABORTING, &us->flags); + clear_bit(US_FLIDX_ABORTING, &us->dflags); /* Need reset here */ } diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 61097cbb158..df67f13c9e7 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -1,7 +1,5 @@ /* Driver for Lexar "Jumpshot" Compact Flash reader * - * $Id: jumpshot.c,v 1.7 2002/02/25 00:40:13 mdharm Exp $ - * * jumpshot driver v0.1: * * First release diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index b9b8ede61fb..3b3357e20ea 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -1,7 +1,5 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: protocol.c,v 1.14 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h index 8737a36891c..487056ffb51 100644 --- a/drivers/usb/storage/protocol.h +++ b/drivers/usb/storage/protocol.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Protocol Functions Header File * - * $Id: protocol.h,v 1.4 2001/02/13 07:10:03 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 3fcde9f0fa5..09779f6a817 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -1,8 +1,6 @@ /* 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) * @@ -73,7 +71,6 @@ static const char* host_info(struct Scsi_Host *host) static int slave_alloc (struct scsi_device *sdev) { struct us_data *us = host_to_us(sdev->host); - struct usb_host_endpoint *bulk_in_ep; /* * Set the INQUIRY transfer length to 36. We don't use any of @@ -82,16 +79,22 @@ static int slave_alloc (struct scsi_device *sdev) */ sdev->inquiry_len = 36; - /* 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. We'll use the maxpacket value of the bulk-IN pipe - * to set the SCSI device queue's DMA alignment mask. + /* USB has unusual DMA-alignment requirements: Although the + * starting address of each scatter-gather element doesn't matter, + * the length of each element except the last must be divisible + * by the Bulk maxpacket value. There's currently no way to + * express this by block-layer constraints, so we'll cop out + * and simply require addresses to be aligned at 512-byte + * boundaries. This is okay since most block I/O involves + * hardware sectors that are multiples of 512 bytes in length, + * and since host controllers up through USB 2.0 have maxpacket + * values no larger than 512. + * + * But it doesn't suffice for Wireless USB, where Bulk maxpacket + * values can be as large as 2048. To make that work properly + * will require changes to the block layer. */ - bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)]; - blk_queue_update_dma_alignment(sdev->request_queue, - le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1); - /* wMaxPacketSize must be a power of 2 */ + blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1)); /* * The UFI spec treates the Peripheral Qualifier bits in an @@ -116,10 +119,10 @@ static int slave_configure(struct scsi_device *sdev) * 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 | US_FL_MAX_SECTORS_MIN)) { + if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) { unsigned int max_sectors = 64; - if (us->flags & US_FL_MAX_SECTORS_MIN) + if (us->fflags & US_FL_MAX_SECTORS_MIN) max_sectors = PAGE_CACHE_SIZE >> 9; if (sdev->request_queue->max_sectors > max_sectors) blk_queue_max_sectors(sdev->request_queue, @@ -148,7 +151,7 @@ static int slave_configure(struct scsi_device *sdev) * 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) + if (us->fflags & US_FL_NO_WP_DETECT) sdev->skip_ms_page_3f = 1; /* A number of devices have problems with MODE SENSE for @@ -158,13 +161,13 @@ static int slave_configure(struct scsi_device *sdev) /* 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) + if (us->fflags & 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) + if (us->fflags & US_FL_CAPACITY_HEURISTICS) sdev->guess_capacity = 1; /* Some devices report a SCSI revision level above 2 but are @@ -213,7 +216,7 @@ static int slave_configure(struct scsi_device *sdev) /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM * REMOVAL command, so suppress those commands. */ - if (us->flags & US_FL_NOT_LOCKABLE) + if (us->fflags & US_FL_NOT_LOCKABLE) sdev->lockable = 0; /* this is to satisfy the compiler, tho I don't think the @@ -238,7 +241,7 @@ static int queuecommand(struct scsi_cmnd *srb, } /* fail the command if we are disconnecting */ - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) { US_DEBUGP("Fail command during disconnect\n"); srb->result = DID_NO_CONNECT << 16; done(srb); @@ -248,7 +251,7 @@ static int queuecommand(struct scsi_cmnd *srb, /* enqueue the command and wake up the control thread */ srb->scsi_done = done; us->srb = srb; - up(&(us->sema)); + complete(&us->cmnd_ready); return 0; } @@ -280,9 +283,9 @@ static int command_abort(struct scsi_cmnd *srb) * with the reset). Note that we must retain the host lock while * calling usb_stor_stop_transport(); otherwise it might interfere * with an auto-reset that begins as soon as we release the lock. */ - set_bit(US_FLIDX_TIMED_OUT, &us->flags); - if (!test_bit(US_FLIDX_RESETTING, &us->flags)) { - set_bit(US_FLIDX_ABORTING, &us->flags); + set_bit(US_FLIDX_TIMED_OUT, &us->dflags); + if (!test_bit(US_FLIDX_RESETTING, &us->dflags)) { + set_bit(US_FLIDX_ABORTING, &us->dflags); usb_stor_stop_transport(us); } scsi_unlock(us_to_host(us)); @@ -329,7 +332,7 @@ void usb_stor_report_device_reset(struct us_data *us) struct Scsi_Host *host = us_to_host(us); scsi_report_device_reset(host, 0, 0); - if (us->flags & US_FL_SCM_MULT_TARG) { + if (us->fflags & US_FL_SCM_MULT_TARG) { for (i = 1; i < host->max_id; ++i) scsi_report_device_reset(host, 0, i); } @@ -400,7 +403,7 @@ static int proc_info (struct Scsi_Host *host, char *buffer, pos += sprintf(pos, " Quirks:"); #define US_FLAG(name, value) \ - if (us->flags & value) pos += sprintf(pos, " " #name); + if (us->fflags & value) pos += sprintf(pos, " " #name); US_DO_ALL_FLAGS #undef US_FLAG diff --git a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h index 737e4fa6045..ffa1cca93d2 100644 --- a/drivers/usb/storage/scsiglue.h +++ b/drivers/usb/storage/scsiglue.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * SCSI Connecting Glue Header File * - * $Id: scsiglue.h,v 1.4 2000/08/25 00:13:51 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 8972b17da84..c5a54b872c2 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1,6 +1,5 @@ /* Driver for SanDisk SDDR-09 SmartMedia reader * - * $Id: sddr09.c,v 1.24 2002/04/22 03:39:43 mdharm Exp $ * (c) 2000, 2001 Robert Baruch (autophile@starband.net) * (c) 2002 Andries Brouwer (aeb@cwi.nl) * Developed with the assistance of: diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h index c03089a9ec3..e50033ad7b1 100644 --- a/drivers/usb/storage/sddr09.h +++ b/drivers/usb/storage/sddr09.h @@ -1,8 +1,6 @@ /* Driver for SanDisk SDDR-09 SmartMedia reader * Header File * - * $Id: sddr09.h,v 1.5 2000/08/25 00:13:51 mdharm Exp $ - * * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * (c) 2002 Andries Brouwer (aeb@cwi.nl) diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 6d14327c921..0d8df757789 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -1,7 +1,5 @@ /* Driver for SanDisk SDDR-55 SmartMedia reader * - * $Id:$ - * * SDDR55 driver v0.1: * * First release diff --git a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/sddr55.h index d6bd32f6c9f..a815a0470c8 100644 --- a/drivers/usb/storage/sddr55.h +++ b/drivers/usb/storage/sddr55.h @@ -1,8 +1,6 @@ /* Driver for SanDisk SDDR-55 SmartMedia reader * Header File * - * $Id:$ - * * Current development and maintenance by: * (c) 2002 Simon Munton * diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 570c1250f6f..ae6d64810d2 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1,7 +1,5 @@ /* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable * - * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 2000, 2001 Robert Baruch (autophile@starband.net) * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h index 3ddf143a1de..d8bfc43e904 100644 --- a/drivers/usb/storage/shuttle_usbat.h +++ b/drivers/usb/storage/shuttle_usbat.h @@ -1,8 +1,6 @@ /* Driver for SCM Microsystems USB-ATAPI cable * Header File * - * $Id: shuttle_usbat.h,v 1.5 2000/09/17 14:44:52 groovyjava Exp $ - * * Current development and maintenance by: * (c) 2000 Robert Baruch (autophile@dol.net) * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 6610d2dd1e7..fcbbfdb7b2b 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -1,7 +1,5 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: transport.c,v 1.47 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * @@ -75,14 +73,14 @@ * by a separate code path.) * * The abort function (usb_storage_command_abort() in scsiglue.c) first - * sets the machine state and the ABORTING bit in us->flags to prevent + * sets the machine state and the ABORTING bit in us->dflags to prevent * new URBs from being submitted. It then calls usb_stor_stop_transport() - * below, which atomically tests-and-clears the URB_ACTIVE bit in us->flags + * below, which atomically tests-and-clears the URB_ACTIVE bit in us->dflags * to see if the current_urb needs to be stopped. Likewise, the SG_ACTIVE * bit is tested to see if the current_sg scatter-gather request needs to be * stopped. The timeout callback routine does much the same thing. * - * When a disconnect occurs, the DISCONNECTING bit in us->flags is set to + * When a disconnect occurs, the DISCONNECTING bit in us->dflags is set to * prevent new URBs from being submitted, and usb_stor_stop_transport() is * called to stop any ongoing requests. * @@ -127,8 +125,8 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) long timeleft; int status; - /* don't submit URBs during abort/disconnect processing */ - if (us->flags & ABORTING_OR_DISCONNECTING) + /* don't submit URBs during abort processing */ + if (test_bit(US_FLIDX_ABORTING, &us->dflags)) return -EIO; /* set up data structures for the wakeup system */ @@ -159,13 +157,13 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) /* since the URB has been submitted successfully, it's now okay * to cancel it */ - set_bit(US_FLIDX_URB_ACTIVE, &us->flags); + set_bit(US_FLIDX_URB_ACTIVE, &us->dflags); - /* did an abort/disconnect occur during the submission? */ - if (us->flags & ABORTING_OR_DISCONNECTING) { + /* did an abort occur during the submission? */ + if (test_bit(US_FLIDX_ABORTING, &us->dflags)) { /* cancel the URB, if it hasn't been cancelled already */ - if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) { + if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) { US_DEBUGP("-- cancelling URB\n"); usb_unlink_urb(us->current_urb); } @@ -175,7 +173,7 @@ static int usb_stor_msg_common(struct us_data *us, int timeout) timeleft = wait_for_completion_interruptible_timeout( &urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT); - clear_bit(US_FLIDX_URB_ACTIVE, &us->flags); + clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags); if (timeleft <= 0) { US_DEBUGP("%s -- cancelling URB\n", @@ -419,8 +417,8 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, { int result; - /* don't submit s-g requests during abort/disconnect processing */ - if (us->flags & ABORTING_OR_DISCONNECTING) + /* don't submit s-g requests during abort processing */ + if (test_bit(US_FLIDX_ABORTING, &us->dflags)) return USB_STOR_XFER_ERROR; /* initialize the scatter-gather request block */ @@ -435,13 +433,13 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, /* since the block has been initialized successfully, it's now * okay to cancel it */ - set_bit(US_FLIDX_SG_ACTIVE, &us->flags); + set_bit(US_FLIDX_SG_ACTIVE, &us->dflags); - /* did an abort/disconnect occur during the submission? */ - if (us->flags & ABORTING_OR_DISCONNECTING) { + /* did an abort occur during the submission? */ + if (test_bit(US_FLIDX_ABORTING, &us->dflags)) { /* cancel the request, if it hasn't been cancelled already */ - if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { + if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) { US_DEBUGP("-- cancelling sg request\n"); usb_sg_cancel(&us->current_sg); } @@ -449,7 +447,7 @@ static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe, /* wait for the completion of the transfer */ usb_sg_wait(&us->current_sg); - clear_bit(US_FLIDX_SG_ACTIVE, &us->flags); + clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags); result = us->current_sg.status; if (act_len) @@ -530,7 +528,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* if the command gets aborted by the higher layers, we need to * short-circuit all other processing */ - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { US_DEBUGP("-- command was aborted\n"); srb->result = DID_ABORT << 16; goto Handle_Errors; @@ -616,7 +614,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* let's clean up right away */ scsi_eh_restore_cmnd(srb, &ses); - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { US_DEBUGP("-- auto-sense aborted\n"); srb->result = DID_ABORT << 16; goto Handle_Errors; @@ -629,7 +627,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) * auto-sense is perfectly valid */ srb->result = DID_ERROR << 16; - if (!(us->flags & US_FL_SCM_MULT_TARG)) + if (!(us->fflags & US_FL_SCM_MULT_TARG)) goto Handle_Errors; return; } @@ -679,8 +677,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* Set the RESETTING bit, and clear the ABORTING bit so that * the reset may proceed. */ scsi_lock(us_to_host(us)); - set_bit(US_FLIDX_RESETTING, &us->flags); - clear_bit(US_FLIDX_ABORTING, &us->flags); + set_bit(US_FLIDX_RESETTING, &us->dflags); + clear_bit(US_FLIDX_ABORTING, &us->dflags); scsi_unlock(us_to_host(us)); /* We must release the device lock because the pre_reset routine @@ -695,7 +693,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) scsi_unlock(us_to_host(us)); us->transport_reset(us); } - clear_bit(US_FLIDX_RESETTING, &us->flags); + clear_bit(US_FLIDX_RESETTING, &us->dflags); } /* Stop the current URB transfer */ @@ -707,13 +705,13 @@ void usb_stor_stop_transport(struct us_data *us) * let's wake it up. The test_and_clear_bit() call * guarantees that if a URB has just been submitted, * it won't be cancelled more than once. */ - if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->flags)) { + if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) { US_DEBUGP("-- cancelling URB\n"); usb_unlink_urb(us->current_urb); } /* If we are waiting for a scatter-gather operation, cancel it. */ - if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) { + if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) { US_DEBUGP("-- cancelling sg request\n"); usb_sg_cancel(&us->current_sg); } @@ -914,7 +912,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) unsigned int cbwlen = US_BULK_CB_WRAP_LEN; /* Take care of BULK32 devices; set extra byte to 0 */ - if ( unlikely(us->flags & US_FL_BULK32)) { + if (unlikely(us->fflags & US_FL_BULK32)) { cbwlen = 32; us->iobuf[31] = 0; } @@ -925,7 +923,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ? 1 << 7 : 0; bcb->Tag = ++us->tag; bcb->Lun = srb->device->lun; - if (us->flags & US_FL_SCM_MULT_TARG) + if (us->fflags & US_FL_SCM_MULT_TARG) bcb->Lun |= srb->device->id << 4; bcb->Length = srb->cmd_len; @@ -951,7 +949,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) /* Some USB-IDE converter chips need a 100us delay between the * command phase and the data phase. Some devices need a little * more than that, probably because of clock rate inaccuracies. */ - if (unlikely(us->flags & US_FL_GO_SLOW)) + if (unlikely(us->fflags & US_FL_GO_SLOW)) udelay(125); if (transfer_length) { @@ -1010,7 +1008,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, residue, bcs->Status); - if (!(bcs->Tag == us->tag || (us->flags & US_FL_BULK_IGNORE_TAG)) || + if (!(bcs->Tag == us->tag || (us->fflags & US_FL_BULK_IGNORE_TAG)) || bcs->Status > US_BULK_STAT_PHASE) { US_DEBUGP("Bulk logical error\n"); return USB_STOR_TRANSPORT_ERROR; @@ -1035,7 +1033,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) /* try to compute the actual residue, based on how much data * was really transferred and what the device tells us */ if (residue) { - if (!(us->flags & US_FL_IGNORE_RESIDUE)) { + if (!(us->fflags & US_FL_IGNORE_RESIDUE)) { residue = min(residue, transfer_length); scsi_set_resid(srb, max(scsi_get_resid(srb), (int) residue)); @@ -1090,7 +1088,7 @@ static int usb_stor_reset_common(struct us_data *us, int result; int result2; - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) { US_DEBUGP("No reset during disconnect\n"); return -EIO; } @@ -1103,12 +1101,12 @@ static int usb_stor_reset_common(struct us_data *us, return result; } - /* Give the device some time to recover from the reset, - * but don't delay disconnect processing. */ - wait_event_interruptible_timeout(us->delay_wait, - test_bit(US_FLIDX_DISCONNECTING, &us->flags), - HZ*6); - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + /* Give the device some time to recover from the reset, + * but don't delay disconnect processing. */ + wait_event_interruptible_timeout(us->delay_wait, + test_bit(US_FLIDX_DISCONNECTING, &us->dflags), + HZ*6); + if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) { US_DEBUGP("Reset interrupted by disconnect\n"); return -EIO; } @@ -1170,13 +1168,12 @@ int usb_stor_port_reset(struct us_data *us) US_DEBUGP("unable to lock device for reset: %d\n", result); else { /* Were we disconnected while waiting for the lock? */ - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) { result = -EIO; US_DEBUGP("No reset during disconnect\n"); } else { - result = usb_reset_composite_device( - us->pusb_dev, us->pusb_intf); - US_DEBUGP("usb_reset_composite_device returns %d\n", + result = usb_reset_device(us->pusb_dev); + US_DEBUGP("usb_reset_device returns %d\n", result); } if (rc_lock) diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index ada7c2f43f8..e70b88182f0 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Transport Functions Header File * - * $Id: transport.h,v 1.18 2002/04/21 02:57:59 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 39a7c11795c..7ae69f55aa9 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Unusual Devices File * - * $Id: unusual_devs.h,v 1.32 2002/02/25 02:41:24 mdharm Exp $ - * * Current development and maintenance by: * (c) 2000-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * @@ -1234,6 +1232,17 @@ UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE), +/* Andrew Lunn <andrew@lunn.ch> + * PanDigital Digital Picture Frame. Does not like ALLOW_MEDIUM_REMOVAL + * on LUN 4. + * Note: Vend:Prod clash with "Ltd Maxell WS30 Slim Digital Camera" +*/ +UNUSUAL_DEV( 0x0851, 0x1543, 0x0200, 0x0200, + "PanDigital", + "Photo Frame", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_NOT_LOCKABLE), + /* Submitted by Jan De Luyck <lkml@kcore.org> */ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, "CITIZEN", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index e268aacb773..bfea851be98 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -1,7 +1,5 @@ /* Driver for USB Mass Storage compliant devices * - * $Id: usb.c,v 1.75 2002/04/22 03:39:43 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2003 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * @@ -312,26 +310,27 @@ static int usb_stor_control_thread(void * __us) for(;;) { US_DEBUGP("*** thread sleeping.\n"); - if(down_interruptible(&us->sema)) + if (wait_for_completion_interruptible(&us->cmnd_ready)) break; - + US_DEBUGP("*** thread awakened.\n"); /* lock the device pointers */ mutex_lock(&(us->dev_mutex)); - /* if the device has disconnected, we are free to exit */ - if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { - US_DEBUGP("-- exiting\n"); + /* lock access to the state */ + scsi_lock(host); + + /* When we are called with no command pending, we're done */ + if (us->srb == NULL) { + scsi_unlock(host); mutex_unlock(&us->dev_mutex); + US_DEBUGP("-- exiting\n"); break; } - /* lock access to the state */ - scsi_lock(host); - /* has the command timed out *already* ? */ - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { us->srb->result = DID_ABORT << 16; goto SkipForAbort; } @@ -350,7 +349,7 @@ static int usb_stor_control_thread(void * __us) * the maximum known LUN */ else if (us->srb->device->id && - !(us->flags & US_FL_SCM_MULT_TARG)) { + !(us->fflags & US_FL_SCM_MULT_TARG)) { US_DEBUGP("Bad target number (%d:%d)\n", us->srb->device->id, us->srb->device->lun); us->srb->result = DID_BAD_TARGET << 16; @@ -365,7 +364,7 @@ static int usb_stor_control_thread(void * __us) /* Handle those devices which need us to fake * their inquiry data */ else if ((us->srb->cmnd[0] == INQUIRY) && - (us->flags & US_FL_FIX_INQUIRY)) { + (us->fflags & US_FL_FIX_INQUIRY)) { unsigned char data_ptr[36] = { 0x00, 0x80, 0x02, 0x02, 0x1F, 0x00, 0x00, 0x00}; @@ -384,12 +383,8 @@ static int usb_stor_control_thread(void * __us) /* lock access to the state */ scsi_lock(host); - /* did the command already complete because of a disconnect? */ - if (!us->srb) - ; /* nothing to do */ - /* indicate that the command is done */ - else if (us->srb->result != DID_ABORT << 16) { + if (us->srb->result != DID_ABORT << 16) { US_DEBUGP("scsi cmd done, result=0x%x\n", us->srb->result); us->srb->scsi_done(us->srb); @@ -403,12 +398,12 @@ SkipForAbort: * the TIMED_OUT flag, not srb->result == DID_ABORT, because * the timeout might have occurred after the command had * already completed with a different result code. */ - if (test_bit(US_FLIDX_TIMED_OUT, &us->flags)) { + if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) { complete(&(us->notify)); /* Allow USB transfers to resume */ - clear_bit(US_FLIDX_ABORTING, &us->flags); - clear_bit(US_FLIDX_TIMED_OUT, &us->flags); + clear_bit(US_FLIDX_ABORTING, &us->dflags); + clear_bit(US_FLIDX_TIMED_OUT, &us->dflags); } /* finished working on this command */ @@ -500,9 +495,9 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ? idesc->bInterfaceProtocol : unusual_dev->useTransport; - us->flags = USB_US_ORIG_FLAGS(id->driver_info); + us->fflags = USB_US_ORIG_FLAGS(id->driver_info); - if (us->flags & US_FL_IGNORE_DEVICE) { + if (us->fflags & US_FL_IGNORE_DEVICE) { printk(KERN_INFO USB_STORAGE "device ignored\n"); return -ENODEV; } @@ -512,7 +507,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) * disable it if we're in full-speed */ if (dev->speed != USB_SPEED_HIGH) - us->flags &= ~US_FL_GO_SLOW; + us->fflags &= ~US_FL_GO_SLOW; /* Log a message if a non-generic unusual_dev entry contains an * unnecessary subclass or protocol override. This may stimulate @@ -533,7 +528,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) if (unusual_dev->useTransport != US_PR_DEVICE && us->protocol == idesc->bInterfaceProtocol) msg += 2; - if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) + if (msg >= 0 && !(us->fflags & US_FL_NEED_OVERRIDE)) printk(KERN_NOTICE USB_STORAGE "This device " "(%04x,%04x,%04x S %02x P %02x)" " has %s in unusual_devs.h (kernel" @@ -663,7 +658,7 @@ static int get_transport(struct us_data *us) US_DEBUGP("Transport: %s\n", us->transport_name); /* fix for single-lun devices */ - if (us->flags & US_FL_SINGLE_LUN) + if (us->fflags & US_FL_SINGLE_LUN) us->max_lun = 0; return 0; } @@ -820,12 +815,11 @@ static void usb_stor_release_resources(struct us_data *us) US_DEBUGP("-- %s\n", __func__); /* Tell the control thread to exit. The SCSI host must - * already have been removed so it won't try to queue - * any more commands. + * already have been removed and the DISCONNECTING flag set + * so that we won't accept any more commands. */ US_DEBUGP("-- sending exit command to thread\n"); - set_bit(US_FLIDX_DISCONNECTING, &us->flags); - up(&us->sema); + complete(&us->cmnd_ready); if (us->ctl_thread) kthread_stop(us->ctl_thread); @@ -859,39 +853,36 @@ static void dissociate_dev(struct us_data *us) usb_set_intfdata(us->pusb_intf, NULL); } -/* First stage of disconnect processing: stop all commands and remove - * the host */ +/* First stage of disconnect processing: stop SCSI scanning, + * remove the host, and stop accepting new commands + */ static void quiesce_and_remove_host(struct us_data *us) { struct Scsi_Host *host = us_to_host(us); - /* Prevent new USB transfers, stop the current command, and - * interrupt a SCSI-scan or device-reset delay */ - scsi_lock(host); - set_bit(US_FLIDX_DISCONNECTING, &us->flags); - scsi_unlock(host); - usb_stor_stop_transport(us); - wake_up(&us->delay_wait); + /* If the device is really gone, cut short reset delays */ + if (us->pusb_dev->state == USB_STATE_NOTATTACHED) + set_bit(US_FLIDX_DISCONNECTING, &us->dflags); - /* queuecommand won't accept any new commands and the control - * thread won't execute a previously-queued command. If there - * is such a command pending, complete it with an error. */ - mutex_lock(&us->dev_mutex); - if (us->srb) { - us->srb->result = DID_NO_CONNECT << 16; - scsi_lock(host); - us->srb->scsi_done(us->srb); - us->srb = NULL; - complete(&us->notify); /* in case of an abort */ - scsi_unlock(host); - } - mutex_unlock(&us->dev_mutex); + /* Prevent SCSI-scanning (if it hasn't started yet) + * and wait for the SCSI-scanning thread to stop. + */ + set_bit(US_FLIDX_DONT_SCAN, &us->dflags); + wake_up(&us->delay_wait); + wait_for_completion(&us->scanning_done); - /* Now we own no commands so it's safe to remove the SCSI host */ + /* Removing the host will perform an orderly shutdown: caches + * synchronized, disks spun down, etc. + */ scsi_remove_host(host); - /* Wait for the SCSI-scanning thread to stop */ - wait_for_completion(&us->scanning_done); + /* Prevent any new commands from being accepted and cut short + * reset delays. + */ + scsi_lock(host); + set_bit(US_FLIDX_DISCONNECTING, &us->dflags); + scsi_unlock(host); + wake_up(&us->delay_wait); } /* Second stage of disconnect processing: deallocate all resources */ @@ -919,16 +910,16 @@ static int usb_stor_scan_thread(void * __us) printk(KERN_DEBUG "usb-storage: waiting for device " "to settle before scanning\n"); wait_event_freezable_timeout(us->delay_wait, - test_bit(US_FLIDX_DISCONNECTING, &us->flags), + test_bit(US_FLIDX_DONT_SCAN, &us->dflags), delay_use * HZ); } /* If the device is still connected, perform the scanning */ - if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) { /* For bulk-only devices, determine the max LUN value */ if (us->protocol == US_PR_BULK && - !(us->flags & US_FL_SINGLE_LUN)) { + !(us->fflags & US_FL_SINGLE_LUN)) { mutex_lock(&us->dev_mutex); us->max_lun = usb_stor_Bulk_max_lun(us); mutex_unlock(&us->dev_mutex); @@ -975,7 +966,7 @@ static int storage_probe(struct usb_interface *intf, us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); mutex_init(&(us->dev_mutex)); - init_MUTEX_LOCKED(&(us->sema)); + init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); init_completion(&us->scanning_done); @@ -1023,6 +1014,7 @@ static int storage_probe(struct usb_interface *intf, if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start the device-scanning thread\n"); + complete(&us->scanning_done); quiesce_and_remove_host(us); result = PTR_ERR(th); goto BadDevice; @@ -1065,6 +1057,7 @@ static struct usb_driver usb_storage_driver = { .pre_reset = storage_pre_reset, .post_reset = storage_post_reset, .id_table = storage_usb_ids, + .soft_unbind = 1, }; static int __init usb_stor_init(void) diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 8d87503e256..a4ad73bd832 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -1,8 +1,6 @@ /* Driver for USB Mass Storage compliant devices * Main Header File * - * $Id: usb.h,v 1.21 2002/04/21 02:57:59 mdharm Exp $ - * * Current development and maintenance by: * (c) 1999-2002 Matthew Dharm (mdharm-usb@one-eyed-alien.net) * @@ -67,16 +65,14 @@ struct us_unusual_dev { }; -/* Dynamic flag definitions: used in set_bit() etc. */ -#define US_FLIDX_URB_ACTIVE 18 /* 0x00040000 current_urb is in use */ -#define US_FLIDX_SG_ACTIVE 19 /* 0x00080000 current_sg is in use */ -#define US_FLIDX_ABORTING 20 /* 0x00100000 abort is in progress */ -#define US_FLIDX_DISCONNECTING 21 /* 0x00200000 disconnect in progress */ -#define ABORTING_OR_DISCONNECTING ((1UL << US_FLIDX_ABORTING) | \ - (1UL << US_FLIDX_DISCONNECTING)) -#define US_FLIDX_RESETTING 22 /* 0x00400000 device reset in progress */ -#define US_FLIDX_TIMED_OUT 23 /* 0x00800000 SCSI midlayer timed out */ - +/* Dynamic bitflag definitions (us->dflags): used in set_bit() etc. */ +#define US_FLIDX_URB_ACTIVE 0 /* current_urb is in use */ +#define US_FLIDX_SG_ACTIVE 1 /* current_sg is in use */ +#define US_FLIDX_ABORTING 2 /* abort is in progress */ +#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ +#define US_FLIDX_RESETTING 4 /* device reset in progress */ +#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ +#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ #define USB_STOR_STRING_LEN 32 @@ -109,7 +105,8 @@ struct us_data { struct usb_device *pusb_dev; /* this usb_device */ struct usb_interface *pusb_intf; /* this interface */ struct us_unusual_dev *unusual_dev; /* device-filter entry */ - unsigned long flags; /* from filter initially */ + unsigned long fflags; /* fixed flags from filter */ + unsigned long dflags; /* dynamic atomic bitflags */ unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int recv_bulk_pipe; unsigned int send_ctrl_pipe; @@ -147,7 +144,7 @@ struct us_data { struct task_struct *ctl_thread; /* the control thread */ /* mutual exclusion and synchronization structures */ - struct semaphore sema; /* to sleep thread on */ + struct completion cmnd_ready; /* to sleep thread on */ struct completion notify; /* thread begin/end */ wait_queue_head_t delay_wait; /* wait during scan, reset */ struct completion scanning_done; /* wait for scan thread */ |