diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2014-02-18 14:55:33 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-15 13:19:03 -0400 |
commit | 283b4a9b98b192ebc0e15351fd6fb60e1be78c5d (patch) | |
tree | 82ec3ca33ea7352e347dcb3b152b6ab95a1c107f /drivers/scsi/hpsa.c | |
parent | 17eb87d216a0d8a9fa9852f331a7c6afb9f45312 (diff) |
[SCSI] hpsa: add ioaccell mode 1 RAID offload support.
This enables sending i/o's destined for RAID logical drives
which can be serviced by a single physical disk down a different,
faster i/o path directly to physical drives for certain logical
volumes on SSDs bypassing the Smart Array RAID stack for a
performance improvement.
Signed-off-by: Matt Gates <matthew.gates@hp.com>
Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: Scott Teel <scott.teel@hp.com>
Signed-off-by: Mike Miller <michael.miller@canonical.com>
Signed-off-by: Don Brace <brace@beardog.cce.hp.com>
Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/hpsa.c')
-rw-r--r-- | drivers/scsi/hpsa.c | 565 |
1 files changed, 524 insertions, 41 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 4b6db4c39b24..e8489a964ea4 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/atomic.h> | 49 | #include <linux/atomic.h> |
50 | #include <linux/kthread.h> | 50 | #include <linux/kthread.h> |
51 | #include <linux/jiffies.h> | 51 | #include <linux/jiffies.h> |
52 | #include <asm/div64.h> | ||
52 | #include "hpsa_cmd.h" | 53 | #include "hpsa_cmd.h" |
53 | #include "hpsa.h" | 54 | #include "hpsa.h" |
54 | 55 | ||
@@ -216,6 +217,7 @@ static int hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); | |||
216 | static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, | 217 | static int hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, |
217 | int wait_for_ready); | 218 | int wait_for_ready); |
218 | static inline void finish_cmd(struct CommandList *c); | 219 | static inline void finish_cmd(struct CommandList *c); |
220 | static void hpsa_wait_for_mode_change_ack(struct ctlr_info *h); | ||
219 | #define BOARD_NOT_READY 0 | 221 | #define BOARD_NOT_READY 0 |
220 | #define BOARD_READY 1 | 222 | #define BOARD_READY 1 |
221 | 223 | ||
@@ -1195,6 +1197,7 @@ static void complete_scsi_command(struct CommandList *cp) | |||
1195 | struct scsi_cmnd *cmd; | 1197 | struct scsi_cmnd *cmd; |
1196 | struct ctlr_info *h; | 1198 | struct ctlr_info *h; |
1197 | struct ErrorInfo *ei; | 1199 | struct ErrorInfo *ei; |
1200 | struct hpsa_scsi_dev_t *dev; | ||
1198 | 1201 | ||
1199 | unsigned char sense_key; | 1202 | unsigned char sense_key; |
1200 | unsigned char asc; /* additional sense code */ | 1203 | unsigned char asc; /* additional sense code */ |
@@ -1204,6 +1207,7 @@ static void complete_scsi_command(struct CommandList *cp) | |||
1204 | ei = cp->err_info; | 1207 | ei = cp->err_info; |
1205 | cmd = (struct scsi_cmnd *) cp->scsi_cmd; | 1208 | cmd = (struct scsi_cmnd *) cp->scsi_cmd; |
1206 | h = cp->h; | 1209 | h = cp->h; |
1210 | dev = cmd->device->hostdata; | ||
1207 | 1211 | ||
1208 | scsi_dma_unmap(cmd); /* undo the DMA mappings */ | 1212 | scsi_dma_unmap(cmd); /* undo the DMA mappings */ |
1209 | if ((cp->cmd_type == CMD_SCSI) && | 1213 | if ((cp->cmd_type == CMD_SCSI) && |
@@ -1242,6 +1246,19 @@ static void complete_scsi_command(struct CommandList *cp) | |||
1242 | cp->Header.Tag.upper = c->Tag.upper; | 1246 | cp->Header.Tag.upper = c->Tag.upper; |
1243 | memcpy(cp->Header.LUN.LunAddrBytes, c->CISS_LUN, 8); | 1247 | memcpy(cp->Header.LUN.LunAddrBytes, c->CISS_LUN, 8); |
1244 | memcpy(cp->Request.CDB, c->CDB, cp->Request.CDBLen); | 1248 | memcpy(cp->Request.CDB, c->CDB, cp->Request.CDBLen); |
1249 | |||
1250 | /* Any RAID offload error results in retry which will use | ||
1251 | * the normal I/O path so the controller can handle whatever's | ||
1252 | * wrong. | ||
1253 | */ | ||
1254 | if (is_logical_dev_addr_mode(dev->scsi3addr)) { | ||
1255 | if (ei->CommandStatus == CMD_IOACCEL_DISABLED) | ||
1256 | dev->offload_enabled = 0; | ||
1257 | cmd->result = DID_SOFT_ERROR << 16; | ||
1258 | cmd_free(h, cp); | ||
1259 | cmd->scsi_done(cmd); | ||
1260 | return; | ||
1261 | } | ||
1245 | } | 1262 | } |
1246 | 1263 | ||
1247 | /* an error has occurred */ | 1264 | /* an error has occurred */ |
@@ -1406,6 +1423,14 @@ static void complete_scsi_command(struct CommandList *cp) | |||
1406 | cmd->result = DID_ERROR << 16; | 1423 | cmd->result = DID_ERROR << 16; |
1407 | dev_warn(&h->pdev->dev, "Command unabortable\n"); | 1424 | dev_warn(&h->pdev->dev, "Command unabortable\n"); |
1408 | break; | 1425 | break; |
1426 | case CMD_IOACCEL_DISABLED: | ||
1427 | /* This only handles the direct pass-through case since RAID | ||
1428 | * offload is handled above. Just attempt a retry. | ||
1429 | */ | ||
1430 | cmd->result = DID_SOFT_ERROR << 16; | ||
1431 | dev_warn(&h->pdev->dev, | ||
1432 | "cp %p had HP SSD Smart Path error\n", cp); | ||
1433 | break; | ||
1409 | default: | 1434 | default: |
1410 | cmd->result = DID_ERROR << 16; | 1435 | cmd->result = DID_ERROR << 16; |
1411 | dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n", | 1436 | dev_warn(&h->pdev->dev, "cp %p returned unknown status %x\n", |
@@ -1650,6 +1675,147 @@ static void hpsa_get_raid_level(struct ctlr_info *h, | |||
1650 | return; | 1675 | return; |
1651 | } | 1676 | } |
1652 | 1677 | ||
1678 | #define HPSA_MAP_DEBUG | ||
1679 | #ifdef HPSA_MAP_DEBUG | ||
1680 | static void hpsa_debug_map_buff(struct ctlr_info *h, int rc, | ||
1681 | struct raid_map_data *map_buff) | ||
1682 | { | ||
1683 | struct raid_map_disk_data *dd = &map_buff->data[0]; | ||
1684 | int map, row, col; | ||
1685 | u16 map_cnt, row_cnt, disks_per_row; | ||
1686 | |||
1687 | if (rc != 0) | ||
1688 | return; | ||
1689 | |||
1690 | dev_info(&h->pdev->dev, "structure_size = %u\n", | ||
1691 | le32_to_cpu(map_buff->structure_size)); | ||
1692 | dev_info(&h->pdev->dev, "volume_blk_size = %u\n", | ||
1693 | le32_to_cpu(map_buff->volume_blk_size)); | ||
1694 | dev_info(&h->pdev->dev, "volume_blk_cnt = 0x%llx\n", | ||
1695 | le64_to_cpu(map_buff->volume_blk_cnt)); | ||
1696 | dev_info(&h->pdev->dev, "physicalBlockShift = %u\n", | ||
1697 | map_buff->phys_blk_shift); | ||
1698 | dev_info(&h->pdev->dev, "parity_rotation_shift = %u\n", | ||
1699 | map_buff->parity_rotation_shift); | ||
1700 | dev_info(&h->pdev->dev, "strip_size = %u\n", | ||
1701 | le16_to_cpu(map_buff->strip_size)); | ||
1702 | dev_info(&h->pdev->dev, "disk_starting_blk = 0x%llx\n", | ||
1703 | le64_to_cpu(map_buff->disk_starting_blk)); | ||
1704 | dev_info(&h->pdev->dev, "disk_blk_cnt = 0x%llx\n", | ||
1705 | le64_to_cpu(map_buff->disk_blk_cnt)); | ||
1706 | dev_info(&h->pdev->dev, "data_disks_per_row = %u\n", | ||
1707 | le16_to_cpu(map_buff->data_disks_per_row)); | ||
1708 | dev_info(&h->pdev->dev, "metadata_disks_per_row = %u\n", | ||
1709 | le16_to_cpu(map_buff->metadata_disks_per_row)); | ||
1710 | dev_info(&h->pdev->dev, "row_cnt = %u\n", | ||
1711 | le16_to_cpu(map_buff->row_cnt)); | ||
1712 | dev_info(&h->pdev->dev, "layout_map_count = %u\n", | ||
1713 | le16_to_cpu(map_buff->layout_map_count)); | ||
1714 | |||
1715 | map_cnt = le16_to_cpu(map_buff->layout_map_count); | ||
1716 | for (map = 0; map < map_cnt; map++) { | ||
1717 | dev_info(&h->pdev->dev, "Map%u:\n", map); | ||
1718 | row_cnt = le16_to_cpu(map_buff->row_cnt); | ||
1719 | for (row = 0; row < row_cnt; row++) { | ||
1720 | dev_info(&h->pdev->dev, " Row%u:\n", row); | ||
1721 | disks_per_row = | ||
1722 | le16_to_cpu(map_buff->data_disks_per_row); | ||
1723 | for (col = 0; col < disks_per_row; col++, dd++) | ||
1724 | dev_info(&h->pdev->dev, | ||
1725 | " D%02u: h=0x%04x xor=%u,%u\n", | ||
1726 | col, dd->ioaccel_handle, | ||
1727 | dd->xor_mult[0], dd->xor_mult[1]); | ||
1728 | disks_per_row = | ||
1729 | le16_to_cpu(map_buff->metadata_disks_per_row); | ||
1730 | for (col = 0; col < disks_per_row; col++, dd++) | ||
1731 | dev_info(&h->pdev->dev, | ||
1732 | " M%02u: h=0x%04x xor=%u,%u\n", | ||
1733 | col, dd->ioaccel_handle, | ||
1734 | dd->xor_mult[0], dd->xor_mult[1]); | ||
1735 | } | ||
1736 | } | ||
1737 | } | ||
1738 | #else | ||
1739 | static void hpsa_debug_map_buff(__attribute__((unused)) struct ctlr_info *h, | ||
1740 | __attribute__((unused)) int rc, | ||
1741 | __attribute__((unused)) struct raid_map_data *map_buff) | ||
1742 | { | ||
1743 | } | ||
1744 | #endif | ||
1745 | |||
1746 | static int hpsa_get_raid_map(struct ctlr_info *h, | ||
1747 | unsigned char *scsi3addr, struct hpsa_scsi_dev_t *this_device) | ||
1748 | { | ||
1749 | int rc = 0; | ||
1750 | struct CommandList *c; | ||
1751 | struct ErrorInfo *ei; | ||
1752 | |||
1753 | c = cmd_special_alloc(h); | ||
1754 | if (c == NULL) { | ||
1755 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); | ||
1756 | return -ENOMEM; | ||
1757 | } | ||
1758 | if (fill_cmd(c, HPSA_GET_RAID_MAP, h, &this_device->raid_map, | ||
1759 | sizeof(this_device->raid_map), 0, | ||
1760 | scsi3addr, TYPE_CMD)) { | ||
1761 | dev_warn(&h->pdev->dev, "Out of memory in hpsa_get_raid_map()\n"); | ||
1762 | cmd_special_free(h, c); | ||
1763 | return -ENOMEM; | ||
1764 | } | ||
1765 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); | ||
1766 | ei = c->err_info; | ||
1767 | if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { | ||
1768 | hpsa_scsi_interpret_error(c); | ||
1769 | cmd_special_free(h, c); | ||
1770 | return -1; | ||
1771 | } | ||
1772 | cmd_special_free(h, c); | ||
1773 | |||
1774 | /* @todo in the future, dynamically allocate RAID map memory */ | ||
1775 | if (le32_to_cpu(this_device->raid_map.structure_size) > | ||
1776 | sizeof(this_device->raid_map)) { | ||
1777 | dev_warn(&h->pdev->dev, "RAID map size is too large!\n"); | ||
1778 | rc = -1; | ||
1779 | } | ||
1780 | hpsa_debug_map_buff(h, rc, &this_device->raid_map); | ||
1781 | return rc; | ||
1782 | } | ||
1783 | |||
1784 | static void hpsa_get_ioaccel_status(struct ctlr_info *h, | ||
1785 | unsigned char *scsi3addr, struct hpsa_scsi_dev_t *this_device) | ||
1786 | { | ||
1787 | int rc; | ||
1788 | unsigned char *buf; | ||
1789 | u8 ioaccel_status; | ||
1790 | |||
1791 | this_device->offload_config = 0; | ||
1792 | this_device->offload_enabled = 0; | ||
1793 | |||
1794 | buf = kzalloc(64, GFP_KERNEL); | ||
1795 | if (!buf) | ||
1796 | return; | ||
1797 | rc = hpsa_scsi_do_inquiry(h, scsi3addr, | ||
1798 | HPSA_VPD_LV_IOACCEL_STATUS, buf, 64); | ||
1799 | if (rc != 0) | ||
1800 | goto out; | ||
1801 | |||
1802 | #define IOACCEL_STATUS_BYTE 4 | ||
1803 | #define OFFLOAD_CONFIGURED_BIT 0x01 | ||
1804 | #define OFFLOAD_ENABLED_BIT 0x02 | ||
1805 | ioaccel_status = buf[IOACCEL_STATUS_BYTE]; | ||
1806 | this_device->offload_config = | ||
1807 | !!(ioaccel_status & OFFLOAD_CONFIGURED_BIT); | ||
1808 | if (this_device->offload_config) { | ||
1809 | this_device->offload_enabled = | ||
1810 | !!(ioaccel_status & OFFLOAD_ENABLED_BIT); | ||
1811 | if (hpsa_get_raid_map(h, scsi3addr, this_device)) | ||
1812 | this_device->offload_enabled = 0; | ||
1813 | } | ||
1814 | out: | ||
1815 | kfree(buf); | ||
1816 | return; | ||
1817 | } | ||
1818 | |||
1653 | /* Get the device id from inquiry page 0x83 */ | 1819 | /* Get the device id from inquiry page 0x83 */ |
1654 | static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr, | 1820 | static int hpsa_get_device_id(struct ctlr_info *h, unsigned char *scsi3addr, |
1655 | unsigned char *device_id, int buflen) | 1821 | unsigned char *device_id, int buflen) |
@@ -1698,6 +1864,14 @@ static int hpsa_scsi_do_report_luns(struct ctlr_info *h, int logical, | |||
1698 | ei->CommandStatus != CMD_DATA_UNDERRUN) { | 1864 | ei->CommandStatus != CMD_DATA_UNDERRUN) { |
1699 | hpsa_scsi_interpret_error(c); | 1865 | hpsa_scsi_interpret_error(c); |
1700 | rc = -1; | 1866 | rc = -1; |
1867 | } else { | ||
1868 | if (buf->extended_response_flag != extended_response) { | ||
1869 | dev_err(&h->pdev->dev, | ||
1870 | "report luns requested format %u, got %u\n", | ||
1871 | extended_response, | ||
1872 | buf->extended_response_flag); | ||
1873 | rc = -1; | ||
1874 | } | ||
1701 | } | 1875 | } |
1702 | out: | 1876 | out: |
1703 | cmd_special_free(h, c); | 1877 | cmd_special_free(h, c); |
@@ -1763,10 +1937,15 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
1763 | sizeof(this_device->device_id)); | 1937 | sizeof(this_device->device_id)); |
1764 | 1938 | ||
1765 | if (this_device->devtype == TYPE_DISK && | 1939 | if (this_device->devtype == TYPE_DISK && |
1766 | is_logical_dev_addr_mode(scsi3addr)) | 1940 | is_logical_dev_addr_mode(scsi3addr)) { |
1767 | hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); | 1941 | hpsa_get_raid_level(h, scsi3addr, &this_device->raid_level); |
1768 | else | 1942 | if (h->fw_support & MISC_FW_RAID_OFFLOAD_BASIC) |
1943 | hpsa_get_ioaccel_status(h, scsi3addr, this_device); | ||
1944 | } else { | ||
1769 | this_device->raid_level = RAID_UNKNOWN; | 1945 | this_device->raid_level = RAID_UNKNOWN; |
1946 | this_device->offload_config = 0; | ||
1947 | this_device->offload_enabled = 0; | ||
1948 | } | ||
1770 | 1949 | ||
1771 | if (is_OBDR_device) { | 1950 | if (is_OBDR_device) { |
1772 | /* See if this is a One-Button-Disaster-Recovery device | 1951 | /* See if this is a One-Button-Disaster-Recovery device |
@@ -1903,15 +2082,25 @@ static int add_ext_target_dev(struct ctlr_info *h, | |||
1903 | */ | 2082 | */ |
1904 | static int hpsa_gather_lun_info(struct ctlr_info *h, | 2083 | static int hpsa_gather_lun_info(struct ctlr_info *h, |
1905 | int reportlunsize, | 2084 | int reportlunsize, |
1906 | struct ReportLUNdata *physdev, u32 *nphysicals, | 2085 | struct ReportLUNdata *physdev, u32 *nphysicals, int *physical_mode, |
1907 | struct ReportLUNdata *logdev, u32 *nlogicals) | 2086 | struct ReportLUNdata *logdev, u32 *nlogicals) |
1908 | { | 2087 | { |
2088 | int physical_entry_size = 8; | ||
2089 | |||
2090 | *physical_mode = 0; | ||
2091 | |||
2092 | /* For I/O accelerator mode we need to read physical device handles */ | ||
2093 | if (h->transMethod & CFGTBL_Trans_io_accel1) { | ||
2094 | *physical_mode = HPSA_REPORT_PHYS_EXTENDED; | ||
2095 | physical_entry_size = 24; | ||
2096 | } | ||
1909 | if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, | 2097 | if (hpsa_scsi_do_report_phys_luns(h, physdev, reportlunsize, |
1910 | HPSA_REPORT_PHYS_EXTENDED)) { | 2098 | *physical_mode)) { |
1911 | dev_err(&h->pdev->dev, "report physical LUNs failed.\n"); | 2099 | dev_err(&h->pdev->dev, "report physical LUNs failed.\n"); |
1912 | return -1; | 2100 | return -1; |
1913 | } | 2101 | } |
1914 | *nphysicals = be32_to_cpu(*((__be32 *)physdev->LUNListLength)) / 24; | 2102 | *nphysicals = be32_to_cpu(*((__be32 *)physdev->LUNListLength)) / |
2103 | physical_entry_size; | ||
1915 | if (*nphysicals > HPSA_MAX_PHYS_LUN) { | 2104 | if (*nphysicals > HPSA_MAX_PHYS_LUN) { |
1916 | dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded." | 2105 | dev_warn(&h->pdev->dev, "maximum physical LUNs (%d) exceeded." |
1917 | " %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, | 2106 | " %d LUNs ignored.\n", HPSA_MAX_PHYS_LUN, |
@@ -1983,10 +2172,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1983 | struct ReportLUNdata *logdev_list = NULL; | 2172 | struct ReportLUNdata *logdev_list = NULL; |
1984 | u32 nphysicals = 0; | 2173 | u32 nphysicals = 0; |
1985 | u32 nlogicals = 0; | 2174 | u32 nlogicals = 0; |
2175 | int physical_mode = 0; | ||
1986 | u32 ndev_allocated = 0; | 2176 | u32 ndev_allocated = 0; |
1987 | struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice; | 2177 | struct hpsa_scsi_dev_t **currentsd, *this_device, *tmpdevice; |
1988 | int ncurrent = 0; | 2178 | int ncurrent = 0; |
1989 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 8; | 2179 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24; |
1990 | int i, n_ext_target_devs, ndevs_to_allocate; | 2180 | int i, n_ext_target_devs, ndevs_to_allocate; |
1991 | int raid_ctlr_position; | 2181 | int raid_ctlr_position; |
1992 | DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS); | 2182 | DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS); |
@@ -2004,7 +2194,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
2004 | 2194 | ||
2005 | if (hpsa_gather_lun_info(h, reportlunsize, | 2195 | if (hpsa_gather_lun_info(h, reportlunsize, |
2006 | (struct ReportLUNdata *) physdev_list, &nphysicals, | 2196 | (struct ReportLUNdata *) physdev_list, &nphysicals, |
2007 | logdev_list, &nlogicals)) | 2197 | &physical_mode, logdev_list, &nlogicals)) |
2008 | goto out; | 2198 | goto out; |
2009 | 2199 | ||
2010 | /* We might see up to the maximum number of logical and physical disks | 2200 | /* We might see up to the maximum number of logical and physical disks |
@@ -2085,12 +2275,16 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
2085 | ncurrent++; | 2275 | ncurrent++; |
2086 | break; | 2276 | break; |
2087 | case TYPE_DISK: | 2277 | case TYPE_DISK: |
2088 | if (i < nphysicals) | 2278 | if (i >= nphysicals) { |
2279 | ncurrent++; | ||
2089 | break; | 2280 | break; |
2090 | memcpy(&this_device->ioaccel_handle, | 2281 | } |
2091 | &lunaddrbytes[20], | 2282 | if (physical_mode == HPSA_REPORT_PHYS_EXTENDED) { |
2092 | sizeof(this_device->ioaccel_handle)); | 2283 | memcpy(&this_device->ioaccel_handle, |
2093 | ncurrent++; | 2284 | &lunaddrbytes[20], |
2285 | sizeof(this_device->ioaccel_handle)); | ||
2286 | ncurrent++; | ||
2287 | } | ||
2094 | break; | 2288 | break; |
2095 | case TYPE_TAPE: | 2289 | case TYPE_TAPE: |
2096 | case TYPE_MEDIUM_CHANGER: | 2290 | case TYPE_MEDIUM_CHANGER: |
@@ -2184,15 +2378,62 @@ sglist_finished: | |||
2184 | return 0; | 2378 | return 0; |
2185 | } | 2379 | } |
2186 | 2380 | ||
2381 | #define IO_ACCEL_INELIGIBLE (1) | ||
2382 | static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len) | ||
2383 | { | ||
2384 | int is_write = 0; | ||
2385 | u32 block; | ||
2386 | u32 block_cnt; | ||
2387 | |||
2388 | /* Perform some CDB fixups if needed using 10 byte reads/writes only */ | ||
2389 | switch (cdb[0]) { | ||
2390 | case WRITE_6: | ||
2391 | case WRITE_12: | ||
2392 | is_write = 1; | ||
2393 | case READ_6: | ||
2394 | case READ_12: | ||
2395 | if (*cdb_len == 6) { | ||
2396 | block = (((u32) cdb[2]) << 8) | cdb[3]; | ||
2397 | block_cnt = cdb[4]; | ||
2398 | } else { | ||
2399 | BUG_ON(*cdb_len != 12); | ||
2400 | block = (((u32) cdb[2]) << 24) | | ||
2401 | (((u32) cdb[3]) << 16) | | ||
2402 | (((u32) cdb[4]) << 8) | | ||
2403 | cdb[5]; | ||
2404 | block_cnt = | ||
2405 | (((u32) cdb[6]) << 24) | | ||
2406 | (((u32) cdb[7]) << 16) | | ||
2407 | (((u32) cdb[8]) << 8) | | ||
2408 | cdb[9]; | ||
2409 | } | ||
2410 | if (block_cnt > 0xffff) | ||
2411 | return IO_ACCEL_INELIGIBLE; | ||
2412 | |||
2413 | cdb[0] = is_write ? WRITE_10 : READ_10; | ||
2414 | cdb[1] = 0; | ||
2415 | cdb[2] = (u8) (block >> 24); | ||
2416 | cdb[3] = (u8) (block >> 16); | ||
2417 | cdb[4] = (u8) (block >> 8); | ||
2418 | cdb[5] = (u8) (block); | ||
2419 | cdb[6] = 0; | ||
2420 | cdb[7] = (u8) (block_cnt >> 8); | ||
2421 | cdb[8] = (u8) (block_cnt); | ||
2422 | cdb[9] = 0; | ||
2423 | *cdb_len = 10; | ||
2424 | break; | ||
2425 | } | ||
2426 | return 0; | ||
2427 | } | ||
2428 | |||
2187 | /* | 2429 | /* |
2188 | * Queue a command to the I/O accelerator path. | 2430 | * Queue a command to the I/O accelerator path. |
2189 | * This method does not currently support S/G chaining. | ||
2190 | */ | 2431 | */ |
2191 | static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h, | 2432 | static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h, |
2192 | struct CommandList *c) | 2433 | struct CommandList *c, u32 ioaccel_handle, u8 *cdb, int cdb_len, |
2434 | u8 *scsi3addr) | ||
2193 | { | 2435 | { |
2194 | struct scsi_cmnd *cmd = c->scsi_cmd; | 2436 | struct scsi_cmnd *cmd = c->scsi_cmd; |
2195 | struct hpsa_scsi_dev_t *dev = cmd->device->hostdata; | ||
2196 | struct io_accel1_cmd *cp = &h->ioaccel_cmd_pool[c->cmdindex]; | 2437 | struct io_accel1_cmd *cp = &h->ioaccel_cmd_pool[c->cmdindex]; |
2197 | unsigned int len; | 2438 | unsigned int len; |
2198 | unsigned int total_len = 0; | 2439 | unsigned int total_len = 0; |
@@ -2202,8 +2443,15 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h, | |||
2202 | struct SGDescriptor *curr_sg; | 2443 | struct SGDescriptor *curr_sg; |
2203 | u32 control = IOACCEL1_CONTROL_SIMPLEQUEUE; | 2444 | u32 control = IOACCEL1_CONTROL_SIMPLEQUEUE; |
2204 | 2445 | ||
2446 | /* TODO: implement chaining support */ | ||
2447 | if (scsi_sg_count(cmd) > h->ioaccel_maxsg) | ||
2448 | return IO_ACCEL_INELIGIBLE; | ||
2449 | |||
2205 | BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX); | 2450 | BUG_ON(cmd->cmd_len > IOACCEL1_IOFLAGS_CDBLEN_MAX); |
2206 | 2451 | ||
2452 | if (fixup_ioaccel_cdb(cdb, &cdb_len)) | ||
2453 | return IO_ACCEL_INELIGIBLE; | ||
2454 | |||
2207 | c->cmd_type = CMD_IOACCEL1; | 2455 | c->cmd_type = CMD_IOACCEL1; |
2208 | 2456 | ||
2209 | /* Adjust the DMA address to point to the accelerated command buffer */ | 2457 | /* Adjust the DMA address to point to the accelerated command buffer */ |
@@ -2254,13 +2502,13 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h, | |||
2254 | } | 2502 | } |
2255 | 2503 | ||
2256 | /* Fill out the command structure to submit */ | 2504 | /* Fill out the command structure to submit */ |
2257 | cp->dev_handle = dev->ioaccel_handle; | 2505 | cp->dev_handle = ioaccel_handle & 0xFFFF; |
2258 | cp->transfer_len = total_len; | 2506 | cp->transfer_len = total_len; |
2259 | cp->io_flags = IOACCEL1_IOFLAGS_IO_REQ | | 2507 | cp->io_flags = IOACCEL1_IOFLAGS_IO_REQ | |
2260 | (cmd->cmd_len & IOACCEL1_IOFLAGS_CDBLEN_MASK); | 2508 | (cdb_len & IOACCEL1_IOFLAGS_CDBLEN_MASK); |
2261 | cp->control = control; | 2509 | cp->control = control; |
2262 | memcpy(cp->CDB, cmd->cmnd, cmd->cmd_len); | 2510 | memcpy(cp->CDB, cdb, cdb_len); |
2263 | memcpy(cp->CISS_LUN, dev->scsi3addr, 8); | 2511 | memcpy(cp->CISS_LUN, scsi3addr, 8); |
2264 | 2512 | ||
2265 | /* Tell the controller to post the reply to the queue for this | 2513 | /* Tell the controller to post the reply to the queue for this |
2266 | * processor. This seems to give the best I/O throughput. | 2514 | * processor. This seems to give the best I/O throughput. |
@@ -2274,15 +2522,214 @@ static int hpsa_scsi_ioaccel_queue_command(struct ctlr_info *h, | |||
2274 | */ | 2522 | */ |
2275 | c->busaddr |= 1 | (h->ioaccel1_blockFetchTable[use_sg] << 1) | | 2523 | c->busaddr |= 1 | (h->ioaccel1_blockFetchTable[use_sg] << 1) | |
2276 | IOACCEL1_BUSADDR_CMDTYPE; | 2524 | IOACCEL1_BUSADDR_CMDTYPE; |
2277 | 2525 | enqueue_cmd_and_start_io(h, c); | |
2278 | /* execute command (bypassing cmd queue if possible) */ | ||
2279 | if (unlikely(h->access.fifo_full(h))) | ||
2280 | enqueue_cmd_and_start_io(h, c); | ||
2281 | else | ||
2282 | h->access.submit_command(h, c); | ||
2283 | return 0; | 2526 | return 0; |
2284 | } | 2527 | } |
2285 | 2528 | ||
2529 | /* | ||
2530 | * Queue a command directly to a device behind the controller using the | ||
2531 | * I/O accelerator path. | ||
2532 | */ | ||
2533 | static int hpsa_scsi_ioaccel_direct_map(struct ctlr_info *h, | ||
2534 | struct CommandList *c) | ||
2535 | { | ||
2536 | struct scsi_cmnd *cmd = c->scsi_cmd; | ||
2537 | struct hpsa_scsi_dev_t *dev = cmd->device->hostdata; | ||
2538 | |||
2539 | return hpsa_scsi_ioaccel_queue_command(h, c, dev->ioaccel_handle, | ||
2540 | cmd->cmnd, cmd->cmd_len, dev->scsi3addr); | ||
2541 | } | ||
2542 | |||
2543 | /* | ||
2544 | * Attempt to perform offload RAID mapping for a logical volume I/O. | ||
2545 | */ | ||
2546 | static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h, | ||
2547 | struct CommandList *c) | ||
2548 | { | ||
2549 | struct scsi_cmnd *cmd = c->scsi_cmd; | ||
2550 | struct hpsa_scsi_dev_t *dev = cmd->device->hostdata; | ||
2551 | struct raid_map_data *map = &dev->raid_map; | ||
2552 | struct raid_map_disk_data *dd = &map->data[0]; | ||
2553 | int is_write = 0; | ||
2554 | u32 map_index; | ||
2555 | u64 first_block, last_block; | ||
2556 | u32 block_cnt; | ||
2557 | u32 blocks_per_row; | ||
2558 | u64 first_row, last_row; | ||
2559 | u32 first_row_offset, last_row_offset; | ||
2560 | u32 first_column, last_column; | ||
2561 | u32 map_row; | ||
2562 | u32 disk_handle; | ||
2563 | u64 disk_block; | ||
2564 | u32 disk_block_cnt; | ||
2565 | u8 cdb[16]; | ||
2566 | u8 cdb_len; | ||
2567 | #if BITS_PER_LONG == 32 | ||
2568 | u64 tmpdiv; | ||
2569 | #endif | ||
2570 | |||
2571 | BUG_ON(!(dev->offload_config && dev->offload_enabled)); | ||
2572 | |||
2573 | /* check for valid opcode, get LBA and block count */ | ||
2574 | switch (cmd->cmnd[0]) { | ||
2575 | case WRITE_6: | ||
2576 | is_write = 1; | ||
2577 | case READ_6: | ||
2578 | first_block = | ||
2579 | (((u64) cmd->cmnd[2]) << 8) | | ||
2580 | cmd->cmnd[3]; | ||
2581 | block_cnt = cmd->cmnd[4]; | ||
2582 | break; | ||
2583 | case WRITE_10: | ||
2584 | is_write = 1; | ||
2585 | case READ_10: | ||
2586 | first_block = | ||
2587 | (((u64) cmd->cmnd[2]) << 24) | | ||
2588 | (((u64) cmd->cmnd[3]) << 16) | | ||
2589 | (((u64) cmd->cmnd[4]) << 8) | | ||
2590 | cmd->cmnd[5]; | ||
2591 | block_cnt = | ||
2592 | (((u32) cmd->cmnd[7]) << 8) | | ||
2593 | cmd->cmnd[8]; | ||
2594 | break; | ||
2595 | case WRITE_12: | ||
2596 | is_write = 1; | ||
2597 | case READ_12: | ||
2598 | first_block = | ||
2599 | (((u64) cmd->cmnd[2]) << 24) | | ||
2600 | (((u64) cmd->cmnd[3]) << 16) | | ||
2601 | (((u64) cmd->cmnd[4]) << 8) | | ||
2602 | cmd->cmnd[5]; | ||
2603 | block_cnt = | ||
2604 | (((u32) cmd->cmnd[6]) << 24) | | ||
2605 | (((u32) cmd->cmnd[7]) << 16) | | ||
2606 | (((u32) cmd->cmnd[8]) << 8) | | ||
2607 | cmd->cmnd[9]; | ||
2608 | break; | ||
2609 | case WRITE_16: | ||
2610 | is_write = 1; | ||
2611 | case READ_16: | ||
2612 | first_block = | ||
2613 | (((u64) cmd->cmnd[2]) << 56) | | ||
2614 | (((u64) cmd->cmnd[3]) << 48) | | ||
2615 | (((u64) cmd->cmnd[4]) << 40) | | ||
2616 | (((u64) cmd->cmnd[5]) << 32) | | ||
2617 | (((u64) cmd->cmnd[6]) << 24) | | ||
2618 | (((u64) cmd->cmnd[7]) << 16) | | ||
2619 | (((u64) cmd->cmnd[8]) << 8) | | ||
2620 | cmd->cmnd[9]; | ||
2621 | block_cnt = | ||
2622 | (((u32) cmd->cmnd[10]) << 24) | | ||
2623 | (((u32) cmd->cmnd[11]) << 16) | | ||
2624 | (((u32) cmd->cmnd[12]) << 8) | | ||
2625 | cmd->cmnd[13]; | ||
2626 | break; | ||
2627 | default: | ||
2628 | return IO_ACCEL_INELIGIBLE; /* process via normal I/O path */ | ||
2629 | } | ||
2630 | BUG_ON(block_cnt == 0); | ||
2631 | last_block = first_block + block_cnt - 1; | ||
2632 | |||
2633 | /* check for write to non-RAID-0 */ | ||
2634 | if (is_write && dev->raid_level != 0) | ||
2635 | return IO_ACCEL_INELIGIBLE; | ||
2636 | |||
2637 | /* check for invalid block or wraparound */ | ||
2638 | if (last_block >= map->volume_blk_cnt || last_block < first_block) | ||
2639 | return IO_ACCEL_INELIGIBLE; | ||
2640 | |||
2641 | /* calculate stripe information for the request */ | ||
2642 | blocks_per_row = map->data_disks_per_row * map->strip_size; | ||
2643 | #if BITS_PER_LONG == 32 | ||
2644 | tmpdiv = first_block; | ||
2645 | (void) do_div(tmpdiv, blocks_per_row); | ||
2646 | first_row = tmpdiv; | ||
2647 | tmpdiv = last_block; | ||
2648 | (void) do_div(tmpdiv, blocks_per_row); | ||
2649 | last_row = tmpdiv; | ||
2650 | first_row_offset = (u32) (first_block - (first_row * blocks_per_row)); | ||
2651 | last_row_offset = (u32) (last_block - (last_row * blocks_per_row)); | ||
2652 | tmpdiv = first_row_offset; | ||
2653 | (void) do_div(tmpdiv, map->strip_size); | ||
2654 | first_column = tmpdiv; | ||
2655 | tmpdiv = last_row_offset; | ||
2656 | (void) do_div(tmpdiv, map->strip_size); | ||
2657 | last_column = tmpdiv; | ||
2658 | #else | ||
2659 | first_row = first_block / blocks_per_row; | ||
2660 | last_row = last_block / blocks_per_row; | ||
2661 | first_row_offset = (u32) (first_block - (first_row * blocks_per_row)); | ||
2662 | last_row_offset = (u32) (last_block - (last_row * blocks_per_row)); | ||
2663 | first_column = first_row_offset / map->strip_size; | ||
2664 | last_column = last_row_offset / map->strip_size; | ||
2665 | #endif | ||
2666 | |||
2667 | /* if this isn't a single row/column then give to the controller */ | ||
2668 | if ((first_row != last_row) || (first_column != last_column)) | ||
2669 | return IO_ACCEL_INELIGIBLE; | ||
2670 | |||
2671 | /* proceeding with driver mapping */ | ||
2672 | map_row = ((u32)(first_row >> map->parity_rotation_shift)) % | ||
2673 | map->row_cnt; | ||
2674 | map_index = (map_row * (map->data_disks_per_row + | ||
2675 | map->metadata_disks_per_row)) + first_column; | ||
2676 | if (dev->raid_level == 2) { | ||
2677 | /* simple round-robin balancing of RAID 1+0 reads across | ||
2678 | * primary and mirror members. this is appropriate for SSD | ||
2679 | * but not optimal for HDD. | ||
2680 | */ | ||
2681 | if (dev->offload_to_mirror) | ||
2682 | map_index += map->data_disks_per_row; | ||
2683 | dev->offload_to_mirror = !dev->offload_to_mirror; | ||
2684 | } | ||
2685 | disk_handle = dd[map_index].ioaccel_handle; | ||
2686 | disk_block = map->disk_starting_blk + (first_row * map->strip_size) + | ||
2687 | (first_row_offset - (first_column * map->strip_size)); | ||
2688 | disk_block_cnt = block_cnt; | ||
2689 | |||
2690 | /* handle differing logical/physical block sizes */ | ||
2691 | if (map->phys_blk_shift) { | ||
2692 | disk_block <<= map->phys_blk_shift; | ||
2693 | disk_block_cnt <<= map->phys_blk_shift; | ||
2694 | } | ||
2695 | BUG_ON(disk_block_cnt > 0xffff); | ||
2696 | |||
2697 | /* build the new CDB for the physical disk I/O */ | ||
2698 | if (disk_block > 0xffffffff) { | ||
2699 | cdb[0] = is_write ? WRITE_16 : READ_16; | ||
2700 | cdb[1] = 0; | ||
2701 | cdb[2] = (u8) (disk_block >> 56); | ||
2702 | cdb[3] = (u8) (disk_block >> 48); | ||
2703 | cdb[4] = (u8) (disk_block >> 40); | ||
2704 | cdb[5] = (u8) (disk_block >> 32); | ||
2705 | cdb[6] = (u8) (disk_block >> 24); | ||
2706 | cdb[7] = (u8) (disk_block >> 16); | ||
2707 | cdb[8] = (u8) (disk_block >> 8); | ||
2708 | cdb[9] = (u8) (disk_block); | ||
2709 | cdb[10] = (u8) (disk_block_cnt >> 24); | ||
2710 | cdb[11] = (u8) (disk_block_cnt >> 16); | ||
2711 | cdb[12] = (u8) (disk_block_cnt >> 8); | ||
2712 | cdb[13] = (u8) (disk_block_cnt); | ||
2713 | cdb[14] = 0; | ||
2714 | cdb[15] = 0; | ||
2715 | cdb_len = 16; | ||
2716 | } else { | ||
2717 | cdb[0] = is_write ? WRITE_10 : READ_10; | ||
2718 | cdb[1] = 0; | ||
2719 | cdb[2] = (u8) (disk_block >> 24); | ||
2720 | cdb[3] = (u8) (disk_block >> 16); | ||
2721 | cdb[4] = (u8) (disk_block >> 8); | ||
2722 | cdb[5] = (u8) (disk_block); | ||
2723 | cdb[6] = 0; | ||
2724 | cdb[7] = (u8) (disk_block_cnt >> 8); | ||
2725 | cdb[8] = (u8) (disk_block_cnt); | ||
2726 | cdb[9] = 0; | ||
2727 | cdb_len = 10; | ||
2728 | } | ||
2729 | return hpsa_scsi_ioaccel_queue_command(h, c, disk_handle, cdb, cdb_len, | ||
2730 | dev->scsi3addr); | ||
2731 | } | ||
2732 | |||
2286 | static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, | 2733 | static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, |
2287 | void (*done)(struct scsi_cmnd *)) | 2734 | void (*done)(struct scsi_cmnd *)) |
2288 | { | 2735 | { |
@@ -2291,6 +2738,7 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, | |||
2291 | unsigned char scsi3addr[8]; | 2738 | unsigned char scsi3addr[8]; |
2292 | struct CommandList *c; | 2739 | struct CommandList *c; |
2293 | unsigned long flags; | 2740 | unsigned long flags; |
2741 | int rc = 0; | ||
2294 | 2742 | ||
2295 | /* Get the ptr to our adapter structure out of cmd->host. */ | 2743 | /* Get the ptr to our adapter structure out of cmd->host. */ |
2296 | h = sdev_to_hba(cmd->device); | 2744 | h = sdev_to_hba(cmd->device); |
@@ -2326,13 +2774,29 @@ static int hpsa_scsi_queue_command_lck(struct scsi_cmnd *cmd, | |||
2326 | c->cmd_type = CMD_SCSI; | 2774 | c->cmd_type = CMD_SCSI; |
2327 | c->scsi_cmd = cmd; | 2775 | c->scsi_cmd = cmd; |
2328 | 2776 | ||
2329 | /* Call alternate submit routine for I/O accelerated commands */ | 2777 | /* Call alternate submit routine for I/O accelerated commands. |
2330 | if ((likely(h->transMethod & CFGTBL_Trans_io_accel1)) && | 2778 | * Retries always go down the normal I/O path. |
2331 | (dev->ioaccel_handle) && | 2779 | */ |
2332 | ((cmd->cmnd[0] == READ_10) || (cmd->cmnd[0] == WRITE_10)) && | 2780 | if (likely(cmd->retries == 0 && |
2333 | (scsi_sg_count(cmd) <= IOACCEL1_MAXSGENTRIES) && | 2781 | cmd->request->cmd_type == REQ_TYPE_FS)) { |
2334 | likely(cmd->request->cmd_type == REQ_TYPE_FS)) | 2782 | if (dev->offload_enabled) { |
2335 | return hpsa_scsi_ioaccel_queue_command(h, c); | 2783 | rc = hpsa_scsi_ioaccel_raid_map(h, c); |
2784 | if (rc == 0) | ||
2785 | return 0; /* Sent on ioaccel path */ | ||
2786 | if (rc < 0) { /* scsi_dma_map failed. */ | ||
2787 | cmd_free(h, c); | ||
2788 | return SCSI_MLQUEUE_HOST_BUSY; | ||
2789 | } | ||
2790 | } else if (dev->ioaccel_handle) { | ||
2791 | rc = hpsa_scsi_ioaccel_direct_map(h, c); | ||
2792 | if (rc == 0) | ||
2793 | return 0; /* Sent on direct map path */ | ||
2794 | if (rc < 0) { /* scsi_dma_map failed. */ | ||
2795 | cmd_free(h, c); | ||
2796 | return SCSI_MLQUEUE_HOST_BUSY; | ||
2797 | } | ||
2798 | } | ||
2799 | } | ||
2336 | 2800 | ||
2337 | c->Header.ReplyQueue = 0; /* unused in simple mode */ | 2801 | c->Header.ReplyQueue = 0; /* unused in simple mode */ |
2338 | memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); | 2802 | memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); |
@@ -3515,6 +3979,18 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | |||
3515 | c->Request.Type.Direction = XFER_NONE; | 3979 | c->Request.Type.Direction = XFER_NONE; |
3516 | c->Request.Timeout = 0; | 3980 | c->Request.Timeout = 0; |
3517 | break; | 3981 | break; |
3982 | case HPSA_GET_RAID_MAP: | ||
3983 | c->Request.CDBLen = 12; | ||
3984 | c->Request.Type.Attribute = ATTR_SIMPLE; | ||
3985 | c->Request.Type.Direction = XFER_READ; | ||
3986 | c->Request.Timeout = 0; | ||
3987 | c->Request.CDB[0] = HPSA_CISS_READ; | ||
3988 | c->Request.CDB[1] = cmd; | ||
3989 | c->Request.CDB[6] = (size >> 24) & 0xFF; /* MSB */ | ||
3990 | c->Request.CDB[7] = (size >> 16) & 0xFF; | ||
3991 | c->Request.CDB[8] = (size >> 8) & 0xFF; | ||
3992 | c->Request.CDB[9] = size & 0xFF; | ||
3993 | break; | ||
3518 | default: | 3994 | default: |
3519 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); | 3995 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); |
3520 | BUG(); | 3996 | BUG(); |
@@ -4485,6 +4961,7 @@ static void hpsa_find_board_params(struct ctlr_info *h) | |||
4485 | hpsa_get_max_perf_mode_cmds(h); | 4961 | hpsa_get_max_perf_mode_cmds(h); |
4486 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ | 4962 | h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ |
4487 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); | 4963 | h->maxsgentries = readl(&(h->cfgtable->MaxScatterGatherElements)); |
4964 | h->fw_support = readl(&(h->cfgtable->misc_fw_support)); | ||
4488 | /* | 4965 | /* |
4489 | * Limit in-command s/g elements to 32 save dma'able memory. | 4966 | * Limit in-command s/g elements to 32 save dma'able memory. |
4490 | * Howvever spec says if 0, use 31 | 4967 | * Howvever spec says if 0, use 31 |
@@ -4569,18 +5046,19 @@ static int hpsa_enter_simple_mode(struct ctlr_info *h) | |||
4569 | return -ENOTSUPP; | 5046 | return -ENOTSUPP; |
4570 | 5047 | ||
4571 | h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); | 5048 | h->max_commands = readl(&(h->cfgtable->CmdsOutMax)); |
5049 | |||
4572 | /* Update the field, and then ring the doorbell */ | 5050 | /* Update the field, and then ring the doorbell */ |
4573 | writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); | 5051 | writel(CFGTBL_Trans_Simple, &(h->cfgtable->HostWrite.TransportRequest)); |
4574 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); | 5052 | writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); |
4575 | hpsa_wait_for_mode_change_ack(h); | 5053 | hpsa_wait_for_mode_change_ack(h); |
4576 | print_cfg_table(&h->pdev->dev, h->cfgtable); | 5054 | print_cfg_table(&h->pdev->dev, h->cfgtable); |
4577 | if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { | 5055 | if (!(readl(&(h->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) |
4578 | dev_warn(&h->pdev->dev, | 5056 | goto error; |
4579 | "unable to get board into simple mode\n"); | ||
4580 | return -ENODEV; | ||
4581 | } | ||
4582 | h->transMethod = CFGTBL_Trans_Simple; | 5057 | h->transMethod = CFGTBL_Trans_Simple; |
4583 | return 0; | 5058 | return 0; |
5059 | error: | ||
5060 | dev_warn(&h->pdev->dev, "unable to get board into simple mode\n"); | ||
5061 | return -ENODEV; | ||
4584 | } | 5062 | } |
4585 | 5063 | ||
4586 | static int hpsa_pci_init(struct ctlr_info *h) | 5064 | static int hpsa_pci_init(struct ctlr_info *h) |
@@ -4961,7 +5439,7 @@ reinit_after_soft_reset: | |||
4961 | * the 5 lower bits of the address are used by the hardware. and by | 5439 | * the 5 lower bits of the address are used by the hardware. and by |
4962 | * the driver. See comments in hpsa.h for more info. | 5440 | * the driver. See comments in hpsa.h for more info. |
4963 | */ | 5441 | */ |
4964 | #define COMMANDLIST_ALIGNMENT 32 | 5442 | #define COMMANDLIST_ALIGNMENT 128 |
4965 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); | 5443 | BUILD_BUG_ON(sizeof(struct CommandList) % COMMANDLIST_ALIGNMENT); |
4966 | h = kzalloc(sizeof(*h), GFP_KERNEL); | 5444 | h = kzalloc(sizeof(*h), GFP_KERNEL); |
4967 | if (!h) | 5445 | if (!h) |
@@ -5338,8 +5816,8 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support) | |||
5338 | h->reply_queue[i].current_entry = | 5816 | h->reply_queue[i].current_entry = |
5339 | readl(h->vaddr + IOACCEL_MODE1_PRODUCER_INDEX); | 5817 | readl(h->vaddr + IOACCEL_MODE1_PRODUCER_INDEX); |
5340 | } | 5818 | } |
5341 | bft[7] = IOACCEL1_MAXSGENTRIES + 8; | 5819 | bft[7] = h->ioaccel_maxsg + 8; |
5342 | calc_bucket_map(bft, ARRAY_SIZE(bft), IOACCEL1_MAXSGENTRIES, 8, | 5820 | calc_bucket_map(bft, ARRAY_SIZE(bft), h->ioaccel_maxsg, 8, |
5343 | h->ioaccel1_blockFetchTable); | 5821 | h->ioaccel1_blockFetchTable); |
5344 | 5822 | ||
5345 | /* initialize all reply queue entries to unused */ | 5823 | /* initialize all reply queue entries to unused */ |
@@ -5370,6 +5848,11 @@ static void hpsa_enter_performant_mode(struct ctlr_info *h, u32 trans_support) | |||
5370 | 5848 | ||
5371 | static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h) | 5849 | static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h) |
5372 | { | 5850 | { |
5851 | h->ioaccel_maxsg = | ||
5852 | readl(&(h->cfgtable->io_accel_max_embedded_sg_count)); | ||
5853 | if (h->ioaccel_maxsg > IOACCEL1_MAXSGENTRIES) | ||
5854 | h->ioaccel_maxsg = IOACCEL1_MAXSGENTRIES; | ||
5855 | |||
5373 | /* Command structures must be aligned on a 128-byte boundary | 5856 | /* Command structures must be aligned on a 128-byte boundary |
5374 | * because the 7 lower bits of the address are used by the | 5857 | * because the 7 lower bits of the address are used by the |
5375 | * hardware. | 5858 | * hardware. |
@@ -5383,7 +5866,7 @@ static int hpsa_alloc_ioaccel_cmd_and_bft(struct ctlr_info *h) | |||
5383 | &(h->ioaccel_cmd_pool_dhandle)); | 5866 | &(h->ioaccel_cmd_pool_dhandle)); |
5384 | 5867 | ||
5385 | h->ioaccel1_blockFetchTable = | 5868 | h->ioaccel1_blockFetchTable = |
5386 | kmalloc(((IOACCEL1_MAXSGENTRIES + 1) * | 5869 | kmalloc(((h->ioaccel_maxsg + 1) * |
5387 | sizeof(u32)), GFP_KERNEL); | 5870 | sizeof(u32)), GFP_KERNEL); |
5388 | 5871 | ||
5389 | if ((h->ioaccel_cmd_pool == NULL) || | 5872 | if ((h->ioaccel_cmd_pool == NULL) || |