diff options
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r-- | drivers/scsi/libata-scsi.c | 291 |
1 files changed, 179 insertions, 112 deletions
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) { |