diff options
| -rw-r--r-- | drivers/scsi/libata-scsi.c | 184 | ||||
| -rw-r--r-- | drivers/scsi/libata.h | 10 |
2 files changed, 121 insertions, 73 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index bca9a5016b17..c64169ca7ff0 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
| @@ -49,6 +49,14 @@ static struct ata_device * | |||
| 49 | ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev); | 49 | ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev); |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | static void ata_scsi_invalid_field(struct scsi_cmnd *cmd, | ||
| 53 | void (*done)(struct scsi_cmnd *)) | ||
| 54 | { | ||
| 55 | ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 56 | /* "Invalid field in cbd" */ | ||
| 57 | done(cmd); | ||
| 58 | } | ||
| 59 | |||
| 52 | /** | 60 | /** |
| 53 | * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. | 61 | * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. |
| 54 | * @sdev: SCSI device for which BIOS geometry is to be determined | 62 | * @sdev: SCSI device for which BIOS geometry is to be determined |
| @@ -182,7 +190,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 182 | { | 190 | { |
| 183 | struct scsi_cmnd *cmd = qc->scsicmd; | 191 | struct scsi_cmnd *cmd = qc->scsicmd; |
| 184 | u8 err = 0; | 192 | u8 err = 0; |
| 185 | unsigned char *sb = cmd->sense_buffer; | ||
| 186 | /* Based on the 3ware driver translation table */ | 193 | /* Based on the 3ware driver translation table */ |
| 187 | static unsigned char sense_table[][4] = { | 194 | static unsigned char sense_table[][4] = { |
| 188 | /* BBD|ECC|ID|MAR */ | 195 | /* BBD|ECC|ID|MAR */ |
| @@ -225,8 +232,6 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 225 | }; | 232 | }; |
| 226 | int i = 0; | 233 | int i = 0; |
| 227 | 234 | ||
| 228 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | ||
| 229 | |||
| 230 | /* | 235 | /* |
| 231 | * Is this an error we can process/parse | 236 | * Is this an error we can process/parse |
| 232 | */ | 237 | */ |
| @@ -281,11 +286,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 281 | /* Look for best matches first */ | 286 | /* Look for best matches first */ |
| 282 | if((sense_table[i][0] & err) == sense_table[i][0]) | 287 | if((sense_table[i][0] & err) == sense_table[i][0]) |
| 283 | { | 288 | { |
| 284 | sb[0] = 0x70; | 289 | ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */, |
| 285 | sb[2] = sense_table[i][1]; | 290 | sense_table[i][2] /* asc */, |
| 286 | sb[7] = 0x0a; | 291 | sense_table[i][3] /* ascq */ ); |
| 287 | sb[12] = sense_table[i][2]; | ||
| 288 | sb[13] = sense_table[i][3]; | ||
| 289 | return; | 292 | return; |
| 290 | } | 293 | } |
| 291 | i++; | 294 | i++; |
| @@ -300,11 +303,9 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 300 | { | 303 | { |
| 301 | if(stat_table[i][0] & drv_stat) | 304 | if(stat_table[i][0] & drv_stat) |
| 302 | { | 305 | { |
| 303 | sb[0] = 0x70; | 306 | ata_scsi_set_sense(cmd, sense_table[i][1] /* sk */, |
| 304 | sb[2] = stat_table[i][1]; | 307 | sense_table[i][2] /* asc */, |
| 305 | sb[7] = 0x0a; | 308 | sense_table[i][3] /* ascq */ ); |
| 306 | sb[12] = stat_table[i][2]; | ||
| 307 | sb[13] = stat_table[i][3]; | ||
| 308 | return; | 309 | return; |
| 309 | } | 310 | } |
| 310 | i++; | 311 | i++; |
| @@ -313,15 +314,12 @@ void ata_to_sense_error(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 313 | printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat); | 314 | printk(KERN_ERR "ata%u: called with no error (%02X)!\n", qc->ap->id, drv_stat); |
| 314 | /* additional-sense-code[-qualifier] */ | 315 | /* additional-sense-code[-qualifier] */ |
| 315 | 316 | ||
| 316 | sb[0] = 0x70; | ||
| 317 | sb[2] = MEDIUM_ERROR; | ||
| 318 | sb[7] = 0x0A; | ||
| 319 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { | 317 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) { |
| 320 | sb[12] = 0x11; /* "unrecovered read error" */ | 318 | ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0x11, 0x4); |
| 321 | sb[13] = 0x04; | 319 | /* "unrecovered read error" */ |
| 322 | } else { | 320 | } else { |
| 323 | sb[12] = 0x0C; /* "write error - */ | 321 | ata_scsi_set_sense(cmd, MEDIUM_ERROR, 0xc, 0x2); |
| 324 | sb[13] = 0x02; /* auto-reallocation failed" */ | 322 | /* "write error - auto-reallocation failed" */ |
| 325 | } | 323 | } |
| 326 | } | 324 | } |
| 327 | 325 | ||
| @@ -430,9 +428,9 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | |||
| 430 | ; /* ignore IMMED bit, violates sat-r05 */ | 428 | ; /* ignore IMMED bit, violates sat-r05 */ |
| 431 | } | 429 | } |
| 432 | if (scsicmd[4] & 0x2) | 430 | if (scsicmd[4] & 0x2) |
| 433 | return 1; /* LOEJ bit set not supported */ | 431 | goto invalid_fld; /* LOEJ bit set not supported */ |
| 434 | if (((scsicmd[4] >> 4) & 0xf) != 0) | 432 | if (((scsicmd[4] >> 4) & 0xf) != 0) |
| 435 | return 1; /* power conditions not supported */ | 433 | goto invalid_fld; /* power conditions not supported */ |
| 436 | if (scsicmd[4] & 0x1) { | 434 | if (scsicmd[4] & 0x1) { |
| 437 | tf->nsect = 1; /* 1 sector, lba=0 */ | 435 | tf->nsect = 1; /* 1 sector, lba=0 */ |
| 438 | 436 | ||
| @@ -464,6 +462,11 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | |||
| 464 | */ | 462 | */ |
| 465 | 463 | ||
| 466 | return 0; | 464 | return 0; |
| 465 | |||
| 466 | invalid_fld: | ||
| 467 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 468 | /* "Invalid field in cbd" */ | ||
| 469 | return 1; | ||
| 467 | } | 470 | } |
| 468 | 471 | ||
| 469 | 472 | ||
| @@ -623,20 +626,20 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 623 | else if (scsicmd[0] == VERIFY_16) | 626 | else if (scsicmd[0] == VERIFY_16) |
| 624 | scsi_16_lba_len(scsicmd, &block, &n_block); | 627 | scsi_16_lba_len(scsicmd, &block, &n_block); |
| 625 | else | 628 | else |
| 626 | return 1; | 629 | goto invalid_fld; |
| 627 | 630 | ||
| 628 | if (!n_block) | 631 | if (!n_block) |
| 629 | return 1; | 632 | goto nothing_to_do; |
| 630 | if (block >= dev_sectors) | 633 | if (block >= dev_sectors) |
| 631 | return 1; | 634 | goto out_of_range; |
| 632 | if ((block + n_block) > dev_sectors) | 635 | if ((block + n_block) > dev_sectors) |
| 633 | return 1; | 636 | goto out_of_range; |
| 634 | if (lba48) { | 637 | if (lba48) { |
| 635 | if (n_block > (64 * 1024)) | 638 | if (n_block > (64 * 1024)) |
| 636 | return 1; | 639 | goto invalid_fld; |
| 637 | } else { | 640 | } else { |
| 638 | if (n_block > 256) | 641 | if (n_block > 256) |
| 639 | return 1; | 642 | goto invalid_fld; |
| 640 | } | 643 | } |
| 641 | 644 | ||
| 642 | if (lba) { | 645 | if (lba) { |
| @@ -679,7 +682,7 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 679 | Head: 0-15 | 682 | Head: 0-15 |
| 680 | Sector: 1-255*/ | 683 | Sector: 1-255*/ |
| 681 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | 684 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) |
| 682 | return 1; | 685 | goto out_of_range; |
| 683 | 686 | ||
| 684 | tf->command = ATA_CMD_VERIFY; | 687 | tf->command = ATA_CMD_VERIFY; |
| 685 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | 688 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ |
| @@ -690,6 +693,20 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 690 | } | 693 | } |
| 691 | 694 | ||
| 692 | return 0; | 695 | return 0; |
| 696 | |||
| 697 | invalid_fld: | ||
| 698 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 699 | /* "Invalid field in cbd" */ | ||
| 700 | return 1; | ||
| 701 | |||
| 702 | out_of_range: | ||
| 703 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); | ||
| 704 | /* "Logical Block Address out of range" */ | ||
| 705 | return 1; | ||
| 706 | |||
| 707 | nothing_to_do: | ||
| 708 | qc->scsicmd->result = SAM_STAT_GOOD; | ||
| 709 | return 1; | ||
| 693 | } | 710 | } |
| 694 | 711 | ||
| 695 | /** | 712 | /** |
| @@ -754,7 +771,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 754 | break; | 771 | break; |
| 755 | default: | 772 | default: |
| 756 | DPRINTK("no-byte command\n"); | 773 | DPRINTK("no-byte command\n"); |
| 757 | return 1; | 774 | goto invalid_fld; |
| 758 | } | 775 | } |
| 759 | 776 | ||
| 760 | /* Check and compose ATA command */ | 777 | /* Check and compose ATA command */ |
| @@ -764,13 +781,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 764 | * However, for ATA R/W commands, sector count 0 means | 781 | * However, for ATA R/W commands, sector count 0 means |
| 765 | * 256 or 65536 sectors, not 0 sectors as in SCSI. | 782 | * 256 or 65536 sectors, not 0 sectors as in SCSI. |
| 766 | */ | 783 | */ |
| 767 | return 1; | 784 | goto nothing_to_do; |
| 768 | 785 | ||
| 769 | if (lba) { | 786 | if (lba) { |
| 770 | if (lba48) { | 787 | if (lba48) { |
| 771 | /* The request -may- be too large for LBA48. */ | 788 | /* The request -may- be too large for LBA48. */ |
| 772 | if ((block >> 48) || (n_block > 65536)) | 789 | if ((block >> 48) || (n_block > 65536)) |
| 773 | return 1; | 790 | goto out_of_range; |
| 774 | 791 | ||
| 775 | tf->hob_nsect = (n_block >> 8) & 0xff; | 792 | tf->hob_nsect = (n_block >> 8) & 0xff; |
| 776 | 793 | ||
| @@ -782,7 +799,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 782 | 799 | ||
| 783 | /* The request -may- be too large for LBA28. */ | 800 | /* The request -may- be too large for LBA28. */ |
| 784 | if ((block >> 28) || (n_block > 256)) | 801 | if ((block >> 28) || (n_block > 256)) |
| 785 | return 1; | 802 | goto out_of_range; |
| 786 | 803 | ||
| 787 | tf->device |= (block >> 24) & 0xf; | 804 | tf->device |= (block >> 24) & 0xf; |
| 788 | } | 805 | } |
| @@ -801,7 +818,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 801 | 818 | ||
| 802 | /* The request -may- be too large for CHS addressing. */ | 819 | /* The request -may- be too large for CHS addressing. */ |
| 803 | if ((block >> 28) || (n_block > 256)) | 820 | if ((block >> 28) || (n_block > 256)) |
| 804 | return 1; | 821 | goto out_of_range; |
| 805 | 822 | ||
| 806 | /* Convert LBA to CHS */ | 823 | /* Convert LBA to CHS */ |
| 807 | track = (u32)block / dev->sectors; | 824 | track = (u32)block / dev->sectors; |
| @@ -817,7 +834,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 817 | Head: 0-15 | 834 | Head: 0-15 |
| 818 | Sector: 1-255*/ | 835 | Sector: 1-255*/ |
| 819 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) | 836 | if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) |
| 820 | return 1; | 837 | goto out_of_range; |
| 821 | 838 | ||
| 822 | qc->nsect = n_block; | 839 | qc->nsect = n_block; |
| 823 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ | 840 | tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ |
| @@ -828,6 +845,20 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
| 828 | } | 845 | } |
| 829 | 846 | ||
| 830 | return 0; | 847 | return 0; |
| 848 | |||
| 849 | invalid_fld: | ||
| 850 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 851 | /* "Invalid field in cbd" */ | ||
| 852 | return 1; | ||
| 853 | |||
| 854 | out_of_range: | ||
| 855 | ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x21, 0x0); | ||
| 856 | /* "Logical Block Address out of range" */ | ||
| 857 | return 1; | ||
| 858 | |||
| 859 | nothing_to_do: | ||
| 860 | qc->scsicmd->result = SAM_STAT_GOOD; | ||
| 861 | return 1; | ||
| 831 | } | 862 | } |
| 832 | 863 | ||
| 833 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | 864 | static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) |
| @@ -859,6 +890,12 @@ static int ata_scsi_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
| 859 | * This function sets up an ata_queued_cmd structure for the | 890 | * This function sets up an ata_queued_cmd structure for the |
| 860 | * SCSI command, and sends that ata_queued_cmd to the hardware. | 891 | * SCSI command, and sends that ata_queued_cmd to the hardware. |
| 861 | * | 892 | * |
| 893 | * The xlat_func argument (actor) returns 0 if ready to execute | ||
| 894 | * ATA command, else 1 to finish translation. If 1 is returned | ||
| 895 | * then cmd->result (and possibly cmd->sense_buffer) are assumed | ||
| 896 | * to be set reflecting an error condition or clean (early) | ||
| 897 | * termination. | ||
| 898 | * | ||
| 862 | * LOCKING: | 899 | * LOCKING: |
| 863 | * spin_lock_irqsave(host_set lock) | 900 | * spin_lock_irqsave(host_set lock) |
| 864 | */ | 901 | */ |
| @@ -875,7 +912,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, | |||
| 875 | 912 | ||
| 876 | qc = ata_scsi_qc_new(ap, dev, cmd, done); | 913 | qc = ata_scsi_qc_new(ap, dev, cmd, done); |
| 877 | if (!qc) | 914 | if (!qc) |
| 878 | return; | 915 | goto err_mem; |
| 879 | 916 | ||
| 880 | /* data is present; dma-map it */ | 917 | /* data is present; dma-map it */ |
| 881 | if (cmd->sc_data_direction == DMA_FROM_DEVICE || | 918 | if (cmd->sc_data_direction == DMA_FROM_DEVICE || |
| @@ -883,7 +920,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, | |||
| 883 | if (unlikely(cmd->request_bufflen < 1)) { | 920 | if (unlikely(cmd->request_bufflen < 1)) { |
| 884 | printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", | 921 | printk(KERN_WARNING "ata%u(%u): WARNING: zero len r/w req\n", |
| 885 | ap->id, dev->devno); | 922 | ap->id, dev->devno); |
| 886 | goto err_out; | 923 | goto err_did; |
| 887 | } | 924 | } |
| 888 | 925 | ||
| 889 | if (cmd->use_sg) | 926 | if (cmd->use_sg) |
| @@ -898,19 +935,28 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev, | |||
| 898 | qc->complete_fn = ata_scsi_qc_complete; | 935 | qc->complete_fn = ata_scsi_qc_complete; |
| 899 | 936 | ||
| 900 | if (xlat_func(qc, scsicmd)) | 937 | if (xlat_func(qc, scsicmd)) |
| 901 | goto err_out; | 938 | goto early_finish; |
| 902 | 939 | ||
| 903 | /* select device, send command to hardware */ | 940 | /* select device, send command to hardware */ |
| 904 | if (ata_qc_issue(qc)) | 941 | if (ata_qc_issue(qc)) |
| 905 | goto err_out; | 942 | goto err_did; |
| 906 | 943 | ||
| 907 | VPRINTK("EXIT\n"); | 944 | VPRINTK("EXIT\n"); |
| 908 | return; | 945 | return; |
| 909 | 946 | ||
| 910 | err_out: | 947 | early_finish: |
| 948 | ata_qc_free(qc); | ||
| 949 | done(cmd); | ||
| 950 | DPRINTK("EXIT - early finish (good or error)\n"); | ||
| 951 | return; | ||
| 952 | |||
| 953 | err_did: | ||
| 911 | ata_qc_free(qc); | 954 | ata_qc_free(qc); |
| 912 | ata_bad_cdb(cmd, done); | 955 | err_mem: |
| 913 | DPRINTK("EXIT - badcmd\n"); | 956 | cmd->result = (DID_ERROR << 16); |
| 957 | done(cmd); | ||
| 958 | DPRINTK("EXIT - internal\n"); | ||
| 959 | return; | ||
| 914 | } | 960 | } |
| 915 | 961 | ||
| 916 | /** | 962 | /** |
| @@ -977,7 +1023,8 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, u8 *buf) | |||
| 977 | * Mapping the response buffer, calling the command's handler, | 1023 | * Mapping the response buffer, calling the command's handler, |
| 978 | * and handling the handler's return value. This return value | 1024 | * and handling the handler's return value. This return value |
| 979 | * indicates whether the handler wishes the SCSI command to be | 1025 | * indicates whether the handler wishes the SCSI command to be |
| 980 | * completed successfully, or not. | 1026 | * completed successfully (0), or not (in which case cmd->result |
| 1027 | * and sense buffer are assumed to be set). | ||
| 981 | * | 1028 | * |
| 982 | * LOCKING: | 1029 | * LOCKING: |
| 983 | * spin_lock_irqsave(host_set lock) | 1030 | * spin_lock_irqsave(host_set lock) |
| @@ -996,12 +1043,9 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | |||
| 996 | rc = actor(args, rbuf, buflen); | 1043 | rc = actor(args, rbuf, buflen); |
| 997 | ata_scsi_rbuf_put(cmd, rbuf); | 1044 | ata_scsi_rbuf_put(cmd, rbuf); |
| 998 | 1045 | ||
| 999 | if (rc) | 1046 | if (rc == 0) |
| 1000 | ata_bad_cdb(cmd, args->done); | ||
| 1001 | else { | ||
| 1002 | cmd->result = SAM_STAT_GOOD; | 1047 | cmd->result = SAM_STAT_GOOD; |
| 1003 | args->done(cmd); | 1048 | args->done(cmd); |
| 1004 | } | ||
| 1005 | } | 1049 | } |
| 1006 | 1050 | ||
| 1007 | /** | 1051 | /** |
| @@ -1307,8 +1351,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
| 1307 | * in the same manner) | 1351 | * in the same manner) |
| 1308 | */ | 1352 | */ |
| 1309 | page_control = scsicmd[2] >> 6; | 1353 | page_control = scsicmd[2] >> 6; |
| 1310 | if ((page_control != 0) && (page_control != 3)) | 1354 | switch (page_control) { |
| 1311 | return 1; | 1355 | case 0: /* current */ |
| 1356 | break; /* supported */ | ||
| 1357 | case 3: /* saved */ | ||
| 1358 | goto saving_not_supp; | ||
| 1359 | case 1: /* changeable */ | ||
| 1360 | case 2: /* defaults */ | ||
| 1361 | default: | ||
| 1362 | goto invalid_fld; | ||
| 1363 | } | ||
| 1312 | 1364 | ||
| 1313 | if (six_byte) | 1365 | if (six_byte) |
| 1314 | output_len = 4; | 1366 | output_len = 4; |
| @@ -1339,7 +1391,7 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
| 1339 | break; | 1391 | break; |
| 1340 | 1392 | ||
| 1341 | default: /* invalid page code */ | 1393 | default: /* invalid page code */ |
| 1342 | return 1; | 1394 | goto invalid_fld; |
| 1343 | } | 1395 | } |
| 1344 | 1396 | ||
| 1345 | if (six_byte) { | 1397 | if (six_byte) { |
| @@ -1352,6 +1404,16 @@ unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf, | |||
| 1352 | } | 1404 | } |
| 1353 | 1405 | ||
| 1354 | return 0; | 1406 | return 0; |
| 1407 | |||
| 1408 | invalid_fld: | ||
| 1409 | ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x24, 0x0); | ||
| 1410 | /* "Invalid field in cbd" */ | ||
| 1411 | return 1; | ||
| 1412 | |||
| 1413 | saving_not_supp: | ||
| 1414 | ata_scsi_set_sense(args->cmd, ILLEGAL_REQUEST, 0x39, 0x0); | ||
| 1415 | /* "Saving parameters not supported" */ | ||
| 1416 | return 1; | ||
| 1355 | } | 1417 | } |
| 1356 | 1418 | ||
| 1357 | /** | 1419 | /** |
| @@ -1496,13 +1558,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) | |||
| 1496 | void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq) | 1558 | void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 asc, u8 ascq) |
| 1497 | { | 1559 | { |
| 1498 | DPRINTK("ENTER\n"); | 1560 | DPRINTK("ENTER\n"); |
| 1499 | cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; | 1561 | ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, asc, ascq); |
| 1500 | |||
| 1501 | cmd->sense_buffer[0] = 0x70; | ||
| 1502 | cmd->sense_buffer[2] = ILLEGAL_REQUEST; | ||
| 1503 | cmd->sense_buffer[7] = 14 - 8; /* addnl. sense len. FIXME: correct? */ | ||
| 1504 | cmd->sense_buffer[12] = asc; | ||
| 1505 | cmd->sense_buffer[13] = ascq; | ||
| 1506 | 1562 | ||
| 1507 | done(cmd); | 1563 | done(cmd); |
| 1508 | } | 1564 | } |
| @@ -1871,7 +1927,7 @@ void ata_scsi_simulate(u16 *id, | |||
| 1871 | 1927 | ||
| 1872 | case INQUIRY: | 1928 | case INQUIRY: |
| 1873 | if (scsicmd[1] & 2) /* is CmdDt set? */ | 1929 | if (scsicmd[1] & 2) /* is CmdDt set? */ |
| 1874 | ata_bad_cdb(cmd, done); | 1930 | ata_scsi_invalid_field(cmd, done); |
| 1875 | else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ | 1931 | else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ |
| 1876 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); | 1932 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); |
| 1877 | else if (scsicmd[2] == 0x00) | 1933 | else if (scsicmd[2] == 0x00) |
| @@ -1881,7 +1937,7 @@ void ata_scsi_simulate(u16 *id, | |||
| 1881 | else if (scsicmd[2] == 0x83) | 1937 | else if (scsicmd[2] == 0x83) |
| 1882 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); | 1938 | ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); |
| 1883 | else | 1939 | else |
| 1884 | ata_bad_cdb(cmd, done); | 1940 | ata_scsi_invalid_field(cmd, done); |
| 1885 | break; | 1941 | break; |
| 1886 | 1942 | ||
| 1887 | case MODE_SENSE: | 1943 | case MODE_SENSE: |
| @@ -1891,7 +1947,7 @@ void ata_scsi_simulate(u16 *id, | |||
| 1891 | 1947 | ||
| 1892 | case MODE_SELECT: /* unconditionally return */ | 1948 | case MODE_SELECT: /* unconditionally return */ |
| 1893 | case MODE_SELECT_10: /* bad-field-in-cdb */ | 1949 | case MODE_SELECT_10: /* bad-field-in-cdb */ |
| 1894 | ata_bad_cdb(cmd, done); | 1950 | ata_scsi_invalid_field(cmd, done); |
| 1895 | break; | 1951 | break; |
| 1896 | 1952 | ||
| 1897 | case READ_CAPACITY: | 1953 | case READ_CAPACITY: |
| @@ -1902,7 +1958,7 @@ void ata_scsi_simulate(u16 *id, | |||
| 1902 | if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) | 1958 | if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) |
| 1903 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); | 1959 | ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); |
| 1904 | else | 1960 | else |
| 1905 | ata_bad_cdb(cmd, done); | 1961 | ata_scsi_invalid_field(cmd, done); |
| 1906 | break; | 1962 | break; |
| 1907 | 1963 | ||
| 1908 | case REPORT_LUNS: | 1964 | case REPORT_LUNS: |
| @@ -1914,7 +1970,9 @@ void ata_scsi_simulate(u16 *id, | |||
| 1914 | 1970 | ||
| 1915 | /* all other commands */ | 1971 | /* all other commands */ |
| 1916 | default: | 1972 | default: |
| 1917 | ata_bad_scsiop(cmd, done); | 1973 | ata_scsi_set_sense(cmd, ILLEGAL_REQUEST, 0x20, 0x0); |
| 1974 | /* "Invalid command operation code" */ | ||
| 1975 | done(cmd); | ||
| 1918 | break; | 1976 | break; |
| 1919 | } | 1977 | } |
| 1920 | } | 1978 | } |
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 4622e643ffd3..a18f2ac1d4a1 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
| @@ -86,14 +86,4 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | |||
| 86 | unsigned int (*actor) (struct ata_scsi_args *args, | 86 | unsigned int (*actor) (struct ata_scsi_args *args, |
| 87 | u8 *rbuf, unsigned int buflen)); | 87 | u8 *rbuf, unsigned int buflen)); |
| 88 | 88 | ||
| 89 | static inline void ata_bad_scsiop(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | ||
| 90 | { | ||
| 91 | ata_scsi_badcmd(cmd, done, 0x20, 0x00); | ||
| 92 | } | ||
| 93 | |||
| 94 | static inline void ata_bad_cdb(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | ||
| 95 | { | ||
| 96 | ata_scsi_badcmd(cmd, done, 0x24, 0x00); | ||
| 97 | } | ||
| 98 | |||
| 99 | #endif /* __LIBATA_H__ */ | 89 | #endif /* __LIBATA_H__ */ |
