--- zzzz-none-000/linux-2.6.13.1/drivers/usb/storage/scsiglue.c 2005-09-10 02:42:58.000000000 +0000 +++ ohio-7170-487/linux-2.6.13.1/drivers/usb/storage/scsiglue.c 2010-01-25 17:11:42.000000000 +0000 @@ -135,6 +135,10 @@ /* Many disks only accept MODE SENSE transfer lengths of * 192 bytes (that's what Windows uses). */ sdev->use_192_bytes_for_3f = 1; + + /* AVM/WK 20100125 From 2.6.19 Branch + * Allow spindown disks to restart automatically */ + sdev->allow_restart = 1; /* Some devices don't like MODE SENSE with page=0x3f, * which is the command used for checking if a device @@ -156,6 +160,14 @@ if (us->flags & US_FL_FIX_CAPACITY) sdev->fix_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. */ + 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 @@ -219,42 +231,42 @@ ***********************************************************************/ /* Command timeout and abort */ -/* This is always called with scsi_lock(host) held */ static int command_abort(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); US_DEBUGP("%s called\n", __FUNCTION__); + /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING + * bits are protected by the host lock. */ + scsi_lock(us_to_host(us)); + /* Is this command still active? */ if (us->srb != srb) { + scsi_unlock(us_to_host(us)); US_DEBUGP ("-- nothing to abort\n"); return FAILED; } /* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if * a device reset isn't already in progress (to avoid interfering - * with the reset). To prevent races with auto-reset, we must - * stop any ongoing USB transfers while still holding the host - * lock. */ + * 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); usb_stor_stop_transport(us); } + scsi_unlock(us_to_host(us)); /* Wait for the aborted command to finish */ wait_for_completion(&us->notify); - - /* Reacquire the lock and allow USB transfers to resume */ - clear_bit(US_FLIDX_ABORTING, &us->flags); - clear_bit(US_FLIDX_TIMED_OUT, &us->flags); return SUCCESS; } /* This invokes the transport reset mechanism to reset the state of the * device */ -/* This is always called with scsi_lock(host) held */ static int device_reset(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); @@ -271,7 +283,6 @@ } /* Simulate a SCSI bus reset by resetting the device's USB port. */ -/* This is always called with scsi_lock(host) held */ static int bus_reset(struct scsi_cmnd *srb) { struct us_data *us = host_to_us(srb->device->host); @@ -283,7 +294,6 @@ result = usb_stor_port_reset(us); up(&(us->dev_semaphore)); - /* lock the host for the return */ return result < 0 ? FAILED : SUCCESS; } @@ -369,6 +379,15 @@ *(pos++) = '\n'; } + + /* + * Help the hotplug machinery to work properly... =OS= 20051201 + */ + if (us->pusb_dev != NULL) { + SPRINTF(" Path: %03d/%03d\n", us->pusb_dev->bus->busnum, us->pusb_dev->devnum); + } else { + SPRINTF(" Path: -\n"); + } /* * Calculate start of next buffer, and return value.