diff options
-rw-r--r-- | drivers/scsi/libata-core.c | 140 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 291 | ||||
-rw-r--r-- | include/linux/ata.h | 14 | ||||
-rw-r--r-- | include/linux/libata.h | 6 |
4 files changed, 314 insertions, 137 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index c4fcdc30f18c..03d422e99e58 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -62,6 +62,7 @@ | |||
62 | static unsigned int ata_busy_sleep (struct ata_port *ap, | 62 | static unsigned int ata_busy_sleep (struct ata_port *ap, |
63 | unsigned long tmout_pat, | 63 | unsigned long tmout_pat, |
64 | unsigned long tmout); | 64 | unsigned long tmout); |
65 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); | ||
65 | static void ata_set_mode(struct ata_port *ap); | 66 | static void ata_set_mode(struct ata_port *ap); |
66 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 67 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); |
67 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); | 68 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); |
@@ -1131,7 +1132,7 @@ static inline void ata_dump_id(struct ata_device *dev) | |||
1131 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 1132 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) |
1132 | { | 1133 | { |
1133 | struct ata_device *dev = &ap->device[device]; | 1134 | struct ata_device *dev = &ap->device[device]; |
1134 | unsigned int i; | 1135 | unsigned int major_version; |
1135 | u16 tmp; | 1136 | u16 tmp; |
1136 | unsigned long xfer_modes; | 1137 | unsigned long xfer_modes; |
1137 | u8 status; | 1138 | u8 status; |
@@ -1229,9 +1230,9 @@ retry: | |||
1229 | * common ATA, ATAPI feature tests | 1230 | * common ATA, ATAPI feature tests |
1230 | */ | 1231 | */ |
1231 | 1232 | ||
1232 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | 1233 | /* we require DMA support (bits 8 of word 49) */ |
1233 | if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { | 1234 | if (!ata_id_has_dma(dev->id)) { |
1234 | printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); | 1235 | printk(KERN_DEBUG "ata%u: no dma\n", ap->id); |
1235 | goto err_out_nosup; | 1236 | goto err_out_nosup; |
1236 | } | 1237 | } |
1237 | 1238 | ||
@@ -1251,32 +1252,69 @@ retry: | |||
1251 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | 1252 | if (!ata_id_is_ata(dev->id)) /* sanity check */ |
1252 | goto err_out_nosup; | 1253 | goto err_out_nosup; |
1253 | 1254 | ||
1255 | /* get major version */ | ||
1254 | tmp = dev->id[ATA_ID_MAJOR_VER]; | 1256 | tmp = dev->id[ATA_ID_MAJOR_VER]; |
1255 | for (i = 14; i >= 1; i--) | 1257 | for (major_version = 14; major_version >= 1; major_version--) |
1256 | if (tmp & (1 << i)) | 1258 | if (tmp & (1 << major_version)) |
1257 | break; | 1259 | break; |
1258 | 1260 | ||
1259 | /* we require at least ATA-3 */ | 1261 | /* |
1260 | if (i < 3) { | 1262 | * The exact sequence expected by certain pre-ATA4 drives is: |
1261 | printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); | 1263 | * SRST RESET |
1262 | goto err_out_nosup; | 1264 | * IDENTIFY |
1263 | } | 1265 | * INITIALIZE DEVICE PARAMETERS |
1266 | * anything else.. | ||
1267 | * Some drives were very specific about that exact sequence. | ||
1268 | */ | ||
1269 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | ||
1270 | ata_dev_init_params(ap, dev); | ||
1271 | |||
1272 | if (ata_id_has_lba(dev->id)) { | ||
1273 | dev->flags |= ATA_DFLAG_LBA; | ||
1274 | |||
1275 | if (ata_id_has_lba48(dev->id)) { | ||
1276 | dev->flags |= ATA_DFLAG_LBA48; | ||
1277 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1278 | } else { | ||
1279 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1280 | } | ||
1281 | |||
1282 | /* print device info to dmesg */ | ||
1283 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | ||
1284 | ap->id, device, | ||
1285 | major_version, | ||
1286 | ata_mode_string(xfer_modes), | ||
1287 | (unsigned long long)dev->n_sectors, | ||
1288 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | ||
1289 | } else { | ||
1290 | /* CHS */ | ||
1291 | |||
1292 | /* Default translation */ | ||
1293 | dev->cylinders = dev->id[1]; | ||
1294 | dev->heads = dev->id[3]; | ||
1295 | dev->sectors = dev->id[6]; | ||
1296 | dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; | ||
1297 | |||
1298 | if (ata_id_current_chs_valid(dev->id)) { | ||
1299 | /* Current CHS translation is valid. */ | ||
1300 | dev->cylinders = dev->id[54]; | ||
1301 | dev->heads = dev->id[55]; | ||
1302 | dev->sectors = dev->id[56]; | ||
1303 | |||
1304 | dev->n_sectors = ata_id_u32(dev->id, 57); | ||
1305 | } | ||
1306 | |||
1307 | /* print device info to dmesg */ | ||
1308 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | ||
1309 | ap->id, device, | ||
1310 | major_version, | ||
1311 | ata_mode_string(xfer_modes), | ||
1312 | (unsigned long long)dev->n_sectors, | ||
1313 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | ||
1264 | 1314 | ||
1265 | if (ata_id_has_lba48(dev->id)) { | ||
1266 | dev->flags |= ATA_DFLAG_LBA48; | ||
1267 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1268 | } else { | ||
1269 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1270 | } | 1315 | } |
1271 | 1316 | ||
1272 | ap->host->max_cmd_len = 16; | 1317 | ap->host->max_cmd_len = 16; |
1273 | |||
1274 | /* print device info to dmesg */ | ||
1275 | printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", | ||
1276 | ap->id, device, | ||
1277 | ata_mode_string(xfer_modes), | ||
1278 | (unsigned long long)dev->n_sectors, | ||
1279 | dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); | ||
1280 | } | 1318 | } |
1281 | 1319 | ||
1282 | /* ATAPI-specific feature tests */ | 1320 | /* ATAPI-specific feature tests */ |
@@ -2144,6 +2182,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2144 | } | 2182 | } |
2145 | 2183 | ||
2146 | /** | 2184 | /** |
2185 | * ata_dev_init_params - Issue INIT DEV PARAMS command | ||
2186 | * @ap: Port associated with device @dev | ||
2187 | * @dev: Device to which command will be sent | ||
2188 | * | ||
2189 | * LOCKING: | ||
2190 | */ | ||
2191 | |||
2192 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | ||
2193 | { | ||
2194 | DECLARE_COMPLETION(wait); | ||
2195 | struct ata_queued_cmd *qc; | ||
2196 | int rc; | ||
2197 | unsigned long flags; | ||
2198 | u16 sectors = dev->id[6]; | ||
2199 | u16 heads = dev->id[3]; | ||
2200 | |||
2201 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | ||
2202 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | ||
2203 | return; | ||
2204 | |||
2205 | /* set up init dev params taskfile */ | ||
2206 | DPRINTK("init dev params \n"); | ||
2207 | |||
2208 | qc = ata_qc_new_init(ap, dev); | ||
2209 | BUG_ON(qc == NULL); | ||
2210 | |||
2211 | qc->tf.command = ATA_CMD_INIT_DEV_PARAMS; | ||
2212 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
2213 | qc->tf.protocol = ATA_PROT_NODATA; | ||
2214 | qc->tf.nsect = sectors; | ||
2215 | qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ | ||
2216 | |||
2217 | qc->waiting = &wait; | ||
2218 | qc->complete_fn = ata_qc_complete_noop; | ||
2219 | |||
2220 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2221 | rc = ata_qc_issue(qc); | ||
2222 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2223 | |||
2224 | if (rc) | ||
2225 | ata_port_disable(ap); | ||
2226 | else | ||
2227 | wait_for_completion(&wait); | ||
2228 | |||
2229 | DPRINTK("EXIT\n"); | ||
2230 | } | ||
2231 | |||
2232 | /** | ||
2147 | * ata_sg_clean - Unmap DMA memory associated with command | 2233 | * ata_sg_clean - Unmap DMA memory associated with command |
2148 | * @qc: Command containing DMA memory to be released | 2234 | * @qc: Command containing DMA memory to be released |
2149 | * | 2235 | * |
@@ -3156,8 +3242,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
3156 | 3242 | ||
3157 | ata_tf_init(ap, &qc->tf, dev->devno); | 3243 | ata_tf_init(ap, &qc->tf, dev->devno); |
3158 | 3244 | ||
3159 | if (dev->flags & ATA_DFLAG_LBA48) | 3245 | if (dev->flags & ATA_DFLAG_LBA) { |
3160 | qc->tf.flags |= ATA_TFLAG_LBA48; | 3246 | qc->tf.flags |= ATA_TFLAG_LBA; |
3247 | |||
3248 | if (dev->flags & ATA_DFLAG_LBA48) | ||
3249 | qc->tf.flags |= ATA_TFLAG_LBA48; | ||
3250 | } | ||
3161 | } | 3251 | } |
3162 | 3252 | ||
3163 | return qc; | 3253 | return qc; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 104fd9a63e73..03b7a6dd95fe 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -504,77 +504,107 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
504 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 504 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
505 | { | 505 | { |
506 | struct ata_taskfile *tf = &qc->tf; | 506 | struct ata_taskfile *tf = &qc->tf; |
507 | struct ata_device *dev = qc->dev; | ||
508 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
507 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 509 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
508 | u64 dev_sectors = qc->dev->n_sectors; | 510 | u64 dev_sectors = qc->dev->n_sectors; |
509 | u64 sect = 0; | 511 | u64 block = 0; |
510 | u32 n_sect = 0; | 512 | u32 n_block = 0; |
511 | 513 | ||
512 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 514 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
513 | tf->protocol = ATA_PROT_NODATA; | 515 | tf->protocol = ATA_PROT_NODATA; |
514 | tf->device |= ATA_LBA; | ||
515 | 516 | ||
516 | if (scsicmd[0] == VERIFY) { | 517 | if (scsicmd[0] == VERIFY) { |
517 | sect |= ((u64)scsicmd[2]) << 24; | 518 | block |= ((u64)scsicmd[2]) << 24; |
518 | sect |= ((u64)scsicmd[3]) << 16; | 519 | block |= ((u64)scsicmd[3]) << 16; |
519 | sect |= ((u64)scsicmd[4]) << 8; | 520 | block |= ((u64)scsicmd[4]) << 8; |
520 | sect |= ((u64)scsicmd[5]); | 521 | block |= ((u64)scsicmd[5]); |
521 | 522 | ||
522 | n_sect |= ((u32)scsicmd[7]) << 8; | 523 | n_block |= ((u32)scsicmd[7]) << 8; |
523 | n_sect |= ((u32)scsicmd[8]); | 524 | n_block |= ((u32)scsicmd[8]); |
524 | } | 525 | } |
525 | 526 | ||
526 | else if (scsicmd[0] == VERIFY_16) { | 527 | else if (scsicmd[0] == VERIFY_16) { |
527 | sect |= ((u64)scsicmd[2]) << 56; | 528 | block |= ((u64)scsicmd[2]) << 56; |
528 | sect |= ((u64)scsicmd[3]) << 48; | 529 | block |= ((u64)scsicmd[3]) << 48; |
529 | sect |= ((u64)scsicmd[4]) << 40; | 530 | block |= ((u64)scsicmd[4]) << 40; |
530 | sect |= ((u64)scsicmd[5]) << 32; | 531 | block |= ((u64)scsicmd[5]) << 32; |
531 | sect |= ((u64)scsicmd[6]) << 24; | 532 | block |= ((u64)scsicmd[6]) << 24; |
532 | sect |= ((u64)scsicmd[7]) << 16; | 533 | block |= ((u64)scsicmd[7]) << 16; |
533 | sect |= ((u64)scsicmd[8]) << 8; | 534 | block |= ((u64)scsicmd[8]) << 8; |
534 | sect |= ((u64)scsicmd[9]); | 535 | block |= ((u64)scsicmd[9]); |
535 | 536 | ||
536 | n_sect |= ((u32)scsicmd[10]) << 24; | 537 | n_block |= ((u32)scsicmd[10]) << 24; |
537 | n_sect |= ((u32)scsicmd[11]) << 16; | 538 | n_block |= ((u32)scsicmd[11]) << 16; |
538 | n_sect |= ((u32)scsicmd[12]) << 8; | 539 | n_block |= ((u32)scsicmd[12]) << 8; |
539 | n_sect |= ((u32)scsicmd[13]); | 540 | n_block |= ((u32)scsicmd[13]); |
540 | } | 541 | } |
541 | 542 | ||
542 | else | 543 | else |
543 | return 1; | 544 | return 1; |
544 | 545 | ||
545 | if (!n_sect) | 546 | if (!n_block) |
546 | return 1; | 547 | return 1; |
547 | if (sect >= dev_sectors) | 548 | if (block >= dev_sectors) |
548 | return 1; | 549 | return 1; |
549 | if ((sect + n_sect) > dev_sectors) | 550 | if ((block + n_block) > dev_sectors) |
550 | return 1; | 551 | return 1; |
551 | if (lba48) { | 552 | if (lba48) { |
552 | if (n_sect > (64 * 1024)) | 553 | if (n_block > (64 * 1024)) |
553 | return 1; | 554 | return 1; |
554 | } else { | 555 | } else { |
555 | if (n_sect > 256) | 556 | if (n_block > 256) |
556 | return 1; | 557 | return 1; |
557 | } | 558 | } |
558 | 559 | ||
559 | if (lba48) { | 560 | if (lba) { |
560 | tf->command = ATA_CMD_VERIFY_EXT; | 561 | if (lba48) { |
562 | tf->command = ATA_CMD_VERIFY_EXT; | ||
561 | 563 | ||
562 | tf->hob_nsect = (n_sect >> 8) & 0xff; | 564 | tf->hob_nsect = (n_block >> 8) & 0xff; |
563 | 565 | ||
564 | tf->hob_lbah = (sect >> 40) & 0xff; | 566 | tf->hob_lbah = (block >> 40) & 0xff; |
565 | tf->hob_lbam = (sect >> 32) & 0xff; | 567 | tf->hob_lbam = (block >> 32) & 0xff; |
566 | tf->hob_lbal = (sect >> 24) & 0xff; | 568 | tf->hob_lbal = (block >> 24) & 0xff; |
567 | } else { | 569 | } else { |
568 | tf->command = ATA_CMD_VERIFY; | 570 | tf->command = ATA_CMD_VERIFY; |
569 | 571 | ||
570 | tf->device |= (sect >> 24) & 0xf; | 572 | tf->device |= (block >> 24) & 0xf; |
571 | } | 573 | } |
574 | |||
575 | tf->nsect = n_block & 0xff; | ||
572 | 576 | ||
573 | tf->nsect = n_sect & 0xff; | 577 | tf->lbah = (block >> 16) & 0xff; |
578 | tf->lbam = (block >> 8) & 0xff; | ||
579 | tf->lbal = block & 0xff; | ||
574 | 580 | ||
575 | tf->lbah = (sect >> 16) & 0xff; | 581 | tf->device |= ATA_LBA; |
576 | tf->lbam = (sect >> 8) & 0xff; | 582 | } else { |
577 | tf->lbal = sect & 0xff; | 583 | /* CHS */ |
584 | u32 sect, head, cyl, track; | ||
585 | |||
586 | /* Convert LBA to CHS */ | ||
587 | track = (u32)block / dev->sectors; | ||
588 | cyl = track / dev->heads; | ||
589 | head = track % dev->heads; | ||
590 | sect = (u32)block % dev->sectors + 1; | ||
591 | |||
592 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", (u32)block, track, cyl, head, sect); | ||
593 | |||
594 | /* Check whether the converted CHS can fit. | ||
595 | Cylinder: 0-65535 | ||
596 | Head: 0-15 | ||
597 | Sector: 1-255*/ | ||
598 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
599 | return 1; | ||
600 | |||
601 | tf->command = ATA_CMD_VERIFY; | ||
602 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
603 | tf->lbal = sect; | ||
604 | tf->lbam = cyl; | ||
605 | tf->lbah = cyl >> 8; | ||
606 | tf->device |= head; | ||
607 | } | ||
578 | 608 | ||
579 | return 0; | 609 | return 0; |
580 | } | 610 | } |
@@ -602,11 +632,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
602 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 632 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
603 | { | 633 | { |
604 | struct ata_taskfile *tf = &qc->tf; | 634 | struct ata_taskfile *tf = &qc->tf; |
635 | struct ata_device *dev = qc->dev; | ||
636 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
605 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 637 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
638 | u64 block = 0; | ||
639 | u32 n_block = 0; | ||
606 | 640 | ||
607 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 641 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
608 | tf->protocol = qc->dev->xfer_protocol; | 642 | tf->protocol = qc->dev->xfer_protocol; |
609 | tf->device |= ATA_LBA; | ||
610 | 643 | ||
611 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || | 644 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || |
612 | scsicmd[0] == READ_16) { | 645 | scsicmd[0] == READ_16) { |
@@ -616,90 +649,114 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
616 | tf->flags |= ATA_TFLAG_WRITE; | 649 | tf->flags |= ATA_TFLAG_WRITE; |
617 | } | 650 | } |
618 | 651 | ||
652 | /* Calculate the SCSI LBA and transfer length. */ | ||
619 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { | 653 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { |
620 | if (lba48) { | 654 | block |= ((u64)scsicmd[2]) << 24; |
621 | tf->hob_nsect = scsicmd[7]; | 655 | block |= ((u64)scsicmd[3]) << 16; |
622 | tf->hob_lbal = scsicmd[2]; | 656 | block |= ((u64)scsicmd[4]) << 8; |
657 | block |= ((u64)scsicmd[5]); | ||
623 | 658 | ||
624 | qc->nsect = ((unsigned int)scsicmd[7] << 8) | | 659 | n_block |= ((u32)scsicmd[7]) << 8; |
625 | scsicmd[8]; | 660 | n_block |= ((u32)scsicmd[8]); |
626 | } else { | ||
627 | /* if we don't support LBA48 addressing, the request | ||
628 | * -may- be too large. */ | ||
629 | if ((scsicmd[2] & 0xf0) || scsicmd[7]) | ||
630 | return 1; | ||
631 | |||
632 | /* stores LBA27:24 in lower 4 bits of device reg */ | ||
633 | tf->device |= scsicmd[2]; | ||
634 | |||
635 | qc->nsect = scsicmd[8]; | ||
636 | } | ||
637 | |||
638 | tf->nsect = scsicmd[8]; | ||
639 | tf->lbal = scsicmd[5]; | ||
640 | tf->lbam = scsicmd[4]; | ||
641 | tf->lbah = scsicmd[3]; | ||
642 | 661 | ||
643 | VPRINTK("ten-byte command\n"); | 662 | VPRINTK("ten-byte command\n"); |
644 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | 663 | } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
645 | return 1; | 664 | block |= ((u64)scsicmd[2]) << 8; |
646 | return 0; | 665 | block |= ((u64)scsicmd[3]); |
647 | } | 666 | |
648 | 667 | n_block |= ((u32)scsicmd[4]); | |
649 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 668 | if (!n_block) |
650 | qc->nsect = tf->nsect = scsicmd[4]; | 669 | n_block = 256; |
651 | if (!qc->nsect) { | 670 | |
652 | qc->nsect = 256; | ||
653 | if (lba48) | ||
654 | tf->hob_nsect = 1; | ||
655 | } | ||
656 | |||
657 | tf->lbal = scsicmd[3]; | ||
658 | tf->lbam = scsicmd[2]; | ||
659 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | ||
660 | |||
661 | VPRINTK("six-byte command\n"); | 671 | VPRINTK("six-byte command\n"); |
662 | return 0; | 672 | } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { |
673 | block |= ((u64)scsicmd[2]) << 56; | ||
674 | block |= ((u64)scsicmd[3]) << 48; | ||
675 | block |= ((u64)scsicmd[4]) << 40; | ||
676 | block |= ((u64)scsicmd[5]) << 32; | ||
677 | block |= ((u64)scsicmd[6]) << 24; | ||
678 | block |= ((u64)scsicmd[7]) << 16; | ||
679 | block |= ((u64)scsicmd[8]) << 8; | ||
680 | block |= ((u64)scsicmd[9]); | ||
681 | |||
682 | n_block |= ((u32)scsicmd[10]) << 24; | ||
683 | n_block |= ((u32)scsicmd[11]) << 16; | ||
684 | n_block |= ((u32)scsicmd[12]) << 8; | ||
685 | n_block |= ((u32)scsicmd[13]); | ||
686 | |||
687 | VPRINTK("sixteen-byte command\n"); | ||
688 | } else { | ||
689 | DPRINTK("no-byte command\n"); | ||
690 | return 1; | ||
663 | } | 691 | } |
664 | 692 | ||
665 | if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { | 693 | /* Check and compose ATA command */ |
666 | /* rule out impossible LBAs and sector counts */ | 694 | if (!n_block) |
667 | if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11]) | 695 | /* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */ |
668 | return 1; | 696 | return 1; |
669 | 697 | ||
698 | if (lba) { | ||
670 | if (lba48) { | 699 | if (lba48) { |
671 | tf->hob_nsect = scsicmd[12]; | 700 | /* The request -may- be too large for LBA48. */ |
672 | tf->hob_lbal = scsicmd[6]; | 701 | if ((block >> 48) || (n_block > 65536)) |
673 | tf->hob_lbam = scsicmd[5]; | ||
674 | tf->hob_lbah = scsicmd[4]; | ||
675 | |||
676 | qc->nsect = ((unsigned int)scsicmd[12] << 8) | | ||
677 | scsicmd[13]; | ||
678 | } else { | ||
679 | /* once again, filter out impossible non-zero values */ | ||
680 | if (scsicmd[4] || scsicmd[5] || scsicmd[12] || | ||
681 | (scsicmd[6] & 0xf0)) | ||
682 | return 1; | 702 | return 1; |
683 | 703 | ||
684 | /* stores LBA27:24 in lower 4 bits of device reg */ | 704 | tf->hob_nsect = (n_block >> 8) & 0xff; |
685 | tf->device |= scsicmd[6]; | 705 | |
706 | tf->hob_lbah = (block >> 40) & 0xff; | ||
707 | tf->hob_lbam = (block >> 32) & 0xff; | ||
708 | tf->hob_lbal = (block >> 24) & 0xff; | ||
709 | } else { | ||
710 | /* LBA28 */ | ||
711 | |||
712 | /* The request -may- be too large for LBA28. */ | ||
713 | if ((block >> 28) || (n_block > 256)) | ||
714 | return 1; | ||
686 | 715 | ||
687 | qc->nsect = scsicmd[13]; | 716 | tf->device |= (block >> 24) & 0xf; |
688 | } | 717 | } |
718 | |||
719 | qc->nsect = n_block; | ||
720 | tf->nsect = n_block & 0xff; | ||
689 | 721 | ||
690 | tf->nsect = scsicmd[13]; | 722 | tf->lbah = (block >> 16) & 0xff; |
691 | tf->lbal = scsicmd[9]; | 723 | tf->lbam = (block >> 8) & 0xff; |
692 | tf->lbam = scsicmd[8]; | 724 | tf->lbal = block & 0xff; |
693 | tf->lbah = scsicmd[7]; | ||
694 | 725 | ||
695 | VPRINTK("sixteen-byte command\n"); | 726 | tf->device |= ATA_LBA; |
696 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | 727 | } else { |
728 | /* CHS */ | ||
729 | u32 sect, head, cyl, track; | ||
730 | |||
731 | /* The request -may- be too large for CHS addressing. */ | ||
732 | if ((block >> 28) || (n_block > 256)) | ||
697 | return 1; | 733 | return 1; |
698 | return 0; | 734 | |
735 | /* Convert LBA to CHS */ | ||
736 | track = (u32)block / dev->sectors; | ||
737 | cyl = track / dev->heads; | ||
738 | head = track % dev->heads; | ||
739 | sect = (u32)block % dev->sectors + 1; | ||
740 | |||
741 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", | ||
742 | (u32)block, track, cyl, head, sect); | ||
743 | |||
744 | /* Check whether the converted CHS can fit. | ||
745 | Cylinder: 0-65535 | ||
746 | Head: 0-15 | ||
747 | Sector: 1-255*/ | ||
748 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
749 | return 1; | ||
750 | |||
751 | qc->nsect = n_block; | ||
752 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
753 | tf->lbal = sect; | ||
754 | tf->lbam = cyl; | ||
755 | tf->lbah = cyl >> 8; | ||
756 | tf->device |= head; | ||
699 | } | 757 | } |
700 | 758 | ||
701 | DPRINTK("no-byte command\n"); | 759 | return 0; |
702 | return 1; | ||
703 | } | 760 | } |
704 | 761 | ||
705 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 762 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) |
@@ -1246,10 +1303,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, | |||
1246 | 1303 | ||
1247 | VPRINTK("ENTER\n"); | 1304 | VPRINTK("ENTER\n"); |
1248 | 1305 | ||
1249 | if (ata_id_has_lba48(args->id)) | 1306 | if (ata_id_has_lba(args->id)) { |
1250 | n_sectors = ata_id_u64(args->id, 100); | 1307 | if (ata_id_has_lba48(args->id)) |
1251 | else | 1308 | n_sectors = ata_id_u64(args->id, 100); |
1252 | n_sectors = ata_id_u32(args->id, 60); | 1309 | else |
1310 | n_sectors = ata_id_u32(args->id, 60); | ||
1311 | } else { | ||
1312 | /* CHS default translation */ | ||
1313 | n_sectors = args->id[1] * args->id[3] * args->id[6]; | ||
1314 | |||
1315 | if (ata_id_current_chs_valid(args->id)) | ||
1316 | /* CHS current translation */ | ||
1317 | n_sectors = ata_id_u32(args->id, 57); | ||
1318 | } | ||
1319 | |||
1253 | n_sectors--; /* ATA TotalUserSectors - 1 */ | 1320 | n_sectors--; /* ATA TotalUserSectors - 1 */ |
1254 | 1321 | ||
1255 | if (args->cmd->cmnd[0] == READ_CAPACITY) { | 1322 | if (args->cmd->cmnd[0] == READ_CAPACITY) { |
diff --git a/include/linux/ata.h b/include/linux/ata.h index a5b74efab067..85169ea9eb01 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -132,6 +132,7 @@ enum { | |||
132 | ATA_CMD_PACKET = 0xA0, | 132 | ATA_CMD_PACKET = 0xA0, |
133 | ATA_CMD_VERIFY = 0x40, | 133 | ATA_CMD_VERIFY = 0x40, |
134 | ATA_CMD_VERIFY_EXT = 0x42, | 134 | ATA_CMD_VERIFY_EXT = 0x42, |
135 | ATA_CMD_INIT_DEV_PARAMS = 0x91, | ||
135 | 136 | ||
136 | /* SETFEATURES stuff */ | 137 | /* SETFEATURES stuff */ |
137 | SETFEATURES_XFER = 0x03, | 138 | SETFEATURES_XFER = 0x03, |
@@ -181,6 +182,7 @@ enum { | |||
181 | ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ | 182 | ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ |
182 | ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ | 183 | ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ |
183 | ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ | 184 | ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ |
185 | ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ | ||
184 | }; | 186 | }; |
185 | 187 | ||
186 | enum ata_tf_protocols { | 188 | enum ata_tf_protocols { |
@@ -250,6 +252,18 @@ struct ata_taskfile { | |||
250 | ((u64) (id)[(n) + 1] << 16) | \ | 252 | ((u64) (id)[(n) + 1] << 16) | \ |
251 | ((u64) (id)[(n) + 0]) ) | 253 | ((u64) (id)[(n) + 0]) ) |
252 | 254 | ||
255 | static inline int ata_id_current_chs_valid(u16 *id) | ||
256 | { | ||
257 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command | ||
258 | has not been issued to the device then the values of | ||
259 | id[54] to id[56] are vendor specific. */ | ||
260 | return (id[53] & 0x01) && /* Current translation valid */ | ||
261 | id[54] && /* cylinders in current translation */ | ||
262 | id[55] && /* heads in current translation */ | ||
263 | id[55] <= 16 && | ||
264 | id[56]; /* sectors in current translation */ | ||
265 | } | ||
266 | |||
253 | static inline int atapi_cdb_len(u16 *dev_id) | 267 | static inline int atapi_cdb_len(u16 *dev_id) |
254 | { | 268 | { |
255 | u16 tmp = dev_id[0] & 0x3; | 269 | u16 tmp = dev_id[0] & 0x3; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index bb2d916bce44..4739a75b983d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -97,6 +97,7 @@ enum { | |||
97 | ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ | 97 | ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ |
98 | ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ | 98 | ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ |
99 | ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ | 99 | ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ |
100 | ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */ | ||
100 | 101 | ||
101 | ATA_DEV_UNKNOWN = 0, /* unknown device */ | 102 | ATA_DEV_UNKNOWN = 0, /* unknown device */ |
102 | ATA_DEV_ATA = 1, /* ATA device */ | 103 | ATA_DEV_ATA = 1, /* ATA device */ |
@@ -282,6 +283,11 @@ struct ata_device { | |||
282 | u8 xfer_protocol; /* taskfile xfer protocol */ | 283 | u8 xfer_protocol; /* taskfile xfer protocol */ |
283 | u8 read_cmd; /* opcode to use on read */ | 284 | u8 read_cmd; /* opcode to use on read */ |
284 | u8 write_cmd; /* opcode to use on write */ | 285 | u8 write_cmd; /* opcode to use on write */ |
286 | |||
287 | /* for CHS addressing */ | ||
288 | u16 cylinders; /* Number of cylinders */ | ||
289 | u16 heads; /* Number of heads */ | ||
290 | u16 sectors; /* Number of sectors per track */ | ||
285 | }; | 291 | }; |
286 | 292 | ||
287 | struct ata_port { | 293 | struct ata_port { |