diff options
author | David S. Miller <davem@davemloft.net> | 2011-09-22 03:23:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-22 03:23:13 -0400 |
commit | 8decf868790b48a727d7e7ca164f2bcd3c1389c0 (patch) | |
tree | b759a5f861f842af7ea76f9011b579d06e9d5508 /drivers/scsi | |
parent | 3fc72370186be2f9d4d6ef06d99e1caa5d92c564 (diff) | |
parent | d93dc5c4478c1fd5de85a3e8aece9aad7bbae044 (diff) |
Merge branch 'master' of github.com:davem330/net
Conflicts:
MAINTAINERS
drivers/net/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/wireless/iwlwifi/iwl-pci.c
drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/wl12xx/main.c
Diffstat (limited to 'drivers/scsi')
27 files changed, 608 insertions, 201 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 9ae80cd5953b..dba72a4e6a1c 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c | |||
@@ -563,7 +563,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn, | |||
563 | nopout_wqe->itt = ((u16)task->itt | | 563 | nopout_wqe->itt = ((u16)task->itt | |
564 | (ISCSI_TASK_TYPE_MPATH << | 564 | (ISCSI_TASK_TYPE_MPATH << |
565 | ISCSI_TMF_REQUEST_TYPE_SHIFT)); | 565 | ISCSI_TMF_REQUEST_TYPE_SHIFT)); |
566 | nopout_wqe->ttt = nopout_hdr->ttt; | 566 | nopout_wqe->ttt = be32_to_cpu(nopout_hdr->ttt); |
567 | nopout_wqe->flags = 0; | 567 | nopout_wqe->flags = 0; |
568 | if (!unsol) | 568 | if (!unsol) |
569 | nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION; | 569 | nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION; |
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 83aa3ac52c40..9d3d81778af1 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c | |||
@@ -432,6 +432,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
432 | u8 flogi_maddr[ETH_ALEN]; | 432 | u8 flogi_maddr[ETH_ALEN]; |
433 | const struct net_device_ops *ops; | 433 | const struct net_device_ops *ops; |
434 | 434 | ||
435 | rtnl_lock(); | ||
436 | |||
435 | /* | 437 | /* |
436 | * Don't listen for Ethernet packets anymore. | 438 | * Don't listen for Ethernet packets anymore. |
437 | * synchronize_net() ensures that the packet handlers are not running | 439 | * synchronize_net() ensures that the packet handlers are not running |
@@ -461,6 +463,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) | |||
461 | " specific feature for LLD.\n"); | 463 | " specific feature for LLD.\n"); |
462 | } | 464 | } |
463 | 465 | ||
466 | rtnl_unlock(); | ||
467 | |||
464 | /* Release the self-reference taken during fcoe_interface_create() */ | 468 | /* Release the self-reference taken during fcoe_interface_create() */ |
465 | fcoe_interface_put(fcoe); | 469 | fcoe_interface_put(fcoe); |
466 | } | 470 | } |
@@ -1951,11 +1955,8 @@ static void fcoe_destroy_work(struct work_struct *work) | |||
1951 | fcoe_if_destroy(port->lport); | 1955 | fcoe_if_destroy(port->lport); |
1952 | 1956 | ||
1953 | /* Do not tear down the fcoe interface for NPIV port */ | 1957 | /* Do not tear down the fcoe interface for NPIV port */ |
1954 | if (!npiv) { | 1958 | if (!npiv) |
1955 | rtnl_lock(); | ||
1956 | fcoe_interface_cleanup(fcoe); | 1959 | fcoe_interface_cleanup(fcoe); |
1957 | rtnl_unlock(); | ||
1958 | } | ||
1959 | 1960 | ||
1960 | mutex_unlock(&fcoe_config_mutex); | 1961 | mutex_unlock(&fcoe_config_mutex); |
1961 | } | 1962 | } |
@@ -2009,8 +2010,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2009 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", | 2010 | printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", |
2010 | netdev->name); | 2011 | netdev->name); |
2011 | rc = -EIO; | 2012 | rc = -EIO; |
2013 | rtnl_unlock(); | ||
2012 | fcoe_interface_cleanup(fcoe); | 2014 | fcoe_interface_cleanup(fcoe); |
2013 | goto out_nodev; | 2015 | goto out_nortnl; |
2014 | } | 2016 | } |
2015 | 2017 | ||
2016 | /* Make this the "master" N_Port */ | 2018 | /* Make this the "master" N_Port */ |
@@ -2027,6 +2029,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) | |||
2027 | 2029 | ||
2028 | out_nodev: | 2030 | out_nodev: |
2029 | rtnl_unlock(); | 2031 | rtnl_unlock(); |
2032 | out_nortnl: | ||
2030 | mutex_unlock(&fcoe_config_mutex); | 2033 | mutex_unlock(&fcoe_config_mutex); |
2031 | return rc; | 2034 | return rc; |
2032 | } | 2035 | } |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index ec61bdb833ac..b200b736b000 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -676,6 +676,16 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno, | |||
676 | BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); | 676 | BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA); |
677 | removed[*nremoved] = h->dev[entry]; | 677 | removed[*nremoved] = h->dev[entry]; |
678 | (*nremoved)++; | 678 | (*nremoved)++; |
679 | |||
680 | /* | ||
681 | * New physical devices won't have target/lun assigned yet | ||
682 | * so we need to preserve the values in the slot we are replacing. | ||
683 | */ | ||
684 | if (new_entry->target == -1) { | ||
685 | new_entry->target = h->dev[entry]->target; | ||
686 | new_entry->lun = h->dev[entry]->lun; | ||
687 | } | ||
688 | |||
679 | h->dev[entry] = new_entry; | 689 | h->dev[entry] = new_entry; |
680 | added[*nadded] = new_entry; | 690 | added[*nadded] = new_entry; |
681 | (*nadded)++; | 691 | (*nadded)++; |
@@ -1548,10 +1558,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device, | |||
1548 | } | 1558 | } |
1549 | 1559 | ||
1550 | static int hpsa_update_device_info(struct ctlr_info *h, | 1560 | static int hpsa_update_device_info(struct ctlr_info *h, |
1551 | unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device) | 1561 | unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device, |
1562 | unsigned char *is_OBDR_device) | ||
1552 | { | 1563 | { |
1553 | #define OBDR_TAPE_INQ_SIZE 49 | 1564 | |
1565 | #define OBDR_SIG_OFFSET 43 | ||
1566 | #define OBDR_TAPE_SIG "$DR-10" | ||
1567 | #define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1) | ||
1568 | #define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN) | ||
1569 | |||
1554 | unsigned char *inq_buff; | 1570 | unsigned char *inq_buff; |
1571 | unsigned char *obdr_sig; | ||
1555 | 1572 | ||
1556 | inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | 1573 | inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); |
1557 | if (!inq_buff) | 1574 | if (!inq_buff) |
@@ -1583,6 +1600,16 @@ static int hpsa_update_device_info(struct ctlr_info *h, | |||
1583 | else | 1600 | else |
1584 | this_device->raid_level = RAID_UNKNOWN; | 1601 | this_device->raid_level = RAID_UNKNOWN; |
1585 | 1602 | ||
1603 | if (is_OBDR_device) { | ||
1604 | /* See if this is a One-Button-Disaster-Recovery device | ||
1605 | * by looking for "$DR-10" at offset 43 in inquiry data. | ||
1606 | */ | ||
1607 | obdr_sig = &inq_buff[OBDR_SIG_OFFSET]; | ||
1608 | *is_OBDR_device = (this_device->devtype == TYPE_ROM && | ||
1609 | strncmp(obdr_sig, OBDR_TAPE_SIG, | ||
1610 | OBDR_SIG_LEN) == 0); | ||
1611 | } | ||
1612 | |||
1586 | kfree(inq_buff); | 1613 | kfree(inq_buff); |
1587 | return 0; | 1614 | return 0; |
1588 | 1615 | ||
@@ -1716,7 +1743,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h, | |||
1716 | return 0; | 1743 | return 0; |
1717 | } | 1744 | } |
1718 | 1745 | ||
1719 | if (hpsa_update_device_info(h, scsi3addr, this_device)) | 1746 | if (hpsa_update_device_info(h, scsi3addr, this_device, NULL)) |
1720 | return 0; | 1747 | return 0; |
1721 | (*nmsa2xxx_enclosures)++; | 1748 | (*nmsa2xxx_enclosures)++; |
1722 | hpsa_set_bus_target_lun(this_device, bus, target, 0); | 1749 | hpsa_set_bus_target_lun(this_device, bus, target, 0); |
@@ -1808,7 +1835,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1808 | */ | 1835 | */ |
1809 | struct ReportLUNdata *physdev_list = NULL; | 1836 | struct ReportLUNdata *physdev_list = NULL; |
1810 | struct ReportLUNdata *logdev_list = NULL; | 1837 | struct ReportLUNdata *logdev_list = NULL; |
1811 | unsigned char *inq_buff = NULL; | ||
1812 | u32 nphysicals = 0; | 1838 | u32 nphysicals = 0; |
1813 | u32 nlogicals = 0; | 1839 | u32 nlogicals = 0; |
1814 | u32 ndev_allocated = 0; | 1840 | u32 ndev_allocated = 0; |
@@ -1824,11 +1850,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1824 | GFP_KERNEL); | 1850 | GFP_KERNEL); |
1825 | physdev_list = kzalloc(reportlunsize, GFP_KERNEL); | 1851 | physdev_list = kzalloc(reportlunsize, GFP_KERNEL); |
1826 | logdev_list = kzalloc(reportlunsize, GFP_KERNEL); | 1852 | logdev_list = kzalloc(reportlunsize, GFP_KERNEL); |
1827 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | ||
1828 | tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); | 1853 | tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); |
1829 | 1854 | ||
1830 | if (!currentsd || !physdev_list || !logdev_list || | 1855 | if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) { |
1831 | !inq_buff || !tmpdevice) { | ||
1832 | dev_err(&h->pdev->dev, "out of memory\n"); | 1856 | dev_err(&h->pdev->dev, "out of memory\n"); |
1833 | goto out; | 1857 | goto out; |
1834 | } | 1858 | } |
@@ -1863,7 +1887,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1863 | /* adjust our table of devices */ | 1887 | /* adjust our table of devices */ |
1864 | nmsa2xxx_enclosures = 0; | 1888 | nmsa2xxx_enclosures = 0; |
1865 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { | 1889 | for (i = 0; i < nphysicals + nlogicals + 1; i++) { |
1866 | u8 *lunaddrbytes; | 1890 | u8 *lunaddrbytes, is_OBDR = 0; |
1867 | 1891 | ||
1868 | /* Figure out where the LUN ID info is coming from */ | 1892 | /* Figure out where the LUN ID info is coming from */ |
1869 | lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, | 1893 | lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position, |
@@ -1874,7 +1898,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1874 | continue; | 1898 | continue; |
1875 | 1899 | ||
1876 | /* Get device type, vendor, model, device id */ | 1900 | /* Get device type, vendor, model, device id */ |
1877 | if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice)) | 1901 | if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice, |
1902 | &is_OBDR)) | ||
1878 | continue; /* skip it if we can't talk to it. */ | 1903 | continue; /* skip it if we can't talk to it. */ |
1879 | figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, | 1904 | figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun, |
1880 | tmpdevice); | 1905 | tmpdevice); |
@@ -1898,7 +1923,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1898 | hpsa_set_bus_target_lun(this_device, bus, target, lun); | 1923 | hpsa_set_bus_target_lun(this_device, bus, target, lun); |
1899 | 1924 | ||
1900 | switch (this_device->devtype) { | 1925 | switch (this_device->devtype) { |
1901 | case TYPE_ROM: { | 1926 | case TYPE_ROM: |
1902 | /* We don't *really* support actual CD-ROM devices, | 1927 | /* We don't *really* support actual CD-ROM devices, |
1903 | * just "One Button Disaster Recovery" tape drive | 1928 | * just "One Button Disaster Recovery" tape drive |
1904 | * which temporarily pretends to be a CD-ROM drive. | 1929 | * which temporarily pretends to be a CD-ROM drive. |
@@ -1906,15 +1931,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
1906 | * device by checking for "$DR-10" in bytes 43-48 of | 1931 | * device by checking for "$DR-10" in bytes 43-48 of |
1907 | * the inquiry data. | 1932 | * the inquiry data. |
1908 | */ | 1933 | */ |
1909 | char obdr_sig[7]; | 1934 | if (is_OBDR) |
1910 | #define OBDR_TAPE_SIG "$DR-10" | 1935 | ncurrent++; |
1911 | strncpy(obdr_sig, &inq_buff[43], 6); | ||
1912 | obdr_sig[6] = '\0'; | ||
1913 | if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0) | ||
1914 | /* Not OBDR device, ignore it. */ | ||
1915 | break; | ||
1916 | } | ||
1917 | ncurrent++; | ||
1918 | break; | 1936 | break; |
1919 | case TYPE_DISK: | 1937 | case TYPE_DISK: |
1920 | if (i < nphysicals) | 1938 | if (i < nphysicals) |
@@ -1947,7 +1965,6 @@ out: | |||
1947 | for (i = 0; i < ndev_allocated; i++) | 1965 | for (i = 0; i < ndev_allocated; i++) |
1948 | kfree(currentsd[i]); | 1966 | kfree(currentsd[i]); |
1949 | kfree(currentsd); | 1967 | kfree(currentsd); |
1950 | kfree(inq_buff); | ||
1951 | kfree(physdev_list); | 1968 | kfree(physdev_list); |
1952 | kfree(logdev_list); | 1969 | kfree(logdev_list); |
1953 | } | 1970 | } |
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 26072f1e9852..6981b773a88d 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
@@ -531,6 +531,9 @@ static void sci_controller_process_completions(struct isci_host *ihost) | |||
531 | break; | 531 | break; |
532 | 532 | ||
533 | case SCU_COMPLETION_TYPE_EVENT: | 533 | case SCU_COMPLETION_TYPE_EVENT: |
534 | sci_controller_event_completion(ihost, ent); | ||
535 | break; | ||
536 | |||
534 | case SCU_COMPLETION_TYPE_NOTIFY: { | 537 | case SCU_COMPLETION_TYPE_NOTIFY: { |
535 | event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) << | 538 | event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) << |
536 | (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT); | 539 | (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT); |
@@ -1091,6 +1094,7 @@ static void isci_host_completion_routine(unsigned long data) | |||
1091 | struct isci_request *request; | 1094 | struct isci_request *request; |
1092 | struct isci_request *next_request; | 1095 | struct isci_request *next_request; |
1093 | struct sas_task *task; | 1096 | struct sas_task *task; |
1097 | u16 active; | ||
1094 | 1098 | ||
1095 | INIT_LIST_HEAD(&completed_request_list); | 1099 | INIT_LIST_HEAD(&completed_request_list); |
1096 | INIT_LIST_HEAD(&errored_request_list); | 1100 | INIT_LIST_HEAD(&errored_request_list); |
@@ -1181,6 +1185,13 @@ static void isci_host_completion_routine(unsigned long data) | |||
1181 | } | 1185 | } |
1182 | } | 1186 | } |
1183 | 1187 | ||
1188 | /* the coalesence timeout doubles at each encoding step, so | ||
1189 | * update it based on the ilog2 value of the outstanding requests | ||
1190 | */ | ||
1191 | active = isci_tci_active(ihost); | ||
1192 | writel(SMU_ICC_GEN_VAL(NUMBER, active) | | ||
1193 | SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)), | ||
1194 | &ihost->smu_registers->interrupt_coalesce_control); | ||
1184 | } | 1195 | } |
1185 | 1196 | ||
1186 | /** | 1197 | /** |
@@ -1471,7 +1482,7 @@ static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm) | |||
1471 | struct isci_host *ihost = container_of(sm, typeof(*ihost), sm); | 1482 | struct isci_host *ihost = container_of(sm, typeof(*ihost), sm); |
1472 | 1483 | ||
1473 | /* set the default interrupt coalescence number and timeout value. */ | 1484 | /* set the default interrupt coalescence number and timeout value. */ |
1474 | sci_controller_set_interrupt_coalescence(ihost, 0x10, 250); | 1485 | sci_controller_set_interrupt_coalescence(ihost, 0, 0); |
1475 | } | 1486 | } |
1476 | 1487 | ||
1477 | static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm) | 1488 | static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm) |
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h index 062101a39f79..9f33831a2f04 100644 --- a/drivers/scsi/isci/host.h +++ b/drivers/scsi/isci/host.h | |||
@@ -369,6 +369,9 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev) | |||
369 | #define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1)) | 369 | #define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1)) |
370 | #define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1)) | 370 | #define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1)) |
371 | 371 | ||
372 | /* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */ | ||
373 | #define ISCI_COALESCE_BASE 9 | ||
374 | |||
372 | /* expander attached sata devices require 3 rnc slots */ | 375 | /* expander attached sata devices require 3 rnc slots */ |
373 | static inline int sci_remote_device_node_count(struct isci_remote_device *idev) | 376 | static inline int sci_remote_device_node_count(struct isci_remote_device *idev) |
374 | { | 377 | { |
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 61e0d09e2b57..29aa34efb0f5 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c | |||
@@ -59,10 +59,19 @@ | |||
59 | #include <linux/firmware.h> | 59 | #include <linux/firmware.h> |
60 | #include <linux/efi.h> | 60 | #include <linux/efi.h> |
61 | #include <asm/string.h> | 61 | #include <asm/string.h> |
62 | #include <scsi/scsi_host.h> | ||
62 | #include "isci.h" | 63 | #include "isci.h" |
63 | #include "task.h" | 64 | #include "task.h" |
64 | #include "probe_roms.h" | 65 | #include "probe_roms.h" |
65 | 66 | ||
67 | #define MAJ 1 | ||
68 | #define MIN 0 | ||
69 | #define BUILD 0 | ||
70 | #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ | ||
71 | __stringify(BUILD) | ||
72 | |||
73 | MODULE_VERSION(DRV_VERSION); | ||
74 | |||
66 | static struct scsi_transport_template *isci_transport_template; | 75 | static struct scsi_transport_template *isci_transport_template; |
67 | 76 | ||
68 | static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = { | 77 | static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = { |
@@ -113,6 +122,22 @@ unsigned char max_concurr_spinup = 1; | |||
113 | module_param(max_concurr_spinup, byte, 0); | 122 | module_param(max_concurr_spinup, byte, 0); |
114 | MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup"); | 123 | MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup"); |
115 | 124 | ||
125 | static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) | ||
126 | { | ||
127 | struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); | ||
128 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | ||
129 | struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); | ||
130 | |||
131 | return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); | ||
132 | } | ||
133 | |||
134 | static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); | ||
135 | |||
136 | struct device_attribute *isci_host_attrs[] = { | ||
137 | &dev_attr_isci_id, | ||
138 | NULL | ||
139 | }; | ||
140 | |||
116 | static struct scsi_host_template isci_sht = { | 141 | static struct scsi_host_template isci_sht = { |
117 | 142 | ||
118 | .module = THIS_MODULE, | 143 | .module = THIS_MODULE, |
@@ -138,6 +163,7 @@ static struct scsi_host_template isci_sht = { | |||
138 | .slave_alloc = sas_slave_alloc, | 163 | .slave_alloc = sas_slave_alloc, |
139 | .target_destroy = sas_target_destroy, | 164 | .target_destroy = sas_target_destroy, |
140 | .ioctl = sas_ioctl, | 165 | .ioctl = sas_ioctl, |
166 | .shost_attrs = isci_host_attrs, | ||
141 | }; | 167 | }; |
142 | 168 | ||
143 | static struct sas_domain_function_template isci_transport_ops = { | 169 | static struct sas_domain_function_template isci_transport_ops = { |
@@ -232,17 +258,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host) | |||
232 | return 0; | 258 | return 0; |
233 | } | 259 | } |
234 | 260 | ||
235 | static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) | ||
236 | { | ||
237 | struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); | ||
238 | struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); | ||
239 | struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); | ||
240 | |||
241 | return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); | ||
242 | } | ||
243 | |||
244 | static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); | ||
245 | |||
246 | static void isci_unregister(struct isci_host *isci_host) | 261 | static void isci_unregister(struct isci_host *isci_host) |
247 | { | 262 | { |
248 | struct Scsi_Host *shost; | 263 | struct Scsi_Host *shost; |
@@ -251,7 +266,6 @@ static void isci_unregister(struct isci_host *isci_host) | |||
251 | return; | 266 | return; |
252 | 267 | ||
253 | shost = isci_host->shost; | 268 | shost = isci_host->shost; |
254 | device_remove_file(&shost->shost_dev, &dev_attr_isci_id); | ||
255 | 269 | ||
256 | sas_unregister_ha(&isci_host->sas_ha); | 270 | sas_unregister_ha(&isci_host->sas_ha); |
257 | 271 | ||
@@ -415,14 +429,8 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id) | |||
415 | if (err) | 429 | if (err) |
416 | goto err_shost_remove; | 430 | goto err_shost_remove; |
417 | 431 | ||
418 | err = device_create_file(&shost->shost_dev, &dev_attr_isci_id); | ||
419 | if (err) | ||
420 | goto err_unregister_ha; | ||
421 | |||
422 | return isci_host; | 432 | return isci_host; |
423 | 433 | ||
424 | err_unregister_ha: | ||
425 | sas_unregister_ha(&(isci_host->sas_ha)); | ||
426 | err_shost_remove: | 434 | err_shost_remove: |
427 | scsi_remove_host(shost); | 435 | scsi_remove_host(shost); |
428 | err_shost: | 436 | err_shost: |
@@ -540,7 +548,8 @@ static __init int isci_init(void) | |||
540 | { | 548 | { |
541 | int err; | 549 | int err; |
542 | 550 | ||
543 | pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME); | 551 | pr_info("%s: Intel(R) C600 SAS Controller Driver - version %s\n", |
552 | DRV_NAME, DRV_VERSION); | ||
544 | 553 | ||
545 | isci_transport_template = sas_domain_attach_transport(&isci_transport_ops); | 554 | isci_transport_template = sas_domain_attach_transport(&isci_transport_ops); |
546 | if (!isci_transport_template) | 555 | if (!isci_transport_template) |
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c index 79313a7a2356..430fc8ff014a 100644 --- a/drivers/scsi/isci/phy.c +++ b/drivers/scsi/isci/phy.c | |||
@@ -104,6 +104,7 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, | |||
104 | u32 parity_count = 0; | 104 | u32 parity_count = 0; |
105 | u32 llctl, link_rate; | 105 | u32 llctl, link_rate; |
106 | u32 clksm_value = 0; | 106 | u32 clksm_value = 0; |
107 | u32 sp_timeouts = 0; | ||
107 | 108 | ||
108 | iphy->link_layer_registers = reg; | 109 | iphy->link_layer_registers = reg; |
109 | 110 | ||
@@ -211,6 +212,18 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy, | |||
211 | llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate); | 212 | llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate); |
212 | writel(llctl, &iphy->link_layer_registers->link_layer_control); | 213 | writel(llctl, &iphy->link_layer_registers->link_layer_control); |
213 | 214 | ||
215 | sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts); | ||
216 | |||
217 | /* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */ | ||
218 | sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF); | ||
219 | |||
220 | /* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can | ||
221 | * lock with 3Gb drive when SCU max rate is set to 1.5Gb. | ||
222 | */ | ||
223 | sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B); | ||
224 | |||
225 | writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts); | ||
226 | |||
214 | if (is_a2(ihost->pdev)) { | 227 | if (is_a2(ihost->pdev)) { |
215 | /* Program the max ARB time for the PHY to 700us so we inter-operate with | 228 | /* Program the max ARB time for the PHY to 700us so we inter-operate with |
216 | * the PMC expander which shuts down PHYs if the expander PHY generates too | 229 | * the PMC expander which shuts down PHYs if the expander PHY generates too |
diff --git a/drivers/scsi/isci/registers.h b/drivers/scsi/isci/registers.h index 9b266c7428e8..00afc738bbed 100644 --- a/drivers/scsi/isci/registers.h +++ b/drivers/scsi/isci/registers.h | |||
@@ -1299,6 +1299,18 @@ struct scu_transport_layer_registers { | |||
1299 | #define SCU_AFE_XCVRCR_OFFSET 0x00DC | 1299 | #define SCU_AFE_XCVRCR_OFFSET 0x00DC |
1300 | #define SCU_AFE_LUTCR_OFFSET 0x00E0 | 1300 | #define SCU_AFE_LUTCR_OFFSET 0x00E0 |
1301 | 1301 | ||
1302 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT (0UL) | ||
1303 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK (0x000000FFUL) | ||
1304 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT (8UL) | ||
1305 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK (0x0000FF00UL) | ||
1306 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT (16UL) | ||
1307 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK (0x00FF0000UL) | ||
1308 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT (24UL) | ||
1309 | #define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK (0xFF000000UL) | ||
1310 | |||
1311 | #define SCU_SAS_PHYTOV_GEN_VAL(name, value) \ | ||
1312 | SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value) | ||
1313 | |||
1302 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0) | 1314 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0) |
1303 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003) | 1315 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003) |
1304 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0) | 1316 | #define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0) |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index a46e07ac789f..b5d3a8c4d329 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -732,12 +732,20 @@ sci_io_request_terminate(struct isci_request *ireq) | |||
732 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); | 732 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); |
733 | return SCI_SUCCESS; | 733 | return SCI_SUCCESS; |
734 | case SCI_REQ_TASK_WAIT_TC_RESP: | 734 | case SCI_REQ_TASK_WAIT_TC_RESP: |
735 | /* The task frame was already confirmed to have been | ||
736 | * sent by the SCU HW. Since the state machine is | ||
737 | * now only waiting for the task response itself, | ||
738 | * abort the request and complete it immediately | ||
739 | * and don't wait for the task response. | ||
740 | */ | ||
735 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); | 741 | sci_change_state(&ireq->sm, SCI_REQ_ABORTING); |
736 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 742 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); |
737 | return SCI_SUCCESS; | 743 | return SCI_SUCCESS; |
738 | case SCI_REQ_ABORTING: | 744 | case SCI_REQ_ABORTING: |
739 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 745 | /* If a request has a termination requested twice, return |
740 | return SCI_SUCCESS; | 746 | * a failure indication, since HW confirmation of the first |
747 | * abort is still outstanding. | ||
748 | */ | ||
741 | case SCI_REQ_COMPLETED: | 749 | case SCI_REQ_COMPLETED: |
742 | default: | 750 | default: |
743 | dev_warn(&ireq->owning_controller->pdev->dev, | 751 | dev_warn(&ireq->owning_controller->pdev->dev, |
@@ -2399,22 +2407,19 @@ static void isci_task_save_for_upper_layer_completion( | |||
2399 | } | 2407 | } |
2400 | } | 2408 | } |
2401 | 2409 | ||
2402 | static void isci_request_process_stp_response(struct sas_task *task, | 2410 | static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis) |
2403 | void *response_buffer) | ||
2404 | { | 2411 | { |
2405 | struct dev_to_host_fis *d2h_reg_fis = response_buffer; | ||
2406 | struct task_status_struct *ts = &task->task_status; | 2412 | struct task_status_struct *ts = &task->task_status; |
2407 | struct ata_task_resp *resp = (void *)&ts->buf[0]; | 2413 | struct ata_task_resp *resp = (void *)&ts->buf[0]; |
2408 | 2414 | ||
2409 | resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6)); | 2415 | resp->frame_len = sizeof(*fis); |
2410 | memcpy(&resp->ending_fis[0], response_buffer + 16, 24); | 2416 | memcpy(resp->ending_fis, fis, sizeof(*fis)); |
2411 | ts->buf_valid_size = sizeof(*resp); | 2417 | ts->buf_valid_size = sizeof(*resp); |
2412 | 2418 | ||
2413 | /** | 2419 | /* If the device fault bit is set in the status register, then |
2414 | * If the device fault bit is set in the status register, then | ||
2415 | * set the sense data and return. | 2420 | * set the sense data and return. |
2416 | */ | 2421 | */ |
2417 | if (d2h_reg_fis->status & ATA_DF) | 2422 | if (fis->status & ATA_DF) |
2418 | ts->stat = SAS_PROTO_RESPONSE; | 2423 | ts->stat = SAS_PROTO_RESPONSE; |
2419 | else | 2424 | else |
2420 | ts->stat = SAM_STAT_GOOD; | 2425 | ts->stat = SAM_STAT_GOOD; |
@@ -2428,7 +2433,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2428 | { | 2433 | { |
2429 | struct sas_task *task = isci_request_access_task(request); | 2434 | struct sas_task *task = isci_request_access_task(request); |
2430 | struct ssp_response_iu *resp_iu; | 2435 | struct ssp_response_iu *resp_iu; |
2431 | void *resp_buf; | ||
2432 | unsigned long task_flags; | 2436 | unsigned long task_flags; |
2433 | struct isci_remote_device *idev = isci_lookup_device(task->dev); | 2437 | struct isci_remote_device *idev = isci_lookup_device(task->dev); |
2434 | enum service_response response = SAS_TASK_UNDELIVERED; | 2438 | enum service_response response = SAS_TASK_UNDELIVERED; |
@@ -2565,9 +2569,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2565 | task); | 2569 | task); |
2566 | 2570 | ||
2567 | if (sas_protocol_ata(task->task_proto)) { | 2571 | if (sas_protocol_ata(task->task_proto)) { |
2568 | resp_buf = &request->stp.rsp; | 2572 | isci_process_stp_response(task, &request->stp.rsp); |
2569 | isci_request_process_stp_response(task, | ||
2570 | resp_buf); | ||
2571 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { | 2573 | } else if (SAS_PROTOCOL_SSP == task->task_proto) { |
2572 | 2574 | ||
2573 | /* crack the iu response buffer. */ | 2575 | /* crack the iu response buffer. */ |
diff --git a/drivers/scsi/isci/unsolicited_frame_control.c b/drivers/scsi/isci/unsolicited_frame_control.c index e9e1e2abacb9..16f88ab939c8 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.c +++ b/drivers/scsi/isci/unsolicited_frame_control.c | |||
@@ -72,7 +72,7 @@ int sci_unsolicited_frame_control_construct(struct isci_host *ihost) | |||
72 | */ | 72 | */ |
73 | buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; | 73 | buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE; |
74 | header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); | 74 | header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header); |
75 | size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t); | 75 | size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]); |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * The Unsolicited Frame buffers are set at the start of the UF | 78 | * The Unsolicited Frame buffers are set at the start of the UF |
diff --git a/drivers/scsi/isci/unsolicited_frame_control.h b/drivers/scsi/isci/unsolicited_frame_control.h index 31cb9506f52d..75d896686f5a 100644 --- a/drivers/scsi/isci/unsolicited_frame_control.h +++ b/drivers/scsi/isci/unsolicited_frame_control.h | |||
@@ -214,7 +214,7 @@ struct sci_uf_address_table_array { | |||
214 | * starting address of the UF address table. | 214 | * starting address of the UF address table. |
215 | * 64-bit pointers are required by the hardware. | 215 | * 64-bit pointers are required by the hardware. |
216 | */ | 216 | */ |
217 | dma_addr_t *array; | 217 | u64 *array; |
218 | 218 | ||
219 | /** | 219 | /** |
220 | * This field specifies the physical address location for the UF | 220 | * This field specifies the physical address location for the UF |
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 01ff082dc34c..d261e982a2fa 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c | |||
@@ -494,6 +494,9 @@ static int fc_seq_send(struct fc_lport *lport, struct fc_seq *sp, | |||
494 | */ | 494 | */ |
495 | error = lport->tt.frame_send(lport, fp); | 495 | error = lport->tt.frame_send(lport, fp); |
496 | 496 | ||
497 | if (fh->fh_type == FC_TYPE_BLS) | ||
498 | return error; | ||
499 | |||
497 | /* | 500 | /* |
498 | * Update the exchange and sequence flags, | 501 | * Update the exchange and sequence flags, |
499 | * assuming all frames for the sequence have been sent. | 502 | * assuming all frames for the sequence have been sent. |
@@ -575,42 +578,35 @@ static void fc_seq_set_resp(struct fc_seq *sp, | |||
575 | } | 578 | } |
576 | 579 | ||
577 | /** | 580 | /** |
578 | * fc_seq_exch_abort() - Abort an exchange and sequence | 581 | * fc_exch_abort_locked() - Abort an exchange |
579 | * @req_sp: The sequence to be aborted | 582 | * @ep: The exchange to be aborted |
580 | * @timer_msec: The period of time to wait before aborting | 583 | * @timer_msec: The period of time to wait before aborting |
581 | * | 584 | * |
582 | * Generally called because of a timeout or an abort from the upper layer. | 585 | * Locking notes: Called with exch lock held |
586 | * | ||
587 | * Return value: 0 on success else error code | ||
583 | */ | 588 | */ |
584 | static int fc_seq_exch_abort(const struct fc_seq *req_sp, | 589 | static int fc_exch_abort_locked(struct fc_exch *ep, |
585 | unsigned int timer_msec) | 590 | unsigned int timer_msec) |
586 | { | 591 | { |
587 | struct fc_seq *sp; | 592 | struct fc_seq *sp; |
588 | struct fc_exch *ep; | ||
589 | struct fc_frame *fp; | 593 | struct fc_frame *fp; |
590 | int error; | 594 | int error; |
591 | 595 | ||
592 | ep = fc_seq_exch(req_sp); | ||
593 | |||
594 | spin_lock_bh(&ep->ex_lock); | ||
595 | if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || | 596 | if (ep->esb_stat & (ESB_ST_COMPLETE | ESB_ST_ABNORMAL) || |
596 | ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) { | 597 | ep->state & (FC_EX_DONE | FC_EX_RST_CLEANUP)) |
597 | spin_unlock_bh(&ep->ex_lock); | ||
598 | return -ENXIO; | 598 | return -ENXIO; |
599 | } | ||
600 | 599 | ||
601 | /* | 600 | /* |
602 | * Send the abort on a new sequence if possible. | 601 | * Send the abort on a new sequence if possible. |
603 | */ | 602 | */ |
604 | sp = fc_seq_start_next_locked(&ep->seq); | 603 | sp = fc_seq_start_next_locked(&ep->seq); |
605 | if (!sp) { | 604 | if (!sp) |
606 | spin_unlock_bh(&ep->ex_lock); | ||
607 | return -ENOMEM; | 605 | return -ENOMEM; |
608 | } | ||
609 | 606 | ||
610 | ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL; | 607 | ep->esb_stat |= ESB_ST_SEQ_INIT | ESB_ST_ABNORMAL; |
611 | if (timer_msec) | 608 | if (timer_msec) |
612 | fc_exch_timer_set_locked(ep, timer_msec); | 609 | fc_exch_timer_set_locked(ep, timer_msec); |
613 | spin_unlock_bh(&ep->ex_lock); | ||
614 | 610 | ||
615 | /* | 611 | /* |
616 | * If not logged into the fabric, don't send ABTS but leave | 612 | * If not logged into the fabric, don't send ABTS but leave |
@@ -633,6 +629,28 @@ static int fc_seq_exch_abort(const struct fc_seq *req_sp, | |||
633 | } | 629 | } |
634 | 630 | ||
635 | /** | 631 | /** |
632 | * fc_seq_exch_abort() - Abort an exchange and sequence | ||
633 | * @req_sp: The sequence to be aborted | ||
634 | * @timer_msec: The period of time to wait before aborting | ||
635 | * | ||
636 | * Generally called because of a timeout or an abort from the upper layer. | ||
637 | * | ||
638 | * Return value: 0 on success else error code | ||
639 | */ | ||
640 | static int fc_seq_exch_abort(const struct fc_seq *req_sp, | ||
641 | unsigned int timer_msec) | ||
642 | { | ||
643 | struct fc_exch *ep; | ||
644 | int error; | ||
645 | |||
646 | ep = fc_seq_exch(req_sp); | ||
647 | spin_lock_bh(&ep->ex_lock); | ||
648 | error = fc_exch_abort_locked(ep, timer_msec); | ||
649 | spin_unlock_bh(&ep->ex_lock); | ||
650 | return error; | ||
651 | } | ||
652 | |||
653 | /** | ||
636 | * fc_exch_timeout() - Handle exchange timer expiration | 654 | * fc_exch_timeout() - Handle exchange timer expiration |
637 | * @work: The work_struct identifying the exchange that timed out | 655 | * @work: The work_struct identifying the exchange that timed out |
638 | */ | 656 | */ |
@@ -1715,6 +1733,7 @@ static void fc_exch_reset(struct fc_exch *ep) | |||
1715 | int rc = 1; | 1733 | int rc = 1; |
1716 | 1734 | ||
1717 | spin_lock_bh(&ep->ex_lock); | 1735 | spin_lock_bh(&ep->ex_lock); |
1736 | fc_exch_abort_locked(ep, 0); | ||
1718 | ep->state |= FC_EX_RST_CLEANUP; | 1737 | ep->state |= FC_EX_RST_CLEANUP; |
1719 | if (cancel_delayed_work(&ep->timeout_work)) | 1738 | if (cancel_delayed_work(&ep->timeout_work)) |
1720 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ | 1739 | atomic_dec(&ep->ex_refcnt); /* drop hold for timer */ |
@@ -1962,6 +1981,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1962 | struct fc_exch *ep; | 1981 | struct fc_exch *ep; |
1963 | struct fc_seq *sp = NULL; | 1982 | struct fc_seq *sp = NULL; |
1964 | struct fc_frame_header *fh; | 1983 | struct fc_frame_header *fh; |
1984 | struct fc_fcp_pkt *fsp = NULL; | ||
1965 | int rc = 1; | 1985 | int rc = 1; |
1966 | 1986 | ||
1967 | ep = fc_exch_alloc(lport, fp); | 1987 | ep = fc_exch_alloc(lport, fp); |
@@ -1984,8 +2004,10 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1984 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); | 2004 | fc_exch_setup_hdr(ep, fp, ep->f_ctl); |
1985 | sp->cnt++; | 2005 | sp->cnt++; |
1986 | 2006 | ||
1987 | if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) | 2007 | if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD) { |
2008 | fsp = fr_fsp(fp); | ||
1988 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); | 2009 | fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); |
2010 | } | ||
1989 | 2011 | ||
1990 | if (unlikely(lport->tt.frame_send(lport, fp))) | 2012 | if (unlikely(lport->tt.frame_send(lport, fp))) |
1991 | goto err; | 2013 | goto err; |
@@ -1999,7 +2021,8 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, | |||
1999 | spin_unlock_bh(&ep->ex_lock); | 2021 | spin_unlock_bh(&ep->ex_lock); |
2000 | return sp; | 2022 | return sp; |
2001 | err: | 2023 | err: |
2002 | fc_fcp_ddp_done(fr_fsp(fp)); | 2024 | if (fsp) |
2025 | fc_fcp_ddp_done(fsp); | ||
2003 | rc = fc_exch_done_locked(ep); | 2026 | rc = fc_exch_done_locked(ep); |
2004 | spin_unlock_bh(&ep->ex_lock); | 2027 | spin_unlock_bh(&ep->ex_lock); |
2005 | if (!rc) | 2028 | if (!rc) |
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index afb63c843144..4c41ee816f0b 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c | |||
@@ -2019,6 +2019,11 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd) | |||
2019 | struct fc_fcp_internal *si; | 2019 | struct fc_fcp_internal *si; |
2020 | int rc = FAILED; | 2020 | int rc = FAILED; |
2021 | unsigned long flags; | 2021 | unsigned long flags; |
2022 | int rval; | ||
2023 | |||
2024 | rval = fc_block_scsi_eh(sc_cmd); | ||
2025 | if (rval) | ||
2026 | return rval; | ||
2022 | 2027 | ||
2023 | lport = shost_priv(sc_cmd->device->host); | 2028 | lport = shost_priv(sc_cmd->device->host); |
2024 | if (lport->state != LPORT_ST_READY) | 2029 | if (lport->state != LPORT_ST_READY) |
@@ -2068,9 +2073,9 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd) | |||
2068 | int rc = FAILED; | 2073 | int rc = FAILED; |
2069 | int rval; | 2074 | int rval; |
2070 | 2075 | ||
2071 | rval = fc_remote_port_chkready(rport); | 2076 | rval = fc_block_scsi_eh(sc_cmd); |
2072 | if (rval) | 2077 | if (rval) |
2073 | goto out; | 2078 | return rval; |
2074 | 2079 | ||
2075 | lport = shost_priv(sc_cmd->device->host); | 2080 | lport = shost_priv(sc_cmd->device->host); |
2076 | 2081 | ||
@@ -2116,6 +2121,8 @@ int fc_eh_host_reset(struct scsi_cmnd *sc_cmd) | |||
2116 | 2121 | ||
2117 | FC_SCSI_DBG(lport, "Resetting host\n"); | 2122 | FC_SCSI_DBG(lport, "Resetting host\n"); |
2118 | 2123 | ||
2124 | fc_block_scsi_eh(sc_cmd); | ||
2125 | |||
2119 | lport->tt.lport_reset(lport); | 2126 | lport->tt.lport_reset(lport); |
2120 | wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; | 2127 | wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT; |
2121 | while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies, | 2128 | while (!fc_fcp_lport_queue_ready(lport) && time_before(jiffies, |
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index e55ed9cf23fb..628f347404f9 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c | |||
@@ -88,6 +88,7 @@ | |||
88 | */ | 88 | */ |
89 | 89 | ||
90 | #include <linux/timer.h> | 90 | #include <linux/timer.h> |
91 | #include <linux/delay.h> | ||
91 | #include <linux/slab.h> | 92 | #include <linux/slab.h> |
92 | #include <asm/unaligned.h> | 93 | #include <asm/unaligned.h> |
93 | 94 | ||
@@ -1029,8 +1030,16 @@ static void fc_lport_enter_reset(struct fc_lport *lport) | |||
1029 | FCH_EVT_LIPRESET, 0); | 1030 | FCH_EVT_LIPRESET, 0); |
1030 | fc_vports_linkchange(lport); | 1031 | fc_vports_linkchange(lport); |
1031 | fc_lport_reset_locked(lport); | 1032 | fc_lport_reset_locked(lport); |
1032 | if (lport->link_up) | 1033 | if (lport->link_up) { |
1034 | /* | ||
1035 | * Wait upto resource allocation time out before | ||
1036 | * doing re-login since incomplete FIP exchanged | ||
1037 | * from last session may collide with exchanges | ||
1038 | * in new session. | ||
1039 | */ | ||
1040 | msleep(lport->r_a_tov); | ||
1033 | fc_lport_enter_flogi(lport); | 1041 | fc_lport_enter_flogi(lport); |
1042 | } | ||
1034 | } | 1043 | } |
1035 | 1044 | ||
1036 | /** | 1045 | /** |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 7836eb01c7fc..a31e05f3bfd4 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1786,13 +1786,16 @@ qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | |||
1786 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); | 1786 | fc_vport_set_state(fc_vport, FC_VPORT_LINKDOWN); |
1787 | } | 1787 | } |
1788 | 1788 | ||
1789 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) { | 1789 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
1790 | if (ha->fw_attributes & BIT_4) { | 1790 | if (ha->fw_attributes & BIT_4) { |
1791 | int prot = 0; | ||
1791 | vha->flags.difdix_supported = 1; | 1792 | vha->flags.difdix_supported = 1; |
1792 | ql_dbg(ql_dbg_user, vha, 0x7082, | 1793 | ql_dbg(ql_dbg_user, vha, 0x7082, |
1793 | "Registered for DIF/DIX type 1 and 3 protection.\n"); | 1794 | "Registered for DIF/DIX type 1 and 3 protection.\n"); |
1795 | if (ql2xenabledif == 1) | ||
1796 | prot = SHOST_DIX_TYPE0_PROTECTION; | ||
1794 | scsi_host_set_prot(vha->host, | 1797 | scsi_host_set_prot(vha->host, |
1795 | SHOST_DIF_TYPE1_PROTECTION | 1798 | prot | SHOST_DIF_TYPE1_PROTECTION |
1796 | | SHOST_DIF_TYPE2_PROTECTION | 1799 | | SHOST_DIF_TYPE2_PROTECTION |
1797 | | SHOST_DIF_TYPE3_PROTECTION | 1800 | | SHOST_DIF_TYPE3_PROTECTION |
1798 | | SHOST_DIX_TYPE1_PROTECTION | 1801 | | SHOST_DIX_TYPE1_PROTECTION |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 2155071f3100..d79cd8a5f831 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -8,24 +8,24 @@ | |||
8 | /* | 8 | /* |
9 | * Table for showing the current message id in use for particular level | 9 | * Table for showing the current message id in use for particular level |
10 | * Change this table for addition of log/debug messages. | 10 | * Change this table for addition of log/debug messages. |
11 | * ----------------------------------------------------- | 11 | * ---------------------------------------------------------------------- |
12 | * | Level | Last Value Used | | 12 | * | Level | Last Value Used | Holes | |
13 | * ----------------------------------------------------- | 13 | * ---------------------------------------------------------------------- |
14 | * | Module Init and Probe | 0x0116 | | 14 | * | Module Init and Probe | 0x0116 | | |
15 | * | Mailbox commands | 0x111e | | 15 | * | Mailbox commands | 0x1126 | | |
16 | * | Device Discovery | 0x2083 | | 16 | * | Device Discovery | 0x2083 | | |
17 | * | Queue Command and IO tracing | 0x302e | | 17 | * | Queue Command and IO tracing | 0x302e | 0x3008 | |
18 | * | DPC Thread | 0x401c | | 18 | * | DPC Thread | 0x401c | | |
19 | * | Async Events | 0x5059 | | 19 | * | Async Events | 0x5059 | | |
20 | * | Timer Routines | 0x600d | | 20 | * | Timer Routines | 0x600d | | |
21 | * | User Space Interactions | 0x709c | | 21 | * | User Space Interactions | 0x709d | | |
22 | * | Task Management | 0x8043 | | 22 | * | Task Management | 0x8041 | | |
23 | * | AER/EEH | 0x900f | | 23 | * | AER/EEH | 0x900f | | |
24 | * | Virtual Port | 0xa007 | | 24 | * | Virtual Port | 0xa007 | | |
25 | * | ISP82XX Specific | 0xb027 | | 25 | * | ISP82XX Specific | 0xb04f | | |
26 | * | MultiQ | 0xc00b | | 26 | * | MultiQ | 0xc00b | | |
27 | * | Misc | 0xd00b | | 27 | * | Misc | 0xd00b | | |
28 | * ----------------------------------------------------- | 28 | * ---------------------------------------------------------------------- |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include "qla_def.h" | 31 | #include "qla_def.h" |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index cc5a79259d33..a03eaf40f377 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2529,6 +2529,7 @@ struct qla_hw_data { | |||
2529 | #define DT_ISP8021 BIT_14 | 2529 | #define DT_ISP8021 BIT_14 |
2530 | #define DT_ISP_LAST (DT_ISP8021 << 1) | 2530 | #define DT_ISP_LAST (DT_ISP8021 << 1) |
2531 | 2531 | ||
2532 | #define DT_T10_PI BIT_25 | ||
2532 | #define DT_IIDMA BIT_26 | 2533 | #define DT_IIDMA BIT_26 |
2533 | #define DT_FWI2 BIT_27 | 2534 | #define DT_FWI2 BIT_27 |
2534 | #define DT_ZIO_SUPPORTED BIT_28 | 2535 | #define DT_ZIO_SUPPORTED BIT_28 |
@@ -2572,6 +2573,7 @@ struct qla_hw_data { | |||
2572 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha)) | 2573 | #define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha)) |
2573 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) | 2574 | #define IS_ALOGIO_CAPABLE(ha) (IS_QLA23XX(ha) || IS_FWI2_CAPABLE(ha)) |
2574 | 2575 | ||
2576 | #define IS_T10_PI_CAPABLE(ha) ((ha)->device_type & DT_T10_PI) | ||
2575 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) | 2577 | #define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA) |
2576 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) | 2578 | #define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2) |
2577 | #define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) | 2579 | #define IS_ZIO_SUPPORTED(ha) ((ha)->device_type & DT_ZIO_SUPPORTED) |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 691783abfb69..aa69486dc064 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -537,6 +537,11 @@ struct sts_entry_24xx { | |||
537 | /* | 537 | /* |
538 | * If DIF Error is set in comp_status, these additional fields are | 538 | * If DIF Error is set in comp_status, these additional fields are |
539 | * defined: | 539 | * defined: |
540 | * | ||
541 | * !!! NOTE: Firmware sends expected/actual DIF data in big endian | ||
542 | * format; but all of the "data" field gets swab32-d in the beginning | ||
543 | * of qla2x00_status_entry(). | ||
544 | * | ||
540 | * &data[10] : uint8_t report_runt_bg[2]; - computed guard | 545 | * &data[10] : uint8_t report_runt_bg[2]; - computed guard |
541 | * &data[12] : uint8_t actual_dif[8]; - DIF Data received | 546 | * &data[12] : uint8_t actual_dif[8]; - DIF Data received |
542 | * &data[20] : uint8_t expected_dif[8]; - DIF Data computed | 547 | * &data[20] : uint8_t expected_dif[8]; - DIF Data computed |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index def694271bf7..37da04d3db26 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -3838,15 +3838,12 @@ qla2x00_loop_resync(scsi_qla_host_t *vha) | |||
3838 | req = vha->req; | 3838 | req = vha->req; |
3839 | rsp = req->rsp; | 3839 | rsp = req->rsp; |
3840 | 3840 | ||
3841 | atomic_set(&vha->loop_state, LOOP_UPDATE); | ||
3842 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); | 3841 | clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags); |
3843 | if (vha->flags.online) { | 3842 | if (vha->flags.online) { |
3844 | if (!(rval = qla2x00_fw_ready(vha))) { | 3843 | if (!(rval = qla2x00_fw_ready(vha))) { |
3845 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ | 3844 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ |
3846 | wait_time = 256; | 3845 | wait_time = 256; |
3847 | do { | 3846 | do { |
3848 | atomic_set(&vha->loop_state, LOOP_UPDATE); | ||
3849 | |||
3850 | /* Issue a marker after FW becomes ready. */ | 3847 | /* Issue a marker after FW becomes ready. */ |
3851 | qla2x00_marker(vha, req, rsp, 0, 0, | 3848 | qla2x00_marker(vha, req, rsp, 0, 0, |
3852 | MK_SYNC_ALL); | 3849 | MK_SYNC_ALL); |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index d2e904bc21c0..9902834e0b74 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -102,3 +102,32 @@ qla2x00_set_fcport_state(fc_port_t *fcport, int state) | |||
102 | fcport->d_id.b.al_pa); | 102 | fcport->d_id.b.al_pa); |
103 | } | 103 | } |
104 | } | 104 | } |
105 | |||
106 | static inline int | ||
107 | qla2x00_hba_err_chk_enabled(srb_t *sp) | ||
108 | { | ||
109 | /* | ||
110 | * Uncomment when corresponding SCSI changes are done. | ||
111 | * | ||
112 | if (!sp->cmd->prot_chk) | ||
113 | return 0; | ||
114 | * | ||
115 | */ | ||
116 | |||
117 | switch (scsi_get_prot_op(sp->cmd)) { | ||
118 | case SCSI_PROT_READ_STRIP: | ||
119 | case SCSI_PROT_WRITE_INSERT: | ||
120 | if (ql2xenablehba_err_chk >= 1) | ||
121 | return 1; | ||
122 | break; | ||
123 | case SCSI_PROT_READ_PASS: | ||
124 | case SCSI_PROT_WRITE_PASS: | ||
125 | if (ql2xenablehba_err_chk >= 2) | ||
126 | return 1; | ||
127 | break; | ||
128 | case SCSI_PROT_READ_INSERT: | ||
129 | case SCSI_PROT_WRITE_STRIP: | ||
130 | return 1; | ||
131 | } | ||
132 | return 0; | ||
133 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 49d6906af886..dbec89622a0f 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -709,20 +709,28 @@ struct fw_dif_context { | |||
709 | * | 709 | * |
710 | */ | 710 | */ |
711 | static inline void | 711 | static inline void |
712 | qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | 712 | qla24xx_set_t10dif_tags(srb_t *sp, struct fw_dif_context *pkt, |
713 | unsigned int protcnt) | 713 | unsigned int protcnt) |
714 | { | 714 | { |
715 | struct sd_dif_tuple *spt; | 715 | struct scsi_cmnd *cmd = sp->cmd; |
716 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 716 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
717 | unsigned char op = scsi_get_prot_op(cmd); | ||
718 | 717 | ||
719 | switch (scsi_get_prot_type(cmd)) { | 718 | switch (scsi_get_prot_type(cmd)) { |
720 | /* For TYPE 0 protection: no checking */ | ||
721 | case SCSI_PROT_DIF_TYPE0: | 719 | case SCSI_PROT_DIF_TYPE0: |
722 | pkt->ref_tag_mask[0] = 0x00; | 720 | /* |
723 | pkt->ref_tag_mask[1] = 0x00; | 721 | * No check for ql2xenablehba_err_chk, as it would be an |
724 | pkt->ref_tag_mask[2] = 0x00; | 722 | * I/O error if hba tag generation is not done. |
725 | pkt->ref_tag_mask[3] = 0x00; | 723 | */ |
724 | pkt->ref_tag = cpu_to_le32((uint32_t) | ||
725 | (0xffffffff & scsi_get_lba(cmd))); | ||
726 | |||
727 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
728 | break; | ||
729 | |||
730 | pkt->ref_tag_mask[0] = 0xff; | ||
731 | pkt->ref_tag_mask[1] = 0xff; | ||
732 | pkt->ref_tag_mask[2] = 0xff; | ||
733 | pkt->ref_tag_mask[3] = 0xff; | ||
726 | break; | 734 | break; |
727 | 735 | ||
728 | /* | 736 | /* |
@@ -730,20 +738,16 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
730 | * match LBA in CDB + N | 738 | * match LBA in CDB + N |
731 | */ | 739 | */ |
732 | case SCSI_PROT_DIF_TYPE2: | 740 | case SCSI_PROT_DIF_TYPE2: |
733 | if (!ql2xenablehba_err_chk) | 741 | pkt->app_tag = __constant_cpu_to_le16(0); |
734 | break; | 742 | pkt->app_tag_mask[0] = 0x0; |
735 | 743 | pkt->app_tag_mask[1] = 0x0; | |
736 | if (scsi_prot_sg_count(cmd)) { | ||
737 | spt = page_address(sg_page(scsi_prot_sglist(cmd))) + | ||
738 | scsi_prot_sglist(cmd)[0].offset; | ||
739 | pkt->app_tag = swab32(spt->app_tag); | ||
740 | pkt->app_tag_mask[0] = 0xff; | ||
741 | pkt->app_tag_mask[1] = 0xff; | ||
742 | } | ||
743 | 744 | ||
744 | pkt->ref_tag = cpu_to_le32((uint32_t) | 745 | pkt->ref_tag = cpu_to_le32((uint32_t) |
745 | (0xffffffff & scsi_get_lba(cmd))); | 746 | (0xffffffff & scsi_get_lba(cmd))); |
746 | 747 | ||
748 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
749 | break; | ||
750 | |||
747 | /* enable ALL bytes of the ref tag */ | 751 | /* enable ALL bytes of the ref tag */ |
748 | pkt->ref_tag_mask[0] = 0xff; | 752 | pkt->ref_tag_mask[0] = 0xff; |
749 | pkt->ref_tag_mask[1] = 0xff; | 753 | pkt->ref_tag_mask[1] = 0xff; |
@@ -763,26 +767,15 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
763 | * 16 bit app tag. | 767 | * 16 bit app tag. |
764 | */ | 768 | */ |
765 | case SCSI_PROT_DIF_TYPE1: | 769 | case SCSI_PROT_DIF_TYPE1: |
766 | if (!ql2xenablehba_err_chk) | 770 | pkt->ref_tag = cpu_to_le32((uint32_t) |
771 | (0xffffffff & scsi_get_lba(cmd))); | ||
772 | pkt->app_tag = __constant_cpu_to_le16(0); | ||
773 | pkt->app_tag_mask[0] = 0x0; | ||
774 | pkt->app_tag_mask[1] = 0x0; | ||
775 | |||
776 | if (!qla2x00_hba_err_chk_enabled(sp)) | ||
767 | break; | 777 | break; |
768 | 778 | ||
769 | if (protcnt && (op == SCSI_PROT_WRITE_STRIP || | ||
770 | op == SCSI_PROT_WRITE_PASS)) { | ||
771 | spt = page_address(sg_page(scsi_prot_sglist(cmd))) + | ||
772 | scsi_prot_sglist(cmd)[0].offset; | ||
773 | ql_dbg(ql_dbg_io, vha, 0x3008, | ||
774 | "LBA from user %p, lba = 0x%x for cmd=%p.\n", | ||
775 | spt, (int)spt->ref_tag, cmd); | ||
776 | pkt->ref_tag = swab32(spt->ref_tag); | ||
777 | pkt->app_tag_mask[0] = 0x0; | ||
778 | pkt->app_tag_mask[1] = 0x0; | ||
779 | } else { | ||
780 | pkt->ref_tag = cpu_to_le32((uint32_t) | ||
781 | (0xffffffff & scsi_get_lba(cmd))); | ||
782 | pkt->app_tag = __constant_cpu_to_le16(0); | ||
783 | pkt->app_tag_mask[0] = 0x0; | ||
784 | pkt->app_tag_mask[1] = 0x0; | ||
785 | } | ||
786 | /* enable ALL bytes of the ref tag */ | 779 | /* enable ALL bytes of the ref tag */ |
787 | pkt->ref_tag_mask[0] = 0xff; | 780 | pkt->ref_tag_mask[0] = 0xff; |
788 | pkt->ref_tag_mask[1] = 0xff; | 781 | pkt->ref_tag_mask[1] = 0xff; |
@@ -798,8 +791,162 @@ qla24xx_set_t10dif_tags(struct scsi_cmnd *cmd, struct fw_dif_context *pkt, | |||
798 | scsi_get_prot_type(cmd), cmd); | 791 | scsi_get_prot_type(cmd), cmd); |
799 | } | 792 | } |
800 | 793 | ||
794 | struct qla2_sgx { | ||
795 | dma_addr_t dma_addr; /* OUT */ | ||
796 | uint32_t dma_len; /* OUT */ | ||
797 | |||
798 | uint32_t tot_bytes; /* IN */ | ||
799 | struct scatterlist *cur_sg; /* IN */ | ||
800 | |||
801 | /* for book keeping, bzero on initial invocation */ | ||
802 | uint32_t bytes_consumed; | ||
803 | uint32_t num_bytes; | ||
804 | uint32_t tot_partial; | ||
805 | |||
806 | /* for debugging */ | ||
807 | uint32_t num_sg; | ||
808 | srb_t *sp; | ||
809 | }; | ||
801 | 810 | ||
802 | static int | 811 | static int |
812 | qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, | ||
813 | uint32_t *partial) | ||
814 | { | ||
815 | struct scatterlist *sg; | ||
816 | uint32_t cumulative_partial, sg_len; | ||
817 | dma_addr_t sg_dma_addr; | ||
818 | |||
819 | if (sgx->num_bytes == sgx->tot_bytes) | ||
820 | return 0; | ||
821 | |||
822 | sg = sgx->cur_sg; | ||
823 | cumulative_partial = sgx->tot_partial; | ||
824 | |||
825 | sg_dma_addr = sg_dma_address(sg); | ||
826 | sg_len = sg_dma_len(sg); | ||
827 | |||
828 | sgx->dma_addr = sg_dma_addr + sgx->bytes_consumed; | ||
829 | |||
830 | if ((cumulative_partial + (sg_len - sgx->bytes_consumed)) >= blk_sz) { | ||
831 | sgx->dma_len = (blk_sz - cumulative_partial); | ||
832 | sgx->tot_partial = 0; | ||
833 | sgx->num_bytes += blk_sz; | ||
834 | *partial = 0; | ||
835 | } else { | ||
836 | sgx->dma_len = sg_len - sgx->bytes_consumed; | ||
837 | sgx->tot_partial += sgx->dma_len; | ||
838 | *partial = 1; | ||
839 | } | ||
840 | |||
841 | sgx->bytes_consumed += sgx->dma_len; | ||
842 | |||
843 | if (sg_len == sgx->bytes_consumed) { | ||
844 | sg = sg_next(sg); | ||
845 | sgx->num_sg++; | ||
846 | sgx->cur_sg = sg; | ||
847 | sgx->bytes_consumed = 0; | ||
848 | } | ||
849 | |||
850 | return 1; | ||
851 | } | ||
852 | |||
853 | static int | ||
854 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | ||
855 | uint32_t *dsd, uint16_t tot_dsds) | ||
856 | { | ||
857 | void *next_dsd; | ||
858 | uint8_t avail_dsds = 0; | ||
859 | uint32_t dsd_list_len; | ||
860 | struct dsd_dma *dsd_ptr; | ||
861 | struct scatterlist *sg_prot; | ||
862 | uint32_t *cur_dsd = dsd; | ||
863 | uint16_t used_dsds = tot_dsds; | ||
864 | |||
865 | uint32_t prot_int; | ||
866 | uint32_t partial; | ||
867 | struct qla2_sgx sgx; | ||
868 | dma_addr_t sle_dma; | ||
869 | uint32_t sle_dma_len, tot_prot_dma_len = 0; | ||
870 | struct scsi_cmnd *cmd = sp->cmd; | ||
871 | |||
872 | prot_int = cmd->device->sector_size; | ||
873 | |||
874 | memset(&sgx, 0, sizeof(struct qla2_sgx)); | ||
875 | sgx.tot_bytes = scsi_bufflen(sp->cmd); | ||
876 | sgx.cur_sg = scsi_sglist(sp->cmd); | ||
877 | sgx.sp = sp; | ||
878 | |||
879 | sg_prot = scsi_prot_sglist(sp->cmd); | ||
880 | |||
881 | while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) { | ||
882 | |||
883 | sle_dma = sgx.dma_addr; | ||
884 | sle_dma_len = sgx.dma_len; | ||
885 | alloc_and_fill: | ||
886 | /* Allocate additional continuation packets? */ | ||
887 | if (avail_dsds == 0) { | ||
888 | avail_dsds = (used_dsds > QLA_DSDS_PER_IOCB) ? | ||
889 | QLA_DSDS_PER_IOCB : used_dsds; | ||
890 | dsd_list_len = (avail_dsds + 1) * 12; | ||
891 | used_dsds -= avail_dsds; | ||
892 | |||
893 | /* allocate tracking DS */ | ||
894 | dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); | ||
895 | if (!dsd_ptr) | ||
896 | return 1; | ||
897 | |||
898 | /* allocate new list */ | ||
899 | dsd_ptr->dsd_addr = next_dsd = | ||
900 | dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, | ||
901 | &dsd_ptr->dsd_list_dma); | ||
902 | |||
903 | if (!next_dsd) { | ||
904 | /* | ||
905 | * Need to cleanup only this dsd_ptr, rest | ||
906 | * will be done by sp_free_dma() | ||
907 | */ | ||
908 | kfree(dsd_ptr); | ||
909 | return 1; | ||
910 | } | ||
911 | |||
912 | list_add_tail(&dsd_ptr->list, | ||
913 | &((struct crc_context *)sp->ctx)->dsd_list); | ||
914 | |||
915 | sp->flags |= SRB_CRC_CTX_DSD_VALID; | ||
916 | |||
917 | /* add new list to cmd iocb or last list */ | ||
918 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | ||
919 | *cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma)); | ||
920 | *cur_dsd++ = dsd_list_len; | ||
921 | cur_dsd = (uint32_t *)next_dsd; | ||
922 | } | ||
923 | *cur_dsd++ = cpu_to_le32(LSD(sle_dma)); | ||
924 | *cur_dsd++ = cpu_to_le32(MSD(sle_dma)); | ||
925 | *cur_dsd++ = cpu_to_le32(sle_dma_len); | ||
926 | avail_dsds--; | ||
927 | |||
928 | if (partial == 0) { | ||
929 | /* Got a full protection interval */ | ||
930 | sle_dma = sg_dma_address(sg_prot) + tot_prot_dma_len; | ||
931 | sle_dma_len = 8; | ||
932 | |||
933 | tot_prot_dma_len += sle_dma_len; | ||
934 | if (tot_prot_dma_len == sg_dma_len(sg_prot)) { | ||
935 | tot_prot_dma_len = 0; | ||
936 | sg_prot = sg_next(sg_prot); | ||
937 | } | ||
938 | |||
939 | partial = 1; /* So as to not re-enter this block */ | ||
940 | goto alloc_and_fill; | ||
941 | } | ||
942 | } | ||
943 | /* Null termination */ | ||
944 | *cur_dsd++ = 0; | ||
945 | *cur_dsd++ = 0; | ||
946 | *cur_dsd++ = 0; | ||
947 | return 0; | ||
948 | } | ||
949 | static int | ||
803 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | 950 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, |
804 | uint16_t tot_dsds) | 951 | uint16_t tot_dsds) |
805 | { | 952 | { |
@@ -981,7 +1128,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
981 | struct scsi_cmnd *cmd; | 1128 | struct scsi_cmnd *cmd; |
982 | struct scatterlist *cur_seg; | 1129 | struct scatterlist *cur_seg; |
983 | int sgc; | 1130 | int sgc; |
984 | uint32_t total_bytes; | 1131 | uint32_t total_bytes = 0; |
985 | uint32_t data_bytes; | 1132 | uint32_t data_bytes; |
986 | uint32_t dif_bytes; | 1133 | uint32_t dif_bytes; |
987 | uint8_t bundling = 1; | 1134 | uint8_t bundling = 1; |
@@ -1023,8 +1170,10 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1023 | __constant_cpu_to_le16(CF_READ_DATA); | 1170 | __constant_cpu_to_le16(CF_READ_DATA); |
1024 | } | 1171 | } |
1025 | 1172 | ||
1026 | tot_prot_dsds = scsi_prot_sg_count(cmd); | 1173 | if ((scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_INSERT) || |
1027 | if (!tot_prot_dsds) | 1174 | (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_STRIP) || |
1175 | (scsi_get_prot_op(sp->cmd) == SCSI_PROT_READ_STRIP) || | ||
1176 | (scsi_get_prot_op(sp->cmd) == SCSI_PROT_WRITE_INSERT)) | ||
1028 | bundling = 0; | 1177 | bundling = 0; |
1029 | 1178 | ||
1030 | /* Allocate CRC context from global pool */ | 1179 | /* Allocate CRC context from global pool */ |
@@ -1047,7 +1196,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1047 | 1196 | ||
1048 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); | 1197 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); |
1049 | 1198 | ||
1050 | qla24xx_set_t10dif_tags(cmd, (struct fw_dif_context *) | 1199 | qla24xx_set_t10dif_tags(sp, (struct fw_dif_context *) |
1051 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); | 1200 | &crc_ctx_pkt->ref_tag, tot_prot_dsds); |
1052 | 1201 | ||
1053 | cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | 1202 | cmd_pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); |
@@ -1076,7 +1225,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1076 | fcp_cmnd->additional_cdb_len |= 2; | 1225 | fcp_cmnd->additional_cdb_len |= 2; |
1077 | 1226 | ||
1078 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); | 1227 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); |
1079 | host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); | ||
1080 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1228 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
1081 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1229 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
1082 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1230 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( |
@@ -1107,15 +1255,28 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1107 | cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ | 1255 | cmd_pkt->fcp_rsp_dseg_len = 0; /* Let response come in status iocb */ |
1108 | 1256 | ||
1109 | /* Compute dif len and adjust data len to incude protection */ | 1257 | /* Compute dif len and adjust data len to incude protection */ |
1110 | total_bytes = data_bytes; | ||
1111 | dif_bytes = 0; | 1258 | dif_bytes = 0; |
1112 | blk_size = cmd->device->sector_size; | 1259 | blk_size = cmd->device->sector_size; |
1113 | if (scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) { | 1260 | dif_bytes = (data_bytes / blk_size) * 8; |
1114 | dif_bytes = (data_bytes / blk_size) * 8; | 1261 | |
1115 | total_bytes += dif_bytes; | 1262 | switch (scsi_get_prot_op(sp->cmd)) { |
1263 | case SCSI_PROT_READ_INSERT: | ||
1264 | case SCSI_PROT_WRITE_STRIP: | ||
1265 | total_bytes = data_bytes; | ||
1266 | data_bytes += dif_bytes; | ||
1267 | break; | ||
1268 | |||
1269 | case SCSI_PROT_READ_STRIP: | ||
1270 | case SCSI_PROT_WRITE_INSERT: | ||
1271 | case SCSI_PROT_READ_PASS: | ||
1272 | case SCSI_PROT_WRITE_PASS: | ||
1273 | total_bytes = data_bytes + dif_bytes; | ||
1274 | break; | ||
1275 | default: | ||
1276 | BUG(); | ||
1116 | } | 1277 | } |
1117 | 1278 | ||
1118 | if (!ql2xenablehba_err_chk) | 1279 | if (!qla2x00_hba_err_chk_enabled(sp)) |
1119 | fw_prot_opts |= 0x10; /* Disable Guard tag checking */ | 1280 | fw_prot_opts |= 0x10; /* Disable Guard tag checking */ |
1120 | 1281 | ||
1121 | if (!bundling) { | 1282 | if (!bundling) { |
@@ -1151,7 +1312,12 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1151 | 1312 | ||
1152 | cmd_pkt->control_flags |= | 1313 | cmd_pkt->control_flags |= |
1153 | __constant_cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE); | 1314 | __constant_cpu_to_le16(CF_DATA_SEG_DESCR_ENABLE); |
1154 | if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, | 1315 | |
1316 | if (!bundling && tot_prot_dsds) { | ||
1317 | if (qla24xx_walk_and_build_sglist_no_difb(ha, sp, | ||
1318 | cur_dsd, tot_dsds)) | ||
1319 | goto crc_queuing_error; | ||
1320 | } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, | ||
1155 | (tot_dsds - tot_prot_dsds))) | 1321 | (tot_dsds - tot_prot_dsds))) |
1156 | goto crc_queuing_error; | 1322 | goto crc_queuing_error; |
1157 | 1323 | ||
@@ -1414,6 +1580,22 @@ qla24xx_dif_start_scsi(srb_t *sp) | |||
1414 | goto queuing_error; | 1580 | goto queuing_error; |
1415 | else | 1581 | else |
1416 | sp->flags |= SRB_DMA_VALID; | 1582 | sp->flags |= SRB_DMA_VALID; |
1583 | |||
1584 | if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) || | ||
1585 | (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) { | ||
1586 | struct qla2_sgx sgx; | ||
1587 | uint32_t partial; | ||
1588 | |||
1589 | memset(&sgx, 0, sizeof(struct qla2_sgx)); | ||
1590 | sgx.tot_bytes = scsi_bufflen(cmd); | ||
1591 | sgx.cur_sg = scsi_sglist(cmd); | ||
1592 | sgx.sp = sp; | ||
1593 | |||
1594 | nseg = 0; | ||
1595 | while (qla24xx_get_one_block_sg( | ||
1596 | cmd->device->sector_size, &sgx, &partial)) | ||
1597 | nseg++; | ||
1598 | } | ||
1417 | } else | 1599 | } else |
1418 | nseg = 0; | 1600 | nseg = 0; |
1419 | 1601 | ||
@@ -1428,6 +1610,11 @@ qla24xx_dif_start_scsi(srb_t *sp) | |||
1428 | goto queuing_error; | 1610 | goto queuing_error; |
1429 | else | 1611 | else |
1430 | sp->flags |= SRB_CRC_PROT_DMA_VALID; | 1612 | sp->flags |= SRB_CRC_PROT_DMA_VALID; |
1613 | |||
1614 | if ((scsi_get_prot_op(cmd) == SCSI_PROT_READ_INSERT) || | ||
1615 | (scsi_get_prot_op(cmd) == SCSI_PROT_WRITE_STRIP)) { | ||
1616 | nseg = scsi_bufflen(cmd) / cmd->device->sector_size; | ||
1617 | } | ||
1431 | } else { | 1618 | } else { |
1432 | nseg = 0; | 1619 | nseg = 0; |
1433 | } | 1620 | } |
@@ -1454,6 +1641,7 @@ qla24xx_dif_start_scsi(srb_t *sp) | |||
1454 | /* Build header part of command packet (excluding the OPCODE). */ | 1641 | /* Build header part of command packet (excluding the OPCODE). */ |
1455 | req->current_outstanding_cmd = handle; | 1642 | req->current_outstanding_cmd = handle; |
1456 | req->outstanding_cmds[handle] = sp; | 1643 | req->outstanding_cmds[handle] = sp; |
1644 | sp->handle = handle; | ||
1457 | sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; | 1645 | sp->cmd->host_scribble = (unsigned char *)(unsigned long)handle; |
1458 | req->cnt -= req_cnt; | 1646 | req->cnt -= req_cnt; |
1459 | 1647 | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index b16b7725dee0..646fc5263d50 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -719,7 +719,6 @@ skip_rio: | |||
719 | vha->flags.rscn_queue_overflow = 1; | 719 | vha->flags.rscn_queue_overflow = 1; |
720 | } | 720 | } |
721 | 721 | ||
722 | atomic_set(&vha->loop_state, LOOP_UPDATE); | ||
723 | atomic_set(&vha->loop_down_timer, 0); | 722 | atomic_set(&vha->loop_down_timer, 0); |
724 | vha->flags.management_server_logged_in = 0; | 723 | vha->flags.management_server_logged_in = 0; |
725 | 724 | ||
@@ -1435,25 +1434,27 @@ struct scsi_dif_tuple { | |||
1435 | * ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST | 1434 | * ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST |
1436 | * to indicate to the kernel that the HBA detected error. | 1435 | * to indicate to the kernel that the HBA detected error. |
1437 | */ | 1436 | */ |
1438 | static inline void | 1437 | static inline int |
1439 | qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) | 1438 | qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) |
1440 | { | 1439 | { |
1441 | struct scsi_qla_host *vha = sp->fcport->vha; | 1440 | struct scsi_qla_host *vha = sp->fcport->vha; |
1442 | struct scsi_cmnd *cmd = sp->cmd; | 1441 | struct scsi_cmnd *cmd = sp->cmd; |
1443 | struct scsi_dif_tuple *ep = | 1442 | uint8_t *ap = &sts24->data[12]; |
1444 | (struct scsi_dif_tuple *)&sts24->data[20]; | 1443 | uint8_t *ep = &sts24->data[20]; |
1445 | struct scsi_dif_tuple *ap = | ||
1446 | (struct scsi_dif_tuple *)&sts24->data[12]; | ||
1447 | uint32_t e_ref_tag, a_ref_tag; | 1444 | uint32_t e_ref_tag, a_ref_tag; |
1448 | uint16_t e_app_tag, a_app_tag; | 1445 | uint16_t e_app_tag, a_app_tag; |
1449 | uint16_t e_guard, a_guard; | 1446 | uint16_t e_guard, a_guard; |
1450 | 1447 | ||
1451 | e_ref_tag = be32_to_cpu(ep->ref_tag); | 1448 | /* |
1452 | a_ref_tag = be32_to_cpu(ap->ref_tag); | 1449 | * swab32 of the "data" field in the beginning of qla2x00_status_entry() |
1453 | e_app_tag = be16_to_cpu(ep->app_tag); | 1450 | * would make guard field appear at offset 2 |
1454 | a_app_tag = be16_to_cpu(ap->app_tag); | 1451 | */ |
1455 | e_guard = be16_to_cpu(ep->guard); | 1452 | a_guard = le16_to_cpu(*(uint16_t *)(ap + 2)); |
1456 | a_guard = be16_to_cpu(ap->guard); | 1453 | a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0)); |
1454 | a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4)); | ||
1455 | e_guard = le16_to_cpu(*(uint16_t *)(ep + 2)); | ||
1456 | e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0)); | ||
1457 | e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4)); | ||
1457 | 1458 | ||
1458 | ql_dbg(ql_dbg_io, vha, 0x3023, | 1459 | ql_dbg(ql_dbg_io, vha, 0x3023, |
1459 | "iocb(s) %p Returned STATUS.\n", sts24); | 1460 | "iocb(s) %p Returned STATUS.\n", sts24); |
@@ -1465,6 +1466,63 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) | |||
1465 | cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag, | 1466 | cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag, |
1466 | a_app_tag, e_app_tag, a_guard, e_guard); | 1467 | a_app_tag, e_app_tag, a_guard, e_guard); |
1467 | 1468 | ||
1469 | /* | ||
1470 | * Ignore sector if: | ||
1471 | * For type 3: ref & app tag is all 'f's | ||
1472 | * For type 0,1,2: app tag is all 'f's | ||
1473 | */ | ||
1474 | if ((a_app_tag == 0xffff) && | ||
1475 | ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) || | ||
1476 | (a_ref_tag == 0xffffffff))) { | ||
1477 | uint32_t blocks_done, resid; | ||
1478 | sector_t lba_s = scsi_get_lba(cmd); | ||
1479 | |||
1480 | /* 2TB boundary case covered automatically with this */ | ||
1481 | blocks_done = e_ref_tag - (uint32_t)lba_s + 1; | ||
1482 | |||
1483 | resid = scsi_bufflen(cmd) - (blocks_done * | ||
1484 | cmd->device->sector_size); | ||
1485 | |||
1486 | scsi_set_resid(cmd, resid); | ||
1487 | cmd->result = DID_OK << 16; | ||
1488 | |||
1489 | /* Update protection tag */ | ||
1490 | if (scsi_prot_sg_count(cmd)) { | ||
1491 | uint32_t i, j = 0, k = 0, num_ent; | ||
1492 | struct scatterlist *sg; | ||
1493 | struct sd_dif_tuple *spt; | ||
1494 | |||
1495 | /* Patch the corresponding protection tags */ | ||
1496 | scsi_for_each_prot_sg(cmd, sg, | ||
1497 | scsi_prot_sg_count(cmd), i) { | ||
1498 | num_ent = sg_dma_len(sg) / 8; | ||
1499 | if (k + num_ent < blocks_done) { | ||
1500 | k += num_ent; | ||
1501 | continue; | ||
1502 | } | ||
1503 | j = blocks_done - k - 1; | ||
1504 | k = blocks_done; | ||
1505 | break; | ||
1506 | } | ||
1507 | |||
1508 | if (k != blocks_done) { | ||
1509 | qla_printk(KERN_WARNING, sp->fcport->vha->hw, | ||
1510 | "unexpected tag values tag:lba=%x:%lx)\n", | ||
1511 | e_ref_tag, lba_s); | ||
1512 | return 1; | ||
1513 | } | ||
1514 | |||
1515 | spt = page_address(sg_page(sg)) + sg->offset; | ||
1516 | spt += j; | ||
1517 | |||
1518 | spt->app_tag = 0xffff; | ||
1519 | if (scsi_get_prot_type(cmd) == SCSI_PROT_DIF_TYPE3) | ||
1520 | spt->ref_tag = 0xffffffff; | ||
1521 | } | ||
1522 | |||
1523 | return 0; | ||
1524 | } | ||
1525 | |||
1468 | /* check guard */ | 1526 | /* check guard */ |
1469 | if (e_guard != a_guard) { | 1527 | if (e_guard != a_guard) { |
1470 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, | 1528 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, |
@@ -1472,28 +1530,30 @@ qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24) | |||
1472 | set_driver_byte(cmd, DRIVER_SENSE); | 1530 | set_driver_byte(cmd, DRIVER_SENSE); |
1473 | set_host_byte(cmd, DID_ABORT); | 1531 | set_host_byte(cmd, DID_ABORT); |
1474 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; | 1532 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; |
1475 | return; | 1533 | return 1; |
1476 | } | 1534 | } |
1477 | 1535 | ||
1478 | /* check appl tag */ | 1536 | /* check ref tag */ |
1479 | if (e_app_tag != a_app_tag) { | 1537 | if (e_ref_tag != a_ref_tag) { |
1480 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, | 1538 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, |
1481 | 0x10, 0x2); | 1539 | 0x10, 0x3); |
1482 | set_driver_byte(cmd, DRIVER_SENSE); | 1540 | set_driver_byte(cmd, DRIVER_SENSE); |
1483 | set_host_byte(cmd, DID_ABORT); | 1541 | set_host_byte(cmd, DID_ABORT); |
1484 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; | 1542 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; |
1485 | return; | 1543 | return 1; |
1486 | } | 1544 | } |
1487 | 1545 | ||
1488 | /* check ref tag */ | 1546 | /* check appl tag */ |
1489 | if (e_ref_tag != a_ref_tag) { | 1547 | if (e_app_tag != a_app_tag) { |
1490 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, | 1548 | scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST, |
1491 | 0x10, 0x3); | 1549 | 0x10, 0x2); |
1492 | set_driver_byte(cmd, DRIVER_SENSE); | 1550 | set_driver_byte(cmd, DRIVER_SENSE); |
1493 | set_host_byte(cmd, DID_ABORT); | 1551 | set_host_byte(cmd, DID_ABORT); |
1494 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; | 1552 | cmd->result |= SAM_STAT_CHECK_CONDITION << 1; |
1495 | return; | 1553 | return 1; |
1496 | } | 1554 | } |
1555 | |||
1556 | return 1; | ||
1497 | } | 1557 | } |
1498 | 1558 | ||
1499 | /** | 1559 | /** |
@@ -1767,7 +1827,7 @@ check_scsi_status: | |||
1767 | break; | 1827 | break; |
1768 | 1828 | ||
1769 | case CS_DIF_ERROR: | 1829 | case CS_DIF_ERROR: |
1770 | qla2x00_handle_dif_error(sp, sts24); | 1830 | logit = qla2x00_handle_dif_error(sp, sts24); |
1771 | break; | 1831 | break; |
1772 | default: | 1832 | default: |
1773 | cp->result = DID_ERROR << 16; | 1833 | cp->result = DID_ERROR << 16; |
@@ -2468,11 +2528,10 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
2468 | goto skip_msi; | 2528 | goto skip_msi; |
2469 | } | 2529 | } |
2470 | 2530 | ||
2471 | if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX || | 2531 | if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX)) { |
2472 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { | ||
2473 | ql_log(ql_log_warn, vha, 0x0035, | 2532 | ql_log(ql_log_warn, vha, 0x0035, |
2474 | "MSI-X; Unsupported ISP2432 (0x%X, 0x%X).\n", | 2533 | "MSI-X; Unsupported ISP2432 (0x%X, 0x%X).\n", |
2475 | ha->pdev->revision, ha->fw_attributes); | 2534 | ha->pdev->revision, QLA_MSIX_CHIP_REV_24XX); |
2476 | goto skip_msix; | 2535 | goto skip_msix; |
2477 | } | 2536 | } |
2478 | 2537 | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index c706ed370000..f488cc69fc79 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -472,7 +472,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
472 | host->can_queue = base_vha->req->length + 128; | 472 | host->can_queue = base_vha->req->length + 128; |
473 | host->this_id = 255; | 473 | host->this_id = 255; |
474 | host->cmd_per_lun = 3; | 474 | host->cmd_per_lun = 3; |
475 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) | 475 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) |
476 | host->max_cmd_len = 32; | 476 | host->max_cmd_len = 32; |
477 | else | 477 | else |
478 | host->max_cmd_len = MAX_CMDSZ; | 478 | host->max_cmd_len = MAX_CMDSZ; |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 5cbf33a50b14..049807cda419 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -2208,6 +2208,7 @@ qla82xx_msix_rsp_q(int irq, void *dev_id) | |||
2208 | struct qla_hw_data *ha; | 2208 | struct qla_hw_data *ha; |
2209 | struct rsp_que *rsp; | 2209 | struct rsp_que *rsp; |
2210 | struct device_reg_82xx __iomem *reg; | 2210 | struct device_reg_82xx __iomem *reg; |
2211 | unsigned long flags; | ||
2211 | 2212 | ||
2212 | rsp = (struct rsp_que *) dev_id; | 2213 | rsp = (struct rsp_que *) dev_id; |
2213 | if (!rsp) { | 2214 | if (!rsp) { |
@@ -2218,11 +2219,11 @@ qla82xx_msix_rsp_q(int irq, void *dev_id) | |||
2218 | 2219 | ||
2219 | ha = rsp->hw; | 2220 | ha = rsp->hw; |
2220 | reg = &ha->iobase->isp82; | 2221 | reg = &ha->iobase->isp82; |
2221 | spin_lock_irq(&ha->hardware_lock); | 2222 | spin_lock_irqsave(&ha->hardware_lock, flags); |
2222 | vha = pci_get_drvdata(ha->pdev); | 2223 | vha = pci_get_drvdata(ha->pdev); |
2223 | qla24xx_process_response_queue(vha, rsp); | 2224 | qla24xx_process_response_queue(vha, rsp); |
2224 | WRT_REG_DWORD(®->host_int, 0); | 2225 | WRT_REG_DWORD(®->host_int, 0); |
2225 | spin_unlock_irq(&ha->hardware_lock); | 2226 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
2226 | return IRQ_HANDLED; | 2227 | return IRQ_HANDLED; |
2227 | } | 2228 | } |
2228 | 2229 | ||
@@ -2838,6 +2839,16 @@ sufficient_dsds: | |||
2838 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 2839 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
2839 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | 2840 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); |
2840 | 2841 | ||
2842 | /* build FCP_CMND IU */ | ||
2843 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | ||
2844 | int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); | ||
2845 | ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; | ||
2846 | |||
2847 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
2848 | ctx->fcp_cmnd->additional_cdb_len |= 1; | ||
2849 | else if (cmd->sc_data_direction == DMA_FROM_DEVICE) | ||
2850 | ctx->fcp_cmnd->additional_cdb_len |= 2; | ||
2851 | |||
2841 | /* | 2852 | /* |
2842 | * Update tagged queuing modifier -- default is TSK_SIMPLE (0). | 2853 | * Update tagged queuing modifier -- default is TSK_SIMPLE (0). |
2843 | */ | 2854 | */ |
@@ -2854,16 +2865,6 @@ sufficient_dsds: | |||
2854 | } | 2865 | } |
2855 | } | 2866 | } |
2856 | 2867 | ||
2857 | /* build FCP_CMND IU */ | ||
2858 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | ||
2859 | int_to_scsilun(sp->cmd->device->lun, &ctx->fcp_cmnd->lun); | ||
2860 | ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; | ||
2861 | |||
2862 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
2863 | ctx->fcp_cmnd->additional_cdb_len |= 1; | ||
2864 | else if (cmd->sc_data_direction == DMA_FROM_DEVICE) | ||
2865 | ctx->fcp_cmnd->additional_cdb_len |= 2; | ||
2866 | |||
2867 | memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 2868 | memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
2868 | 2869 | ||
2869 | fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 + | 2870 | fcp_dl = (uint32_t *)(ctx->fcp_cmnd->cdb + 16 + |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index e02df276804e..4cace3f20c04 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -106,17 +106,21 @@ MODULE_PARM_DESC(ql2xmaxqdepth, | |||
106 | "Maximum queue depth to report for target devices."); | 106 | "Maximum queue depth to report for target devices."); |
107 | 107 | ||
108 | /* Do not change the value of this after module load */ | 108 | /* Do not change the value of this after module load */ |
109 | int ql2xenabledif = 1; | 109 | int ql2xenabledif = 0; |
110 | module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR); | 110 | module_param(ql2xenabledif, int, S_IRUGO|S_IWUSR); |
111 | MODULE_PARM_DESC(ql2xenabledif, | 111 | MODULE_PARM_DESC(ql2xenabledif, |
112 | " Enable T10-CRC-DIF " | 112 | " Enable T10-CRC-DIF " |
113 | " Default is 0 - No DIF Support. 1 - Enable it"); | 113 | " Default is 0 - No DIF Support. 1 - Enable it" |
114 | ", 2 - Enable DIF for all types, except Type 0."); | ||
114 | 115 | ||
115 | int ql2xenablehba_err_chk; | 116 | int ql2xenablehba_err_chk = 2; |
116 | module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR); | 117 | module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR); |
117 | MODULE_PARM_DESC(ql2xenablehba_err_chk, | 118 | MODULE_PARM_DESC(ql2xenablehba_err_chk, |
118 | " Enable T10-CRC-DIF Error isolation by HBA" | 119 | " Enable T10-CRC-DIF Error isolation by HBA:\n" |
119 | " Default is 0 - Error isolation disabled, 1 - Enable it"); | 120 | " Default is 1.\n" |
121 | " 0 -- Error isolation disabled\n" | ||
122 | " 1 -- Error isolation enabled only for DIX Type 0\n" | ||
123 | " 2 -- Error isolation enabled for all Types\n"); | ||
120 | 124 | ||
121 | int ql2xiidmaenable=1; | 125 | int ql2xiidmaenable=1; |
122 | module_param(ql2xiidmaenable, int, S_IRUGO); | 126 | module_param(ql2xiidmaenable, int, S_IRUGO); |
@@ -909,7 +913,14 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
909 | "Abort command mbx success.\n"); | 913 | "Abort command mbx success.\n"); |
910 | wait = 1; | 914 | wait = 1; |
911 | } | 915 | } |
916 | |||
917 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
912 | qla2x00_sp_compl(ha, sp); | 918 | qla2x00_sp_compl(ha, sp); |
919 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
920 | |||
921 | /* Did the command return during mailbox execution? */ | ||
922 | if (ret == FAILED && !CMD_SP(cmd)) | ||
923 | ret = SUCCESS; | ||
913 | 924 | ||
914 | /* Wait for the command to be returned. */ | 925 | /* Wait for the command to be returned. */ |
915 | if (wait) { | 926 | if (wait) { |
@@ -2251,7 +2262,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2251 | host->this_id = 255; | 2262 | host->this_id = 255; |
2252 | host->cmd_per_lun = 3; | 2263 | host->cmd_per_lun = 3; |
2253 | host->unique_id = host->host_no; | 2264 | host->unique_id = host->host_no; |
2254 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) | 2265 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) |
2255 | host->max_cmd_len = 32; | 2266 | host->max_cmd_len = 32; |
2256 | else | 2267 | else |
2257 | host->max_cmd_len = MAX_CMDSZ; | 2268 | host->max_cmd_len = MAX_CMDSZ; |
@@ -2378,13 +2389,16 @@ skip_dpc: | |||
2378 | "Detected hba at address=%p.\n", | 2389 | "Detected hba at address=%p.\n", |
2379 | ha); | 2390 | ha); |
2380 | 2391 | ||
2381 | if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && ql2xenabledif) { | 2392 | if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { |
2382 | if (ha->fw_attributes & BIT_4) { | 2393 | if (ha->fw_attributes & BIT_4) { |
2394 | int prot = 0; | ||
2383 | base_vha->flags.difdix_supported = 1; | 2395 | base_vha->flags.difdix_supported = 1; |
2384 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, | 2396 | ql_dbg(ql_dbg_init, base_vha, 0x00f1, |
2385 | "Registering for DIF/DIX type 1 and 3 protection.\n"); | 2397 | "Registering for DIF/DIX type 1 and 3 protection.\n"); |
2398 | if (ql2xenabledif == 1) | ||
2399 | prot = SHOST_DIX_TYPE0_PROTECTION; | ||
2386 | scsi_host_set_prot(host, | 2400 | scsi_host_set_prot(host, |
2387 | SHOST_DIF_TYPE1_PROTECTION | 2401 | prot | SHOST_DIF_TYPE1_PROTECTION |
2388 | | SHOST_DIF_TYPE2_PROTECTION | 2402 | | SHOST_DIF_TYPE2_PROTECTION |
2389 | | SHOST_DIF_TYPE3_PROTECTION | 2403 | | SHOST_DIF_TYPE3_PROTECTION |
2390 | | SHOST_DIX_TYPE1_PROTECTION | 2404 | | SHOST_DIX_TYPE1_PROTECTION |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 062c97bf62f5..13b6357c1fa2 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.07.03-k" | 10 | #define QLA2XXX_VERSION "8.03.07.07-k" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
diff --git a/drivers/scsi/qla4xxx/Kconfig b/drivers/scsi/qla4xxx/Kconfig index 2c33ce6eac1e..0f5599e0abf6 100644 --- a/drivers/scsi/qla4xxx/Kconfig +++ b/drivers/scsi/qla4xxx/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SCSI_QLA_ISCSI | 1 | config SCSI_QLA_ISCSI |
2 | tristate "QLogic ISP4XXX and ISP82XX host adapter family support" | 2 | tristate "QLogic ISP4XXX and ISP82XX host adapter family support" |
3 | depends on PCI && SCSI | 3 | depends on PCI && SCSI && NET |
4 | select SCSI_ISCSI_ATTRS | 4 | select SCSI_ISCSI_ATTRS |
5 | ---help--- | 5 | ---help--- |
6 | This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX) | 6 | This driver supports the QLogic 40xx (ISP4XXX) and 8022 (ISP82XX) |