]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/storage/scsiglue.c
USB: storage: add last-sector hacks
[linux-2.6-omap-h63xx.git] / drivers / usb / storage / scsiglue.c
index 09779f6a8179944c922b9e5d7c43b1839c5fbc06..8d78084abf9f54773f9c82ab771435df257529cf 100644 (file)
@@ -129,6 +129,14 @@ static int slave_configure(struct scsi_device *sdev)
                                              max_sectors);
        }
 
+       /* Some USB host controllers can't do DMA; they have to use PIO.
+        * They indicate this by setting their dma_mask to NULL.  For
+        * such controllers we need to make sure the block layer sets
+        * up bounce buffers in addressable memory.
+        */
+       if (!us->pusb_dev->bus->controller->dma_mask)
+               blk_queue_bounce_limit(sdev->request_queue, BLK_BOUNCE_HIGH);
+
        /* 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. */
@@ -170,6 +178,10 @@ static int slave_configure(struct scsi_device *sdev)
                if (us->fflags & US_FL_CAPACITY_HEURISTICS)
                        sdev->guess_capacity = 1;
 
+               /* assume SPC3 or latter devices support sense size > 18 */
+               if (sdev->scsi_level > SCSI_SPC_2)
+                       us->fflags |= US_FL_SANE_SENSE;
+
                /* 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
@@ -196,6 +208,14 @@ static int slave_configure(struct scsi_device *sdev)
                 * sector in a larger then 1 sector read, since the performance
                 * impact is negible we set this flag for all USB disks */
                sdev->last_sector_bug = 1;
+
+               /* Enable last-sector hacks for single-target devices using
+                * the Bulk-only transport, unless we already know the
+                * capacity will be decremented or is correct. */
+               if (!(us->fflags & (US_FL_FIX_CAPACITY | US_FL_CAPACITY_OK |
+                                       US_FL_SCM_MULT_TARG)) &&
+                               us->protocol == US_PR_BULK)
+                       us->use_last_sector_hacks = 1;
        } else {
 
                /* Non-disk-type devices don't need to blacklist any pages