Merge branch 'master'
authorJeff Garzik <jgarzik@pobox.com>
Sat, 5 Nov 2005 20:44:48 +0000 (15:44 -0500)
committerJeff Garzik <jgarzik@pobox.com>
Sat, 5 Nov 2005 20:44:48 +0000 (15:44 -0500)
1  2 
drivers/scsi/libata-scsi.c

index 4f8a013a12f553b2e4e60d02fc35fc7ad01906d7,eb604b0a8990043de0c43123b42c6dbf6bd1b58a..0dc5503633a3b41385da5e6333e6ecdfb98c2072
@@@ -355,10 -355,10 +355,10 @@@ struct ata_queued_cmd *ata_scsi_qc_new(
                qc->scsidone = done;
  
                if (cmd->use_sg) {
-                       qc->sg = (struct scatterlist *) cmd->request_buffer;
+                       qc->__sg = (struct scatterlist *) cmd->request_buffer;
                        qc->n_elem = cmd->use_sg;
                } else {
-                       qc->sg = &qc->sgent;
+                       qc->__sg = &qc->sgent;
                        qc->n_elem = 1;
                }
        } else {
@@@ -702,6 -702,16 +702,16 @@@ int ata_scsi_slave_config(struct scsi_d
                         */
                        blk_queue_max_sectors(sdev->request_queue, 2048);
                }
+               /*
+                * SATA DMA transfers must be multiples of 4 byte, so
+                * we need to pad ATAPI transfers using an extra sg.
+                * Decrement max hw segments accordingly.
+                */
+               if (dev->class == ATA_DEV_ATAPI) {
+                       request_queue_t *q = sdev->request_queue;
+                       blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
+               }
        }
  
        return 0;       /* scsi layer doesn't check return value, sigh */
@@@ -976,13 -986,9 +986,13 @@@ static unsigned int ata_scsi_verify_xla
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
  
 -              if (dev->flags & ATA_DFLAG_LBA48) {
 -                      if (n_block > (64 * 1024))
 -                              goto invalid_fld;
 +              if (lba_28_ok(block, n_block)) {
 +                      /* use LBA28 */
 +                      tf->command = ATA_CMD_VERIFY;
 +                      tf->device |= (block >> 24) & 0xf;
 +              } else if (lba_48_ok(block, n_block)) {
 +                      if (!(dev->flags & ATA_DFLAG_LBA48))
 +                              goto out_of_range;
  
                        /* use LBA48 */
                        tf->flags |= ATA_TFLAG_LBA48;
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
 -              } else {
 -                      if (n_block > 256)
 -                              goto invalid_fld;
 -
 -                      /* use LBA28 */
 -                      tf->command = ATA_CMD_VERIFY;
 -
 -                      tf->device |= (block >> 24) & 0xf;
 -              }
 +              } else
 +                      /* request too large even for LBA48 */
 +                      goto out_of_range;
  
                tf->nsect = n_block & 0xff;
  
                /* CHS */
                u32 sect, head, cyl, track;
  
 -              if (n_block > 256)
 -                      goto invalid_fld;
 +              if (!lba_28_ok(block, n_block))
 +                      goto out_of_range;
  
                /* Convert LBA to CHS */
                track = (u32)block / dev->sectors;
@@@ -1122,11 -1134,9 +1132,11 @@@ static unsigned int ata_scsi_rw_xlat(st
        if (dev->flags & ATA_DFLAG_LBA) {
                tf->flags |= ATA_TFLAG_LBA;
  
 -              if (dev->flags & ATA_DFLAG_LBA48) {
 -                      /* The request -may- be too large for LBA48. */
 -                      if ((block >> 48) || (n_block > 65536))
 +              if (lba_28_ok(block, n_block)) {
 +                      /* use LBA28 */
 +                      tf->device |= (block >> 24) & 0xf;
 +              } else if (lba_48_ok(block, n_block)) {
 +                      if (!(dev->flags & ATA_DFLAG_LBA48))
                                goto out_of_range;
  
                        /* use LBA48 */
                        tf->hob_lbah = (block >> 40) & 0xff;
                        tf->hob_lbam = (block >> 32) & 0xff;
                        tf->hob_lbal = (block >> 24) & 0xff;
 -              } else { 
 -                      /* use LBA28 */
 -
 -                      /* The request -may- be too large for LBA28. */
 -                      if ((block >> 28) || (n_block > 256))
 -                              goto out_of_range;
 -
 -                      tf->device |= (block >> 24) & 0xf;
 -              }
 +              } else
 +                      /* request too large even for LBA48 */
 +                      goto out_of_range;
  
                ata_rwcmd_protocol(qc);
  
                u32 sect, head, cyl, track;
  
                /* The request -may- be too large for CHS addressing. */
 -              if ((block >> 28) || (n_block > 256))
 +              if (!lba_28_ok(block, n_block))
                        goto out_of_range;
  
                ata_rwcmd_protocol(qc);