aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
authorAlbert Lee <albertcc@tw.ibm.com>2005-05-12 15:29:42 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-05-12 15:29:42 -0400
commit8bf62ecee58360749c5f0e68bc97d5e02a6816b1 (patch)
treea3da6e695fc5a71ac7f3246707380a9ac22f6402 /drivers/scsi/libata-scsi.c
parent88d7bd8cb9eb8d64bf7997600b0d64f7834047c5 (diff)
[libata] C/H/S support, for older devices
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c280
1 files changed, 177 insertions, 103 deletions
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)
435static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) 435static 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)
533static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) 563static 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
626static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) 690static 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 */