]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/storage/scsiglue.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[linux-2.6-omap-h63xx.git] / drivers / usb / storage / scsiglue.c
index 09779f6a8179944c922b9e5d7c43b1839c5fbc06..2a42b862aa9fdb0808f32cb772745512b3ca4edd 100644 (file)
 #include "transport.h"
 #include "protocol.h"
 
+/* Vendor IDs for companies that seem to include the READ CAPACITY bug
+ * in all their devices
+ */
+#define VENDOR_ID_NOKIA                0x0421
+#define VENDOR_ID_NIKON                0x04b0
+#define VENDOR_ID_MOTOROLA     0x22b8
+
 /***********************************************************************
  * Host functions 
  ***********************************************************************/
@@ -129,11 +136,35 @@ 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. */
        if (sdev->type == TYPE_DISK) {
 
+               /* Some vendors seem to put the READ CAPACITY bug into
+                * all their devices -- primarily makers of cell phones
+                * and digital cameras.  Since these devices always use
+                * flash media and can be expected to have an even number
+                * of sectors, we will always enable the CAPACITY_HEURISTICS
+                * flag unless told otherwise. */
+               switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) {
+               case VENDOR_ID_NOKIA:
+               case VENDOR_ID_NIKON:
+               case VENDOR_ID_MOTOROLA:
+                       if (!(us->fflags & (US_FL_FIX_CAPACITY |
+                                       US_FL_CAPACITY_OK)))
+                               us->fflags |= US_FL_CAPACITY_HEURISTICS;
+                       break;
+               }
+
                /* Disk-type devices use MODE SENSE(6) if the protocol
                 * (SubClass) is Transparent SCSI, otherwise they use
                 * MODE SENSE(10). */
@@ -170,6 +201,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 +231,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