diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 67 |
1 files changed, 43 insertions, 24 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b3900cfbd880..c228df298bd8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1363,12 +1363,22 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc) | |||
1363 | * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE | 1363 | * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE |
1364 | * cache | 1364 | * cache |
1365 | */ | 1365 | */ |
1366 | if (ap->ops->error_handler && | 1366 | if (ap->ops->error_handler && !need_sense) { |
1367 | !need_sense && (qc->tf.command == ATA_CMD_SET_FEATURES) && | 1367 | switch (qc->tf.command) { |
1368 | ((qc->tf.feature == SETFEATURES_WC_ON) || | 1368 | case ATA_CMD_SET_FEATURES: |
1369 | (qc->tf.feature == SETFEATURES_WC_OFF))) { | 1369 | if ((qc->tf.feature == SETFEATURES_WC_ON) || |
1370 | ap->eh_info.action |= ATA_EH_REVALIDATE; | 1370 | (qc->tf.feature == SETFEATURES_WC_OFF)) { |
1371 | ata_port_schedule_eh(ap); | 1371 | ap->eh_info.action |= ATA_EH_REVALIDATE; |
1372 | ata_port_schedule_eh(ap); | ||
1373 | } | ||
1374 | break; | ||
1375 | |||
1376 | case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */ | ||
1377 | case ATA_CMD_SET_MULTI: /* multi_count changed */ | ||
1378 | ap->eh_info.action |= ATA_EH_REVALIDATE; | ||
1379 | ata_port_schedule_eh(ap); | ||
1380 | break; | ||
1381 | } | ||
1372 | } | 1382 | } |
1373 | 1383 | ||
1374 | /* For ATA pass thru (SAT) commands, generate a sense block if | 1384 | /* For ATA pass thru (SAT) commands, generate a sense block if |
@@ -2506,22 +2516,21 @@ ata_scsi_map_proto(u8 byte1) | |||
2506 | return ATA_PROT_NODATA; | 2516 | return ATA_PROT_NODATA; |
2507 | 2517 | ||
2508 | case 6: /* DMA */ | 2518 | case 6: /* DMA */ |
2519 | case 10: /* UDMA Data-in */ | ||
2520 | case 11: /* UDMA Data-Out */ | ||
2509 | return ATA_PROT_DMA; | 2521 | return ATA_PROT_DMA; |
2510 | 2522 | ||
2511 | case 4: /* PIO Data-in */ | 2523 | case 4: /* PIO Data-in */ |
2512 | case 5: /* PIO Data-out */ | 2524 | case 5: /* PIO Data-out */ |
2513 | return ATA_PROT_PIO; | 2525 | return ATA_PROT_PIO; |
2514 | 2526 | ||
2515 | case 10: /* Device Reset */ | ||
2516 | case 0: /* Hard Reset */ | 2527 | case 0: /* Hard Reset */ |
2517 | case 1: /* SRST */ | 2528 | case 1: /* SRST */ |
2518 | case 2: /* Bus Idle */ | 2529 | case 8: /* Device Diagnostic */ |
2519 | case 7: /* Packet */ | 2530 | case 9: /* Device Reset */ |
2520 | case 8: /* DMA Queued */ | 2531 | case 7: /* DMA Queued */ |
2521 | case 9: /* Device Diagnostic */ | 2532 | case 12: /* FPDMA */ |
2522 | case 11: /* UDMA Data-in */ | 2533 | case 15: /* Return Response Info */ |
2523 | case 12: /* UDMA Data-Out */ | ||
2524 | case 13: /* FPDMA */ | ||
2525 | default: /* Reserved */ | 2534 | default: /* Reserved */ |
2526 | break; | 2535 | break; |
2527 | } | 2536 | } |
@@ -2552,10 +2561,6 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
2552 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) | 2561 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) |
2553 | goto invalid_fld; | 2562 | goto invalid_fld; |
2554 | 2563 | ||
2555 | if (cdb[1] & 0xe0) | ||
2556 | /* PIO multi not supported yet */ | ||
2557 | goto invalid_fld; | ||
2558 | |||
2559 | /* | 2564 | /* |
2560 | * 12 and 16 byte CDBs use different offsets to | 2565 | * 12 and 16 byte CDBs use different offsets to |
2561 | * provide the various register values. | 2566 | * provide the various register values. |
@@ -2600,12 +2605,26 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
2600 | tf->device = cdb[8]; | 2605 | tf->device = cdb[8]; |
2601 | tf->command = cdb[9]; | 2606 | tf->command = cdb[9]; |
2602 | } | 2607 | } |
2603 | /* | 2608 | |
2604 | * If slave is possible, enforce correct master/slave bit | 2609 | /* enforce correct master/slave bit */ |
2605 | */ | 2610 | tf->device = dev->devno ? |
2606 | if (qc->ap->flags & ATA_FLAG_SLAVE_POSS) | 2611 | tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; |
2607 | tf->device = qc->dev->devno ? | 2612 | |
2608 | tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; | 2613 | /* sanity check for pio multi commands */ |
2614 | if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) | ||
2615 | goto invalid_fld; | ||
2616 | |||
2617 | if (is_multi_taskfile(tf)) { | ||
2618 | unsigned int multi_count = 1 << (cdb[1] >> 5); | ||
2619 | |||
2620 | /* compare the passed through multi_count | ||
2621 | * with the cached multi_count of libata | ||
2622 | */ | ||
2623 | if (multi_count != dev->multi_count) | ||
2624 | ata_dev_printk(dev, KERN_WARNING, | ||
2625 | "invalid multi_count %u ignored\n", | ||
2626 | multi_count); | ||
2627 | } | ||
2609 | 2628 | ||
2610 | /* READ/WRITE LONG use a non-standard sect_size */ | 2629 | /* READ/WRITE LONG use a non-standard sect_size */ |
2611 | qc->sect_size = ATA_SECT_SIZE; | 2630 | qc->sect_size = ATA_SECT_SIZE; |