diff options
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r-- | drivers/scsi/aacraid/aachba.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 7e26ebc26661..7df2dd1d2c6f 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -328,6 +328,16 @@ int aac_get_config_status(struct aac_dev *dev, int commit_flag) | |||
328 | return status; | 328 | return status; |
329 | } | 329 | } |
330 | 330 | ||
331 | static void aac_expose_phy_device(struct scsi_cmnd *scsicmd) | ||
332 | { | ||
333 | char inq_data; | ||
334 | scsi_sg_copy_to_buffer(scsicmd, &inq_data, sizeof(inq_data)); | ||
335 | if ((inq_data & 0x20) && (inq_data & 0x1f) == TYPE_DISK) { | ||
336 | inq_data &= 0xdf; | ||
337 | scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data)); | ||
338 | } | ||
339 | } | ||
340 | |||
331 | /** | 341 | /** |
332 | * aac_get_containers - list containers | 342 | * aac_get_containers - list containers |
333 | * @common: adapter to probe | 343 | * @common: adapter to probe |
@@ -1598,6 +1608,7 @@ static int aac_read(struct scsi_cmnd * scsicmd) | |||
1598 | int status; | 1608 | int status; |
1599 | struct aac_dev *dev; | 1609 | struct aac_dev *dev; |
1600 | struct fib * cmd_fibcontext; | 1610 | struct fib * cmd_fibcontext; |
1611 | int cid; | ||
1601 | 1612 | ||
1602 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 1613 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
1603 | /* | 1614 | /* |
@@ -1647,6 +1658,22 @@ static int aac_read(struct scsi_cmnd * scsicmd) | |||
1647 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 1658 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
1648 | break; | 1659 | break; |
1649 | } | 1660 | } |
1661 | |||
1662 | if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) { | ||
1663 | cid = scmd_id(scsicmd); | ||
1664 | dprintk((KERN_DEBUG "aacraid: Illegal lba\n")); | ||
1665 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | | ||
1666 | SAM_STAT_CHECK_CONDITION; | ||
1667 | set_sense(&dev->fsa_dev[cid].sense_data, | ||
1668 | HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, | ||
1669 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); | ||
1670 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1671 | min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), | ||
1672 | SCSI_SENSE_BUFFERSIZE)); | ||
1673 | scsicmd->scsi_done(scsicmd); | ||
1674 | return 1; | ||
1675 | } | ||
1676 | |||
1650 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", | 1677 | dprintk((KERN_DEBUG "aac_read[cpu %d]: lba = %llu, t = %ld.\n", |
1651 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1678 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1652 | if (aac_adapter_bounds(dev,scsicmd,lba)) | 1679 | if (aac_adapter_bounds(dev,scsicmd,lba)) |
@@ -1688,6 +1715,7 @@ static int aac_write(struct scsi_cmnd * scsicmd) | |||
1688 | int status; | 1715 | int status; |
1689 | struct aac_dev *dev; | 1716 | struct aac_dev *dev; |
1690 | struct fib * cmd_fibcontext; | 1717 | struct fib * cmd_fibcontext; |
1718 | int cid; | ||
1691 | 1719 | ||
1692 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; | 1720 | dev = (struct aac_dev *)scsicmd->device->host->hostdata; |
1693 | /* | 1721 | /* |
@@ -1727,6 +1755,22 @@ static int aac_write(struct scsi_cmnd * scsicmd) | |||
1727 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; | 1755 | count = (scsicmd->cmnd[7] << 8) | scsicmd->cmnd[8]; |
1728 | fua = scsicmd->cmnd[1] & 0x8; | 1756 | fua = scsicmd->cmnd[1] & 0x8; |
1729 | } | 1757 | } |
1758 | |||
1759 | if ((lba + count) > (dev->fsa_dev[scmd_id(scsicmd)].size)) { | ||
1760 | cid = scmd_id(scsicmd); | ||
1761 | dprintk((KERN_DEBUG "aacraid: Illegal lba\n")); | ||
1762 | scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | | ||
1763 | SAM_STAT_CHECK_CONDITION; | ||
1764 | set_sense(&dev->fsa_dev[cid].sense_data, | ||
1765 | HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, | ||
1766 | ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0); | ||
1767 | memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, | ||
1768 | min_t(size_t, sizeof(dev->fsa_dev[cid].sense_data), | ||
1769 | SCSI_SENSE_BUFFERSIZE)); | ||
1770 | scsicmd->scsi_done(scsicmd); | ||
1771 | return 1; | ||
1772 | } | ||
1773 | |||
1730 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", | 1774 | dprintk((KERN_DEBUG "aac_write[cpu %d]: lba = %llu, t = %ld.\n", |
1731 | smp_processor_id(), (unsigned long long)lba, jiffies)); | 1775 | smp_processor_id(), (unsigned long long)lba, jiffies)); |
1732 | if (aac_adapter_bounds(dev,scsicmd,lba)) | 1776 | if (aac_adapter_bounds(dev,scsicmd,lba)) |
@@ -2573,6 +2617,11 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
2573 | 2617 | ||
2574 | scsi_dma_unmap(scsicmd); | 2618 | scsi_dma_unmap(scsicmd); |
2575 | 2619 | ||
2620 | /* expose physical device if expose_physicald flag is on */ | ||
2621 | if (scsicmd->cmnd[0] == INQUIRY && !(scsicmd->cmnd[1] & 0x01) | ||
2622 | && expose_physicals > 0) | ||
2623 | aac_expose_phy_device(scsicmd); | ||
2624 | |||
2576 | /* | 2625 | /* |
2577 | * First check the fib status | 2626 | * First check the fib status |
2578 | */ | 2627 | */ |
@@ -2678,8 +2727,22 @@ static void aac_srb_callback(void *context, struct fib * fibptr) | |||
2678 | scsicmd->cmnd[0], | 2727 | scsicmd->cmnd[0], |
2679 | le32_to_cpu(srbreply->scsi_status)); | 2728 | le32_to_cpu(srbreply->scsi_status)); |
2680 | #endif | 2729 | #endif |
2681 | scsicmd->result = DID_ERROR << 16 | COMMAND_COMPLETE << 8; | 2730 | if ((scsicmd->cmnd[0] == ATA_12) |
2682 | break; | 2731 | || (scsicmd->cmnd[0] == ATA_16)) { |
2732 | if (scsicmd->cmnd[2] & (0x01 << 5)) { | ||
2733 | scsicmd->result = DID_OK << 16 | ||
2734 | | COMMAND_COMPLETE << 8; | ||
2735 | break; | ||
2736 | } else { | ||
2737 | scsicmd->result = DID_ERROR << 16 | ||
2738 | | COMMAND_COMPLETE << 8; | ||
2739 | break; | ||
2740 | } | ||
2741 | } else { | ||
2742 | scsicmd->result = DID_ERROR << 16 | ||
2743 | | COMMAND_COMPLETE << 8; | ||
2744 | break; | ||
2745 | } | ||
2683 | } | 2746 | } |
2684 | if (le32_to_cpu(srbreply->scsi_status) == SAM_STAT_CHECK_CONDITION) { | 2747 | if (le32_to_cpu(srbreply->scsi_status) == SAM_STAT_CHECK_CONDITION) { |
2685 | int len; | 2748 | int len; |