diff options
-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 36b401fee1f1..141de479caca 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); |
@@ -1117,7 +1118,7 @@ static inline void ata_dump_id(struct ata_device *dev) | |||
1117 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) | 1118 | static void ata_dev_identify(struct ata_port *ap, unsigned int device) |
1118 | { | 1119 | { |
1119 | struct ata_device *dev = &ap->device[device]; | 1120 | struct ata_device *dev = &ap->device[device]; |
1120 | unsigned int i; | 1121 | unsigned int major_version; |
1121 | u16 tmp; | 1122 | u16 tmp; |
1122 | unsigned long xfer_modes; | 1123 | unsigned long xfer_modes; |
1123 | u8 status; | 1124 | u8 status; |
@@ -1215,9 +1216,9 @@ retry: | |||
1215 | * common ATA, ATAPI feature tests | 1216 | * common ATA, ATAPI feature tests |
1216 | */ | 1217 | */ |
1217 | 1218 | ||
1218 | /* we require LBA and DMA support (bits 8 & 9 of word 49) */ | 1219 | /* we require DMA support (bits 8 of word 49) */ |
1219 | if (!ata_id_has_dma(dev->id) || !ata_id_has_lba(dev->id)) { | 1220 | if (!ata_id_has_dma(dev->id)) { |
1220 | printk(KERN_DEBUG "ata%u: no dma/lba\n", ap->id); | 1221 | printk(KERN_DEBUG "ata%u: no dma\n", ap->id); |
1221 | goto err_out_nosup; | 1222 | goto err_out_nosup; |
1222 | } | 1223 | } |
1223 | 1224 | ||
@@ -1237,32 +1238,69 @@ retry: | |||
1237 | if (!ata_id_is_ata(dev->id)) /* sanity check */ | 1238 | if (!ata_id_is_ata(dev->id)) /* sanity check */ |
1238 | goto err_out_nosup; | 1239 | goto err_out_nosup; |
1239 | 1240 | ||
1241 | /* get major version */ | ||
1240 | tmp = dev->id[ATA_ID_MAJOR_VER]; | 1242 | tmp = dev->id[ATA_ID_MAJOR_VER]; |
1241 | for (i = 14; i >= 1; i--) | 1243 | for (major_version = 14; major_version >= 1; major_version--) |
1242 | if (tmp & (1 << i)) | 1244 | if (tmp & (1 << major_version)) |
1243 | break; | 1245 | break; |
1244 | 1246 | ||
1245 | /* we require at least ATA-3 */ | 1247 | /* |
1246 | if (i < 3) { | 1248 | * The exact sequence expected by certain pre-ATA4 drives is: |
1247 | printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id); | 1249 | * SRST RESET |
1248 | goto err_out_nosup; | 1250 | * IDENTIFY |
1249 | } | 1251 | * INITIALIZE DEVICE PARAMETERS |
1252 | * anything else.. | ||
1253 | * Some drives were very specific about that exact sequence. | ||
1254 | */ | ||
1255 | if (major_version < 4 || (!ata_id_has_lba(dev->id))) | ||
1256 | ata_dev_init_params(ap, dev); | ||
1257 | |||
1258 | if (ata_id_has_lba(dev->id)) { | ||
1259 | dev->flags |= ATA_DFLAG_LBA; | ||
1260 | |||
1261 | if (ata_id_has_lba48(dev->id)) { | ||
1262 | dev->flags |= ATA_DFLAG_LBA48; | ||
1263 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1264 | } else { | ||
1265 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1266 | } | ||
1267 | |||
1268 | /* print device info to dmesg */ | ||
1269 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors:%s\n", | ||
1270 | ap->id, device, | ||
1271 | major_version, | ||
1272 | ata_mode_string(xfer_modes), | ||
1273 | (unsigned long long)dev->n_sectors, | ||
1274 | dev->flags & ATA_DFLAG_LBA48 ? " LBA48" : " LBA"); | ||
1275 | } else { | ||
1276 | /* CHS */ | ||
1277 | |||
1278 | /* Default translation */ | ||
1279 | dev->cylinders = dev->id[1]; | ||
1280 | dev->heads = dev->id[3]; | ||
1281 | dev->sectors = dev->id[6]; | ||
1282 | dev->n_sectors = dev->cylinders * dev->heads * dev->sectors; | ||
1283 | |||
1284 | if (ata_id_current_chs_valid(dev->id)) { | ||
1285 | /* Current CHS translation is valid. */ | ||
1286 | dev->cylinders = dev->id[54]; | ||
1287 | dev->heads = dev->id[55]; | ||
1288 | dev->sectors = dev->id[56]; | ||
1289 | |||
1290 | dev->n_sectors = ata_id_u32(dev->id, 57); | ||
1291 | } | ||
1292 | |||
1293 | /* print device info to dmesg */ | ||
1294 | printk(KERN_INFO "ata%u: dev %u ATA-%d, max %s, %Lu sectors: CHS %d/%d/%d\n", | ||
1295 | ap->id, device, | ||
1296 | major_version, | ||
1297 | ata_mode_string(xfer_modes), | ||
1298 | (unsigned long long)dev->n_sectors, | ||
1299 | (int)dev->cylinders, (int)dev->heads, (int)dev->sectors); | ||
1250 | 1300 | ||
1251 | if (ata_id_has_lba48(dev->id)) { | ||
1252 | dev->flags |= ATA_DFLAG_LBA48; | ||
1253 | dev->n_sectors = ata_id_u64(dev->id, 100); | ||
1254 | } else { | ||
1255 | dev->n_sectors = ata_id_u32(dev->id, 60); | ||
1256 | } | 1301 | } |
1257 | 1302 | ||
1258 | ap->host->max_cmd_len = 16; | 1303 | ap->host->max_cmd_len = 16; |
1259 | |||
1260 | /* print device info to dmesg */ | ||
1261 | printk(KERN_INFO "ata%u: dev %u ATA, max %s, %Lu sectors:%s\n", | ||
1262 | ap->id, device, | ||
1263 | ata_mode_string(xfer_modes), | ||
1264 | (unsigned long long)dev->n_sectors, | ||
1265 | dev->flags & ATA_DFLAG_LBA48 ? " lba48" : ""); | ||
1266 | } | 1304 | } |
1267 | 1305 | ||
1268 | /* ATAPI-specific feature tests */ | 1306 | /* ATAPI-specific feature tests */ |
@@ -2128,6 +2166,54 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) | |||
2128 | } | 2166 | } |
2129 | 2167 | ||
2130 | /** | 2168 | /** |
2169 | * ata_dev_init_params - Issue INIT DEV PARAMS command | ||
2170 | * @ap: Port associated with device @dev | ||
2171 | * @dev: Device to which command will be sent | ||
2172 | * | ||
2173 | * LOCKING: | ||
2174 | */ | ||
2175 | |||
2176 | static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) | ||
2177 | { | ||
2178 | DECLARE_COMPLETION(wait); | ||
2179 | struct ata_queued_cmd *qc; | ||
2180 | int rc; | ||
2181 | unsigned long flags; | ||
2182 | u16 sectors = dev->id[6]; | ||
2183 | u16 heads = dev->id[3]; | ||
2184 | |||
2185 | /* Number of sectors per track 1-255. Number of heads 1-16 */ | ||
2186 | if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16) | ||
2187 | return; | ||
2188 | |||
2189 | /* set up init dev params taskfile */ | ||
2190 | DPRINTK("init dev params \n"); | ||
2191 | |||
2192 | qc = ata_qc_new_init(ap, dev); | ||
2193 | BUG_ON(qc == NULL); | ||
2194 | |||
2195 | qc->tf.command = ATA_CMD_INIT_DEV_PARAMS; | ||
2196 | qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | ||
2197 | qc->tf.protocol = ATA_PROT_NODATA; | ||
2198 | qc->tf.nsect = sectors; | ||
2199 | qc->tf.device |= (heads - 1) & 0x0f; /* max head = num. of heads - 1 */ | ||
2200 | |||
2201 | qc->waiting = &wait; | ||
2202 | qc->complete_fn = ata_qc_complete_noop; | ||
2203 | |||
2204 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2205 | rc = ata_qc_issue(qc); | ||
2206 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2207 | |||
2208 | if (rc) | ||
2209 | ata_port_disable(ap); | ||
2210 | else | ||
2211 | wait_for_completion(&wait); | ||
2212 | |||
2213 | DPRINTK("EXIT\n"); | ||
2214 | } | ||
2215 | |||
2216 | /** | ||
2131 | * ata_sg_clean - Unmap DMA memory associated with command | 2217 | * ata_sg_clean - Unmap DMA memory associated with command |
2132 | * @qc: Command containing DMA memory to be released | 2218 | * @qc: Command containing DMA memory to be released |
2133 | * | 2219 | * |
@@ -3006,8 +3092,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, | |||
3006 | 3092 | ||
3007 | ata_tf_init(ap, &qc->tf, dev->devno); | 3093 | ata_tf_init(ap, &qc->tf, dev->devno); |
3008 | 3094 | ||
3009 | if (dev->flags & ATA_DFLAG_LBA48) | 3095 | if (dev->flags & ATA_DFLAG_LBA) { |
3010 | qc->tf.flags |= ATA_TFLAG_LBA48; | 3096 | qc->tf.flags |= ATA_TFLAG_LBA; |
3097 | |||
3098 | if (dev->flags & ATA_DFLAG_LBA48) | ||
3099 | qc->tf.flags |= ATA_TFLAG_LBA48; | ||
3100 | } | ||
3011 | } | 3101 | } |
3012 | 3102 | ||
3013 | return qc; | 3103 | return qc; |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 7a4adc4c8f09..5367c10e4db8 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -438,77 +438,107 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
438 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 438 | static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
439 | { | 439 | { |
440 | struct ata_taskfile *tf = &qc->tf; | 440 | struct ata_taskfile *tf = &qc->tf; |
441 | struct ata_device *dev = qc->dev; | ||
442 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
441 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 443 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
442 | u64 dev_sectors = qc->dev->n_sectors; | 444 | u64 dev_sectors = qc->dev->n_sectors; |
443 | u64 sect = 0; | 445 | u64 block = 0; |
444 | u32 n_sect = 0; | 446 | u32 n_block = 0; |
445 | 447 | ||
446 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 448 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
447 | tf->protocol = ATA_PROT_NODATA; | 449 | tf->protocol = ATA_PROT_NODATA; |
448 | tf->device |= ATA_LBA; | ||
449 | 450 | ||
450 | if (scsicmd[0] == VERIFY) { | 451 | if (scsicmd[0] == VERIFY) { |
451 | sect |= ((u64)scsicmd[2]) << 24; | 452 | block |= ((u64)scsicmd[2]) << 24; |
452 | sect |= ((u64)scsicmd[3]) << 16; | 453 | block |= ((u64)scsicmd[3]) << 16; |
453 | sect |= ((u64)scsicmd[4]) << 8; | 454 | block |= ((u64)scsicmd[4]) << 8; |
454 | sect |= ((u64)scsicmd[5]); | 455 | block |= ((u64)scsicmd[5]); |
455 | 456 | ||
456 | n_sect |= ((u32)scsicmd[7]) << 8; | 457 | n_block |= ((u32)scsicmd[7]) << 8; |
457 | n_sect |= ((u32)scsicmd[8]); | 458 | n_block |= ((u32)scsicmd[8]); |
458 | } | 459 | } |
459 | 460 | ||
460 | else if (scsicmd[0] == VERIFY_16) { | 461 | else if (scsicmd[0] == VERIFY_16) { |
461 | sect |= ((u64)scsicmd[2]) << 56; | 462 | block |= ((u64)scsicmd[2]) << 56; |
462 | sect |= ((u64)scsicmd[3]) << 48; | 463 | block |= ((u64)scsicmd[3]) << 48; |
463 | sect |= ((u64)scsicmd[4]) << 40; | 464 | block |= ((u64)scsicmd[4]) << 40; |
464 | sect |= ((u64)scsicmd[5]) << 32; | 465 | block |= ((u64)scsicmd[5]) << 32; |
465 | sect |= ((u64)scsicmd[6]) << 24; | 466 | block |= ((u64)scsicmd[6]) << 24; |
466 | sect |= ((u64)scsicmd[7]) << 16; | 467 | block |= ((u64)scsicmd[7]) << 16; |
467 | sect |= ((u64)scsicmd[8]) << 8; | 468 | block |= ((u64)scsicmd[8]) << 8; |
468 | sect |= ((u64)scsicmd[9]); | 469 | block |= ((u64)scsicmd[9]); |
469 | 470 | ||
470 | n_sect |= ((u32)scsicmd[10]) << 24; | 471 | n_block |= ((u32)scsicmd[10]) << 24; |
471 | n_sect |= ((u32)scsicmd[11]) << 16; | 472 | n_block |= ((u32)scsicmd[11]) << 16; |
472 | n_sect |= ((u32)scsicmd[12]) << 8; | 473 | n_block |= ((u32)scsicmd[12]) << 8; |
473 | n_sect |= ((u32)scsicmd[13]); | 474 | n_block |= ((u32)scsicmd[13]); |
474 | } | 475 | } |
475 | 476 | ||
476 | else | 477 | else |
477 | return 1; | 478 | return 1; |
478 | 479 | ||
479 | if (!n_sect) | 480 | if (!n_block) |
480 | return 1; | 481 | return 1; |
481 | if (sect >= dev_sectors) | 482 | if (block >= dev_sectors) |
482 | return 1; | 483 | return 1; |
483 | if ((sect + n_sect) > dev_sectors) | 484 | if ((block + n_block) > dev_sectors) |
484 | return 1; | 485 | return 1; |
485 | if (lba48) { | 486 | if (lba48) { |
486 | if (n_sect > (64 * 1024)) | 487 | if (n_block > (64 * 1024)) |
487 | return 1; | 488 | return 1; |
488 | } else { | 489 | } else { |
489 | if (n_sect > 256) | 490 | if (n_block > 256) |
490 | return 1; | 491 | return 1; |
491 | } | 492 | } |
492 | 493 | ||
493 | if (lba48) { | 494 | if (lba) { |
494 | tf->command = ATA_CMD_VERIFY_EXT; | 495 | if (lba48) { |
496 | tf->command = ATA_CMD_VERIFY_EXT; | ||
495 | 497 | ||
496 | tf->hob_nsect = (n_sect >> 8) & 0xff; | 498 | tf->hob_nsect = (n_block >> 8) & 0xff; |
497 | 499 | ||
498 | tf->hob_lbah = (sect >> 40) & 0xff; | 500 | tf->hob_lbah = (block >> 40) & 0xff; |
499 | tf->hob_lbam = (sect >> 32) & 0xff; | 501 | tf->hob_lbam = (block >> 32) & 0xff; |
500 | tf->hob_lbal = (sect >> 24) & 0xff; | 502 | tf->hob_lbal = (block >> 24) & 0xff; |
501 | } else { | 503 | } else { |
502 | tf->command = ATA_CMD_VERIFY; | 504 | tf->command = ATA_CMD_VERIFY; |
503 | 505 | ||
504 | tf->device |= (sect >> 24) & 0xf; | 506 | tf->device |= (block >> 24) & 0xf; |
505 | } | 507 | } |
508 | |||
509 | tf->nsect = n_block & 0xff; | ||
506 | 510 | ||
507 | tf->nsect = n_sect & 0xff; | 511 | tf->lbah = (block >> 16) & 0xff; |
512 | tf->lbam = (block >> 8) & 0xff; | ||
513 | tf->lbal = block & 0xff; | ||
508 | 514 | ||
509 | tf->lbah = (sect >> 16) & 0xff; | 515 | tf->device |= ATA_LBA; |
510 | tf->lbam = (sect >> 8) & 0xff; | 516 | } else { |
511 | tf->lbal = sect & 0xff; | 517 | /* CHS */ |
518 | u32 sect, head, cyl, track; | ||
519 | |||
520 | /* Convert LBA to CHS */ | ||
521 | track = (u32)block / dev->sectors; | ||
522 | cyl = track / dev->heads; | ||
523 | head = track % dev->heads; | ||
524 | sect = (u32)block % dev->sectors + 1; | ||
525 | |||
526 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", (u32)block, track, cyl, head, sect); | ||
527 | |||
528 | /* Check whether the converted CHS can fit. | ||
529 | Cylinder: 0-65535 | ||
530 | Head: 0-15 | ||
531 | Sector: 1-255*/ | ||
532 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
533 | return 1; | ||
534 | |||
535 | tf->command = ATA_CMD_VERIFY; | ||
536 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
537 | tf->lbal = sect; | ||
538 | tf->lbam = cyl; | ||
539 | tf->lbah = cyl >> 8; | ||
540 | tf->device |= head; | ||
541 | } | ||
512 | 542 | ||
513 | return 0; | 543 | return 0; |
514 | } | 544 | } |
@@ -536,11 +566,14 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
536 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | 566 | static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) |
537 | { | 567 | { |
538 | struct ata_taskfile *tf = &qc->tf; | 568 | struct ata_taskfile *tf = &qc->tf; |
569 | struct ata_device *dev = qc->dev; | ||
570 | unsigned int lba = tf->flags & ATA_TFLAG_LBA; | ||
539 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; | 571 | unsigned int lba48 = tf->flags & ATA_TFLAG_LBA48; |
572 | u64 block = 0; | ||
573 | u32 n_block = 0; | ||
540 | 574 | ||
541 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; | 575 | tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; |
542 | tf->protocol = qc->dev->xfer_protocol; | 576 | tf->protocol = qc->dev->xfer_protocol; |
543 | tf->device |= ATA_LBA; | ||
544 | 577 | ||
545 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || | 578 | if (scsicmd[0] == READ_10 || scsicmd[0] == READ_6 || |
546 | scsicmd[0] == READ_16) { | 579 | scsicmd[0] == READ_16) { |
@@ -550,80 +583,111 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
550 | tf->flags |= ATA_TFLAG_WRITE; | 583 | tf->flags |= ATA_TFLAG_WRITE; |
551 | } | 584 | } |
552 | 585 | ||
586 | /* Calculate the SCSI LBA and transfer length. */ | ||
553 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { | 587 | if (scsicmd[0] == READ_10 || scsicmd[0] == WRITE_10) { |
554 | if (lba48) { | 588 | block |= ((u64)scsicmd[2]) << 24; |
555 | tf->hob_nsect = scsicmd[7]; | 589 | block |= ((u64)scsicmd[3]) << 16; |
556 | tf->hob_lbal = scsicmd[2]; | 590 | block |= ((u64)scsicmd[4]) << 8; |
557 | 591 | block |= ((u64)scsicmd[5]); | |
558 | qc->nsect = ((unsigned int)scsicmd[7] << 8) | | ||
559 | scsicmd[8]; | ||
560 | } else { | ||
561 | /* if we don't support LBA48 addressing, the request | ||
562 | * -may- be too large. */ | ||
563 | if ((scsicmd[2] & 0xf0) || scsicmd[7]) | ||
564 | return 1; | ||
565 | |||
566 | /* stores LBA27:24 in lower 4 bits of device reg */ | ||
567 | tf->device |= scsicmd[2]; | ||
568 | 592 | ||
569 | qc->nsect = scsicmd[8]; | 593 | n_block |= ((u32)scsicmd[7]) << 8; |
570 | } | 594 | n_block |= ((u32)scsicmd[8]); |
571 | |||
572 | tf->nsect = scsicmd[8]; | ||
573 | tf->lbal = scsicmd[5]; | ||
574 | tf->lbam = scsicmd[4]; | ||
575 | tf->lbah = scsicmd[3]; | ||
576 | 595 | ||
577 | VPRINTK("ten-byte command\n"); | 596 | VPRINTK("ten-byte command\n"); |
578 | return 0; | 597 | } else if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
579 | } | 598 | block |= ((u64)scsicmd[2]) << 8; |
580 | 599 | block |= ((u64)scsicmd[3]); | |
581 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 600 | n_block |= ((u32)scsicmd[4]); |
582 | qc->nsect = tf->nsect = scsicmd[4]; | 601 | |
583 | tf->lbal = scsicmd[3]; | ||
584 | tf->lbam = scsicmd[2]; | ||
585 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | ||
586 | |||
587 | VPRINTK("six-byte command\n"); | 602 | VPRINTK("six-byte command\n"); |
588 | return 0; | 603 | } else if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { |
604 | block |= ((u64)scsicmd[2]) << 56; | ||
605 | block |= ((u64)scsicmd[3]) << 48; | ||
606 | block |= ((u64)scsicmd[4]) << 40; | ||
607 | block |= ((u64)scsicmd[5]) << 32; | ||
608 | block |= ((u64)scsicmd[6]) << 24; | ||
609 | block |= ((u64)scsicmd[7]) << 16; | ||
610 | block |= ((u64)scsicmd[8]) << 8; | ||
611 | block |= ((u64)scsicmd[9]); | ||
612 | |||
613 | n_block |= ((u32)scsicmd[10]) << 24; | ||
614 | n_block |= ((u32)scsicmd[11]) << 16; | ||
615 | n_block |= ((u32)scsicmd[12]) << 8; | ||
616 | n_block |= ((u32)scsicmd[13]); | ||
617 | |||
618 | VPRINTK("sixteen-byte command\n"); | ||
619 | } else { | ||
620 | DPRINTK("no-byte command\n"); | ||
621 | return 1; | ||
589 | } | 622 | } |
590 | 623 | ||
591 | if (scsicmd[0] == READ_16 || scsicmd[0] == WRITE_16) { | 624 | /* Check and compose ATA command */ |
592 | /* rule out impossible LBAs and sector counts */ | 625 | if (!n_block) |
593 | if (scsicmd[2] || scsicmd[3] || scsicmd[10] || scsicmd[11]) | 626 | /* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */ |
594 | return 1; | 627 | return 1; |
595 | 628 | ||
629 | if (lba) { | ||
596 | if (lba48) { | 630 | if (lba48) { |
597 | tf->hob_nsect = scsicmd[12]; | 631 | /* The request -may- be too large for LBA48. */ |
598 | tf->hob_lbal = scsicmd[6]; | 632 | if ((block >> 48) || (n_block > 65536)) |
599 | tf->hob_lbam = scsicmd[5]; | ||
600 | tf->hob_lbah = scsicmd[4]; | ||
601 | |||
602 | qc->nsect = ((unsigned int)scsicmd[12] << 8) | | ||
603 | scsicmd[13]; | ||
604 | } else { | ||
605 | /* once again, filter out impossible non-zero values */ | ||
606 | if (scsicmd[4] || scsicmd[5] || scsicmd[12] || | ||
607 | (scsicmd[6] & 0xf0)) | ||
608 | return 1; | 633 | return 1; |
609 | 634 | ||
610 | /* stores LBA27:24 in lower 4 bits of device reg */ | 635 | tf->hob_nsect = (n_block >> 8) & 0xff; |
611 | tf->device |= scsicmd[6]; | 636 | |
637 | tf->hob_lbah = (block >> 40) & 0xff; | ||
638 | tf->hob_lbam = (block >> 32) & 0xff; | ||
639 | tf->hob_lbal = (block >> 24) & 0xff; | ||
640 | } else { | ||
641 | /* LBA28 */ | ||
642 | |||
643 | /* The request -may- be too large for LBA28. */ | ||
644 | if ((block >> 28) || (n_block > 256)) | ||
645 | return 1; | ||
612 | 646 | ||
613 | qc->nsect = scsicmd[13]; | 647 | tf->device |= (block >> 24) & 0xf; |
614 | } | 648 | } |
649 | |||
650 | qc->nsect = n_block; | ||
651 | tf->nsect = n_block & 0xff; | ||
615 | 652 | ||
616 | tf->nsect = scsicmd[13]; | 653 | tf->lbah = (block >> 16) & 0xff; |
617 | tf->lbal = scsicmd[9]; | 654 | tf->lbam = (block >> 8) & 0xff; |
618 | tf->lbam = scsicmd[8]; | 655 | tf->lbal = block & 0xff; |
619 | tf->lbah = scsicmd[7]; | ||
620 | 656 | ||
621 | VPRINTK("sixteen-byte command\n"); | 657 | tf->device |= ATA_LBA; |
622 | return 0; | 658 | } else { |
659 | /* CHS */ | ||
660 | u32 sect, head, cyl, track; | ||
661 | |||
662 | /* The request -may- be too large for CHS addressing. */ | ||
663 | if ((block >> 28) || (n_block > 256)) | ||
664 | return 1; | ||
665 | |||
666 | /* Convert LBA to CHS */ | ||
667 | track = (u32)block / dev->sectors; | ||
668 | cyl = track / dev->heads; | ||
669 | head = track % dev->heads; | ||
670 | sect = (u32)block % dev->sectors + 1; | ||
671 | |||
672 | DPRINTK("block[%u] track[%u] cyl[%u] head[%u] sect[%u] \n", | ||
673 | (u32)block, track, cyl, head, sect); | ||
674 | |||
675 | /* Check whether the converted CHS can fit. | ||
676 | Cylinder: 0-65535 | ||
677 | Head: 0-15 | ||
678 | Sector: 1-255*/ | ||
679 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | ||
680 | return 1; | ||
681 | |||
682 | qc->nsect = n_block; | ||
683 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | ||
684 | tf->lbal = sect; | ||
685 | tf->lbam = cyl; | ||
686 | tf->lbah = cyl >> 8; | ||
687 | tf->device |= head; | ||
623 | } | 688 | } |
624 | 689 | ||
625 | DPRINTK("no-byte command\n"); | 690 | return 0; |
626 | return 1; | ||
627 | } | 691 | } |
628 | 692 | ||
629 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 693 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) |
@@ -1170,10 +1234,20 @@ unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, | |||
1170 | 1234 | ||
1171 | VPRINTK("ENTER\n"); | 1235 | VPRINTK("ENTER\n"); |
1172 | 1236 | ||
1173 | if (ata_id_has_lba48(args->id)) | 1237 | if (ata_id_has_lba(args->id)) { |
1174 | n_sectors = ata_id_u64(args->id, 100); | 1238 | if (ata_id_has_lba48(args->id)) |
1175 | else | 1239 | n_sectors = ata_id_u64(args->id, 100); |
1176 | n_sectors = ata_id_u32(args->id, 60); | 1240 | else |
1241 | n_sectors = ata_id_u32(args->id, 60); | ||
1242 | } else { | ||
1243 | /* CHS default translation */ | ||
1244 | n_sectors = args->id[1] * args->id[3] * args->id[6]; | ||
1245 | |||
1246 | if (ata_id_current_chs_valid(args->id)) | ||
1247 | /* CHS current translation */ | ||
1248 | n_sectors = ata_id_u32(args->id, 57); | ||
1249 | } | ||
1250 | |||
1177 | n_sectors--; /* ATA TotalUserSectors - 1 */ | 1251 | n_sectors--; /* ATA TotalUserSectors - 1 */ |
1178 | 1252 | ||
1179 | tmp = n_sectors; /* note: truncates, if lba48 */ | 1253 | tmp = n_sectors; /* note: truncates, if lba48 */ |
diff --git a/include/linux/ata.h b/include/linux/ata.h index ca5fcadf9981..6962e26fc6df 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 { |
@@ -243,6 +245,18 @@ struct ata_taskfile { | |||
243 | ((u64) (id)[(n) + 1] << 16) | \ | 245 | ((u64) (id)[(n) + 1] << 16) | \ |
244 | ((u64) (id)[(n) + 0]) ) | 246 | ((u64) (id)[(n) + 0]) ) |
245 | 247 | ||
248 | static inline int ata_id_current_chs_valid(u16 *id) | ||
249 | { | ||
250 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command | ||
251 | has not been issued to the device then the values of | ||
252 | id[54] to id[56] are vendor specific. */ | ||
253 | return (id[53] & 0x01) && /* Current translation valid */ | ||
254 | id[54] && /* cylinders in current translation */ | ||
255 | id[55] && /* heads in current translation */ | ||
256 | id[55] <= 16 && | ||
257 | id[56]; /* sectors in current translation */ | ||
258 | } | ||
259 | |||
246 | static inline int atapi_cdb_len(u16 *dev_id) | 260 | static inline int atapi_cdb_len(u16 *dev_id) |
247 | { | 261 | { |
248 | u16 tmp = dev_id[0] & 0x3; | 262 | u16 tmp = dev_id[0] & 0x3; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6cd9ba63563b..973090be7fc4 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 { |