diff options
author | Albert Lee <albertcc@tw.ibm.com> | 2005-05-12 15:29:42 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-12 15:29:42 -0400 |
commit | 8bf62ecee58360749c5f0e68bc97d5e02a6816b1 (patch) | |
tree | a3da6e695fc5a71ac7f3246707380a9ac22f6402 | |
parent | 88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff) |
[libata] C/H/S support, for older devices
-rw-r--r-- | drivers/scsi/libata-core.c | 140 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 280 | ||||
-rw-r--r-- | include/linux/ata.h | 14 | ||||
-rw-r--r-- | include/linux/libata.h | 6 |
4 files changed, 312 insertions, 128 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0b5d3a5b7eda..96355b05fe5c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -52,6 +52,7 @@ | |||
52 | static unsigned int ata_busy_sleep (struct ata_port *ap, | 52 | static unsigned int ata_busy_sleep (struct ata_port *ap, |
53 | unsigned long tmout_pat, | 53 | unsigned long tmout_pat, |
54 | unsigned long tmout); | 54 | unsigned long tmout); |
55 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev); | ||
55 | static void ata_set_mode(struct ata_port *ap); | 56 | static void ata_set_mode(struct ata_port *ap); |
56 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); | 57 | static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev); |
57 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); | 58 | static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift); |
@@ -1008,7 +1009,7 @@ static inline void ata_dump_id(struct ata_device *dev) | |||
1008 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 1009 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) |
1009 | { | 1010 | { |
1010 | struct ata_device *dev = &ap->device[device]; | 1011 | struct ata_device *dev = &ap->device[device]; |
1011 | unsigned int i; | 1012 | unsigned int major_version; |
1012 | u16 tmp; | 1013 | u16 tmp; |
1013 | unsigned long xfer_modes; | 1014 | unsigned long xfer_modes; |
1014 | u8 status; | 1015 | u8 status; |
@@ -1106,9 +1107,9 @@ retry: | |||
1106 | * common ATA, ATAPI feature tests | 1107 | * common ATA, ATAPI feature tests |
1107 | */ | 1108 | */ |
1108 | 1109 | ||
1109 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | 1110 | /* we require DMA support (bits 8 of word 49) */ |
1110 | if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { | 1111 | if (!ata_id_has_dma(dev->id)) { |
1111 | printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); | 1112 | printk(KERN_DEBUG "ata%u: no dma\n", ap->id); |
1112 | goto err_out_nosup; | 1113 | goto err_out_nosup; |
1113 | } | 1114 | } |
1114 | 1115 | ||
@@ -1128,32 +1129,69 @@ retry: | |||
1128 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | 1129 | if (!ata_id_is_ata(dev->id)) /* sanity check */ |
1129 | goto err_out_nosup; | 1130 | goto err_out_nosup; |
1130 | 1131 | ||
1132 | /* get major version */ | ||
1131 | tmp = dev->id[ATA_ID_MAJOR_VER]; | 1133 | tmp = dev->id[ATA_ID_MAJOR_VER]; |
1132 | for (i = 14; i >= 1; i--) | 1134 | for (major_version = 14; major_version >= 1; major_version--) |
1133 | if (tmp & (1 << i)) | 1135 | if (tmp & (1 << major_version)) |
1134 | break; | 1136 | break; |
1135 | 1137 | ||
1136 | /* we require at least ATA-3 */ | 1138 | /* |
1137 | if (i < 3) { | 1139 | * The exact sequence expected by certain pre-ATA4 drives is: |
1138 | printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); | 1140 | * SRST RESET |
1139 | goto err_out_nosup; | 1141 | * IDENTIFY |
1140 | } | 1142 | * INITIALIZE DEVICE PARAMETERS |
1143 | * anything else.. | ||
1144 | * Some drives were very specific about that exact sequence. | ||
1145 | */ | ||
1146 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | ||
1147 | ata_dev_init_params(ap, dev); | ||
1148 | |||
1149 | if (ata_id_has_lba(dev->id)) { | ||
1150 | dev->flags |= ATA_DFLAG_LBA; | ||
1151 | |||
1152 | if (ata_id_has_lba48(dev->id)) { | ||
1153 | dev->flags |= ATA_DFLAG_LBA48; | ||
1154 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1155 | } else { | ||
1156 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1157 | } | ||
1158 | |||
1159 | /* print device info to dmesg */ | ||
1160 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | ||
1161 | ap->id, device, | ||
1162 | major_version, | ||
1163 | ata_mode_string(xfer_modes), | ||
1164 | (unsigned long long)dev->n_sectors, | ||
1165 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | ||
1166 | } else { | ||
1167 | /* CHS */ | ||
1168 | |||
1169 | /* Default translation */ | ||
1170 | dev->cylinders = dev->id[1]; | ||
1171 | dev->heads = dev->id[3]; | ||
1172 | dev->sectors = dev->id[6]; | ||
1173 | dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; | ||
1174 | |||
1175 | if (ata_id_current_chs_valid(dev->id)) { | ||
1176 | /* Current CHS translation is valid. */ | ||
1177 | dev->cylinders = dev->id[54]; | ||
1178 | dev->heads = dev->id[55]; | ||
1179 | dev->sectors = dev->id[56]; | ||
1180 | |||
1181 | dev->n_sectors = ata_id_u32(dev->id, 57); | ||
1182 | } | ||
1183 | |||
1184 | /* print device info to dmesg */ | ||
1185 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | ||
1186 | ap->id, device, | ||
1187 | major_version, | ||
1188 | ata_mode_string(xfer_modes), | ||
1189 | (unsigned long long)dev->n_sectors, | ||
1190 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | ||
1141 | 1191 | ||
1142 | if (ata_id_has_lba48(dev->id)) { | ||
1143 | dev->flags |= ATA_DFLAG_LBA48; | ||
1144 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1145 | } else { | ||
1146 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1147 | } | 1192 | } |
1148 | 1193 | ||
1149 | ap->host->max_cmd_len = 16; | 1194 | ap->host->max_cmd_len = 16; |
1150 | |||
1151 | /* print device info to dmesg */ | ||
1152 | printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", | ||
1153 | ap->id, device, | ||
1154 | ata_mode_string(xfer_modes), | ||
1155 | (unsigned long long)dev->n_sectors, | ||
1156 | dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); | ||
1157 | } | 1195 | } |
1158 | 1196 | ||
1159 | /* ATAPI-specific feature tests */ | 1197 | /* ATAPI-specific feature tests */ |
@@ -1947,6 +1985,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
1947 | } | 1985 | } |
1948 | 1986 | ||
1949 | /** | 1987 | /** |
1988 | * ata_dev_init_params - Issue INIT DEV PARAMS command | ||
1989 | * @ap: Port associated with device @dev | ||
1990 | * @dev: Device to which command will be sent | ||
1991 | * | ||
1992 | * LOCKING: | ||
1993 | */ | ||
1994 | |||
1995 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | ||
1996 | { | ||
1997 | DECLARE_COMPLETION(wait); | ||
1998 | struct ata_queued_cmd *qc; | ||
1999 | int rc; | ||
2000 | unsigned long flags; | ||
2001 | u16 sectors = dev->id[6]; | ||
2002 | u16 heads = dev->id[3]; | ||
2003 | |||
2004 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | ||
2005 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | ||
2006 | return; | ||
2007 | |||
2008 | /* set up init dev params taskfile */ | ||
2009 | DPRINTK("init dev params \n"); | ||
2010 | |||
2011 | qc = ata_qc_new_init(ap, dev); | ||
2012 | BUG_ON(qc == NULL); | ||
2013 | |||
2014 | qc->tf.command = ATA_CMD_INIT_DEV_PARAMS; | ||
2015 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
2016 | qc->tf.protocol = ATA_PROT_NODATA; | ||
2017 | qc->tf.nsect = sectors; | ||
2018 | qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ | ||
2019 | |||
2020 | qc->waiting = &wait; | ||
2021 | qc->complete_fn = ata_qc_complete_noop; | ||
2022 | |||
2023 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2024 | rc = ata_qc_issue(qc); | ||
2025 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2026 | |||
2027 | if (rc) | ||
2028 | ata_port_disable(ap); | ||
2029 | else | ||
2030 | wait_for_completion(&wait); | ||
2031 | |||
2032 | DPRINTK("EXIT\n"); | ||
2033 | } | ||
2034 | |||
2035 | /** | ||
1950 | * ata_sg_clean - | 2036 | * ata_sg_clean - |
1951 | * @qc: | 2037 | * @qc: |
1952 | * | 2038 | * |
@@ -2736,8 +2822,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
2736 | 2822 | ||
2737 | ata_tf_init(ap, &qc->tf, dev->devno); | 2823 | ata_tf_init(ap, &qc->tf, dev->devno); |
2738 | 2824 | ||
2739 | if (dev->flags & ATA_DFLAG_LBA48) | 2825 | if (dev->flags & ATA_DFLAG_LBA) { |
2740 | qc->tf.flags |= ATA_TFLAG_LBA48; | 2826 | qc->tf.flags |= ATA_TFLAG_LBA; |
2827 | |||
2828 | if (dev->flags & ATA_DFLAG_LBA48) | ||
2829 | qc->tf.flags |= ATA_TFLAG_LBA48; | ||
2830 | } | ||
2741 | } | 2831 | } |
2742 | 2832 | ||
2743 | return qc; | 2833 | return qc; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 4c96df060c3b..8b065ef0e39a 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -435,77 +435,107 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
435 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 435 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
436 | { | 436 | { |
437 | struct ata_taskfile *tf = &qc->tf; | 437 | struct ata_taskfile *tf = &qc->tf; |
438 | struct ata_device *dev = qc->dev; | ||
439 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
438 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 440 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
439 | u64 dev_sectors = qc->dev->n_sectors; | 441 | u64 dev_sectors = qc->dev->n_sectors; |
440 | u64 sect = 0; | 442 | u64 block = 0; |
441 | u32 n_sect = 0; | 443 | u32 n_block = 0; |
442 | 444 | ||
443 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 445 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
444 | tf->protocol = ATA_PROT_NODATA; | 446 | tf->protocol = ATA_PROT_NODATA; |
445 | tf->device |= ATA_LBA; | ||
446 | 447 | ||
447 | if (scsicmd[0] == VERIFY) { | 448 | if (scsicmd[0] == VERIFY) { |
448 | sect |= ((u64)scsicmd[2]) << 24; | 449 | block |= ((u64)scsicmd[2]) << 24; |
449 | sect |= ((u64)scsicmd[3]) << 16; | 450 | block |= ((u64)scsicmd[3]) << 16; |
450 | sect |= ((u64)scsicmd[4]) << 8; | 451 | block |= ((u64)scsicmd[4]) << 8; |
451 | sect |= ((u64)scsicmd[5]); | 452 | block |= ((u64)scsicmd[5]); |
452 | 453 | ||
453 | n_sect |= ((u32)scsicmd[7]) << 8; | 454 | n_block |= ((u32)scsicmd[7]) << 8; |
454 | n_sect |= ((u32)scsicmd[8]); | 455 | n_block |= ((u32)scsicmd[8]); |
455 | } | 456 | } |
456 | 457 | ||
457 | else if (scsicmd[0] == VERIFY_16) { | 458 | else if (scsicmd[0] == VERIFY_16) { |
458 | sect |= ((u64)scsicmd[2]) << 56; | 459 | block |= ((u64)scsicmd[2]) << 56; |
459 | sect |= ((u64)scsicmd[3]) << 48; | 460 | block |= ((u64)scsicmd[3]) << 48; |
460 | sect |= ((u64)scsicmd[4]) << 40; | 461 | block |= ((u64)scsicmd[4]) << 40; |
461 | sect |= ((u64)scsicmd[5]) << 32; | 462 | block |= ((u64)scsicmd[5]) << 32; |
462 | sect |= ((u64)scsicmd[6]) << 24; | 463 | block |= ((u64)scsicmd[6]) << 24; |
463 | sect |= ((u64)scsicmd[7]) << 16; | 464 | block |= ((u64)scsicmd[7]) << 16; |
464 | sect |= ((u64)scsicmd[8]) << 8; | 465 | block |= ((u64)scsicmd[8]) << 8; |
465 | sect |= ((u64)scsicmd[9]); | 466 | block |= ((u64)scsicmd[9]); |
466 | 467 | ||
467 | n_sect |= ((u32)scsicmd[10]) << 24; | 468 | n_block |= ((u32)scsicmd[10]) << 24; |
468 | n_sect |= ((u32)scsicmd[11]) << 16; | 469 | n_block |= ((u32)scsicmd[11]) << 16; |
469 | n_sect |= ((u32)scsicmd[12]) << 8; | 470 | n_block |= ((u32)scsicmd[12]) << 8; |
470 | n_sect |= ((u32)scsicmd[13]); | 471 | n_block |= ((u32)scsicmd[13]); |
471 | } | 472 | } |
472 | 473 | ||
473 | else | 474 | else |
474 | return 1; | 475 | return 1; |
475 | 476 | ||
476 | if (!n_sect) | 477 | if (!n_block) |
477 | return 1; | 478 | return 1; |
478 | if (sect >= dev_sectors) | 479 | if (block >= dev_sectors) |
479 | return 1; | 480 | return 1; |
480 | if ((sect + n_sect) > dev_sectors) | 481 | if ((block + n_block) > dev_sectors) |
481 | return 1; | 482 | return 1; |
482 | if (lba48) { | 483 | if (lba48) { |
483 | if (n_sect > (64 * 1024)) | 484 | if (n_block > (64 * 1024)) |
484 | return 1; | 485 | return 1; |
485 | } else { | 486 | } else { |
486 | if (n_sect > 256) | 487 | if (n_block > 256) |
487 | return 1; | 488 | return 1; |
488 | } | 489 | } |
489 | 490 | ||
490 | if (lba48) { | 491 | if (lba) { |
491 | tf->command = ATA_CMD_VERIFY_EXT; | 492 | if (lba48) { |
493 | tf->command = ATA_CMD_VERIFY_EXT; | ||
492 | 494 | ||
493 | tf->hob_nsect = (n_sect >> 8) & 0xff; | 495 | tf->hob_nsect = (n_block >> 8) & 0xff; |
494 | 496 | ||
495 | tf->hob_lbah = (sect >> 40) & 0xff; | 497 | tf->hob_lbah = (block >> 40) & 0xff; |
496 | tf->hob_lbam = (sect >> 32) & 0xff; | 498 | tf->hob_lbam = (block >> 32) & 0xff; |
497 | tf->hob_lbal = (sect >> 24) & 0xff; | 499 | tf->hob_lbal = (block >> 24) & 0xff; |
498 | } else { | 500 | } else { |
499 | tf->command = ATA_CMD_VERIFY; | 501 | tf->command = ATA_CMD_VERIFY; |
500 | 502 | ||
501 | tf->device |= (sect >> 24) & 0xf; | 503 | tf->device |= (block >> 24) & 0xf; |
502 | } | 504 | } |
505 | |||
506 | tf->nsect = n_block & 0xff; | ||
503 | 507 | ||
504 | tf->nsect = n_sect & 0xff; | 508 | tf->lbah = (block >> 16) & 0xff; |
509 | tf->lbam = (block >> 8) & 0xff; | ||
510 | tf->lbal = block & 0xff; | ||
505 | 511 | ||
506 | tf->lbah = (sect >> 16) & 0xff; | 512 | tf->device |= ATA_LBA; |
507 | tf->lbam = (sect >> 8) & 0xff; | 513 | } else { |
508 | tf->lbal = sect & 0xff; | 514 | /* CHS */ |
515 | u32 sect, head, cyl, track; | ||
516 | |||
517 | /* Convert LBA to CHS */ | ||
518 | track = (u32)block / dev->sectors; | ||
519 | cyl = track / dev->heads; | ||
520 | head = track % dev->heads; | ||
521 | sect = (u32)block % dev->sectors + 1; | ||
522 | |||
523 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", (u32)block, track, cyl, head, sect); | ||
524 | |||
525 | /* Check whether the converted CHS can fit. | ||
526 | Cylinder: 0-65535 | ||
527 | Head: 0-15 | ||
528 | Sector: 1-255*/ | ||
529 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
530 | return 1; | ||
531 | |||
532 | tf->command = ATA_CMD_VERIFY; | ||
533 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
534 | tf->lbal = sect; | ||
535 | tf->lbam = cyl; | ||
536 | tf->lbah = cyl >> 8; | ||
537 | tf->device |= head; | ||
538 | } | ||
509 | 539 | ||
510 | return 0; | 540 | return 0; |
511 | } | 541 | } |
@@ -533,11 +563,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
533 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 563 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
534 | { | 564 | { |
535 | struct ata_taskfile *tf = &qc->tf; | 565 | struct ata_taskfile *tf = &qc->tf; |
566 | struct ata_device *dev = qc->dev; | ||
567 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
536 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 568 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
569 | u64 block = 0; | ||
570 | u32 n_block = 0; | ||
537 | 571 | ||
538 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 572 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
539 | tf->protocol = qc->dev->xfer_protocol; | 573 | tf->protocol = qc->dev->xfer_protocol; |
540 | tf->device |= ATA_LBA; | ||
541 | 574 | ||
542 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || | 575 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || |
543 | scsicmd[0] == READ_16) { | 576 | scsicmd[0] == READ_16) { |
@@ -547,80 +580,111 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
547 | tf->flags |= ATA_TFLAG_WRITE; | 580 | tf->flags |= ATA_TFLAG_WRITE; |
548 | } | 581 | } |
549 | 582 | ||
583 | /* Calculate the SCSI LBA and transfer length. */ | ||
550 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { | 584 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { |
551 | if (lba48) { | 585 | block |= ((u64)scsicmd[2]) << 24; |
552 | tf->hob_nsect = scsicmd[7]; | 586 | block |= ((u64)scsicmd[3]) << 16; |
553 | tf->hob_lbal = scsicmd[2]; | 587 | block |= ((u64)scsicmd[4]) << 8; |
554 | 588 | block |= ((u64)scsicmd[5]); | |
555 | qc->nsect = ((unsigned int)scsicmd[7] << 8) | | ||
556 | scsicmd[8]; | ||
557 | } else { | ||
558 | /* if we don't support LBA48 addressing, the request | ||
559 | * -may- be too large. */ | ||
560 | if ((scsicmd[2] & 0xf0) || scsicmd[7]) | ||
561 | return 1; | ||
562 | |||
563 | /* stores LBA27:24 in lower 4 bits of device reg */ | ||
564 | tf->device |= scsicmd[2]; | ||
565 | 589 | ||
566 | qc->nsect = scsicmd[8]; | 590 | n_block |= ((u32)scsicmd[7]) << 8; |
567 | } | 591 | n_block |= ((u32)scsicmd[8]); |
568 | |||
569 | tf->nsect = scsicmd[8]; | ||
570 | tf->lbal = scsicmd[5]; | ||
571 | tf->lbam = scsicmd[4]; | ||
572 | tf->lbah = scsicmd[3]; | ||
573 | 592 | ||
574 | VPRINTK("ten-byte command\n"); | 593 | VPRINTK("ten-byte command\n"); |
575 | return 0; | 594 | } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
576 | } | 595 | block |= ((u64)scsicmd[2]) << 8; |
577 | 596 | block |= ((u64)scsicmd[3]); | |
578 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 597 | n_block |= ((u32)scsicmd[4]); |
579 | qc->nsect = tf->nsect = scsicmd[4]; | 598 | |
580 | tf->lbal = scsicmd[3]; | ||
581 | tf->lbam = scsicmd[2]; | ||
582 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | ||
583 | |||
584 | VPRINTK("six-byte command\n"); | 599 | VPRINTK("six-byte command\n"); |
585 | return 0; | 600 | } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { |
601 | block |= ((u64)scsicmd[2]) << 56; | ||
602 | block |= ((u64)scsicmd[3]) << 48; | ||
603 | block |= ((u64)scsicmd[4]) << 40; | ||
604 | block |= ((u64)scsicmd[5]) << 32; | ||
605 | block |= ((u64)scsicmd[6]) << 24; | ||
606 | block |= ((u64)scsicmd[7]) << 16; | ||
607 | block |= ((u64)scsicmd[8]) << 8; | ||
608 | block |= ((u64)scsicmd[9]); | ||
609 | |||
610 | n_block |= ((u32)scsicmd[10]) << 24; | ||
611 | n_block |= ((u32)scsicmd[11]) << 16; | ||
612 | n_block |= ((u32)scsicmd[12]) << 8; | ||
613 | n_block |= ((u32)scsicmd[13]); | ||
614 | |||
615 | VPRINTK("sixteen-byte command\n"); | ||
616 | } else { | ||
617 | DPRINTK("no-byte command\n"); | ||
618 | return 1; | ||
586 | } | 619 | } |
587 | 620 | ||
588 | if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { | 621 | /* Check and compose ATA command */ |
589 | /* rule out impossible LBAs and sector counts */ | 622 | if (!n_block) |
590 | if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11]) | 623 | /* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */ |
591 | return 1; | 624 | return 1; |
592 | 625 | ||
626 | if (lba) { | ||
593 | if (lba48) { | 627 | if (lba48) { |
594 | tf->hob_nsect = scsicmd[12]; | 628 | /* The request -may- be too large for LBA48. */ |
595 | tf->hob_lbal = scsicmd[6]; | 629 | if ((block >> 48) || (n_block > 65536)) |
596 | tf->hob_lbam = scsicmd[5]; | ||
597 | tf->hob_lbah = scsicmd[4]; | ||
598 | |||
599 | qc->nsect = ((unsigned int)scsicmd[12] << 8) | | ||
600 | scsicmd[13]; | ||
601 | } else { | ||
602 | /* once again, filter out impossible non-zero values */ | ||
603 | if (scsicmd[4] || scsicmd[5] || scsicmd[12] || | ||
604 | (scsicmd[6] & 0xf0)) | ||
605 | return 1; | 630 | return 1; |
606 | 631 | ||
607 | /* stores LBA27:24 in lower 4 bits of device reg */ | 632 | tf->hob_nsect = (n_block >> 8) & 0xff; |
608 | tf->device |= scsicmd[6]; | 633 | |
634 | tf->hob_lbah = (block >> 40) & 0xff; | ||
635 | tf->hob_lbam = (block >> 32) & 0xff; | ||
636 | tf->hob_lbal = (block >> 24) & 0xff; | ||
637 | } else { | ||
638 | /* LBA28 */ | ||
639 | |||
640 | /* The request -may- be too large for LBA28. */ | ||
641 | if ((block >> 28) || (n_block > 256)) | ||
642 | return 1; | ||
609 | 643 | ||
610 | qc->nsect = scsicmd[13]; | 644 | tf->device |= (block >> 24) & 0xf; |
611 | } | 645 | } |
646 | |||
647 | qc->nsect = n_block; | ||
648 | tf->nsect = n_block & 0xff; | ||
612 | 649 | ||
613 | tf->nsect = scsicmd[13]; | 650 | tf->lbah = (block >> 16) & 0xff; |
614 | tf->lbal = scsicmd[9]; | 651 | tf->lbam = (block >> 8) & 0xff; |
615 | tf->lbam = scsicmd[8]; | 652 | tf->lbal = block & 0xff; |
616 | tf->lbah = scsicmd[7]; | ||
617 | 653 | ||
618 | VPRINTK("sixteen-byte command\n"); | 654 | tf->device |= ATA_LBA; |
619 | return 0; | 655 | } else { |
656 | /* CHS */ | ||
657 | u32 sect, head, cyl, track; | ||
658 | |||
659 | /* The request -may- be too large for CHS addressing. */ | ||
660 | if ((block >> 28) || (n_block > 256)) | ||
661 | return 1; | ||
662 | |||
663 | /* Convert LBA to CHS */ | ||
664 | track = (u32)block / dev->sectors; | ||
665 | cyl = track / dev->heads; | ||
666 | head = track % dev->heads; | ||
667 | sect = (u32)block % dev->sectors + 1; | ||
668 | |||
669 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", | ||
670 | (u32)block, track, cyl, head, sect); | ||
671 | |||
672 | /* Check whether the converted CHS can fit. | ||
673 | Cylinder: 0-65535 | ||
674 | Head: 0-15 | ||
675 | Sector: 1-255*/ | ||
676 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
677 | return 1; | ||
678 | |||
679 | qc->nsect = n_block; | ||
680 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
681 | tf->lbal = sect; | ||
682 | tf->lbam = cyl; | ||
683 | tf->lbah = cyl >> 8; | ||
684 | tf->device |= head; | ||
620 | } | 685 | } |
621 | 686 | ||
622 | DPRINTK("no-byte command\n"); | 687 | return 0; |
623 | return 1; | ||
624 | } | 688 | } |
625 | 689 | ||
626 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 690 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) |
@@ -1167,10 +1231,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, | |||
1167 | 1231 | ||
1168 | VPRINTK("ENTER\n"); | 1232 | VPRINTK("ENTER\n"); |
1169 | 1233 | ||
1170 | if (ata_id_has_lba48(args->id)) | 1234 | if (ata_id_has_lba(args->id)) { |
1171 | n_sectors = ata_id_u64(args->id, 100); | 1235 | if (ata_id_has_lba48(args->id)) |
1172 | else | 1236 | n_sectors = ata_id_u64(args->id, 100); |
1173 | n_sectors = ata_id_u32(args->id, 60); | 1237 | else |
1238 | n_sectors = ata_id_u32(args->id, 60); | ||
1239 | } else { | ||
1240 | /* CHS default translation */ | ||
1241 | n_sectors = args->id[1] * args->id[3] * args->id[6]; | ||
1242 | |||
1243 | if (ata_id_current_chs_valid(args->id)) | ||
1244 | /* CHS current translation */ | ||
1245 | n_sectors = ata_id_u32(args->id, 57); | ||
1246 | } | ||
1247 | |||
1174 | n_sectors--; /* ATA TotalUserSectors - 1 */ | 1248 | n_sectors--; /* ATA TotalUserSectors - 1 */ |
1175 | 1249 | ||
1176 | tmp = n_sectors; /* note: truncates, if lba48 */ | 1250 | tmp = n_sectors; /* note: truncates, if lba48 */ |
diff --git a/include/linux/ata.h b/include/linux/ata.h index f178894edd04..d8981402cd5b 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -125,6 +125,7 @@ enum { | |||
125 | ATA_CMD_PACKET = 0xA0, | 125 | ATA_CMD_PACKET = 0xA0, |
126 | ATA_CMD_VERIFY = 0x40, | 126 | ATA_CMD_VERIFY = 0x40, |
127 | ATA_CMD_VERIFY_EXT = 0x42, | 127 | ATA_CMD_VERIFY_EXT = 0x42, |
128 | ATA_CMD_INIT_DEV_PARAMS = 0x91, | ||
128 | 129 | ||
129 | /* SETFEATURES stuff */ | 130 | /* SETFEATURES stuff */ |
130 | SETFEATURES_XFER = 0x03, | 131 | SETFEATURES_XFER = 0x03, |
@@ -174,6 +175,7 @@ enum { | |||
174 | ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ | 175 | ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ |
175 | ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ | 176 | ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ |
176 | ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ | 177 | ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ |
178 | ATA_TFLAG_LBA = (1 << 4), /* enable LBA */ | ||
177 | }; | 179 | }; |
178 | 180 | ||
179 | enum ata_tf_protocols { | 181 | enum ata_tf_protocols { |
@@ -242,6 +244,18 @@ struct ata_taskfile { | |||
242 | ((u64) (id)[(n) + 1] << 16) | \ | 244 | ((u64) (id)[(n) + 1] << 16) | \ |
243 | ((u64) (id)[(n) + 0]) ) | 245 | ((u64) (id)[(n) + 0]) ) |
244 | 246 | ||
247 | static inline int ata_id_current_chs_valid(u16 *id) | ||
248 | { | ||
249 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command | ||
250 | has not been issued to the device then the values of | ||
251 | id[54] to id[56] are vendor specific. */ | ||
252 | return (id[53] & 0x01) && /* Current translation valid */ | ||
253 | id[54] && /* cylinders in current translation */ | ||
254 | id[55] && /* heads in current translation */ | ||
255 | id[55] <= 16 && | ||
256 | id[56]; /* sectors in current translation */ | ||
257 | } | ||
258 | |||
245 | static inline int atapi_cdb_len(u16 *dev_id) | 259 | static inline int atapi_cdb_len(u16 *dev_id) |
246 | { | 260 | { |
247 | u16 tmp = dev_id[0] & 0x3; | 261 | u16 tmp = dev_id[0] & 0x3; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 505160ab472b..bd0df84cfd87 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -95,6 +95,7 @@ enum { | |||
95 | ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ | 95 | ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ |
96 | ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ | 96 | ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ |
97 | ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ | 97 | ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ |
98 | ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */ | ||
98 | 99 | ||
99 | ATA_DEV_UNKNOWN = 0, /* unknown device */ | 100 | ATA_DEV_UNKNOWN = 0, /* unknown device */ |
100 | ATA_DEV_ATA = 1, /* ATA device */ | 101 | ATA_DEV_ATA = 1, /* ATA device */ |
@@ -278,6 +279,11 @@ struct ata_device { | |||
278 | u8 xfer_protocol; /* taskfile xfer protocol */ | 279 | u8 xfer_protocol; /* taskfile xfer protocol */ |
279 | u8 read_cmd; /* opcode to use on read */ | 280 | u8 read_cmd; /* opcode to use on read */ |
280 | u8 write_cmd; /* opcode to use on write */ | 281 | u8 write_cmd; /* opcode to use on write */ |
282 | |||
283 | /* for CHS addressing */ | ||
284 | u16 cylinders; /* Number of cylinders */ | ||
285 | u16 heads; /* Number of heads */ | ||
286 | u16 sectors; /* Number of sectors per track */ | ||
281 | }; | 287 | }; |
282 | 288 | ||
283 | struct ata_port { | 289 | struct ata_port { |