aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/aachba.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/aachba.c')
-rw-r--r--drivers/scsi/aacraid/aachba.c67
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
331static 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;