Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull final round of SCSI updates from James Bottomley:
"This is primarily another round of driver updates (bnx2fc, qla2xxx,
qla4xxx) including the target mode driver for qla2xxx. We've also got
a couple of regression fixes (async scanning, broken this merge window
and a fix to a long standing break in the scsi_wait_scan module)."

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (45 commits)
[SCSI] fix scsi_wait_scan
[SCSI] fix async probe regression
[SCSI] be2iscsi: fix dma free size mismatch regression
[SCSI] qla4xxx: Update driver version to 5.02.00-k17
[SCSI] qla4xxx: Capture minidump for ISP82XX on firmware failure
[SCSI] qla4xxx: Add change_queue_depth API support
[SCSI] qla4xxx: Fix clear ddb mbx command failure issue.
[SCSI] qla4xxx: Fix kernel panic during discovery logout.
[SCSI] qla4xxx: Correct early completion of pending mbox.
[SCSI] fcoe, bnx2fc, libfcoe: SW FCoE and bnx2fc use FCoE Syfs
[SCSI] libfcoe: Add fcoe_sysfs
[SCSI] bnx2fc: Allocate fcoe_ctlr with bnx2fc_interface, not as a member
[SCSI] fcoe: Allocate fcoe_ctlr with fcoe_interface, not as a member
[SCSI] Fix dm-multipath starvation when scsi host is busy
[SCSI] ufs: fix potential NULL pointer dereferencing error in ufshcd_prove.
[SCSI] qla2xxx: don't free pool that wasn't allocated
[SCSI] mptfusion: unlock on error in mpt_config()
[SCSI] tcm_qla2xxx: Add >= 24xx series fabric module for target-core
[SCSI] qla2xxx: Add LLD target-mode infrastructure for >= 24xx series
[SCSI] Revert "qla2xxx: During loopdown perform Diagnostic loopback."
...

+12124 -673
+77
Documentation/ABI/testing/sysfs-bus-fcoe
··· 1 + What: /sys/bus/fcoe/ctlr_X 2 + Date: March 2012 3 + KernelVersion: TBD 4 + Contact: Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org 5 + Description: 'FCoE Controller' instances on the fcoe bus 6 + Attributes: 7 + 8 + fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing 9 + this value will change the dev_loss_tmo for all 10 + FCFs discovered by this controller. 11 + 12 + lesb_link_fail: Link Error Status Block (LESB) link failure count. 13 + 14 + lesb_vlink_fail: Link Error Status Block (LESB) virtual link 15 + failure count. 16 + 17 + lesb_miss_fka: Link Error Status Block (LESB) missed FCoE 18 + Initialization Protocol (FIP) Keep-Alives (FKA). 19 + 20 + lesb_symb_err: Link Error Status Block (LESB) symbolic error count. 21 + 22 + lesb_err_block: Link Error Status Block (LESB) block error count. 23 + 24 + lesb_fcs_error: Link Error Status Block (LESB) Fibre Channel 25 + Serivces error count. 26 + 27 + Notes: ctlr_X (global increment starting at 0) 28 + 29 + What: /sys/bus/fcoe/fcf_X 30 + Date: March 2012 31 + KernelVersion: TBD 32 + Contact: Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org 33 + Description: 'FCoE FCF' instances on the fcoe bus. A FCF is a Fibre Channel 34 + Forwarder, which is a FCoE switch that can accept FCoE 35 + (Ethernet) packets, unpack them, and forward the embedded 36 + Fibre Channel frames into a FC fabric. It can also take 37 + outbound FC frames and pack them in Ethernet packets to 38 + be sent to their destination on the Ethernet segment. 39 + Attributes: 40 + 41 + fabric_name: Identifies the fabric that the FCF services. 42 + 43 + switch_name: Identifies the FCF. 44 + 45 + priority: The switch's priority amongst other FCFs on the same 46 + fabric. 47 + 48 + selected: 1 indicates that the switch has been selected for use; 49 + 0 indicates that the swich will not be used. 50 + 51 + fc_map: The Fibre Channel MAP 52 + 53 + vfid: The Virtual Fabric ID 54 + 55 + mac: The FCF's MAC address 56 + 57 + fka_peroid: The FIP Keep-Alive peroid 58 + 59 + fabric_state: The internal kernel state 60 + "Unknown" - Initialization value 61 + "Disconnected" - No link to the FCF/fabric 62 + "Connected" - Host is connected to the FCF 63 + "Deleted" - FCF is being removed from the system 64 + 65 + dev_loss_tmo: The device loss timeout peroid for this FCF. 66 + 67 + Notes: A device loss infrastructre similar to the FC Transport's 68 + is present in fcoe_sysfs. It is nice to have so that a 69 + link flapping adapter doesn't continually advance the count 70 + used to identify the discovered FCF. FCFs will exist in a 71 + "Disconnected" state until either the timer expires and the 72 + FCF becomes "Deleted" or the FCF is rediscovered and becomes 73 + "Connected." 74 + 75 + 76 + Users: The first user of this interface will be the fcoeadm application, 77 + which is commonly packaged in the fcoe-utils package.
+1
drivers/message/fusion/mptbase.c
··· 6483 6483 printk(MYIOC_s_INFO_FMT "%s: host reset in" 6484 6484 " progress mpt_config timed out.!!\n", 6485 6485 __func__, ioc->name); 6486 + mutex_unlock(&ioc->mptbase_cmds.mutex); 6486 6487 return -EFAULT; 6487 6488 } 6488 6489 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
+2 -3
drivers/scsi/be2iscsi/be_mgmt.c
··· 571 571 static int mgmt_alloc_cmd_data(struct beiscsi_hba *phba, struct be_dma_mem *cmd, 572 572 int iscsi_cmd, int size) 573 573 { 574 - cmd->va = pci_alloc_consistent(phba->ctrl.pdev, sizeof(size), 575 - &cmd->dma); 574 + cmd->va = pci_alloc_consistent(phba->ctrl.pdev, size, &cmd->dma); 576 575 if (!cmd->va) { 577 576 SE_DEBUG(DBG_LVL_1, "Failed to allocate memory for if info\n"); 578 577 return -ENOMEM; 579 578 } 580 - memset(cmd->va, 0, sizeof(size)); 579 + memset(cmd->va, 0, size); 581 580 cmd->size = size; 582 581 be_cmd_hdr_prepare(cmd->va, CMD_SUBSYSTEM_ISCSI, iscsi_cmd, size); 583 582 return 0;
+17
drivers/scsi/bfa/bfad_attr.c
··· 426 426 vshost = vport->drv_port.im_port->shost; 427 427 fc_host_node_name(vshost) = wwn_to_u64((u8 *)&port_cfg.nwwn); 428 428 fc_host_port_name(vshost) = wwn_to_u64((u8 *)&port_cfg.pwwn); 429 + fc_host_supported_classes(vshost) = FC_COS_CLASS3; 430 + 431 + memset(fc_host_supported_fc4s(vshost), 0, 432 + sizeof(fc_host_supported_fc4s(vshost))); 433 + 434 + /* For FCP type 0x08 */ 435 + if (supported_fc4s & BFA_LPORT_ROLE_FCP_IM) 436 + fc_host_supported_fc4s(vshost)[2] = 1; 437 + 438 + /* For fibre channel services type 0x20 */ 439 + fc_host_supported_fc4s(vshost)[7] = 1; 440 + 441 + fc_host_supported_speeds(vshost) = 442 + bfad_im_supported_speeds(&bfad->bfa); 443 + fc_host_maxframe_size(vshost) = 444 + bfa_fcport_get_maxfrsize(&bfad->bfa); 445 + 429 446 fc_vport->dd_data = vport; 430 447 vport->drv_port.im_port->fc_vport = fc_vport; 431 448 } else if (rc == BFA_STATUS_INVALID_WWN)
+1 -1
drivers/scsi/bfa/bfad_im.c
··· 987 987 return 0; 988 988 } 989 989 990 - static u32 990 + u32 991 991 bfad_im_supported_speeds(struct bfa_s *bfa) 992 992 { 993 993 struct bfa_ioc_attr_s *ioc_attr;
+1
drivers/scsi/bfa/bfad_im.h
··· 37 37 struct bfad_im_port_s *im_port, struct device *dev); 38 38 void bfad_im_scsi_host_free(struct bfad_s *bfad, 39 39 struct bfad_im_port_s *im_port); 40 + u32 bfad_im_supported_speeds(struct bfa_s *bfa); 40 41 41 42 #define MAX_FCP_TARGET 1024 42 43 #define MAX_FCP_LUN 16384
+6 -3
drivers/scsi/bnx2fc/bnx2fc.h
··· 62 62 #include "bnx2fc_constants.h" 63 63 64 64 #define BNX2FC_NAME "bnx2fc" 65 - #define BNX2FC_VERSION "1.0.10" 65 + #define BNX2FC_VERSION "1.0.11" 66 66 67 67 #define PFX "bnx2fc: " 68 68 ··· 228 228 struct packet_type fip_packet_type; 229 229 struct workqueue_struct *timer_work_queue; 230 230 struct kref kref; 231 - struct fcoe_ctlr ctlr; 232 231 u8 vlan_enabled; 233 232 int vlan_id; 234 233 bool enabled; 235 234 }; 236 235 237 - #define bnx2fc_from_ctlr(fip) container_of(fip, struct bnx2fc_interface, ctlr) 236 + #define bnx2fc_from_ctlr(x) \ 237 + ((struct bnx2fc_interface *)((x) + 1)) 238 + 239 + #define bnx2fc_to_ctlr(x) \ 240 + ((struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1)) 238 241 239 242 struct bnx2fc_lport { 240 243 struct list_head list;
+4 -14
drivers/scsi/bnx2fc/bnx2fc_els.c
··· 854 854 struct fc_exch *exch = fc_seq_exch(seq); 855 855 struct fc_lport *lport = exch->lp; 856 856 u8 *mac; 857 - struct fc_frame_header *fh; 858 857 u8 op; 859 858 860 859 if (IS_ERR(fp)) ··· 861 862 862 863 mac = fr_cb(fp)->granted_mac; 863 864 if (is_zero_ether_addr(mac)) { 864 - fh = fc_frame_header_get(fp); 865 - if (fh->fh_type != FC_TYPE_ELS) { 866 - printk(KERN_ERR PFX "bnx2fc_flogi_resp:" 867 - "fh_type != FC_TYPE_ELS\n"); 868 - fc_frame_free(fp); 869 - return; 870 - } 871 865 op = fc_frame_payload_op(fp); 872 866 if (lport->vport) { 873 867 if (op == ELS_LS_RJT) { ··· 870 878 return; 871 879 } 872 880 } 873 - if (fcoe_ctlr_recv_flogi(fip, lport, fp)) { 874 - fc_frame_free(fp); 875 - return; 876 - } 881 + fcoe_ctlr_recv_flogi(fip, lport, fp); 877 882 } 878 - fip->update_mac(lport, mac); 883 + if (!is_zero_ether_addr(mac)) 884 + fip->update_mac(lport, mac); 879 885 done: 880 886 fc_lport_flogi_resp(seq, fp, lport); 881 887 } ··· 900 910 { 901 911 struct fcoe_port *port = lport_priv(lport); 902 912 struct bnx2fc_interface *interface = port->priv; 903 - struct fcoe_ctlr *fip = &interface->ctlr; 913 + struct fcoe_ctlr *fip = bnx2fc_to_ctlr(interface); 904 914 struct fc_frame_header *fh = fc_frame_header_get(fp); 905 915 906 916 switch (op) {
+130 -43
drivers/scsi/bnx2fc/bnx2fc_fcoe.c
··· 22 22 23 23 #define DRV_MODULE_NAME "bnx2fc" 24 24 #define DRV_MODULE_VERSION BNX2FC_VERSION 25 - #define DRV_MODULE_RELDATE "Jan 22, 2011" 25 + #define DRV_MODULE_RELDATE "Apr 24, 2012" 26 26 27 27 28 28 static char version[] __devinitdata = ··· 54 54 static struct libfc_function_template bnx2fc_libfc_fcn_templ; 55 55 static struct scsi_host_template bnx2fc_shost_template; 56 56 static struct fc_function_template bnx2fc_transport_function; 57 + static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ; 57 58 static struct fc_function_template bnx2fc_vport_xport_function; 58 59 static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode); 59 60 static void __bnx2fc_destroy(struct bnx2fc_interface *interface); ··· 89 88 static void bnx2fc_stop(struct bnx2fc_interface *interface); 90 89 static int __init bnx2fc_mod_init(void); 91 90 static void __exit bnx2fc_mod_exit(void); 91 + static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev); 92 92 93 93 unsigned int bnx2fc_debug_level; 94 94 module_param_named(debug_logging, bnx2fc_debug_level, int, S_IRUGO|S_IWUSR); ··· 118 116 struct net_device *netdev = bnx2fc_netdev(lport); 119 117 120 118 __fcoe_get_lesb(lport, fc_lesb, netdev); 119 + } 120 + 121 + static void bnx2fc_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) 122 + { 123 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 124 + struct net_device *netdev = bnx2fc_netdev(fip->lp); 125 + struct fcoe_fc_els_lesb *fcoe_lesb; 126 + struct fc_els_lesb fc_lesb; 127 + 128 + __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); 129 + fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); 130 + 131 + ctlr_dev->lesb.lesb_link_fail = 132 + ntohl(fcoe_lesb->lesb_link_fail); 133 + ctlr_dev->lesb.lesb_vlink_fail = 134 + ntohl(fcoe_lesb->lesb_vlink_fail); 135 + ctlr_dev->lesb.lesb_miss_fka = 136 + ntohl(fcoe_lesb->lesb_miss_fka); 137 + ctlr_dev->lesb.lesb_symb_err = 138 + ntohl(fcoe_lesb->lesb_symb_err); 139 + ctlr_dev->lesb.lesb_err_block = 140 + ntohl(fcoe_lesb->lesb_err_block); 141 + ctlr_dev->lesb.lesb_fcs_error = 142 + ntohl(fcoe_lesb->lesb_fcs_error); 143 + } 144 + EXPORT_SYMBOL(bnx2fc_ctlr_get_lesb); 145 + 146 + static void bnx2fc_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 147 + { 148 + struct fcoe_ctlr_device *ctlr_dev = 149 + fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 150 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 151 + struct bnx2fc_interface *fcoe = fcoe_ctlr_priv(ctlr); 152 + 153 + fcf_dev->vlan_id = fcoe->vlan_id; 121 154 } 122 155 123 156 static void bnx2fc_clean_rx_queue(struct fc_lport *lp) ··· 281 244 struct sk_buff *skb; 282 245 struct fc_frame_header *fh; 283 246 struct bnx2fc_interface *interface; 247 + struct fcoe_ctlr *ctlr; 284 248 struct bnx2fc_hba *hba; 285 249 struct fcoe_port *port; 286 250 struct fcoe_hdr *hp; ··· 294 256 295 257 port = (struct fcoe_port *)lport_priv(lport); 296 258 interface = port->priv; 259 + ctlr = bnx2fc_to_ctlr(interface); 297 260 hba = interface->hba; 298 261 299 262 fh = fc_frame_header_get(fp); ··· 307 268 } 308 269 309 270 if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) { 310 - if (!interface->ctlr.sel_fcf) { 271 + if (!ctlr->sel_fcf) { 311 272 BNX2FC_HBA_DBG(lport, "FCF not selected yet!\n"); 312 273 kfree_skb(skb); 313 274 return -EINVAL; 314 275 } 315 - if (fcoe_ctlr_els_send(&interface->ctlr, lport, skb)) 276 + if (fcoe_ctlr_els_send(ctlr, lport, skb)) 316 277 return 0; 317 278 } 318 279 ··· 385 346 /* fill up mac and fcoe headers */ 386 347 eh = eth_hdr(skb); 387 348 eh->h_proto = htons(ETH_P_FCOE); 388 - if (interface->ctlr.map_dest) 349 + if (ctlr->map_dest) 389 350 fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id); 390 351 else 391 352 /* insert GW address */ 392 - memcpy(eh->h_dest, interface->ctlr.dest_addr, ETH_ALEN); 353 + memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN); 393 354 394 - if (unlikely(interface->ctlr.flogi_oxid != FC_XID_UNKNOWN)) 395 - memcpy(eh->h_source, interface->ctlr.ctl_src_addr, ETH_ALEN); 355 + if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN)) 356 + memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN); 396 357 else 397 358 memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); 398 359 ··· 442 403 { 443 404 struct fc_lport *lport; 444 405 struct bnx2fc_interface *interface; 406 + struct fcoe_ctlr *ctlr; 445 407 struct fc_frame_header *fh; 446 408 struct fcoe_rcv_info *fr; 447 409 struct fcoe_percpu_s *bg; ··· 450 410 451 411 interface = container_of(ptype, struct bnx2fc_interface, 452 412 fcoe_packet_type); 453 - lport = interface->ctlr.lp; 413 + ctlr = bnx2fc_to_ctlr(interface); 414 + lport = ctlr->lp; 454 415 455 416 if (unlikely(lport == NULL)) { 456 417 printk(KERN_ERR PFX "bnx2fc_rcv: lport is NULL\n"); ··· 799 758 { 800 759 struct bnx2fc_hba *hba; 801 760 struct bnx2fc_interface *interface; 761 + struct fcoe_ctlr *ctlr; 802 762 struct fcoe_port *port; 803 763 u64 wwnn, wwpn; 804 764 805 765 port = lport_priv(lport); 806 766 interface = port->priv; 767 + ctlr = bnx2fc_to_ctlr(interface); 807 768 hba = interface->hba; 808 769 809 770 /* require support for get_pauseparam ethtool op. */ ··· 824 781 825 782 if (!lport->vport) { 826 783 if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) 827 - wwnn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 784 + wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 828 785 1, 0); 829 786 BNX2FC_HBA_DBG(lport, "WWNN = 0x%llx\n", wwnn); 830 787 fc_set_wwnn(lport, wwnn); 831 788 832 789 if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) 833 - wwpn = fcoe_wwn_from_mac(interface->ctlr.ctl_src_addr, 790 + wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 834 791 2, 0); 835 792 836 793 BNX2FC_HBA_DBG(lport, "WWPN = 0x%llx\n", wwpn); ··· 867 824 struct fc_lport *lport; 868 825 struct fc_lport *vport; 869 826 struct bnx2fc_interface *interface, *tmp; 827 + struct fcoe_ctlr *ctlr; 870 828 int wait_for_upload = 0; 871 829 u32 link_possible = 1; 872 830 ··· 918 874 if (interface->hba != hba) 919 875 continue; 920 876 921 - lport = interface->ctlr.lp; 877 + ctlr = bnx2fc_to_ctlr(interface); 878 + lport = ctlr->lp; 922 879 BNX2FC_HBA_DBG(lport, "netevent handler - event=%s %ld\n", 923 880 interface->netdev->name, event); 924 881 ··· 934 889 * on a stale vlan 935 890 */ 936 891 if (interface->enabled) 937 - fcoe_ctlr_link_up(&interface->ctlr); 938 - } else if (fcoe_ctlr_link_down(&interface->ctlr)) { 892 + fcoe_ctlr_link_up(ctlr); 893 + } else if (fcoe_ctlr_link_down(ctlr)) { 939 894 mutex_lock(&lport->lp_mutex); 940 895 list_for_each_entry(vport, &lport->vports, list) 941 896 fc_host_port_type(vport->host) = ··· 1040 995 struct net_device *orig_dev) 1041 996 { 1042 997 struct bnx2fc_interface *interface; 998 + struct fcoe_ctlr *ctlr; 1043 999 interface = container_of(ptype, struct bnx2fc_interface, 1044 1000 fip_packet_type); 1045 - fcoe_ctlr_recv(&interface->ctlr, skb); 1001 + ctlr = bnx2fc_to_ctlr(interface); 1002 + fcoe_ctlr_recv(ctlr, skb); 1046 1003 return 0; 1047 1004 } 1048 1005 ··· 1202 1155 { 1203 1156 struct net_device *netdev = interface->netdev; 1204 1157 struct net_device *physdev = interface->hba->phys_dev; 1158 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1205 1159 struct netdev_hw_addr *ha; 1206 1160 int sel_san_mac = 0; 1207 1161 ··· 1217 1169 1218 1170 if ((ha->type == NETDEV_HW_ADDR_T_SAN) && 1219 1171 (is_valid_ether_addr(ha->addr))) { 1220 - memcpy(interface->ctlr.ctl_src_addr, ha->addr, 1172 + memcpy(ctlr->ctl_src_addr, ha->addr, 1221 1173 ETH_ALEN); 1222 1174 sel_san_mac = 1; 1223 1175 BNX2FC_MISC_DBG("Found SAN MAC\n"); ··· 1272 1224 1273 1225 static void bnx2fc_interface_release(struct kref *kref) 1274 1226 { 1227 + struct fcoe_ctlr_device *ctlr_dev; 1275 1228 struct bnx2fc_interface *interface; 1229 + struct fcoe_ctlr *ctlr; 1276 1230 struct net_device *netdev; 1277 1231 1278 1232 interface = container_of(kref, struct bnx2fc_interface, kref); 1279 1233 BNX2FC_MISC_DBG("Interface is being released\n"); 1280 1234 1235 + ctlr = bnx2fc_to_ctlr(interface); 1236 + ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); 1281 1237 netdev = interface->netdev; 1282 1238 1283 1239 /* tear-down FIP controller */ 1284 1240 if (test_and_clear_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags)) 1285 - fcoe_ctlr_destroy(&interface->ctlr); 1241 + fcoe_ctlr_destroy(ctlr); 1286 1242 1287 - kfree(interface); 1243 + fcoe_ctlr_device_delete(ctlr_dev); 1288 1244 1289 1245 dev_put(netdev); 1290 1246 module_put(THIS_MODULE); ··· 1381 1329 struct net_device *netdev, 1382 1330 enum fip_state fip_mode) 1383 1331 { 1332 + struct fcoe_ctlr_device *ctlr_dev; 1384 1333 struct bnx2fc_interface *interface; 1334 + struct fcoe_ctlr *ctlr; 1335 + int size; 1385 1336 int rc = 0; 1386 1337 1387 - interface = kzalloc(sizeof(*interface), GFP_KERNEL); 1388 - if (!interface) { 1338 + size = (sizeof(*interface) + sizeof(struct fcoe_ctlr)); 1339 + ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &bnx2fc_fcoe_sysfs_templ, 1340 + size); 1341 + if (!ctlr_dev) { 1389 1342 printk(KERN_ERR PFX "Unable to allocate interface structure\n"); 1390 1343 return NULL; 1391 1344 } 1345 + ctlr = fcoe_ctlr_device_priv(ctlr_dev); 1346 + interface = fcoe_ctlr_priv(ctlr); 1392 1347 dev_hold(netdev); 1393 1348 kref_init(&interface->kref); 1394 1349 interface->hba = hba; 1395 1350 interface->netdev = netdev; 1396 1351 1397 1352 /* Initialize FIP */ 1398 - fcoe_ctlr_init(&interface->ctlr, fip_mode); 1399 - interface->ctlr.send = bnx2fc_fip_send; 1400 - interface->ctlr.update_mac = bnx2fc_update_src_mac; 1401 - interface->ctlr.get_src_addr = bnx2fc_get_src_mac; 1353 + fcoe_ctlr_init(ctlr, fip_mode); 1354 + ctlr->send = bnx2fc_fip_send; 1355 + ctlr->update_mac = bnx2fc_update_src_mac; 1356 + ctlr->get_src_addr = bnx2fc_get_src_mac; 1402 1357 set_bit(BNX2FC_CTLR_INIT_DONE, &interface->if_flags); 1403 1358 1404 1359 rc = bnx2fc_interface_setup(interface); 1405 1360 if (!rc) 1406 1361 return interface; 1407 1362 1408 - fcoe_ctlr_destroy(&interface->ctlr); 1363 + fcoe_ctlr_destroy(ctlr); 1409 1364 dev_put(netdev); 1410 - kfree(interface); 1365 + fcoe_ctlr_device_delete(ctlr_dev); 1411 1366 return NULL; 1412 1367 } 1413 1368 ··· 1432 1373 static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, 1433 1374 struct device *parent, int npiv) 1434 1375 { 1376 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1435 1377 struct fc_lport *lport, *n_port; 1436 1378 struct fcoe_port *port; 1437 1379 struct Scsi_Host *shost; ··· 1443 1383 1444 1384 blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL); 1445 1385 if (!blport) { 1446 - BNX2FC_HBA_DBG(interface->ctlr.lp, "Unable to alloc blport\n"); 1386 + BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n"); 1447 1387 return NULL; 1448 1388 } 1449 1389 ··· 1539 1479 1540 1480 static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) 1541 1481 { 1542 - struct fc_lport *lport = interface->ctlr.lp; 1482 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1483 + struct fc_lport *lport = ctlr->lp; 1543 1484 struct fcoe_port *port = lport_priv(lport); 1544 1485 struct bnx2fc_hba *hba = interface->hba; 1545 1486 ··· 1580 1519 1581 1520 static void __bnx2fc_destroy(struct bnx2fc_interface *interface) 1582 1521 { 1583 - struct fc_lport *lport = interface->ctlr.lp; 1522 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1523 + struct fc_lport *lport = ctlr->lp; 1584 1524 struct fcoe_port *port = lport_priv(lport); 1585 1525 1586 1526 bnx2fc_interface_cleanup(interface); ··· 1605 1543 { 1606 1544 struct bnx2fc_interface *interface = NULL; 1607 1545 struct workqueue_struct *timer_work_queue; 1546 + struct fcoe_ctlr *ctlr; 1608 1547 int rc = 0; 1609 1548 1610 1549 rtnl_lock(); 1611 1550 mutex_lock(&bnx2fc_dev_lock); 1612 1551 1613 1552 interface = bnx2fc_interface_lookup(netdev); 1614 - if (!interface || !interface->ctlr.lp) { 1553 + ctlr = bnx2fc_to_ctlr(interface); 1554 + if (!interface || !ctlr->lp) { 1615 1555 rc = -ENODEV; 1616 1556 printk(KERN_ERR PFX "bnx2fc_destroy: interface or lport not found\n"); 1617 1557 goto netdev_err; ··· 1710 1646 { 1711 1647 struct bnx2fc_hba *hba = handle; 1712 1648 struct bnx2fc_interface *interface; 1649 + struct fcoe_ctlr *ctlr; 1713 1650 struct fc_lport *lport; 1714 1651 1715 1652 mutex_lock(&bnx2fc_dev_lock); ··· 1722 1657 1723 1658 list_for_each_entry(interface, &if_list, list) { 1724 1659 if (interface->hba == hba) { 1725 - lport = interface->ctlr.lp; 1660 + ctlr = bnx2fc_to_ctlr(interface); 1661 + lport = ctlr->lp; 1726 1662 /* Kick off Fabric discovery*/ 1727 1663 printk(KERN_ERR PFX "ulp_init: start discovery\n"); 1728 1664 lport->tt.frame_send = bnx2fc_xmit; ··· 1743 1677 1744 1678 static void bnx2fc_stop(struct bnx2fc_interface *interface) 1745 1679 { 1680 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1746 1681 struct fc_lport *lport; 1747 1682 struct fc_lport *vport; 1748 1683 1749 1684 if (!test_bit(BNX2FC_FLAG_FW_INIT_DONE, &interface->hba->flags)) 1750 1685 return; 1751 1686 1752 - lport = interface->ctlr.lp; 1687 + lport = ctlr->lp; 1753 1688 bnx2fc_port_shutdown(lport); 1754 1689 1755 1690 mutex_lock(&lport->lp_mutex); ··· 1759 1692 FC_PORTTYPE_UNKNOWN; 1760 1693 mutex_unlock(&lport->lp_mutex); 1761 1694 fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; 1762 - fcoe_ctlr_link_down(&interface->ctlr); 1695 + fcoe_ctlr_link_down(ctlr); 1763 1696 fcoe_clean_pending_queue(lport); 1764 1697 } 1765 1698 ··· 1871 1804 1872 1805 static void bnx2fc_start_disc(struct bnx2fc_interface *interface) 1873 1806 { 1807 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 1874 1808 struct fc_lport *lport; 1875 1809 int wait_cnt = 0; 1876 1810 ··· 1882 1814 return; 1883 1815 } 1884 1816 1885 - lport = interface->ctlr.lp; 1817 + lport = ctlr->lp; 1886 1818 BNX2FC_HBA_DBG(lport, "calling fc_fabric_login\n"); 1887 1819 1888 1820 if (!bnx2fc_link_ok(lport) && interface->enabled) { 1889 1821 BNX2FC_HBA_DBG(lport, "ctlr_link_up\n"); 1890 - fcoe_ctlr_link_up(&interface->ctlr); 1822 + fcoe_ctlr_link_up(ctlr); 1891 1823 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; 1892 1824 set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); 1893 1825 } 1894 1826 1895 1827 /* wait for the FCF to be selected before issuing FLOGI */ 1896 - while (!interface->ctlr.sel_fcf) { 1828 + while (!ctlr->sel_fcf) { 1897 1829 msleep(250); 1898 1830 /* give up after 3 secs */ 1899 1831 if (++wait_cnt > 12) ··· 1957 1889 static int bnx2fc_disable(struct net_device *netdev) 1958 1890 { 1959 1891 struct bnx2fc_interface *interface; 1892 + struct fcoe_ctlr *ctlr; 1960 1893 int rc = 0; 1961 1894 1962 1895 rtnl_lock(); 1963 1896 mutex_lock(&bnx2fc_dev_lock); 1964 1897 1965 1898 interface = bnx2fc_interface_lookup(netdev); 1966 - if (!interface || !interface->ctlr.lp) { 1899 + ctlr = bnx2fc_to_ctlr(interface); 1900 + if (!interface || !ctlr->lp) { 1967 1901 rc = -ENODEV; 1968 1902 printk(KERN_ERR PFX "bnx2fc_disable: interface or lport not found\n"); 1969 1903 } else { 1970 1904 interface->enabled = false; 1971 - fcoe_ctlr_link_down(&interface->ctlr); 1972 - fcoe_clean_pending_queue(interface->ctlr.lp); 1905 + fcoe_ctlr_link_down(ctlr); 1906 + fcoe_clean_pending_queue(ctlr->lp); 1973 1907 } 1974 1908 1975 1909 mutex_unlock(&bnx2fc_dev_lock); ··· 1983 1913 static int bnx2fc_enable(struct net_device *netdev) 1984 1914 { 1985 1915 struct bnx2fc_interface *interface; 1916 + struct fcoe_ctlr *ctlr; 1986 1917 int rc = 0; 1987 1918 1988 1919 rtnl_lock(); 1989 1920 mutex_lock(&bnx2fc_dev_lock); 1990 1921 1991 1922 interface = bnx2fc_interface_lookup(netdev); 1992 - if (!interface || !interface->ctlr.lp) { 1923 + ctlr = bnx2fc_to_ctlr(interface); 1924 + if (!interface || !ctlr->lp) { 1993 1925 rc = -ENODEV; 1994 1926 printk(KERN_ERR PFX "bnx2fc_enable: interface or lport not found\n"); 1995 - } else if (!bnx2fc_link_ok(interface->ctlr.lp)) { 1996 - fcoe_ctlr_link_up(&interface->ctlr); 1927 + } else if (!bnx2fc_link_ok(ctlr->lp)) { 1928 + fcoe_ctlr_link_up(ctlr); 1997 1929 interface->enabled = true; 1998 1930 } 1999 1931 ··· 2016 1944 */ 2017 1945 static int bnx2fc_create(struct net_device *netdev, enum fip_state fip_mode) 2018 1946 { 1947 + struct fcoe_ctlr *ctlr; 2019 1948 struct bnx2fc_interface *interface; 2020 1949 struct bnx2fc_hba *hba; 2021 1950 struct net_device *phys_dev; ··· 2083 2010 goto ifput_err; 2084 2011 } 2085 2012 2013 + ctlr = bnx2fc_to_ctlr(interface); 2086 2014 interface->vlan_id = vlan_id; 2087 2015 interface->vlan_enabled = 1; 2088 2016 ··· 2109 2035 lport->boot_time = jiffies; 2110 2036 2111 2037 /* Make this master N_port */ 2112 - interface->ctlr.lp = lport; 2038 + ctlr->lp = lport; 2113 2039 2114 2040 if (!bnx2fc_link_ok(lport)) { 2115 - fcoe_ctlr_link_up(&interface->ctlr); 2041 + fcoe_ctlr_link_up(ctlr); 2116 2042 fc_host_port_type(lport->host) = FC_PORTTYPE_NPORT; 2117 2043 set_bit(ADAPTER_STATE_READY, &interface->hba->adapter_state); 2118 2044 } ··· 2512 2438 2513 2439 module_init(bnx2fc_mod_init); 2514 2440 module_exit(bnx2fc_mod_exit); 2441 + 2442 + static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = { 2443 + .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 2444 + .get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb, 2445 + .get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb, 2446 + .get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb, 2447 + .get_fcoe_ctlr_symb_err = bnx2fc_ctlr_get_lesb, 2448 + .get_fcoe_ctlr_err_block = bnx2fc_ctlr_get_lesb, 2449 + .get_fcoe_ctlr_fcs_error = bnx2fc_ctlr_get_lesb, 2450 + 2451 + .get_fcoe_fcf_selected = fcoe_fcf_get_selected, 2452 + .get_fcoe_fcf_vlan_id = bnx2fc_fcf_get_vlan_id, 2453 + }; 2515 2454 2516 2455 static struct fc_function_template bnx2fc_transport_function = { 2517 2456 .show_host_node_name = 1,
+21 -18
drivers/scsi/bnx2fc/bnx2fc_hwi.c
··· 167 167 { 168 168 struct fc_lport *lport = port->lport; 169 169 struct bnx2fc_interface *interface = port->priv; 170 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 170 171 struct bnx2fc_hba *hba = interface->hba; 171 172 struct kwqe *kwqe_arr[4]; 172 173 struct fcoe_kwqe_conn_offload1 ofld_req1; ··· 315 314 ofld_req4.src_mac_addr_mid[1] = port->data_src_addr[2]; 316 315 ofld_req4.src_mac_addr_hi[0] = port->data_src_addr[1]; 317 316 ofld_req4.src_mac_addr_hi[1] = port->data_src_addr[0]; 318 - ofld_req4.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; 317 + ofld_req4.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; 319 318 /* fcf mac */ 320 - ofld_req4.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; 321 - ofld_req4.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; 322 - ofld_req4.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; 323 - ofld_req4.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; 324 - ofld_req4.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; 319 + ofld_req4.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; 320 + ofld_req4.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; 321 + ofld_req4.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; 322 + ofld_req4.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; 323 + ofld_req4.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; 325 324 326 325 ofld_req4.lcq_addr_lo = (u32) tgt->lcq_dma; 327 326 ofld_req4.lcq_addr_hi = (u32)((u64) tgt->lcq_dma >> 32); ··· 352 351 { 353 352 struct kwqe *kwqe_arr[2]; 354 353 struct bnx2fc_interface *interface = port->priv; 354 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 355 355 struct bnx2fc_hba *hba = interface->hba; 356 356 struct fcoe_kwqe_conn_enable_disable enbl_req; 357 357 struct fc_lport *lport = port->lport; ··· 376 374 enbl_req.src_mac_addr_hi[1] = port->data_src_addr[0]; 377 375 memcpy(tgt->src_addr, port->data_src_addr, ETH_ALEN); 378 376 379 - enbl_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; 380 - enbl_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; 381 - enbl_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; 382 - enbl_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; 383 - enbl_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; 384 - enbl_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; 377 + enbl_req.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; 378 + enbl_req.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; 379 + enbl_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; 380 + enbl_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; 381 + enbl_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; 382 + enbl_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; 385 383 386 384 port_id = fc_host_port_id(lport->host); 387 385 if (port_id != tgt->sid) { ··· 421 419 struct bnx2fc_rport *tgt) 422 420 { 423 421 struct bnx2fc_interface *interface = port->priv; 422 + struct fcoe_ctlr *ctlr = bnx2fc_to_ctlr(interface); 424 423 struct bnx2fc_hba *hba = interface->hba; 425 424 struct fcoe_kwqe_conn_enable_disable disable_req; 426 425 struct kwqe *kwqe_arr[2]; ··· 443 440 disable_req.src_mac_addr_hi[0] = tgt->src_addr[1]; 444 441 disable_req.src_mac_addr_hi[1] = tgt->src_addr[0]; 445 442 446 - disable_req.dst_mac_addr_lo[0] = interface->ctlr.dest_addr[5]; 447 - disable_req.dst_mac_addr_lo[1] = interface->ctlr.dest_addr[4]; 448 - disable_req.dst_mac_addr_mid[0] = interface->ctlr.dest_addr[3]; 449 - disable_req.dst_mac_addr_mid[1] = interface->ctlr.dest_addr[2]; 450 - disable_req.dst_mac_addr_hi[0] = interface->ctlr.dest_addr[1]; 451 - disable_req.dst_mac_addr_hi[1] = interface->ctlr.dest_addr[0]; 443 + disable_req.dst_mac_addr_lo[0] = ctlr->dest_addr[5]; 444 + disable_req.dst_mac_addr_lo[1] = ctlr->dest_addr[4]; 445 + disable_req.dst_mac_addr_mid[0] = ctlr->dest_addr[3]; 446 + disable_req.dst_mac_addr_mid[1] = ctlr->dest_addr[2]; 447 + disable_req.dst_mac_addr_hi[0] = ctlr->dest_addr[1]; 448 + disable_req.dst_mac_addr_hi[1] = ctlr->dest_addr[0]; 452 449 453 450 port_id = tgt->sid; 454 451 disable_req.s_id[0] = (port_id & 0x000000FF);
+75 -47
drivers/scsi/bnx2fc/bnx2fc_io.c
··· 810 810 spin_lock_bh(&tgt->tgt_lock); 811 811 812 812 io_req->wait_for_comp = 0; 813 - if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) 813 + if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) { 814 814 set_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags); 815 + if (io_req->on_tmf_queue) { 816 + list_del_init(&io_req->link); 817 + io_req->on_tmf_queue = 0; 818 + } 819 + io_req->wait_for_comp = 1; 820 + bnx2fc_initiate_cleanup(io_req); 821 + spin_unlock_bh(&tgt->tgt_lock); 822 + rc = wait_for_completion_timeout(&io_req->tm_done, 823 + BNX2FC_FW_TIMEOUT); 824 + spin_lock_bh(&tgt->tgt_lock); 825 + io_req->wait_for_comp = 0; 826 + if (!rc) 827 + kref_put(&io_req->refcount, bnx2fc_cmd_release); 828 + } 815 829 816 830 spin_unlock_bh(&tgt->tgt_lock); 817 831 ··· 1103 1089 return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); 1104 1090 } 1105 1091 1092 + int bnx2fc_expl_logo(struct fc_lport *lport, struct bnx2fc_cmd *io_req) 1093 + { 1094 + struct bnx2fc_rport *tgt = io_req->tgt; 1095 + struct fc_rport_priv *rdata = tgt->rdata; 1096 + int logo_issued; 1097 + int rc = SUCCESS; 1098 + int wait_cnt = 0; 1099 + 1100 + BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n", 1101 + tgt->flags); 1102 + logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO, 1103 + &tgt->flags); 1104 + io_req->wait_for_comp = 1; 1105 + bnx2fc_initiate_cleanup(io_req); 1106 + 1107 + spin_unlock_bh(&tgt->tgt_lock); 1108 + 1109 + wait_for_completion(&io_req->tm_done); 1110 + 1111 + io_req->wait_for_comp = 0; 1112 + /* 1113 + * release the reference taken in eh_abort to allow the 1114 + * target to re-login after flushing IOs 1115 + */ 1116 + kref_put(&io_req->refcount, bnx2fc_cmd_release); 1117 + 1118 + if (!logo_issued) { 1119 + clear_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags); 1120 + mutex_lock(&lport->disc.disc_mutex); 1121 + lport->tt.rport_logoff(rdata); 1122 + mutex_unlock(&lport->disc.disc_mutex); 1123 + do { 1124 + msleep(BNX2FC_RELOGIN_WAIT_TIME); 1125 + if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) { 1126 + rc = FAILED; 1127 + break; 1128 + } 1129 + } while (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)); 1130 + } 1131 + spin_lock_bh(&tgt->tgt_lock); 1132 + return rc; 1133 + } 1106 1134 /** 1107 1135 * bnx2fc_eh_abort - eh_abort_handler api to abort an outstanding 1108 1136 * SCSI command ··· 1159 1103 struct fc_rport_libfc_priv *rp = rport->dd_data; 1160 1104 struct bnx2fc_cmd *io_req; 1161 1105 struct fc_lport *lport; 1162 - struct fc_rport_priv *rdata; 1163 1106 struct bnx2fc_rport *tgt; 1164 - int logo_issued; 1165 - int wait_cnt = 0; 1166 1107 int rc = FAILED; 1167 1108 1168 1109 ··· 1236 1183 list_add_tail(&io_req->link, &tgt->io_retire_queue); 1237 1184 1238 1185 init_completion(&io_req->tm_done); 1239 - io_req->wait_for_comp = 1; 1240 1186 1241 - if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) { 1242 - /* Cancel the current timer running on this io_req */ 1243 - if (cancel_delayed_work(&io_req->timeout_work)) 1244 - kref_put(&io_req->refcount, 1245 - bnx2fc_cmd_release); /* drop timer hold */ 1246 - set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags); 1247 - rc = bnx2fc_initiate_abts(io_req); 1248 - } else { 1187 + if (test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) { 1249 1188 printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) " 1250 1189 "already in abts processing\n", io_req->xid); 1251 1190 if (cancel_delayed_work(&io_req->timeout_work)) 1252 1191 kref_put(&io_req->refcount, 1253 1192 bnx2fc_cmd_release); /* drop timer hold */ 1193 + rc = bnx2fc_expl_logo(lport, io_req); 1194 + goto out; 1195 + } 1196 + 1197 + /* Cancel the current timer running on this io_req */ 1198 + if (cancel_delayed_work(&io_req->timeout_work)) 1199 + kref_put(&io_req->refcount, 1200 + bnx2fc_cmd_release); /* drop timer hold */ 1201 + set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags); 1202 + io_req->wait_for_comp = 1; 1203 + rc = bnx2fc_initiate_abts(io_req); 1204 + if (rc == FAILED) { 1254 1205 bnx2fc_initiate_cleanup(io_req); 1255 - 1256 1206 spin_unlock_bh(&tgt->tgt_lock); 1257 - 1258 1207 wait_for_completion(&io_req->tm_done); 1259 - 1260 1208 spin_lock_bh(&tgt->tgt_lock); 1261 1209 io_req->wait_for_comp = 0; 1262 - rdata = io_req->tgt->rdata; 1263 - logo_issued = test_and_set_bit(BNX2FC_FLAG_EXPL_LOGO, 1264 - &tgt->flags); 1265 - kref_put(&io_req->refcount, bnx2fc_cmd_release); 1266 - spin_unlock_bh(&tgt->tgt_lock); 1267 - 1268 - if (!logo_issued) { 1269 - BNX2FC_IO_DBG(io_req, "Expl logo - tgt flags = 0x%lx\n", 1270 - tgt->flags); 1271 - mutex_lock(&lport->disc.disc_mutex); 1272 - lport->tt.rport_logoff(rdata); 1273 - mutex_unlock(&lport->disc.disc_mutex); 1274 - do { 1275 - msleep(BNX2FC_RELOGIN_WAIT_TIME); 1276 - /* 1277 - * If session not recovered, let SCSI-ml 1278 - * escalate error recovery. 1279 - */ 1280 - if (wait_cnt++ > BNX2FC_RELOGIN_WAIT_CNT) 1281 - return FAILED; 1282 - } while (!test_bit(BNX2FC_FLAG_SESSION_READY, 1283 - &tgt->flags)); 1284 - } 1285 - return SUCCESS; 1286 - } 1287 - if (rc == FAILED) { 1288 - kref_put(&io_req->refcount, bnx2fc_cmd_release); 1289 - spin_unlock_bh(&tgt->tgt_lock); 1290 - return rc; 1210 + goto done; 1291 1211 } 1292 1212 spin_unlock_bh(&tgt->tgt_lock); 1293 1213 ··· 1273 1247 /* Let the scsi-ml try to recover this command */ 1274 1248 printk(KERN_ERR PFX "abort failed, xid = 0x%x\n", 1275 1249 io_req->xid); 1276 - rc = FAILED; 1250 + rc = bnx2fc_expl_logo(lport, io_req); 1251 + goto out; 1277 1252 } else { 1278 1253 /* 1279 1254 * We come here even when there was a race condition ··· 1286 1259 bnx2fc_scsi_done(io_req, DID_ABORT); 1287 1260 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1288 1261 } 1289 - 1262 + done: 1290 1263 /* release the reference taken in eh_abort */ 1291 1264 kref_put(&io_req->refcount, bnx2fc_cmd_release); 1265 + out: 1292 1266 spin_unlock_bh(&tgt->tgt_lock); 1293 1267 return rc; 1294 1268 }
+20 -1
drivers/scsi/bnx2fc/bnx2fc_tgt.c
··· 185 185 BUG_ON(rc); 186 186 } 187 187 188 + list_for_each_safe(list, tmp, &tgt->active_tm_queue) { 189 + i++; 190 + io_req = (struct bnx2fc_cmd *)list; 191 + list_del_init(&io_req->link); 192 + io_req->on_tmf_queue = 0; 193 + BNX2FC_IO_DBG(io_req, "tm_queue cleanup\n"); 194 + if (io_req->wait_for_comp) 195 + complete(&io_req->tm_done); 196 + } 197 + 188 198 list_for_each_safe(list, tmp, &tgt->els_queue) { 189 199 i++; 190 200 io_req = (struct bnx2fc_cmd *)list; ··· 223 213 224 214 BNX2FC_IO_DBG(io_req, "retire_queue flush\n"); 225 215 226 - if (cancel_delayed_work(&io_req->timeout_work)) 216 + if (cancel_delayed_work(&io_req->timeout_work)) { 217 + if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT, 218 + &io_req->req_flags)) { 219 + /* Handle eh_abort timeout */ 220 + BNX2FC_IO_DBG(io_req, "eh_abort for IO " 221 + "in retire_q\n"); 222 + if (io_req->wait_for_comp) 223 + complete(&io_req->tm_done); 224 + } 227 225 kref_put(&io_req->refcount, bnx2fc_cmd_release); 226 + } 228 227 229 228 clear_bit(BNX2FC_FLAG_ISSUE_RRQ, &io_req->req_flags); 230 229 }
+1 -1
drivers/scsi/fcoe/Makefile
··· 1 1 obj-$(CONFIG_FCOE) += fcoe.o 2 2 obj-$(CONFIG_LIBFCOE) += libfcoe.o 3 3 4 - libfcoe-objs := fcoe_ctlr.o fcoe_transport.o 4 + libfcoe-objs := fcoe_ctlr.o fcoe_transport.o fcoe_sysfs.o
+148 -52
drivers/scsi/fcoe/fcoe.c
··· 41 41 42 42 #include <scsi/fc/fc_encaps.h> 43 43 #include <scsi/fc/fc_fip.h> 44 + #include <scsi/fc/fc_fcoe.h> 44 45 45 46 #include <scsi/libfc.h> 46 47 #include <scsi/fc_frame.h> ··· 151 150 static int fcoe_vport_disable(struct fc_vport *, bool disable); 152 151 static void fcoe_set_vport_symbolic_name(struct fc_vport *); 153 152 static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); 153 + static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *); 154 + static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *); 155 + 156 + static struct fcoe_sysfs_function_template fcoe_sysfs_templ = { 157 + .get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode, 158 + .get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb, 159 + .get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb, 160 + .get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb, 161 + .get_fcoe_ctlr_symb_err = fcoe_ctlr_get_lesb, 162 + .get_fcoe_ctlr_err_block = fcoe_ctlr_get_lesb, 163 + .get_fcoe_ctlr_fcs_error = fcoe_ctlr_get_lesb, 164 + 165 + .get_fcoe_fcf_selected = fcoe_fcf_get_selected, 166 + .get_fcoe_fcf_vlan_id = fcoe_fcf_get_vlan_id, 167 + }; 154 168 155 169 static struct libfc_function_template fcoe_libfc_fcn_templ = { 156 170 .frame_send = fcoe_xmit, ··· 298 282 static int fcoe_interface_setup(struct fcoe_interface *fcoe, 299 283 struct net_device *netdev) 300 284 { 301 - struct fcoe_ctlr *fip = &fcoe->ctlr; 285 + struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 302 286 struct netdev_hw_addr *ha; 303 287 struct net_device *real_dev; 304 288 u8 flogi_maddr[ETH_ALEN]; ··· 382 366 static struct fcoe_interface *fcoe_interface_create(struct net_device *netdev, 383 367 enum fip_state fip_mode) 384 368 { 369 + struct fcoe_ctlr_device *ctlr_dev; 370 + struct fcoe_ctlr *ctlr; 385 371 struct fcoe_interface *fcoe; 372 + int size; 386 373 int err; 387 374 388 375 if (!try_module_get(THIS_MODULE)) { ··· 395 376 goto out; 396 377 } 397 378 398 - fcoe = kzalloc(sizeof(*fcoe), GFP_KERNEL); 399 - if (!fcoe) { 400 - FCOE_NETDEV_DBG(netdev, "Could not allocate fcoe structure\n"); 379 + size = sizeof(struct fcoe_ctlr) + sizeof(struct fcoe_interface); 380 + ctlr_dev = fcoe_ctlr_device_add(&netdev->dev, &fcoe_sysfs_templ, 381 + size); 382 + if (!ctlr_dev) { 383 + FCOE_DBG("Failed to add fcoe_ctlr_device\n"); 401 384 fcoe = ERR_PTR(-ENOMEM); 402 385 goto out_putmod; 403 386 } 387 + 388 + ctlr = fcoe_ctlr_device_priv(ctlr_dev); 389 + fcoe = fcoe_ctlr_priv(ctlr); 404 390 405 391 dev_hold(netdev); 406 392 407 393 /* 408 394 * Initialize FIP. 409 395 */ 410 - fcoe_ctlr_init(&fcoe->ctlr, fip_mode); 411 - fcoe->ctlr.send = fcoe_fip_send; 412 - fcoe->ctlr.update_mac = fcoe_update_src_mac; 413 - fcoe->ctlr.get_src_addr = fcoe_get_src_mac; 396 + fcoe_ctlr_init(ctlr, fip_mode); 397 + ctlr->send = fcoe_fip_send; 398 + ctlr->update_mac = fcoe_update_src_mac; 399 + ctlr->get_src_addr = fcoe_get_src_mac; 414 400 415 401 err = fcoe_interface_setup(fcoe, netdev); 416 402 if (err) { 417 - fcoe_ctlr_destroy(&fcoe->ctlr); 418 - kfree(fcoe); 403 + fcoe_ctlr_destroy(ctlr); 404 + fcoe_ctlr_device_delete(ctlr_dev); 419 405 dev_put(netdev); 420 406 fcoe = ERR_PTR(err); 421 407 goto out_putmod; ··· 443 419 static void fcoe_interface_remove(struct fcoe_interface *fcoe) 444 420 { 445 421 struct net_device *netdev = fcoe->netdev; 446 - struct fcoe_ctlr *fip = &fcoe->ctlr; 422 + struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 447 423 u8 flogi_maddr[ETH_ALEN]; 448 424 const struct net_device_ops *ops; 449 425 ··· 486 462 static void fcoe_interface_cleanup(struct fcoe_interface *fcoe) 487 463 { 488 464 struct net_device *netdev = fcoe->netdev; 489 - struct fcoe_ctlr *fip = &fcoe->ctlr; 465 + struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 466 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 490 467 491 468 rtnl_lock(); 492 469 if (!fcoe->removed) ··· 497 472 /* Release the self-reference taken during fcoe_interface_create() */ 498 473 /* tear-down the FCoE controller */ 499 474 fcoe_ctlr_destroy(fip); 500 - scsi_host_put(fcoe->ctlr.lp->host); 501 - kfree(fcoe); 475 + scsi_host_put(fip->lp->host); 476 + fcoe_ctlr_device_delete(ctlr_dev); 502 477 dev_put(netdev); 503 478 module_put(THIS_MODULE); 504 479 } ··· 518 493 struct net_device *orig_dev) 519 494 { 520 495 struct fcoe_interface *fcoe; 496 + struct fcoe_ctlr *ctlr; 521 497 522 498 fcoe = container_of(ptype, struct fcoe_interface, fip_packet_type); 523 - fcoe_ctlr_recv(&fcoe->ctlr, skb); 499 + ctlr = fcoe_to_ctlr(fcoe); 500 + fcoe_ctlr_recv(ctlr, skb); 524 501 return 0; 525 502 } 526 503 ··· 672 645 u32 mfs; 673 646 u64 wwnn, wwpn; 674 647 struct fcoe_interface *fcoe; 648 + struct fcoe_ctlr *ctlr; 675 649 struct fcoe_port *port; 676 650 677 651 /* Setup lport private data to point to fcoe softc */ 678 652 port = lport_priv(lport); 679 653 fcoe = port->priv; 654 + ctlr = fcoe_to_ctlr(fcoe); 680 655 681 656 /* 682 657 * Determine max frame size based on underlying device and optional ··· 705 676 706 677 if (!lport->vport) { 707 678 if (fcoe_get_wwn(netdev, &wwnn, NETDEV_FCOE_WWNN)) 708 - wwnn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 1, 0); 679 + wwnn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 1, 0); 709 680 fc_set_wwnn(lport, wwnn); 710 681 if (fcoe_get_wwn(netdev, &wwpn, NETDEV_FCOE_WWPN)) 711 - wwpn = fcoe_wwn_from_mac(fcoe->ctlr.ctl_src_addr, 682 + wwpn = fcoe_wwn_from_mac(ctlr->ctl_src_addr, 712 683 2, 0); 713 684 fc_set_wwpn(lport, wwpn); 714 685 } ··· 1085 1056 static struct fc_lport *fcoe_if_create(struct fcoe_interface *fcoe, 1086 1057 struct device *parent, int npiv) 1087 1058 { 1059 + struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 1088 1060 struct net_device *netdev = fcoe->netdev; 1089 1061 struct fc_lport *lport, *n_port; 1090 1062 struct fcoe_port *port; ··· 1149 1119 } 1150 1120 1151 1121 /* Initialize the library */ 1152 - rc = fcoe_libfc_config(lport, &fcoe->ctlr, &fcoe_libfc_fcn_templ, 1); 1122 + rc = fcoe_libfc_config(lport, ctlr, &fcoe_libfc_fcn_templ, 1); 1153 1123 if (rc) { 1154 1124 FCOE_NETDEV_DBG(netdev, "Could not configure libfc for the " 1155 1125 "interface\n"); ··· 1416 1386 { 1417 1387 struct fc_lport *lport; 1418 1388 struct fcoe_rcv_info *fr; 1389 + struct fcoe_ctlr *ctlr; 1419 1390 struct fcoe_interface *fcoe; 1420 1391 struct fc_frame_header *fh; 1421 1392 struct fcoe_percpu_s *fps; ··· 1424 1393 unsigned int cpu; 1425 1394 1426 1395 fcoe = container_of(ptype, struct fcoe_interface, fcoe_packet_type); 1427 - lport = fcoe->ctlr.lp; 1396 + ctlr = fcoe_to_ctlr(fcoe); 1397 + lport = ctlr->lp; 1428 1398 if (unlikely(!lport)) { 1429 1399 FCOE_NETDEV_DBG(netdev, "Cannot find hba structure"); 1430 1400 goto err2; ··· 1441 1409 1442 1410 eh = eth_hdr(skb); 1443 1411 1444 - if (is_fip_mode(&fcoe->ctlr) && 1445 - compare_ether_addr(eh->h_source, fcoe->ctlr.dest_addr)) { 1412 + if (is_fip_mode(ctlr) && 1413 + compare_ether_addr(eh->h_source, ctlr->dest_addr)) { 1446 1414 FCOE_NETDEV_DBG(netdev, "wrong source mac address:%pM\n", 1447 1415 eh->h_source); 1448 1416 goto err; ··· 1576 1544 unsigned int elen; /* eth header, may include vlan */ 1577 1545 struct fcoe_port *port = lport_priv(lport); 1578 1546 struct fcoe_interface *fcoe = port->priv; 1547 + struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 1579 1548 u8 sof, eof; 1580 1549 struct fcoe_hdr *hp; 1581 1550 ··· 1592 1559 } 1593 1560 1594 1561 if (unlikely(fh->fh_type == FC_TYPE_ELS) && 1595 - fcoe_ctlr_els_send(&fcoe->ctlr, lport, skb)) 1562 + fcoe_ctlr_els_send(ctlr, lport, skb)) 1596 1563 return 0; 1597 1564 1598 1565 sof = fr_sof(fp); ··· 1656 1623 /* fill up mac and fcoe headers */ 1657 1624 eh = eth_hdr(skb); 1658 1625 eh->h_proto = htons(ETH_P_FCOE); 1659 - memcpy(eh->h_dest, fcoe->ctlr.dest_addr, ETH_ALEN); 1660 - if (fcoe->ctlr.map_dest) 1626 + memcpy(eh->h_dest, ctlr->dest_addr, ETH_ALEN); 1627 + if (ctlr->map_dest) 1661 1628 memcpy(eh->h_dest + 3, fh->fh_d_id, 3); 1662 1629 1663 - if (unlikely(fcoe->ctlr.flogi_oxid != FC_XID_UNKNOWN)) 1664 - memcpy(eh->h_source, fcoe->ctlr.ctl_src_addr, ETH_ALEN); 1630 + if (unlikely(ctlr->flogi_oxid != FC_XID_UNKNOWN)) 1631 + memcpy(eh->h_source, ctlr->ctl_src_addr, ETH_ALEN); 1665 1632 else 1666 1633 memcpy(eh->h_source, port->data_src_addr, ETH_ALEN); 1667 1634 ··· 1710 1677 static inline int fcoe_filter_frames(struct fc_lport *lport, 1711 1678 struct fc_frame *fp) 1712 1679 { 1680 + struct fcoe_ctlr *ctlr; 1713 1681 struct fcoe_interface *fcoe; 1714 1682 struct fc_frame_header *fh; 1715 1683 struct sk_buff *skb = (struct sk_buff *)fp; ··· 1732 1698 return 0; 1733 1699 1734 1700 fcoe = ((struct fcoe_port *)lport_priv(lport))->priv; 1735 - if (is_fip_mode(&fcoe->ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && 1701 + ctlr = fcoe_to_ctlr(fcoe); 1702 + if (is_fip_mode(ctlr) && fc_frame_payload_op(fp) == ELS_LOGO && 1736 1703 ntoh24(fh->fh_s_id) == FC_FID_FLOGI) { 1737 1704 FCOE_DBG("fcoe: dropping FCoE lport LOGO in fip mode\n"); 1738 1705 return -EINVAL; ··· 1912 1877 ulong event, void *ptr) 1913 1878 { 1914 1879 struct dcb_app_type *entry = ptr; 1880 + struct fcoe_ctlr *ctlr; 1915 1881 struct fcoe_interface *fcoe; 1916 1882 struct net_device *netdev; 1917 1883 struct fcoe_port *port; ··· 1930 1894 if (!fcoe) 1931 1895 return NOTIFY_OK; 1932 1896 1897 + ctlr = fcoe_to_ctlr(fcoe); 1898 + 1933 1899 if (entry->dcbx & DCB_CAP_DCBX_VER_CEE) 1934 1900 prio = ffs(entry->app.priority) - 1; 1935 1901 else ··· 1942 1904 1943 1905 if (entry->app.protocol == ETH_P_FIP || 1944 1906 entry->app.protocol == ETH_P_FCOE) 1945 - fcoe->ctlr.priority = prio; 1907 + ctlr->priority = prio; 1946 1908 1947 1909 if (entry->app.protocol == ETH_P_FCOE) { 1948 - port = lport_priv(fcoe->ctlr.lp); 1910 + port = lport_priv(ctlr->lp); 1949 1911 port->priority = prio; 1950 1912 } 1951 1913 ··· 1967 1929 { 1968 1930 struct fc_lport *lport = NULL; 1969 1931 struct net_device *netdev = ptr; 1932 + struct fcoe_ctlr *ctlr; 1970 1933 struct fcoe_interface *fcoe; 1971 1934 struct fcoe_port *port; 1972 1935 struct fcoe_dev_stats *stats; ··· 1977 1938 1978 1939 list_for_each_entry(fcoe, &fcoe_hostlist, list) { 1979 1940 if (fcoe->netdev == netdev) { 1980 - lport = fcoe->ctlr.lp; 1941 + ctlr = fcoe_to_ctlr(fcoe); 1942 + lport = ctlr->lp; 1981 1943 break; 1982 1944 } 1983 1945 } ··· 2007 1967 break; 2008 1968 case NETDEV_UNREGISTER: 2009 1969 list_del(&fcoe->list); 2010 - port = lport_priv(fcoe->ctlr.lp); 1970 + port = lport_priv(ctlr->lp); 2011 1971 queue_work(fcoe_wq, &port->destroy_work); 2012 1972 goto out; 2013 1973 break; ··· 2022 1982 fcoe_link_speed_update(lport); 2023 1983 2024 1984 if (link_possible && !fcoe_link_ok(lport)) 2025 - fcoe_ctlr_link_up(&fcoe->ctlr); 2026 - else if (fcoe_ctlr_link_down(&fcoe->ctlr)) { 1985 + fcoe_ctlr_link_up(ctlr); 1986 + else if (fcoe_ctlr_link_down(ctlr)) { 2027 1987 stats = per_cpu_ptr(lport->dev_stats, get_cpu()); 2028 1988 stats->LinkFailureCount++; 2029 1989 put_cpu(); ··· 2043 2003 */ 2044 2004 static int fcoe_disable(struct net_device *netdev) 2045 2005 { 2006 + struct fcoe_ctlr *ctlr; 2046 2007 struct fcoe_interface *fcoe; 2047 2008 int rc = 0; 2048 2009 ··· 2054 2013 rtnl_unlock(); 2055 2014 2056 2015 if (fcoe) { 2057 - fcoe_ctlr_link_down(&fcoe->ctlr); 2058 - fcoe_clean_pending_queue(fcoe->ctlr.lp); 2016 + ctlr = fcoe_to_ctlr(fcoe); 2017 + fcoe_ctlr_link_down(ctlr); 2018 + fcoe_clean_pending_queue(ctlr->lp); 2059 2019 } else 2060 2020 rc = -ENODEV; 2061 2021 ··· 2074 2032 */ 2075 2033 static int fcoe_enable(struct net_device *netdev) 2076 2034 { 2035 + struct fcoe_ctlr *ctlr; 2077 2036 struct fcoe_interface *fcoe; 2078 2037 int rc = 0; 2079 2038 ··· 2083 2040 fcoe = fcoe_hostlist_lookup_port(netdev); 2084 2041 rtnl_unlock(); 2085 2042 2086 - if (!fcoe) 2043 + if (!fcoe) { 2087 2044 rc = -ENODEV; 2088 - else if (!fcoe_link_ok(fcoe->ctlr.lp)) 2089 - fcoe_ctlr_link_up(&fcoe->ctlr); 2045 + goto out; 2046 + } 2090 2047 2048 + ctlr = fcoe_to_ctlr(fcoe); 2049 + 2050 + if (!fcoe_link_ok(ctlr->lp)) 2051 + fcoe_ctlr_link_up(ctlr); 2052 + 2053 + out: 2091 2054 mutex_unlock(&fcoe_config_mutex); 2092 2055 return rc; 2093 2056 } ··· 2108 2059 */ 2109 2060 static int fcoe_destroy(struct net_device *netdev) 2110 2061 { 2062 + struct fcoe_ctlr *ctlr; 2111 2063 struct fcoe_interface *fcoe; 2112 2064 struct fc_lport *lport; 2113 2065 struct fcoe_port *port; ··· 2121 2071 rc = -ENODEV; 2122 2072 goto out_nodev; 2123 2073 } 2124 - lport = fcoe->ctlr.lp; 2074 + ctlr = fcoe_to_ctlr(fcoe); 2075 + lport = ctlr->lp; 2125 2076 port = lport_priv(lport); 2126 2077 list_del(&fcoe->list); 2127 2078 queue_work(fcoe_wq, &port->destroy_work); ··· 2177 2126 int dcbx; 2178 2127 u8 fup, up; 2179 2128 struct net_device *netdev = fcoe->realdev; 2180 - struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); 2129 + struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 2130 + struct fcoe_port *port = lport_priv(ctlr->lp); 2181 2131 struct dcb_app app = { 2182 2132 .priority = 0, 2183 2133 .protocol = ETH_P_FCOE ··· 2201 2149 } 2202 2150 2203 2151 port->priority = ffs(up) ? ffs(up) - 1 : 0; 2204 - fcoe->ctlr.priority = ffs(fup) ? ffs(fup) - 1 : port->priority; 2152 + ctlr->priority = ffs(fup) ? ffs(fup) - 1 : port->priority; 2205 2153 } 2206 2154 #endif 2207 2155 } ··· 2218 2166 static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) 2219 2167 { 2220 2168 int rc = 0; 2169 + struct fcoe_ctlr_device *ctlr_dev; 2170 + struct fcoe_ctlr *ctlr; 2221 2171 struct fcoe_interface *fcoe; 2222 2172 struct fc_lport *lport; 2223 2173 ··· 2238 2184 goto out_nodev; 2239 2185 } 2240 2186 2241 - lport = fcoe_if_create(fcoe, &netdev->dev, 0); 2187 + ctlr = fcoe_to_ctlr(fcoe); 2188 + ctlr_dev = fcoe_ctlr_to_ctlr_dev(ctlr); 2189 + lport = fcoe_if_create(fcoe, &ctlr_dev->dev, 0); 2242 2190 if (IS_ERR(lport)) { 2243 2191 printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", 2244 2192 netdev->name); ··· 2251 2195 } 2252 2196 2253 2197 /* Make this the "master" N_Port */ 2254 - fcoe->ctlr.lp = lport; 2198 + ctlr->lp = lport; 2255 2199 2256 2200 /* setup DCB priority attributes. */ 2257 2201 fcoe_dcb_create(fcoe); ··· 2264 2208 fc_fabric_login(lport); 2265 2209 if (!fcoe_link_ok(lport)) { 2266 2210 rtnl_unlock(); 2267 - fcoe_ctlr_link_up(&fcoe->ctlr); 2211 + fcoe_ctlr_link_up(ctlr); 2268 2212 mutex_unlock(&fcoe_config_mutex); 2269 2213 return rc; 2270 2214 } ··· 2376 2320 struct fc_lport *lport = shost_priv(shost); 2377 2321 struct fcoe_port *port = lport_priv(lport); 2378 2322 struct fcoe_interface *fcoe = port->priv; 2323 + struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 2379 2324 2380 - fcoe_ctlr_link_down(&fcoe->ctlr); 2381 - fcoe_clean_pending_queue(fcoe->ctlr.lp); 2382 - if (!fcoe_link_ok(fcoe->ctlr.lp)) 2383 - fcoe_ctlr_link_up(&fcoe->ctlr); 2325 + fcoe_ctlr_link_down(ctlr); 2326 + fcoe_clean_pending_queue(ctlr->lp); 2327 + if (!fcoe_link_ok(ctlr->lp)) 2328 + fcoe_ctlr_link_up(ctlr); 2384 2329 return 0; 2385 2330 } 2386 2331 ··· 2416 2359 */ 2417 2360 static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev) 2418 2361 { 2362 + struct fcoe_ctlr *ctlr; 2419 2363 struct fcoe_interface *fcoe; 2420 2364 2421 2365 fcoe = fcoe_hostlist_lookup_port(netdev); 2422 - return (fcoe) ? fcoe->ctlr.lp : NULL; 2366 + ctlr = fcoe_to_ctlr(fcoe); 2367 + return (fcoe) ? ctlr->lp : NULL; 2423 2368 } 2424 2369 2425 2370 /** ··· 2525 2466 static void __exit fcoe_exit(void) 2526 2467 { 2527 2468 struct fcoe_interface *fcoe, *tmp; 2469 + struct fcoe_ctlr *ctlr; 2528 2470 struct fcoe_port *port; 2529 2471 unsigned int cpu; 2530 2472 ··· 2537 2477 rtnl_lock(); 2538 2478 list_for_each_entry_safe(fcoe, tmp, &fcoe_hostlist, list) { 2539 2479 list_del(&fcoe->list); 2540 - port = lport_priv(fcoe->ctlr.lp); 2480 + ctlr = fcoe_to_ctlr(fcoe); 2481 + port = lport_priv(ctlr->lp); 2541 2482 queue_work(fcoe_wq, &port->destroy_work); 2542 2483 } 2543 2484 rtnl_unlock(); ··· 2634 2573 { 2635 2574 struct fcoe_port *port = lport_priv(lport); 2636 2575 struct fcoe_interface *fcoe = port->priv; 2637 - struct fcoe_ctlr *fip = &fcoe->ctlr; 2576 + struct fcoe_ctlr *fip = fcoe_to_ctlr(fcoe); 2638 2577 struct fc_frame_header *fh = fc_frame_header_get(fp); 2639 2578 2640 2579 switch (op) { ··· 2791 2730 __fcoe_get_lesb(lport, fc_lesb, netdev); 2792 2731 } 2793 2732 2733 + static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *ctlr_dev) 2734 + { 2735 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 2736 + struct net_device *netdev = fcoe_netdev(fip->lp); 2737 + struct fcoe_fc_els_lesb *fcoe_lesb; 2738 + struct fc_els_lesb fc_lesb; 2739 + 2740 + __fcoe_get_lesb(fip->lp, &fc_lesb, netdev); 2741 + fcoe_lesb = (struct fcoe_fc_els_lesb *)(&fc_lesb); 2742 + 2743 + ctlr_dev->lesb.lesb_link_fail = 2744 + ntohl(fcoe_lesb->lesb_link_fail); 2745 + ctlr_dev->lesb.lesb_vlink_fail = 2746 + ntohl(fcoe_lesb->lesb_vlink_fail); 2747 + ctlr_dev->lesb.lesb_miss_fka = 2748 + ntohl(fcoe_lesb->lesb_miss_fka); 2749 + ctlr_dev->lesb.lesb_symb_err = 2750 + ntohl(fcoe_lesb->lesb_symb_err); 2751 + ctlr_dev->lesb.lesb_err_block = 2752 + ntohl(fcoe_lesb->lesb_err_block); 2753 + ctlr_dev->lesb.lesb_fcs_error = 2754 + ntohl(fcoe_lesb->lesb_fcs_error); 2755 + } 2756 + 2757 + static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *fcf_dev) 2758 + { 2759 + struct fcoe_ctlr_device *ctlr_dev = 2760 + fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 2761 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 2762 + struct fcoe_interface *fcoe = fcoe_ctlr_priv(ctlr); 2763 + 2764 + fcf_dev->vlan_id = vlan_dev_vlan_id(fcoe->netdev); 2765 + } 2766 + 2794 2767 /** 2795 2768 * fcoe_set_port_id() - Callback from libfc when Port_ID is set. 2796 2769 * @lport: the local port ··· 2842 2747 { 2843 2748 struct fcoe_port *port = lport_priv(lport); 2844 2749 struct fcoe_interface *fcoe = port->priv; 2750 + struct fcoe_ctlr *ctlr = fcoe_to_ctlr(fcoe); 2845 2751 2846 2752 if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) 2847 - fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); 2753 + fcoe_ctlr_recv_flogi(ctlr, lport, fp); 2848 2754 }
+5 -3
drivers/scsi/fcoe/fcoe.h
··· 68 68 * @netdev: The associated net device 69 69 * @fcoe_packet_type: FCoE packet type 70 70 * @fip_packet_type: FIP packet type 71 - * @ctlr: The FCoE controller (for FIP) 72 71 * @oem: The offload exchange manager for all local port 73 72 * instances associated with this port 74 73 * @removed: Indicates fcoe interface removed from net device ··· 79 80 struct net_device *realdev; 80 81 struct packet_type fcoe_packet_type; 81 82 struct packet_type fip_packet_type; 82 - struct fcoe_ctlr ctlr; 83 83 struct fc_exch_mgr *oem; 84 84 u8 removed; 85 85 }; 86 86 87 - #define fcoe_from_ctlr(fip) container_of(fip, struct fcoe_interface, ctlr) 87 + #define fcoe_to_ctlr(x) \ 88 + (struct fcoe_ctlr *)(((struct fcoe_ctlr *)(x)) - 1) 89 + 90 + #define fcoe_from_ctlr(x) \ 91 + ((struct fcoe_interface *)((x) + 1)) 88 92 89 93 /** 90 94 * fcoe_netdev() - Return the net device associated with a local port
+145 -14
drivers/scsi/fcoe/fcoe_ctlr.c
··· 160 160 } 161 161 EXPORT_SYMBOL(fcoe_ctlr_init); 162 162 163 + static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) 164 + { 165 + struct fcoe_ctlr *fip = new->fip; 166 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 167 + struct fcoe_fcf_device temp, *fcf_dev; 168 + int rc = 0; 169 + 170 + LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n", 171 + new->fabric_name, new->fcf_mac); 172 + 173 + mutex_lock(&ctlr_dev->lock); 174 + 175 + temp.fabric_name = new->fabric_name; 176 + temp.switch_name = new->switch_name; 177 + temp.fc_map = new->fc_map; 178 + temp.vfid = new->vfid; 179 + memcpy(temp.mac, new->fcf_mac, ETH_ALEN); 180 + temp.priority = new->pri; 181 + temp.fka_period = new->fka_period; 182 + temp.selected = 0; /* default to unselected */ 183 + 184 + fcf_dev = fcoe_fcf_device_add(ctlr_dev, &temp); 185 + if (unlikely(!fcf_dev)) { 186 + rc = -ENOMEM; 187 + goto out; 188 + } 189 + 190 + /* 191 + * The fcoe_sysfs layer can return a CONNECTED fcf that 192 + * has a priv (fcf was never deleted) or a CONNECTED fcf 193 + * that doesn't have a priv (fcf was deleted). However, 194 + * libfcoe will always delete FCFs before trying to add 195 + * them. This is ensured because both recv_adv and 196 + * age_fcfs are protected by the the fcoe_ctlr's mutex. 197 + * This means that we should never get a FCF with a 198 + * non-NULL priv pointer. 199 + */ 200 + BUG_ON(fcf_dev->priv); 201 + 202 + fcf_dev->priv = new; 203 + new->fcf_dev = fcf_dev; 204 + 205 + list_add(&new->list, &fip->fcfs); 206 + fip->fcf_count++; 207 + 208 + out: 209 + mutex_unlock(&ctlr_dev->lock); 210 + return rc; 211 + } 212 + 213 + static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new) 214 + { 215 + struct fcoe_ctlr *fip = new->fip; 216 + struct fcoe_ctlr_device *ctlr_dev = fcoe_ctlr_to_ctlr_dev(fip); 217 + struct fcoe_fcf_device *fcf_dev; 218 + 219 + list_del(&new->list); 220 + fip->fcf_count--; 221 + 222 + mutex_lock(&ctlr_dev->lock); 223 + 224 + fcf_dev = fcoe_fcf_to_fcf_dev(new); 225 + WARN_ON(!fcf_dev); 226 + new->fcf_dev = NULL; 227 + fcoe_fcf_device_delete(fcf_dev); 228 + kfree(new); 229 + 230 + mutex_unlock(&ctlr_dev->lock); 231 + } 232 + 163 233 /** 164 234 * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller 165 235 * @fip: The FCoE controller whose FCFs are to be reset ··· 243 173 244 174 fip->sel_fcf = NULL; 245 175 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 246 - list_del(&fcf->list); 247 - kfree(fcf); 176 + fcoe_sysfs_fcf_del(fcf); 248 177 } 249 - fip->fcf_count = 0; 178 + WARN_ON(fip->fcf_count); 179 + 250 180 fip->sel_time = 0; 251 181 } 252 182 ··· 787 717 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 788 718 unsigned long deadline; 789 719 unsigned long sel_time = 0; 720 + struct list_head del_list; 790 721 struct fcoe_dev_stats *stats; 722 + 723 + INIT_LIST_HEAD(&del_list); 791 724 792 725 stats = per_cpu_ptr(fip->lp->dev_stats, get_cpu()); 793 726 ··· 812 739 if (time_after_eq(jiffies, deadline)) { 813 740 if (fip->sel_fcf == fcf) 814 741 fip->sel_fcf = NULL; 742 + /* 743 + * Move to delete list so we can call 744 + * fcoe_sysfs_fcf_del (which can sleep) 745 + * after the put_cpu(). 746 + */ 815 747 list_del(&fcf->list); 816 - WARN_ON(!fip->fcf_count); 817 - fip->fcf_count--; 818 - kfree(fcf); 748 + list_add(&fcf->list, &del_list); 819 749 stats->VLinkFailureCount++; 820 750 } else { 821 751 if (time_after(next_timer, deadline)) ··· 829 753 } 830 754 } 831 755 put_cpu(); 756 + 757 + list_for_each_entry_safe(fcf, next, &del_list, list) { 758 + /* Removes fcf from current list */ 759 + fcoe_sysfs_fcf_del(fcf); 760 + } 761 + 832 762 if (sel_time && !fip->sel_fcf && !fip->sel_time) { 833 763 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY); 834 764 fip->sel_time = sel_time; ··· 985 903 { 986 904 struct fcoe_fcf *fcf; 987 905 struct fcoe_fcf new; 988 - struct fcoe_fcf *found; 989 906 unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV); 990 907 int first = 0; 991 908 int mtu_valid; 909 + int found = 0; 910 + int rc = 0; 992 911 993 912 if (fcoe_ctlr_parse_adv(fip, skb, &new)) 994 913 return; 995 914 996 915 mutex_lock(&fip->ctlr_mutex); 997 916 first = list_empty(&fip->fcfs); 998 - found = NULL; 999 917 list_for_each_entry(fcf, &fip->fcfs, list) { 1000 918 if (fcf->switch_name == new.switch_name && 1001 919 fcf->fabric_name == new.fabric_name && 1002 920 fcf->fc_map == new.fc_map && 1003 921 compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) { 1004 - found = fcf; 922 + found = 1; 1005 923 break; 1006 924 } 1007 925 } ··· 1013 931 if (!fcf) 1014 932 goto out; 1015 933 1016 - fip->fcf_count++; 1017 934 memcpy(fcf, &new, sizeof(new)); 1018 - list_add(&fcf->list, &fip->fcfs); 935 + fcf->fip = fip; 936 + rc = fcoe_sysfs_fcf_add(fcf); 937 + if (rc) { 938 + printk(KERN_ERR "Failed to allocate sysfs instance " 939 + "for FCF, fab %16.16llx mac %pM\n", 940 + new.fabric_name, new.fcf_mac); 941 + kfree(fcf); 942 + goto out; 943 + } 1019 944 } else { 1020 945 /* 1021 946 * Update the FCF's keep-alive descriptor flags. ··· 1043 954 fcf->fka_period = new.fka_period; 1044 955 memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN); 1045 956 } 957 + 1046 958 mtu_valid = fcoe_ctlr_mtu_valid(fcf); 1047 959 fcf->time = jiffies; 1048 960 if (!found) ··· 1086 996 time_before(fip->sel_time, fip->timer.expires)) 1087 997 mod_timer(&fip->timer, fip->sel_time); 1088 998 } 999 + 1089 1000 out: 1090 1001 mutex_unlock(&fip->ctlr_mutex); 1091 1002 } ··· 2809 2718 2810 2719 /** 2811 2720 * fcoe_libfc_config() - Sets up libfc related properties for local port 2812 - * @lp: The local port to configure libfc for 2813 - * @fip: The FCoE controller in use by the local port 2814 - * @tt: The libfc function template 2721 + * @lport: The local port to configure libfc for 2722 + * @fip: The FCoE controller in use by the local port 2723 + * @tt: The libfc function template 2815 2724 * @init_fcp: If non-zero, the FCP portion of libfc should be initialized 2816 2725 * 2817 2726 * Returns : 0 for success ··· 2844 2753 return 0; 2845 2754 } 2846 2755 EXPORT_SYMBOL_GPL(fcoe_libfc_config); 2756 + 2757 + void fcoe_fcf_get_selected(struct fcoe_fcf_device *fcf_dev) 2758 + { 2759 + struct fcoe_ctlr_device *ctlr_dev = fcoe_fcf_dev_to_ctlr_dev(fcf_dev); 2760 + struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr_dev); 2761 + struct fcoe_fcf *fcf; 2762 + 2763 + mutex_lock(&fip->ctlr_mutex); 2764 + mutex_lock(&ctlr_dev->lock); 2765 + 2766 + fcf = fcoe_fcf_device_priv(fcf_dev); 2767 + if (fcf) 2768 + fcf_dev->selected = (fcf == fip->sel_fcf) ? 1 : 0; 2769 + else 2770 + fcf_dev->selected = 0; 2771 + 2772 + mutex_unlock(&ctlr_dev->lock); 2773 + mutex_unlock(&fip->ctlr_mutex); 2774 + } 2775 + EXPORT_SYMBOL(fcoe_fcf_get_selected); 2776 + 2777 + void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *ctlr_dev) 2778 + { 2779 + struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 2780 + 2781 + mutex_lock(&ctlr->ctlr_mutex); 2782 + switch (ctlr->mode) { 2783 + case FIP_MODE_FABRIC: 2784 + ctlr_dev->mode = FIP_CONN_TYPE_FABRIC; 2785 + break; 2786 + case FIP_MODE_VN2VN: 2787 + ctlr_dev->mode = FIP_CONN_TYPE_VN2VN; 2788 + break; 2789 + default: 2790 + ctlr_dev->mode = FIP_CONN_TYPE_UNKNOWN; 2791 + break; 2792 + } 2793 + mutex_unlock(&ctlr->ctlr_mutex); 2794 + } 2795 + EXPORT_SYMBOL(fcoe_ctlr_get_fip_mode);
+832
drivers/scsi/fcoe/fcoe_sysfs.c
··· 1 + /* 2 + * Copyright(c) 2011 - 2012 Intel Corporation. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program; if not, write to the Free Software Foundation, Inc., 15 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 + * 17 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + #include <linux/module.h> 21 + #include <linux/types.h> 22 + #include <linux/kernel.h> 23 + #include <linux/etherdevice.h> 24 + 25 + #include <scsi/fcoe_sysfs.h> 26 + 27 + static atomic_t ctlr_num; 28 + static atomic_t fcf_num; 29 + 30 + /* 31 + * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs 32 + * should insulate the loss of a fcf. 33 + */ 34 + static unsigned int fcoe_fcf_dev_loss_tmo = 1800; /* seconds */ 35 + 36 + module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo, 37 + uint, S_IRUGO|S_IWUSR); 38 + MODULE_PARM_DESC(fcf_dev_loss_tmo, 39 + "Maximum number of seconds that libfcoe should" 40 + " insulate the loss of a fcf. Once this value is" 41 + " exceeded, the fcf is removed."); 42 + 43 + /* 44 + * These are used by the fcoe_*_show_function routines, they 45 + * are intentionally placed in the .c file as they're not intended 46 + * for use throughout the code. 47 + */ 48 + #define fcoe_ctlr_id(x) \ 49 + ((x)->id) 50 + #define fcoe_ctlr_work_q_name(x) \ 51 + ((x)->work_q_name) 52 + #define fcoe_ctlr_work_q(x) \ 53 + ((x)->work_q) 54 + #define fcoe_ctlr_devloss_work_q_name(x) \ 55 + ((x)->devloss_work_q_name) 56 + #define fcoe_ctlr_devloss_work_q(x) \ 57 + ((x)->devloss_work_q) 58 + #define fcoe_ctlr_mode(x) \ 59 + ((x)->mode) 60 + #define fcoe_ctlr_fcf_dev_loss_tmo(x) \ 61 + ((x)->fcf_dev_loss_tmo) 62 + #define fcoe_ctlr_link_fail(x) \ 63 + ((x)->lesb.lesb_link_fail) 64 + #define fcoe_ctlr_vlink_fail(x) \ 65 + ((x)->lesb.lesb_vlink_fail) 66 + #define fcoe_ctlr_miss_fka(x) \ 67 + ((x)->lesb.lesb_miss_fka) 68 + #define fcoe_ctlr_symb_err(x) \ 69 + ((x)->lesb.lesb_symb_err) 70 + #define fcoe_ctlr_err_block(x) \ 71 + ((x)->lesb.lesb_err_block) 72 + #define fcoe_ctlr_fcs_error(x) \ 73 + ((x)->lesb.lesb_fcs_error) 74 + #define fcoe_fcf_state(x) \ 75 + ((x)->state) 76 + #define fcoe_fcf_fabric_name(x) \ 77 + ((x)->fabric_name) 78 + #define fcoe_fcf_switch_name(x) \ 79 + ((x)->switch_name) 80 + #define fcoe_fcf_fc_map(x) \ 81 + ((x)->fc_map) 82 + #define fcoe_fcf_vfid(x) \ 83 + ((x)->vfid) 84 + #define fcoe_fcf_mac(x) \ 85 + ((x)->mac) 86 + #define fcoe_fcf_priority(x) \ 87 + ((x)->priority) 88 + #define fcoe_fcf_fka_period(x) \ 89 + ((x)->fka_period) 90 + #define fcoe_fcf_dev_loss_tmo(x) \ 91 + ((x)->dev_loss_tmo) 92 + #define fcoe_fcf_selected(x) \ 93 + ((x)->selected) 94 + #define fcoe_fcf_vlan_id(x) \ 95 + ((x)->vlan_id) 96 + 97 + /* 98 + * dev_loss_tmo attribute 99 + */ 100 + static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val) 101 + { 102 + int ret; 103 + 104 + ret = kstrtoul(buf, 0, val); 105 + if (ret || *val < 0) 106 + return -EINVAL; 107 + /* 108 + * Check for overflow; dev_loss_tmo is u32 109 + */ 110 + if (*val > UINT_MAX) 111 + return -EINVAL; 112 + 113 + return 0; 114 + } 115 + 116 + static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf, 117 + unsigned long val) 118 + { 119 + if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) || 120 + (fcf->state == FCOE_FCF_STATE_DISCONNECTED) || 121 + (fcf->state == FCOE_FCF_STATE_DELETED)) 122 + return -EBUSY; 123 + /* 124 + * Check for overflow; dev_loss_tmo is u32 125 + */ 126 + if (val > UINT_MAX) 127 + return -EINVAL; 128 + 129 + fcoe_fcf_dev_loss_tmo(fcf) = val; 130 + return 0; 131 + } 132 + 133 + #define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store) \ 134 + struct device_attribute device_attr_fcoe_##_prefix##_##_name = \ 135 + __ATTR(_name, _mode, _show, _store) 136 + 137 + #define fcoe_ctlr_show_function(field, format_string, sz, cast) \ 138 + static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 139 + struct device_attribute *attr, \ 140 + char *buf) \ 141 + { \ 142 + struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 143 + if (ctlr->f->get_fcoe_ctlr_##field) \ 144 + ctlr->f->get_fcoe_ctlr_##field(ctlr); \ 145 + return snprintf(buf, sz, format_string, \ 146 + cast fcoe_ctlr_##field(ctlr)); \ 147 + } 148 + 149 + #define fcoe_fcf_show_function(field, format_string, sz, cast) \ 150 + static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 151 + struct device_attribute *attr, \ 152 + char *buf) \ 153 + { \ 154 + struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 155 + struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); \ 156 + if (ctlr->f->get_fcoe_fcf_##field) \ 157 + ctlr->f->get_fcoe_fcf_##field(fcf); \ 158 + return snprintf(buf, sz, format_string, \ 159 + cast fcoe_fcf_##field(fcf)); \ 160 + } 161 + 162 + #define fcoe_ctlr_private_show_function(field, format_string, sz, cast) \ 163 + static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 164 + struct device_attribute *attr, \ 165 + char *buf) \ 166 + { \ 167 + struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 168 + return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \ 169 + } 170 + 171 + #define fcoe_fcf_private_show_function(field, format_string, sz, cast) \ 172 + static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 173 + struct device_attribute *attr, \ 174 + char *buf) \ 175 + { \ 176 + struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 177 + return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \ 178 + } 179 + 180 + #define fcoe_ctlr_private_rd_attr(field, format_string, sz) \ 181 + fcoe_ctlr_private_show_function(field, format_string, sz, ) \ 182 + static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 183 + show_fcoe_ctlr_device_##field, NULL) 184 + 185 + #define fcoe_ctlr_rd_attr(field, format_string, sz) \ 186 + fcoe_ctlr_show_function(field, format_string, sz, ) \ 187 + static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 188 + show_fcoe_ctlr_device_##field, NULL) 189 + 190 + #define fcoe_fcf_rd_attr(field, format_string, sz) \ 191 + fcoe_fcf_show_function(field, format_string, sz, ) \ 192 + static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 193 + show_fcoe_fcf_device_##field, NULL) 194 + 195 + #define fcoe_fcf_private_rd_attr(field, format_string, sz) \ 196 + fcoe_fcf_private_show_function(field, format_string, sz, ) \ 197 + static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 198 + show_fcoe_fcf_device_##field, NULL) 199 + 200 + #define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast) \ 201 + fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \ 202 + static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 203 + show_fcoe_ctlr_device_##field, NULL) 204 + 205 + #define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast) \ 206 + fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \ 207 + static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 208 + show_fcoe_fcf_device_##field, NULL) 209 + 210 + #define fcoe_enum_name_search(title, table_type, table) \ 211 + static const char *get_fcoe_##title##_name(enum table_type table_key) \ 212 + { \ 213 + int i; \ 214 + char *name = NULL; \ 215 + \ 216 + for (i = 0; i < ARRAY_SIZE(table); i++) { \ 217 + if (table[i].value == table_key) { \ 218 + name = table[i].name; \ 219 + break; \ 220 + } \ 221 + } \ 222 + return name; \ 223 + } 224 + 225 + static struct { 226 + enum fcf_state value; 227 + char *name; 228 + } fcf_state_names[] = { 229 + { FCOE_FCF_STATE_UNKNOWN, "Unknown" }, 230 + { FCOE_FCF_STATE_DISCONNECTED, "Disconnected" }, 231 + { FCOE_FCF_STATE_CONNECTED, "Connected" }, 232 + }; 233 + fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names) 234 + #define FCOE_FCF_STATE_MAX_NAMELEN 50 235 + 236 + static ssize_t show_fcf_state(struct device *dev, 237 + struct device_attribute *attr, 238 + char *buf) 239 + { 240 + struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 241 + const char *name; 242 + name = get_fcoe_fcf_state_name(fcf->state); 243 + if (!name) 244 + return -EINVAL; 245 + return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name); 246 + } 247 + static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL); 248 + 249 + static struct { 250 + enum fip_conn_type value; 251 + char *name; 252 + } fip_conn_type_names[] = { 253 + { FIP_CONN_TYPE_UNKNOWN, "Unknown" }, 254 + { FIP_CONN_TYPE_FABRIC, "Fabric" }, 255 + { FIP_CONN_TYPE_VN2VN, "VN2VN" }, 256 + }; 257 + fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names) 258 + #define FCOE_CTLR_MODE_MAX_NAMELEN 50 259 + 260 + static ssize_t show_ctlr_mode(struct device *dev, 261 + struct device_attribute *attr, 262 + char *buf) 263 + { 264 + struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 265 + const char *name; 266 + 267 + if (ctlr->f->get_fcoe_ctlr_mode) 268 + ctlr->f->get_fcoe_ctlr_mode(ctlr); 269 + 270 + name = get_fcoe_ctlr_mode_name(ctlr->mode); 271 + if (!name) 272 + return -EINVAL; 273 + return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN, 274 + "%s\n", name); 275 + } 276 + static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO, 277 + show_ctlr_mode, NULL); 278 + 279 + static ssize_t 280 + store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev, 281 + struct device_attribute *attr, 282 + const char *buf, size_t count) 283 + { 284 + struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 285 + struct fcoe_fcf_device *fcf; 286 + unsigned long val; 287 + int rc; 288 + 289 + rc = fcoe_str_to_dev_loss(buf, &val); 290 + if (rc) 291 + return rc; 292 + 293 + fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val; 294 + mutex_lock(&ctlr->lock); 295 + list_for_each_entry(fcf, &ctlr->fcfs, peers) 296 + fcoe_fcf_set_dev_loss_tmo(fcf, val); 297 + mutex_unlock(&ctlr->lock); 298 + return count; 299 + } 300 + fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, ); 301 + static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR, 302 + show_fcoe_ctlr_device_fcf_dev_loss_tmo, 303 + store_private_fcoe_ctlr_fcf_dev_loss_tmo); 304 + 305 + /* Link Error Status Block (LESB) */ 306 + fcoe_ctlr_rd_attr(link_fail, "%u\n", 20); 307 + fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20); 308 + fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20); 309 + fcoe_ctlr_rd_attr(symb_err, "%u\n", 20); 310 + fcoe_ctlr_rd_attr(err_block, "%u\n", 20); 311 + fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20); 312 + 313 + fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 314 + fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long); 315 + fcoe_fcf_private_rd_attr(priority, "%u\n", 20); 316 + fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20); 317 + fcoe_fcf_private_rd_attr(vfid, "%u\n", 20); 318 + fcoe_fcf_private_rd_attr(mac, "%pM\n", 20); 319 + fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20); 320 + fcoe_fcf_rd_attr(selected, "%u\n", 20); 321 + fcoe_fcf_rd_attr(vlan_id, "%u\n", 20); 322 + 323 + fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, ) 324 + static ssize_t 325 + store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 326 + const char *buf, size_t count) 327 + { 328 + struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 329 + unsigned long val; 330 + int rc; 331 + 332 + rc = fcoe_str_to_dev_loss(buf, &val); 333 + if (rc) 334 + return rc; 335 + 336 + rc = fcoe_fcf_set_dev_loss_tmo(fcf, val); 337 + if (rc) 338 + return rc; 339 + return count; 340 + } 341 + static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR, 342 + show_fcoe_fcf_device_dev_loss_tmo, 343 + store_fcoe_fcf_dev_loss_tmo); 344 + 345 + static struct attribute *fcoe_ctlr_lesb_attrs[] = { 346 + &device_attr_fcoe_ctlr_link_fail.attr, 347 + &device_attr_fcoe_ctlr_vlink_fail.attr, 348 + &device_attr_fcoe_ctlr_miss_fka.attr, 349 + &device_attr_fcoe_ctlr_symb_err.attr, 350 + &device_attr_fcoe_ctlr_err_block.attr, 351 + &device_attr_fcoe_ctlr_fcs_error.attr, 352 + NULL, 353 + }; 354 + 355 + static struct attribute_group fcoe_ctlr_lesb_attr_group = { 356 + .name = "lesb", 357 + .attrs = fcoe_ctlr_lesb_attrs, 358 + }; 359 + 360 + static struct attribute *fcoe_ctlr_attrs[] = { 361 + &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr, 362 + &device_attr_fcoe_ctlr_mode.attr, 363 + NULL, 364 + }; 365 + 366 + static struct attribute_group fcoe_ctlr_attr_group = { 367 + .attrs = fcoe_ctlr_attrs, 368 + }; 369 + 370 + static const struct attribute_group *fcoe_ctlr_attr_groups[] = { 371 + &fcoe_ctlr_attr_group, 372 + &fcoe_ctlr_lesb_attr_group, 373 + NULL, 374 + }; 375 + 376 + static struct attribute *fcoe_fcf_attrs[] = { 377 + &device_attr_fcoe_fcf_fabric_name.attr, 378 + &device_attr_fcoe_fcf_switch_name.attr, 379 + &device_attr_fcoe_fcf_dev_loss_tmo.attr, 380 + &device_attr_fcoe_fcf_fc_map.attr, 381 + &device_attr_fcoe_fcf_vfid.attr, 382 + &device_attr_fcoe_fcf_mac.attr, 383 + &device_attr_fcoe_fcf_priority.attr, 384 + &device_attr_fcoe_fcf_fka_period.attr, 385 + &device_attr_fcoe_fcf_state.attr, 386 + &device_attr_fcoe_fcf_selected.attr, 387 + &device_attr_fcoe_fcf_vlan_id.attr, 388 + NULL 389 + }; 390 + 391 + static struct attribute_group fcoe_fcf_attr_group = { 392 + .attrs = fcoe_fcf_attrs, 393 + }; 394 + 395 + static const struct attribute_group *fcoe_fcf_attr_groups[] = { 396 + &fcoe_fcf_attr_group, 397 + NULL, 398 + }; 399 + 400 + struct bus_type fcoe_bus_type; 401 + 402 + static int fcoe_bus_match(struct device *dev, 403 + struct device_driver *drv) 404 + { 405 + if (dev->bus == &fcoe_bus_type) 406 + return 1; 407 + return 0; 408 + } 409 + 410 + /** 411 + * fcoe_ctlr_device_release() - Release the FIP ctlr memory 412 + * @dev: Pointer to the FIP ctlr's embedded device 413 + * 414 + * Called when the last FIP ctlr reference is released. 415 + */ 416 + static void fcoe_ctlr_device_release(struct device *dev) 417 + { 418 + struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 419 + kfree(ctlr); 420 + } 421 + 422 + /** 423 + * fcoe_fcf_device_release() - Release the FIP fcf memory 424 + * @dev: Pointer to the fcf's embedded device 425 + * 426 + * Called when the last FIP fcf reference is released. 427 + */ 428 + static void fcoe_fcf_device_release(struct device *dev) 429 + { 430 + struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 431 + kfree(fcf); 432 + } 433 + 434 + struct device_type fcoe_ctlr_device_type = { 435 + .name = "fcoe_ctlr", 436 + .groups = fcoe_ctlr_attr_groups, 437 + .release = fcoe_ctlr_device_release, 438 + }; 439 + 440 + struct device_type fcoe_fcf_device_type = { 441 + .name = "fcoe_fcf", 442 + .groups = fcoe_fcf_attr_groups, 443 + .release = fcoe_fcf_device_release, 444 + }; 445 + 446 + struct bus_type fcoe_bus_type = { 447 + .name = "fcoe", 448 + .match = &fcoe_bus_match, 449 + }; 450 + 451 + /** 452 + * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue 453 + * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed 454 + */ 455 + void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) 456 + { 457 + if (!fcoe_ctlr_work_q(ctlr)) { 458 + printk(KERN_ERR 459 + "ERROR: FIP Ctlr '%d' attempted to flush work, " 460 + "when no workqueue created.\n", ctlr->id); 461 + dump_stack(); 462 + return; 463 + } 464 + 465 + flush_workqueue(fcoe_ctlr_work_q(ctlr)); 466 + } 467 + 468 + /** 469 + * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue 470 + * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 471 + * @work: Work to queue for execution 472 + * 473 + * Return value: 474 + * 1 on success / 0 already queued / < 0 for error 475 + */ 476 + int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, 477 + struct work_struct *work) 478 + { 479 + if (unlikely(!fcoe_ctlr_work_q(ctlr))) { 480 + printk(KERN_ERR 481 + "ERROR: FIP Ctlr '%d' attempted to queue work, " 482 + "when no workqueue created.\n", ctlr->id); 483 + dump_stack(); 484 + 485 + return -EINVAL; 486 + } 487 + 488 + return queue_work(fcoe_ctlr_work_q(ctlr), work); 489 + } 490 + 491 + /** 492 + * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue 493 + * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed 494 + */ 495 + void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) 496 + { 497 + if (!fcoe_ctlr_devloss_work_q(ctlr)) { 498 + printk(KERN_ERR 499 + "ERROR: FIP Ctlr '%d' attempted to flush work, " 500 + "when no workqueue created.\n", ctlr->id); 501 + dump_stack(); 502 + return; 503 + } 504 + 505 + flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr)); 506 + } 507 + 508 + /** 509 + * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue 510 + * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 511 + * @work: Work to queue for execution 512 + * @delay: jiffies to delay the work queuing 513 + * 514 + * Return value: 515 + * 1 on success / 0 already queued / < 0 for error 516 + */ 517 + int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, 518 + struct delayed_work *work, 519 + unsigned long delay) 520 + { 521 + if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) { 522 + printk(KERN_ERR 523 + "ERROR: FIP Ctlr '%d' attempted to queue work, " 524 + "when no workqueue created.\n", ctlr->id); 525 + dump_stack(); 526 + 527 + return -EINVAL; 528 + } 529 + 530 + return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay); 531 + } 532 + 533 + static int fcoe_fcf_device_match(struct fcoe_fcf_device *new, 534 + struct fcoe_fcf_device *old) 535 + { 536 + if (new->switch_name == old->switch_name && 537 + new->fabric_name == old->fabric_name && 538 + new->fc_map == old->fc_map && 539 + compare_ether_addr(new->mac, old->mac) == 0) 540 + return 1; 541 + return 0; 542 + } 543 + 544 + /** 545 + * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs 546 + * @parent: The parent device to which the fcoe_ctlr instance 547 + * should be attached 548 + * @f: The LLD's FCoE sysfs function template pointer 549 + * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD 550 + * 551 + * This routine allocates a FIP ctlr object with some additional memory 552 + * for the LLD. The FIP ctlr is initialized, added to sysfs and then 553 + * attributes are added to it. 554 + */ 555 + struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, 556 + struct fcoe_sysfs_function_template *f, 557 + int priv_size) 558 + { 559 + struct fcoe_ctlr_device *ctlr; 560 + int error = 0; 561 + 562 + ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size, 563 + GFP_KERNEL); 564 + if (!ctlr) 565 + goto out; 566 + 567 + ctlr->id = atomic_inc_return(&ctlr_num) - 1; 568 + ctlr->f = f; 569 + INIT_LIST_HEAD(&ctlr->fcfs); 570 + mutex_init(&ctlr->lock); 571 + ctlr->dev.parent = parent; 572 + ctlr->dev.bus = &fcoe_bus_type; 573 + ctlr->dev.type = &fcoe_ctlr_device_type; 574 + 575 + ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo; 576 + 577 + snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name), 578 + "ctlr_wq_%d", ctlr->id); 579 + ctlr->work_q = create_singlethread_workqueue( 580 + ctlr->work_q_name); 581 + if (!ctlr->work_q) 582 + goto out_del; 583 + 584 + snprintf(ctlr->devloss_work_q_name, 585 + sizeof(ctlr->devloss_work_q_name), 586 + "ctlr_dl_wq_%d", ctlr->id); 587 + ctlr->devloss_work_q = create_singlethread_workqueue( 588 + ctlr->devloss_work_q_name); 589 + if (!ctlr->devloss_work_q) 590 + goto out_del_q; 591 + 592 + dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); 593 + error = device_register(&ctlr->dev); 594 + if (error) 595 + goto out_del_q2; 596 + 597 + return ctlr; 598 + 599 + out_del_q2: 600 + destroy_workqueue(ctlr->devloss_work_q); 601 + ctlr->devloss_work_q = NULL; 602 + out_del_q: 603 + destroy_workqueue(ctlr->work_q); 604 + ctlr->work_q = NULL; 605 + out_del: 606 + kfree(ctlr); 607 + out: 608 + return NULL; 609 + } 610 + EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add); 611 + 612 + /** 613 + * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs 614 + * @ctlr: A pointer to the ctlr to be deleted 615 + * 616 + * Deletes a FIP ctlr and any fcfs attached 617 + * to it. Deleting fcfs will cause their childen 618 + * to be deleted as well. 619 + * 620 + * The ctlr is detached from sysfs and it's resources 621 + * are freed (work q), but the memory is not freed 622 + * until its last reference is released. 623 + * 624 + * This routine expects no locks to be held before 625 + * calling. 626 + * 627 + * TODO: Currently there are no callbacks to clean up LLD data 628 + * for a fcoe_fcf_device. LLDs must keep this in mind as they need 629 + * to clean up each of their LLD data for all fcoe_fcf_device before 630 + * calling fcoe_ctlr_device_delete. 631 + */ 632 + void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr) 633 + { 634 + struct fcoe_fcf_device *fcf, *next; 635 + /* Remove any attached fcfs */ 636 + mutex_lock(&ctlr->lock); 637 + list_for_each_entry_safe(fcf, next, 638 + &ctlr->fcfs, peers) { 639 + list_del(&fcf->peers); 640 + fcf->state = FCOE_FCF_STATE_DELETED; 641 + fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 642 + } 643 + mutex_unlock(&ctlr->lock); 644 + 645 + fcoe_ctlr_device_flush_work(ctlr); 646 + 647 + destroy_workqueue(ctlr->devloss_work_q); 648 + ctlr->devloss_work_q = NULL; 649 + destroy_workqueue(ctlr->work_q); 650 + ctlr->work_q = NULL; 651 + 652 + device_unregister(&ctlr->dev); 653 + } 654 + EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete); 655 + 656 + /** 657 + * fcoe_fcf_device_final_delete() - Final delete routine 658 + * @work: The FIP fcf's embedded work struct 659 + * 660 + * It is expected that the fcf has been removed from 661 + * the FIP ctlr's list before calling this routine. 662 + */ 663 + static void fcoe_fcf_device_final_delete(struct work_struct *work) 664 + { 665 + struct fcoe_fcf_device *fcf = 666 + container_of(work, struct fcoe_fcf_device, delete_work); 667 + struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 668 + 669 + /* 670 + * Cancel any outstanding timers. These should really exist 671 + * only when rmmod'ing the LLDD and we're asking for 672 + * immediate termination of the rports 673 + */ 674 + if (!cancel_delayed_work(&fcf->dev_loss_work)) 675 + fcoe_ctlr_device_flush_devloss(ctlr); 676 + 677 + device_unregister(&fcf->dev); 678 + } 679 + 680 + /** 681 + * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires 682 + * @work: The FIP fcf's embedded work struct 683 + * 684 + * Removes the fcf from the FIP ctlr's list of fcfs and 685 + * queues the final deletion. 686 + */ 687 + static void fip_timeout_deleted_fcf(struct work_struct *work) 688 + { 689 + struct fcoe_fcf_device *fcf = 690 + container_of(work, struct fcoe_fcf_device, dev_loss_work.work); 691 + struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 692 + 693 + mutex_lock(&ctlr->lock); 694 + 695 + /* 696 + * If the fcf is deleted or reconnected before the timer 697 + * fires the devloss queue will be flushed, but the state will 698 + * either be CONNECTED or DELETED. If that is the case we 699 + * cancel deleting the fcf. 700 + */ 701 + if (fcf->state != FCOE_FCF_STATE_DISCONNECTED) 702 + goto out; 703 + 704 + dev_printk(KERN_ERR, &fcf->dev, 705 + "FIP fcf connection time out: removing fcf\n"); 706 + 707 + list_del(&fcf->peers); 708 + fcf->state = FCOE_FCF_STATE_DELETED; 709 + fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 710 + 711 + out: 712 + mutex_unlock(&ctlr->lock); 713 + } 714 + 715 + /** 716 + * fcoe_fcf_device_delete() - Delete a FIP fcf 717 + * @fcf: Pointer to the fcf which is to be deleted 718 + * 719 + * Queues the FIP fcf on the devloss workqueue 720 + * 721 + * Expects the ctlr_attrs mutex to be held for fcf 722 + * state change. 723 + */ 724 + void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf) 725 + { 726 + struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 727 + int timeout = fcf->dev_loss_tmo; 728 + 729 + if (fcf->state != FCOE_FCF_STATE_CONNECTED) 730 + return; 731 + 732 + fcf->state = FCOE_FCF_STATE_DISCONNECTED; 733 + 734 + /* 735 + * FCF will only be re-connected by the LLD calling 736 + * fcoe_fcf_device_add, and it should be setting up 737 + * priv then. 738 + */ 739 + fcf->priv = NULL; 740 + 741 + fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work, 742 + timeout * HZ); 743 + } 744 + EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete); 745 + 746 + /** 747 + * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system 748 + * @ctlr: The fcoe_ctlr_device that will be the fcoe_fcf_device parent 749 + * @new_fcf: A temporary FCF used for lookups on the current list of fcfs 750 + * 751 + * Expects to be called with the ctlr->lock held 752 + */ 753 + struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, 754 + struct fcoe_fcf_device *new_fcf) 755 + { 756 + struct fcoe_fcf_device *fcf; 757 + int error = 0; 758 + 759 + list_for_each_entry(fcf, &ctlr->fcfs, peers) { 760 + if (fcoe_fcf_device_match(new_fcf, fcf)) { 761 + if (fcf->state == FCOE_FCF_STATE_CONNECTED) 762 + return fcf; 763 + 764 + fcf->state = FCOE_FCF_STATE_CONNECTED; 765 + 766 + if (!cancel_delayed_work(&fcf->dev_loss_work)) 767 + fcoe_ctlr_device_flush_devloss(ctlr); 768 + 769 + return fcf; 770 + } 771 + } 772 + 773 + fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC); 774 + if (unlikely(!fcf)) 775 + goto out; 776 + 777 + INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete); 778 + INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf); 779 + 780 + fcf->dev.parent = &ctlr->dev; 781 + fcf->dev.bus = &fcoe_bus_type; 782 + fcf->dev.type = &fcoe_fcf_device_type; 783 + fcf->id = atomic_inc_return(&fcf_num) - 1; 784 + fcf->state = FCOE_FCF_STATE_UNKNOWN; 785 + 786 + fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo; 787 + 788 + dev_set_name(&fcf->dev, "fcf_%d", fcf->id); 789 + 790 + fcf->fabric_name = new_fcf->fabric_name; 791 + fcf->switch_name = new_fcf->switch_name; 792 + fcf->fc_map = new_fcf->fc_map; 793 + fcf->vfid = new_fcf->vfid; 794 + memcpy(fcf->mac, new_fcf->mac, ETH_ALEN); 795 + fcf->priority = new_fcf->priority; 796 + fcf->fka_period = new_fcf->fka_period; 797 + fcf->selected = new_fcf->selected; 798 + 799 + error = device_register(&fcf->dev); 800 + if (error) 801 + goto out_del; 802 + 803 + fcf->state = FCOE_FCF_STATE_CONNECTED; 804 + list_add_tail(&fcf->peers, &ctlr->fcfs); 805 + 806 + return fcf; 807 + 808 + out_del: 809 + kfree(fcf); 810 + out: 811 + return NULL; 812 + } 813 + EXPORT_SYMBOL_GPL(fcoe_fcf_device_add); 814 + 815 + int __init fcoe_sysfs_setup(void) 816 + { 817 + int error; 818 + 819 + atomic_set(&ctlr_num, 0); 820 + atomic_set(&fcf_num, 0); 821 + 822 + error = bus_register(&fcoe_bus_type); 823 + if (error) 824 + return error; 825 + 826 + return 0; 827 + } 828 + 829 + void __exit fcoe_sysfs_teardown(void) 830 + { 831 + bus_unregister(&fcoe_bus_type); 832 + }
+11 -2
drivers/scsi/fcoe/fcoe_transport.c
··· 815 815 */ 816 816 static int __init libfcoe_init(void) 817 817 { 818 - fcoe_transport_init(); 818 + int rc = 0; 819 819 820 - return 0; 820 + rc = fcoe_transport_init(); 821 + if (rc) 822 + return rc; 823 + 824 + rc = fcoe_sysfs_setup(); 825 + if (rc) 826 + fcoe_transport_exit(); 827 + 828 + return rc; 821 829 } 822 830 module_init(libfcoe_init); 823 831 ··· 834 826 */ 835 827 static void __exit libfcoe_exit(void) 836 828 { 829 + fcoe_sysfs_teardown(); 837 830 fcoe_transport_exit(); 838 831 } 839 832 module_exit(libfcoe_exit);
+9
drivers/scsi/qla2xxx/Kconfig
··· 25 25 Firmware images can be retrieved from: 26 26 27 27 ftp://ftp.qlogic.com/outgoing/linux/firmware/ 28 + 29 + config TCM_QLA2XXX 30 + tristate "TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs" 31 + depends on SCSI_QLA_FC && TARGET_CORE 32 + select LIBFC 33 + select BTREE 34 + default n 35 + ---help--- 36 + Say Y here to enable the TCM_QLA2XXX fabric module for Qlogic 2xxx series target mode HBAs
+2 -1
drivers/scsi/qla2xxx/Makefile
··· 1 1 qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ 2 2 qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ 3 - qla_nx.o 3 + qla_nx.o qla_target.o 4 4 5 5 obj-$(CONFIG_SCSI_QLA_FC) += qla2xxx.o 6 + obj-$(CONFIG_TCM_QLA2XXX) += tcm_qla2xxx.o
+14 -8
drivers/scsi/qla2xxx/qla_attr.c
··· 5 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 6 */ 7 7 #include "qla_def.h" 8 + #include "qla_target.h" 8 9 9 10 #include <linux/kthread.h> 10 11 #include <linux/vmalloc.h> ··· 577 576 scsi_block_requests(vha->host); 578 577 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 579 578 if (IS_QLA82XX(ha)) { 579 + ha->flags.isp82xx_no_md_cap = 1; 580 580 qla82xx_idc_lock(ha); 581 581 qla82xx_set_reset_owner(vha); 582 582 qla82xx_idc_unlock(ha); ··· 587 585 scsi_unblock_requests(vha->host); 588 586 break; 589 587 case 0x2025d: 590 - if (!IS_QLA81XX(ha)) 588 + if (!IS_QLA81XX(ha) || !IS_QLA8031(ha)) 591 589 return -EPERM; 592 590 593 591 ql_log(ql_log_info, vha, 0x706f, ··· 1107 1105 struct device_attribute *attr, char *buf) 1108 1106 { 1109 1107 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); 1110 - struct qla_hw_data *ha = vha->hw; 1111 1108 return snprintf(buf, PAGE_SIZE, "%d\n", 1112 - ha->qla_stats.total_isp_aborts); 1109 + vha->qla_stats.total_isp_aborts); 1113 1110 } 1114 1111 1115 1112 static ssize_t ··· 1155 1154 scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); 1156 1155 struct qla_hw_data *ha = vha->hw; 1157 1156 1158 - if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 1157 + if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 1159 1158 return snprintf(buf, PAGE_SIZE, "\n"); 1160 1159 1161 1160 return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n", ··· 1538 1537 dma_addr_t stats_dma; 1539 1538 struct fc_host_statistics *pfc_host_stat; 1540 1539 1541 - pfc_host_stat = &ha->fc_host_stat; 1540 + pfc_host_stat = &vha->fc_host_stat; 1542 1541 memset(pfc_host_stat, -1, sizeof(struct fc_host_statistics)); 1543 1542 1544 1543 if (test_bit(UNLOADING, &vha->dpc_flags)) ··· 1581 1580 pfc_host_stat->dumped_frames = stats->dumped_frames; 1582 1581 pfc_host_stat->nos_count = stats->nos_rcvd; 1583 1582 } 1584 - pfc_host_stat->fcp_input_megabytes = ha->qla_stats.input_bytes >> 20; 1585 - pfc_host_stat->fcp_output_megabytes = ha->qla_stats.output_bytes >> 20; 1583 + pfc_host_stat->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20; 1584 + pfc_host_stat->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20; 1586 1585 1587 1586 done_free: 1588 1587 dma_pool_free(ha->s_dma_pool, stats, stats_dma); ··· 1738 1737 fc_host_supported_speeds(vha->host) = 1739 1738 fc_host_supported_speeds(base_vha->host); 1740 1739 1740 + qlt_vport_create(vha, ha); 1741 1741 qla24xx_vport_disable(fc_vport, disable); 1742 1742 1743 1743 if (ha->flags.cpu_affinity_enabled) { ··· 1953 1951 fc_host_dev_loss_tmo(vha->host) = ha->port_down_retry_count; 1954 1952 fc_host_node_name(vha->host) = wwn_to_u64(vha->node_name); 1955 1953 fc_host_port_name(vha->host) = wwn_to_u64(vha->port_name); 1956 - fc_host_supported_classes(vha->host) = FC_COS_CLASS3; 1954 + fc_host_supported_classes(vha->host) = ha->tgt.enable_class_2 ? 1955 + (FC_COS_CLASS2|FC_COS_CLASS3) : FC_COS_CLASS3; 1957 1956 fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; 1958 1957 fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; 1959 1958 1960 1959 if (IS_CNA_CAPABLE(ha)) 1961 1960 speed = FC_PORTSPEED_10GBIT; 1961 + else if (IS_QLA2031(ha)) 1962 + speed = FC_PORTSPEED_16GBIT | FC_PORTSPEED_8GBIT | 1963 + FC_PORTSPEED_4GBIT; 1962 1964 else if (IS_QLA25XX(ha)) 1963 1965 speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT | 1964 1966 FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
+6 -6
drivers/scsi/qla2xxx/qla_bsg.c
··· 297 297 298 298 /* Initialize all required fields of fcport */ 299 299 fcport->vha = vha; 300 - fcport->vp_idx = vha->vp_idx; 301 300 fcport->d_id.b.al_pa = 302 301 bsg_job->request->rqst_data.h_els.port_id[0]; 303 302 fcport->d_id.b.area = ··· 482 483 483 484 /* Initialize all required fields of fcport */ 484 485 fcport->vha = vha; 485 - fcport->vp_idx = vha->vp_idx; 486 486 fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0]; 487 487 fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1]; 488 488 fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2]; ··· 542 544 int rval = 0; 543 545 struct qla_hw_data *ha = vha->hw; 544 546 545 - if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 547 + if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 546 548 goto done_set_internal; 547 549 548 550 new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1); ··· 584 586 uint16_t new_config[4]; 585 587 struct qla_hw_data *ha = vha->hw; 586 588 587 - if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 589 + if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 588 590 goto done_reset_internal; 589 591 590 592 memset(new_config, 0 , sizeof(new_config)); ··· 708 710 elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1]; 709 711 710 712 if ((ha->current_topology == ISP_CFG_F || 711 - (atomic_read(&vha->loop_state) == LOOP_DOWN) || 712 - ((IS_QLA81XX(ha) || IS_QLA83XX(ha)) && 713 + ((IS_QLA81XX(ha) || IS_QLA8031(ha)) && 713 714 le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE 714 715 && req_data_len == MAX_ELS_FRAME_PAYLOAD)) && 715 716 elreq.options == EXTERNAL_LOOPBACK) { ··· 1398 1401 rval = qla2x00_optrom_setup(bsg_job, vha, 1); 1399 1402 if (rval) 1400 1403 return rval; 1404 + 1405 + /* Set the isp82xx_no_md_cap not to capture minidump */ 1406 + ha->flags.isp82xx_no_md_cap = 1; 1401 1407 1402 1408 sg_copy_to_buffer(bsg_job->request_payload.sg_list, 1403 1409 bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
+74 -7
drivers/scsi/qla2xxx/qla_dbg.c
··· 11 11 * ---------------------------------------------------------------------- 12 12 * | Level | Last Value Used | Holes | 13 13 * ---------------------------------------------------------------------- 14 - * | Module Init and Probe | 0x0120 | 0x4b,0xba,0xfa | 15 - * | Mailbox commands | 0x113e | 0x112c-0x112e | 14 + * | Module Init and Probe | 0x0122 | 0x4b,0xba,0xfa | 15 + * | Mailbox commands | 0x1140 | 0x111a-0x111b | 16 + * | | | 0x112c-0x112e | 16 17 * | | | 0x113a | 17 18 * | Device Discovery | 0x2086 | 0x2020-0x2022 | 18 19 * | Queue Command and IO tracing | 0x3030 | 0x3006,0x3008 | 19 20 * | | | 0x302d-0x302e | 20 - * | DPC Thread | 0x401c | | 21 - * | Async Events | 0x505d | 0x502b-0x502f | 21 + * | DPC Thread | 0x401c | 0x4002,0x4013 | 22 + * | Async Events | 0x505f | 0x502b-0x502f | 22 23 * | | | 0x5047,0x5052 | 23 - * | Timer Routines | 0x6011 | 0x600e-0x600f | 24 + * | Timer Routines | 0x6011 | | 24 25 * | User Space Interactions | 0x709f | 0x7018,0x702e, | 25 26 * | | | 0x7039,0x7045, | 26 27 * | | | 0x7073-0x7075, | 27 28 * | | | 0x708c | 28 29 * | Task Management | 0x803c | 0x8025-0x8026 | 29 30 * | | | 0x800b,0x8039 | 30 - * | AER/EEH | 0x900f | | 31 + * | AER/EEH | 0x9011 | | 31 32 * | Virtual Port | 0xa007 | | 32 - * | ISP82XX Specific | 0xb054 | 0xb053 | 33 + * | ISP82XX Specific | 0xb054 | 0xb024 | 33 34 * | MultiQ | 0xc00c | | 34 35 * | Misc | 0xd010 | | 36 + * | Target Mode | 0xe06f | | 37 + * | Target Mode Management | 0xf071 | | 38 + * | Target Mode Task Management | 0x1000b | | 35 39 * ---------------------------------------------------------------------- 36 40 */ 37 41 ··· 380 376 memcpy(iter_reg, ha->fce, ntohl(fcec->size)); 381 377 382 378 return (char *)iter_reg + ntohl(fcec->size); 379 + } 380 + 381 + static inline void * 382 + qla2xxx_copy_atioqueues(struct qla_hw_data *ha, void *ptr, 383 + uint32_t **last_chain) 384 + { 385 + struct qla2xxx_mqueue_chain *q; 386 + struct qla2xxx_mqueue_header *qh; 387 + uint32_t num_queues; 388 + int que; 389 + struct { 390 + int length; 391 + void *ring; 392 + } aq, *aqp; 393 + 394 + if (!ha->tgt.atio_q_length) 395 + return ptr; 396 + 397 + num_queues = 1; 398 + aqp = &aq; 399 + aqp->length = ha->tgt.atio_q_length; 400 + aqp->ring = ha->tgt.atio_ring; 401 + 402 + for (que = 0; que < num_queues; que++) { 403 + /* aqp = ha->atio_q_map[que]; */ 404 + q = ptr; 405 + *last_chain = &q->type; 406 + q->type = __constant_htonl(DUMP_CHAIN_QUEUE); 407 + q->chain_size = htonl( 408 + sizeof(struct qla2xxx_mqueue_chain) + 409 + sizeof(struct qla2xxx_mqueue_header) + 410 + (aqp->length * sizeof(request_t))); 411 + ptr += sizeof(struct qla2xxx_mqueue_chain); 412 + 413 + /* Add header. */ 414 + qh = ptr; 415 + qh->queue = __constant_htonl(TYPE_ATIO_QUEUE); 416 + qh->number = htonl(que); 417 + qh->size = htonl(aqp->length * sizeof(request_t)); 418 + ptr += sizeof(struct qla2xxx_mqueue_header); 419 + 420 + /* Add data. */ 421 + memcpy(ptr, aqp->ring, aqp->length * sizeof(request_t)); 422 + 423 + ptr += aqp->length * sizeof(request_t); 424 + } 425 + 426 + return ptr; 383 427 } 384 428 385 429 static inline void * ··· 925 873 struct qla24xx_fw_dump *fw; 926 874 uint32_t ext_mem_cnt; 927 875 void *nxt; 876 + void *nxt_chain; 877 + uint32_t *last_chain = NULL; 928 878 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 929 879 930 880 if (IS_QLA82XX(ha)) ··· 1144 1090 nxt = qla2xxx_copy_queues(ha, nxt); 1145 1091 1146 1092 qla24xx_copy_eft(ha, nxt); 1093 + 1094 + nxt_chain = (void *)ha->fw_dump + ha->chain_offset; 1095 + nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 1096 + if (last_chain) { 1097 + ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 1098 + *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); 1099 + } 1100 + 1101 + /* Adjust valid length. */ 1102 + ha->fw_dump_len = (nxt_chain - (void *)ha->fw_dump); 1147 1103 1148 1104 qla24xx_fw_dump_failed_0: 1149 1105 qla2xxx_dump_post_process(base_vha, rval); ··· 1463 1399 /* Chain entries -- started with MQ. */ 1464 1400 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 1465 1401 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 1402 + nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 1466 1403 if (last_chain) { 1467 1404 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 1468 1405 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); ··· 1782 1717 /* Chain entries -- started with MQ. */ 1783 1718 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 1784 1719 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 1720 + nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 1785 1721 if (last_chain) { 1786 1722 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 1787 1723 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST); ··· 2284 2218 /* Chain entries -- started with MQ. */ 2285 2219 nxt_chain = qla25xx_copy_fce(ha, nxt_chain, &last_chain); 2286 2220 nxt_chain = qla25xx_copy_mqueues(ha, nxt_chain, &last_chain); 2221 + nxt_chain = qla2xxx_copy_atioqueues(ha, nxt_chain, &last_chain); 2287 2222 if (last_chain) { 2288 2223 ha->fw_dump->version |= __constant_htonl(DUMP_CHAIN_VARIANT); 2289 2224 *last_chain |= __constant_htonl(DUMP_CHAIN_LAST);
+9
drivers/scsi/qla2xxx/qla_dbg.h
··· 244 244 uint32_t queue; 245 245 #define TYPE_REQUEST_QUEUE 0x1 246 246 #define TYPE_RESPONSE_QUEUE 0x2 247 + #define TYPE_ATIO_QUEUE 0x3 247 248 uint32_t number; 248 249 uint32_t size; 249 250 }; ··· 340 339 #define ql_dbg_misc 0x00010000 /* For dumping everything that is not 341 340 * not covered by upper categories 342 341 */ 342 + #define ql_dbg_verbose 0x00008000 /* More verbosity for each level 343 + * This is to be used with other levels where 344 + * more verbosity is required. It might not 345 + * be applicable to all the levels. 346 + */ 347 + #define ql_dbg_tgt 0x00004000 /* Target mode */ 348 + #define ql_dbg_tgt_mgt 0x00002000 /* Target mode management */ 349 + #define ql_dbg_tgt_tmr 0x00001000 /* Target mode task management */
+73 -5
drivers/scsi/qla2xxx/qla_def.h
··· 186 186 #define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/ 187 187 #define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/ 188 188 #define RESPONSE_ENTRY_CNT_MQ 128 /* Number of response entries.*/ 189 + #define ATIO_ENTRY_CNT_24XX 4096 /* Number of ATIO entries. */ 189 190 190 191 struct req_que; 191 192 ··· 1235 1234 * ISP queue - response queue entry definition. 1236 1235 */ 1237 1236 typedef struct { 1238 - uint8_t data[60]; 1237 + uint8_t entry_type; /* Entry type. */ 1238 + uint8_t entry_count; /* Entry count. */ 1239 + uint8_t sys_define; /* System defined. */ 1240 + uint8_t entry_status; /* Entry Status. */ 1241 + uint32_t handle; /* System defined handle */ 1242 + uint8_t data[52]; 1239 1243 uint32_t signature; 1240 1244 #define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */ 1241 1245 } response_t; 1246 + 1247 + /* 1248 + * ISP queue - ATIO queue entry definition. 1249 + */ 1250 + struct atio { 1251 + uint8_t entry_type; /* Entry type. */ 1252 + uint8_t entry_count; /* Entry count. */ 1253 + uint8_t data[58]; 1254 + uint32_t signature; 1255 + #define ATIO_PROCESSED 0xDEADDEAD /* Signature */ 1256 + }; 1242 1257 1243 1258 typedef union { 1244 1259 uint16_t extended; ··· 1736 1719 struct fc_rport *rport, *drport; 1737 1720 u32 supported_classes; 1738 1721 1739 - uint16_t vp_idx; 1740 1722 uint8_t fc4_type; 1741 1723 uint8_t scan_state; 1742 1724 } fc_port_t; 1725 + 1726 + #define QLA_FCPORT_SCAN_NONE 0 1727 + #define QLA_FCPORT_SCAN_FOUND 1 1743 1728 1744 1729 /* 1745 1730 * Fibre channel port/lun states. ··· 1766 1747 #define FCF_LOGIN_NEEDED BIT_1 1767 1748 #define FCF_FCP2_DEVICE BIT_2 1768 1749 #define FCF_ASYNC_SENT BIT_3 1750 + #define FCF_CONF_COMP_SUPPORTED BIT_4 1769 1751 1770 1752 /* No loop ID flag. */ 1771 1753 #define FC_NO_LOOP_ID 0x1000 ··· 2439 2419 uint32_t len; 2440 2420 }; 2441 2421 2422 + struct qlt_hw_data { 2423 + /* Protected by hw lock */ 2424 + uint32_t enable_class_2:1; 2425 + uint32_t enable_explicit_conf:1; 2426 + uint32_t ini_mode_force_reverse:1; 2427 + uint32_t node_name_set:1; 2428 + 2429 + dma_addr_t atio_dma; /* Physical address. */ 2430 + struct atio *atio_ring; /* Base virtual address */ 2431 + struct atio *atio_ring_ptr; /* Current address. */ 2432 + uint16_t atio_ring_index; /* Current index. */ 2433 + uint16_t atio_q_length; 2434 + 2435 + void *target_lport_ptr; 2436 + struct qla_tgt_func_tmpl *tgt_ops; 2437 + struct qla_tgt *qla_tgt; 2438 + struct qla_tgt_cmd *cmds[MAX_OUTSTANDING_COMMANDS]; 2439 + uint16_t current_handle; 2440 + 2441 + struct qla_tgt_vp_map *tgt_vp_map; 2442 + struct mutex tgt_mutex; 2443 + struct mutex tgt_host_action_mutex; 2444 + 2445 + int saved_set; 2446 + uint16_t saved_exchange_count; 2447 + uint32_t saved_firmware_options_1; 2448 + uint32_t saved_firmware_options_2; 2449 + uint32_t saved_firmware_options_3; 2450 + uint8_t saved_firmware_options[2]; 2451 + uint8_t saved_add_firmware_options[2]; 2452 + 2453 + uint8_t tgt_node_name[WWN_SIZE]; 2454 + }; 2455 + 2442 2456 /* 2443 2457 * Qlogic host adapter specific data structure. 2444 2458 */ ··· 2514 2460 uint32_t thermal_supported:1; 2515 2461 uint32_t isp82xx_reset_hdlr_active:1; 2516 2462 uint32_t isp82xx_reset_owner:1; 2517 - /* 28 bits */ 2463 + uint32_t isp82xx_no_md_cap:1; 2464 + uint32_t host_shutting_down:1; 2465 + /* 30 bits */ 2518 2466 } flags; 2519 2467 2520 2468 /* This spinlock is used to protect "io transactions", you must ··· 2860 2804 /* ISP2322: red, green, amber. */ 2861 2805 uint16_t zio_mode; 2862 2806 uint16_t zio_timer; 2863 - struct fc_host_statistics fc_host_stat; 2864 2807 2865 2808 struct qla_msix_entry *msix_entries; 2866 2809 ··· 2872 2817 int cur_vport_count; 2873 2818 2874 2819 struct qla_chip_state_84xx *cs84xx; 2875 - struct qla_statistics qla_stats; 2876 2820 struct isp_operations *isp_ops; 2877 2821 struct workqueue_struct *wq; 2878 2822 struct qlfc_fw fw_buf; ··· 2917 2863 dma_addr_t md_tmplt_hdr_dma; 2918 2864 void *md_dump; 2919 2865 uint32_t md_dump_size; 2866 + 2867 + struct qlt_hw_data tgt; 2920 2868 }; 2921 2869 2922 2870 /* ··· 2976 2920 #define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ 2977 2921 #define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */ 2978 2922 #define ISP_QUIESCE_NEEDED 20 /* Driver need some quiescence */ 2923 + #define SCR_PENDING 21 /* SCR in target mode */ 2979 2924 2980 2925 uint32_t device_flags; 2981 2926 #define SWITCH_FOUND BIT_0 ··· 3036 2979 struct req_que *req; 3037 2980 int fw_heartbeat_counter; 3038 2981 int seconds_since_last_heartbeat; 2982 + struct fc_host_statistics fc_host_stat; 2983 + struct qla_statistics qla_stats; 3039 2984 3040 2985 atomic_t vref_count; 3041 2986 } scsi_qla_host_t; 2987 + 2988 + #define SET_VP_IDX 1 2989 + #define SET_AL_PA 2 2990 + #define RESET_VP_IDX 3 2991 + #define RESET_AL_PA 4 2992 + struct qla_tgt_vp_map { 2993 + uint8_t idx; 2994 + scsi_qla_host_t *vha; 2995 + }; 3042 2996 3043 2997 /* 3044 2998 * Macros to help code, maintain, etc.
+9
drivers/scsi/qla2xxx/qla_gbl.h
··· 175 175 /* 176 176 * Global Function Prototypes in qla_iocb.c source file. 177 177 */ 178 + 178 179 extern uint16_t qla2x00_calc_iocbs_32(uint16_t); 179 180 extern uint16_t qla2x00_calc_iocbs_64(uint16_t); 180 181 extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t); ··· 189 188 extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *, uint16_t); 190 189 extern int qla24xx_dif_start_scsi(srb_t *); 191 190 191 + extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); 192 + extern int qla2x00_issue_marker(scsi_qla_host_t *, int); 192 193 193 194 /* 194 195 * Global Function Prototypes in qla_mbx.c source file. ··· 240 237 241 238 extern int 242 239 qla2x00_init_firmware(scsi_qla_host_t *, uint16_t); 240 + 241 + extern int 242 + qla2x00_get_node_name_list(scsi_qla_host_t *, void **, int *); 243 243 244 244 extern int 245 245 qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t); ··· 389 383 extern void qla2x00_free_irqs(scsi_qla_host_t *); 390 384 391 385 extern int qla2x00_get_data_rate(scsi_qla_host_t *); 386 + extern char *qla2x00_get_link_speed_str(struct qla_hw_data *); 387 + 392 388 /* 393 389 * Global Function Prototypes in qla_sup.c source file. 394 390 */ ··· 554 546 extern void qla2x00_sp_timeout(unsigned long); 555 547 extern void qla2x00_bsg_job_done(void *, void *, int); 556 548 extern void qla2x00_bsg_sp_free(void *, void *); 549 + extern void qla2x00_start_iocbs(struct scsi_qla_host *, struct req_que *); 557 550 558 551 /* Interrupt related */ 559 552 extern irqreturn_t qla82xx_intr_handler(int, void *);
+3 -1
drivers/scsi/qla2xxx/qla_gs.c
··· 5 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 6 */ 7 7 #include "qla_def.h" 8 + #include "qla_target.h" 8 9 9 10 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); 10 11 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); ··· 557 556 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area; 558 557 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa; 559 558 560 - ct_req->req.rff_id.fc4_feature = BIT_1; 559 + qlt_rff_id(vha, ct_req); 560 + 561 561 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */ 562 562 563 563 /* Execute MS IOCB */
+100 -97
drivers/scsi/qla2xxx/qla_init.c
··· 17 17 #include <asm/prom.h> 18 18 #endif 19 19 20 + #include <target/target_core_base.h> 21 + #include "qla_target.h" 22 + 20 23 /* 21 24 * QLogic ISP2x00 Hardware Support Function Prototypes. 22 25 */ ··· 521 518 return QLA_FUNCTION_FAILED; 522 519 } 523 520 } 524 - rval = qla2x00_init_rings(vha); 521 + 522 + if (qla_ini_mode_enabled(vha)) 523 + rval = qla2x00_init_rings(vha); 524 + 525 525 ha->flags.chip_reset_done = 1; 526 526 527 527 if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) { ··· 1239 1233 mq_size += ha->max_rsp_queues * 1240 1234 (rsp->length * sizeof(response_t)); 1241 1235 } 1236 + if (ha->tgt.atio_q_length) 1237 + mq_size += ha->tgt.atio_q_length * sizeof(request_t); 1242 1238 /* Allocate memory for Fibre Channel Event Buffer. */ 1243 1239 if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 1244 1240 goto try_eft; ··· 1704 1696 icb->response_q_address[0] = cpu_to_le32(LSD(rsp->dma)); 1705 1697 icb->response_q_address[1] = cpu_to_le32(MSD(rsp->dma)); 1706 1698 1699 + /* Setup ATIO queue dma pointers for target mode */ 1700 + icb->atio_q_inpointer = __constant_cpu_to_le16(0); 1701 + icb->atio_q_length = cpu_to_le16(ha->tgt.atio_q_length); 1702 + icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); 1703 + icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); 1704 + 1707 1705 if (ha->mqenable || IS_QLA83XX(ha)) { 1708 1706 icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); 1709 1707 icb->rid = __constant_cpu_to_le16(rid); ··· 1753 1739 WRT_REG_DWORD(&reg->isp24.rsp_q_in, 0); 1754 1740 WRT_REG_DWORD(&reg->isp24.rsp_q_out, 0); 1755 1741 } 1742 + qlt_24xx_config_rings(vha, reg); 1743 + 1756 1744 /* PCI posting */ 1757 1745 RD_REG_DWORD(&ioreg->hccr); 1758 1746 } ··· 1809 1793 spin_lock(&ha->vport_slock); 1810 1794 1811 1795 spin_unlock(&ha->vport_slock); 1796 + 1797 + ha->tgt.atio_ring_ptr = ha->tgt.atio_ring; 1798 + ha->tgt.atio_ring_index = 0; 1799 + /* Initialize ATIO queue entries */ 1800 + qlt_init_atio_q_entries(vha); 1812 1801 1813 1802 ha->isp_ops->config_rings(vha); 1814 1803 ··· 2072 2051 vha->d_id.b.area = area; 2073 2052 vha->d_id.b.al_pa = al_pa; 2074 2053 2054 + spin_lock(&ha->vport_slock); 2055 + qlt_update_vp_map(vha, SET_AL_PA); 2056 + spin_unlock(&ha->vport_slock); 2057 + 2075 2058 if (!vha->flags.init_done) 2076 2059 ql_log(ql_log_info, vha, 0x2010, 2077 2060 "Topology - %s, Host Loop address 0x%x.\n", ··· 2210 2185 nv->id[2] != 'P' || nv->id[3] != ' ' || nv->nvram_version < 1) { 2211 2186 /* Reset NVRAM data. */ 2212 2187 ql_log(ql_log_warn, vha, 0x0064, 2213 - "Inconisistent NVRAM " 2188 + "Inconsistent NVRAM " 2214 2189 "detected: checksum=0x%x id=%c version=0x%x.\n", 2215 2190 chksum, nv->id[0], nv->nvram_version); 2216 2191 ql_log(ql_log_warn, vha, 0x0065, ··· 2295 2270 if (IS_QLA23XX(ha)) { 2296 2271 nv->firmware_options[0] |= BIT_2; 2297 2272 nv->firmware_options[0] &= ~BIT_3; 2298 - nv->firmware_options[0] &= ~BIT_6; 2273 + nv->special_options[0] &= ~BIT_6; 2299 2274 nv->add_firmware_options[1] |= BIT_5 | BIT_4; 2300 2275 2301 2276 if (IS_QLA2300(ha)) { ··· 2492 2467 { 2493 2468 fc_port_t *fcport = data; 2494 2469 struct fc_rport *rport; 2470 + scsi_qla_host_t *vha = fcport->vha; 2495 2471 unsigned long flags; 2496 2472 2497 2473 spin_lock_irqsave(fcport->vha->host->host_lock, flags); 2498 2474 rport = fcport->drport ? fcport->drport: fcport->rport; 2499 2475 fcport->drport = NULL; 2500 2476 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); 2501 - if (rport) 2477 + if (rport) { 2502 2478 fc_remote_port_delete(rport); 2479 + /* 2480 + * Release the target mode FC NEXUS in qla_target.c code 2481 + * if target mod is enabled. 2482 + */ 2483 + qlt_fc_port_deleted(vha, fcport); 2484 + } 2503 2485 } 2504 2486 2505 2487 /** ··· 2527 2495 2528 2496 /* Setup fcport template structure. */ 2529 2497 fcport->vha = vha; 2530 - fcport->vp_idx = vha->vp_idx; 2531 2498 fcport->port_type = FCT_UNKNOWN; 2532 2499 fcport->loop_id = FC_NO_LOOP_ID; 2533 2500 qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); 2534 2501 fcport->supported_classes = FC_COS_UNSPECIFIED; 2502 + fcport->scan_state = QLA_FCPORT_SCAN_NONE; 2535 2503 2536 2504 return fcport; 2537 2505 } ··· 2758 2726 new_fcport->d_id.b.area = area; 2759 2727 new_fcport->d_id.b.al_pa = al_pa; 2760 2728 new_fcport->loop_id = loop_id; 2761 - new_fcport->vp_idx = vha->vp_idx; 2762 2729 rval2 = qla2x00_get_port_database(vha, new_fcport, 0); 2763 2730 if (rval2 != QLA_SUCCESS) { 2764 2731 ql_dbg(ql_dbg_disc, vha, 0x201a, ··· 2791 2760 2792 2761 if (!found) { 2793 2762 /* New device, add to fcports list. */ 2794 - if (vha->vp_idx) { 2795 - new_fcport->vha = vha; 2796 - new_fcport->vp_idx = vha->vp_idx; 2797 - } 2798 2763 list_add_tail(&new_fcport->list, &vha->vp_fcports); 2799 2764 2800 2765 /* Allocate a new replacement fcport. */ ··· 2827 2800 static void 2828 2801 qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) 2829 2802 { 2830 - #define LS_UNKNOWN 2 2831 - static char *link_speeds[] = { "1", "2", "?", "4", "8", "10" }; 2832 2803 char *link_speed; 2833 2804 int rval; 2834 2805 uint16_t mb[4]; ··· 2854 2829 fcport->port_name[6], fcport->port_name[7], rval, 2855 2830 fcport->fp_speed, mb[0], mb[1]); 2856 2831 } else { 2857 - link_speed = link_speeds[LS_UNKNOWN]; 2858 - if (fcport->fp_speed < 5) 2859 - link_speed = link_speeds[fcport->fp_speed]; 2860 - else if (fcport->fp_speed == 0x13) 2861 - link_speed = link_speeds[5]; 2832 + link_speed = qla2x00_get_link_speed_str(ha); 2862 2833 ql_dbg(ql_dbg_disc, vha, 0x2005, 2863 2834 "iIDMA adjusted to %s GB/s " 2864 2835 "on %02x%02x%02x%02x%02x%02x%02x%02x.\n", link_speed, ··· 2885 2864 "Unable to allocate fc remote port.\n"); 2886 2865 return; 2887 2866 } 2867 + /* 2868 + * Create target mode FC NEXUS in qla_target.c if target mode is 2869 + * enabled.. 2870 + */ 2871 + qlt_fc_port_added(vha, fcport); 2872 + 2888 2873 spin_lock_irqsave(fcport->vha->host->host_lock, flags); 2889 2874 *((fc_port_t **)rport->dd_data) = fcport; 2890 2875 spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); ··· 2948 2921 qla2x00_configure_fabric(scsi_qla_host_t *vha) 2949 2922 { 2950 2923 int rval; 2951 - fc_port_t *fcport, *fcptemp; 2924 + fc_port_t *fcport; 2952 2925 uint16_t next_loopid; 2953 2926 uint16_t mb[MAILBOX_REGISTER_COUNT]; 2954 2927 uint16_t loop_id; ··· 2986 2959 0xfc, mb, BIT_1|BIT_0); 2987 2960 if (rval != QLA_SUCCESS) { 2988 2961 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 2989 - return rval; 2962 + break; 2990 2963 } 2991 2964 if (mb[0] != MBS_COMMAND_COMPLETE) { 2992 2965 ql_dbg(ql_dbg_disc, vha, 0x2042, ··· 3018 2991 } 3019 2992 } 3020 2993 3021 - #define QLA_FCPORT_SCAN 1 3022 - #define QLA_FCPORT_FOUND 2 3023 - 3024 - list_for_each_entry(fcport, &vha->vp_fcports, list) { 3025 - fcport->scan_state = QLA_FCPORT_SCAN; 3026 - } 3027 - 3028 2994 rval = qla2x00_find_all_fabric_devs(vha, &new_fcports); 3029 2995 if (rval != QLA_SUCCESS) 3030 2996 break; 3031 2997 3032 - /* 3033 - * Logout all previous fabric devices marked lost, except 3034 - * FCP2 devices. 3035 - */ 2998 + /* Add new ports to existing port list */ 2999 + list_splice_tail_init(&new_fcports, &vha->vp_fcports); 3000 + 3001 + /* Starting free loop ID. */ 3002 + next_loopid = ha->min_external_loopid; 3003 + 3036 3004 list_for_each_entry(fcport, &vha->vp_fcports, list) { 3037 3005 if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) 3038 3006 break; ··· 3035 3013 if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) 3036 3014 continue; 3037 3015 3038 - if (fcport->scan_state == QLA_FCPORT_SCAN && 3016 + /* Logout lost/gone fabric devices (non-FCP2) */ 3017 + if (fcport->scan_state != QLA_FCPORT_SCAN_FOUND && 3039 3018 atomic_read(&fcport->state) == FCS_ONLINE) { 3040 3019 qla2x00_mark_device_lost(vha, fcport, 3041 3020 ql2xplogiabsentdevice, 0); ··· 3049 3026 fcport->d_id.b.domain, 3050 3027 fcport->d_id.b.area, 3051 3028 fcport->d_id.b.al_pa); 3052 - fcport->loop_id = FC_NO_LOOP_ID; 3053 3029 } 3054 - } 3055 - } 3056 - 3057 - /* Starting free loop ID. */ 3058 - next_loopid = ha->min_external_loopid; 3059 - 3060 - /* 3061 - * Scan through our port list and login entries that need to be 3062 - * logged in. 3063 - */ 3064 - list_for_each_entry(fcport, &vha->vp_fcports, list) { 3065 - if (atomic_read(&vha->loop_down_timer) || 3066 - test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) 3067 - break; 3068 - 3069 - if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || 3070 - (fcport->flags & FCF_LOGIN_NEEDED) == 0) 3071 3030 continue; 3031 + } 3032 + fcport->scan_state = QLA_FCPORT_SCAN_NONE; 3072 3033 3073 - if (fcport->loop_id == FC_NO_LOOP_ID) { 3074 - fcport->loop_id = next_loopid; 3075 - rval = qla2x00_find_new_loop_id( 3076 - base_vha, fcport); 3077 - if (rval != QLA_SUCCESS) { 3078 - /* Ran out of IDs to use */ 3079 - break; 3034 + /* Login fabric devices that need a login */ 3035 + if ((fcport->flags & FCF_LOGIN_NEEDED) != 0 && 3036 + atomic_read(&vha->loop_down_timer) == 0) { 3037 + if (fcport->loop_id == FC_NO_LOOP_ID) { 3038 + fcport->loop_id = next_loopid; 3039 + rval = qla2x00_find_new_loop_id( 3040 + base_vha, fcport); 3041 + if (rval != QLA_SUCCESS) { 3042 + /* Ran out of IDs to use */ 3043 + continue; 3044 + } 3080 3045 } 3081 3046 } 3082 - /* Login and update database */ 3083 - qla2x00_fabric_dev_login(vha, fcport, &next_loopid); 3084 - } 3085 - 3086 - /* Exit if out of loop IDs. */ 3087 - if (rval != QLA_SUCCESS) { 3088 - break; 3089 - } 3090 - 3091 - /* 3092 - * Login and add the new devices to our port list. 3093 - */ 3094 - list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { 3095 - if (atomic_read(&vha->loop_down_timer) || 3096 - test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) 3097 - break; 3098 - 3099 - /* Find a new loop ID to use. */ 3100 - fcport->loop_id = next_loopid; 3101 - rval = qla2x00_find_new_loop_id(base_vha, fcport); 3102 - if (rval != QLA_SUCCESS) { 3103 - /* Ran out of IDs to use */ 3104 - break; 3105 - } 3106 3047 3107 3048 /* Login and update database */ 3108 3049 qla2x00_fabric_dev_login(vha, fcport, &next_loopid); 3109 - 3110 - if (vha->vp_idx) { 3111 - fcport->vha = vha; 3112 - fcport->vp_idx = vha->vp_idx; 3113 - } 3114 - list_move_tail(&fcport->list, &vha->vp_fcports); 3115 3050 } 3116 3051 } while (0); 3117 - 3118 - /* Free all new device structures not processed. */ 3119 - list_for_each_entry_safe(fcport, fcptemp, &new_fcports, list) { 3120 - list_del(&fcport->list); 3121 - kfree(fcport); 3122 - } 3123 3052 3124 3053 if (rval) { 3125 3054 ql_dbg(ql_dbg_disc, vha, 0x2068, ··· 3262 3287 WWN_SIZE)) 3263 3288 continue; 3264 3289 3265 - fcport->scan_state = QLA_FCPORT_FOUND; 3290 + fcport->scan_state = QLA_FCPORT_SCAN_FOUND; 3266 3291 3267 3292 found++; 3268 3293 ··· 3570 3595 if (mb[10] & BIT_1) 3571 3596 fcport->supported_classes |= FC_COS_CLASS3; 3572 3597 3598 + if (IS_FWI2_CAPABLE(ha)) { 3599 + if (mb[10] & BIT_7) 3600 + fcport->flags |= 3601 + FCF_CONF_COMP_SUPPORTED; 3602 + } 3603 + 3573 3604 rval = QLA_SUCCESS; 3574 3605 break; 3575 3606 } else if (mb[0] == MBS_LOOP_ID_USED) { ··· 3822 3841 vha->flags.online = 0; 3823 3842 ha->flags.chip_reset_done = 0; 3824 3843 clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 3825 - ha->qla_stats.total_isp_aborts++; 3844 + vha->qla_stats.total_isp_aborts++; 3826 3845 3827 3846 ql_log(ql_log_info, vha, 0x00af, 3828 3847 "Performing ISP error recovery - ha=%p.\n", ha); ··· 4047 4066 struct qla_hw_data *ha = vha->hw; 4048 4067 struct req_que *req = ha->req_q_map[0]; 4049 4068 struct rsp_que *rsp = ha->rsp_q_map[0]; 4069 + unsigned long flags; 4050 4070 4051 4071 /* If firmware needs to be loaded */ 4052 4072 if (qla2x00_isp_firmware(vha)) { ··· 4072 4090 qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); 4073 4091 4074 4092 vha->flags.online = 1; 4093 + 4094 + /* 4095 + * Process any ATIO queue entries that came in 4096 + * while we weren't online. 4097 + */ 4098 + spin_lock_irqsave(&ha->hardware_lock, flags); 4099 + if (qla_tgt_mode_enabled(vha)) 4100 + qlt_24xx_process_atio_queue(vha); 4101 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4102 + 4075 4103 /* Wait at most MAX_TARGET RSCNs for a stable link. */ 4076 4104 wait_time = 256; 4077 4105 do { ··· 4271 4279 nv->nvram_version < __constant_cpu_to_le16(ICB_VERSION)) { 4272 4280 /* Reset NVRAM data. */ 4273 4281 ql_log(ql_log_warn, vha, 0x006b, 4274 - "Inconisistent NVRAM detected: checksum=0x%x id=%c " 4282 + "Inconsistent NVRAM detected: checksum=0x%x id=%c " 4275 4283 "version=0x%x.\n", chksum, nv->id[0], nv->nvram_version); 4276 4284 ql_log(ql_log_warn, vha, 0x006c, 4277 4285 "Falling back to functioning (yet invalid -- WWPN) " ··· 4322 4330 rval = 1; 4323 4331 } 4324 4332 4333 + if (!qla_ini_mode_enabled(vha)) { 4334 + /* Don't enable full login after initial LIP */ 4335 + nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13); 4336 + /* Don't enable LIP full login for initiator */ 4337 + nv->host_p &= __constant_cpu_to_le32(~BIT_10); 4338 + } 4339 + 4340 + qlt_24xx_config_nvram_stage1(vha, nv); 4341 + 4325 4342 /* Reset Initialization control block */ 4326 4343 memset(icb, 0, ha->init_cb_size); 4327 4344 ··· 4358 4357 qla2x00_set_model_info(vha, nv->model_name, sizeof(nv->model_name), 4359 4358 "QLA2462"); 4360 4359 4361 - /* Use alternate WWN? */ 4360 + qlt_24xx_config_nvram_stage2(vha, icb); 4361 + 4362 4362 if (nv->host_p & __constant_cpu_to_le32(BIT_15)) { 4363 + /* Use alternate WWN? */ 4363 4364 memcpy(icb->node_name, nv->alternate_node_name, WWN_SIZE); 4364 4365 memcpy(icb->port_name, nv->alternate_port_name, WWN_SIZE); 4365 4366 } ··· 5032 5029 nv->nvram_version < __constant_cpu_to_le16(ICB_VERSION)) { 5033 5030 /* Reset NVRAM data. */ 5034 5031 ql_log(ql_log_info, vha, 0x0073, 5035 - "Inconisistent NVRAM detected: checksum=0x%x id=%c " 5032 + "Inconsistent NVRAM detected: checksum=0x%x id=%c " 5036 5033 "version=0x%x.\n", chksum, nv->id[0], 5037 5034 le16_to_cpu(nv->nvram_version)); 5038 5035 ql_log(ql_log_info, vha, 0x0074,
+55 -35
drivers/scsi/qla2xxx/qla_iocb.c
··· 5 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 6 */ 7 7 #include "qla_def.h" 8 + #include "qla_target.h" 8 9 9 10 #include <linux/blkdev.h> 10 11 #include <linux/delay.h> ··· 24 23 { 25 24 uint16_t cflags; 26 25 struct scsi_cmnd *cmd = GET_CMD_SP(sp); 26 + struct scsi_qla_host *vha = sp->fcport->vha; 27 27 28 28 cflags = 0; 29 29 30 30 /* Set transfer direction */ 31 31 if (cmd->sc_data_direction == DMA_TO_DEVICE) { 32 32 cflags = CF_WRITE; 33 - sp->fcport->vha->hw->qla_stats.output_bytes += 34 - scsi_bufflen(cmd); 33 + vha->qla_stats.output_bytes += scsi_bufflen(cmd); 35 34 } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { 36 35 cflags = CF_READ; 37 - sp->fcport->vha->hw->qla_stats.input_bytes += 38 - scsi_bufflen(cmd); 36 + vha->qla_stats.input_bytes += scsi_bufflen(cmd); 39 37 } 40 38 return (cflags); 41 39 } ··· 385 385 else 386 386 req->cnt = req->length - 387 387 (req->ring_index - cnt); 388 + /* If still no head room then bail out */ 389 + if (req->cnt < (req_cnt + 2)) 390 + goto queuing_error; 388 391 } 389 - if (req->cnt < (req_cnt + 2)) 390 - goto queuing_error; 391 392 392 393 /* Build command packet */ 393 394 req->current_outstanding_cmd = handle; ··· 471 470 /** 472 471 * qla2x00_start_iocbs() - Execute the IOCB command 473 472 */ 474 - static void 473 + void 475 474 qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) 476 475 { 477 476 struct qla_hw_data *ha = vha->hw; ··· 572 571 return (ret); 573 572 } 574 573 574 + /* 575 + * qla2x00_issue_marker 576 + * 577 + * Issue marker 578 + * Caller CAN have hardware lock held as specified by ha_locked parameter. 579 + * Might release it, then reaquire. 580 + */ 581 + int qla2x00_issue_marker(scsi_qla_host_t *vha, int ha_locked) 582 + { 583 + if (ha_locked) { 584 + if (__qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0, 585 + MK_SYNC_ALL) != QLA_SUCCESS) 586 + return QLA_FUNCTION_FAILED; 587 + } else { 588 + if (qla2x00_marker(vha, vha->req, vha->req->rsp, 0, 0, 589 + MK_SYNC_ALL) != QLA_SUCCESS) 590 + return QLA_FUNCTION_FAILED; 591 + } 592 + vha->marker_needed = 0; 593 + 594 + return QLA_SUCCESS; 595 + } 596 + 575 597 /** 576 598 * qla24xx_calc_iocbs() - Determine number of Command Type 3 and 577 599 * Continuation Type 1 IOCBs to allocate. ··· 653 629 if (cmd->sc_data_direction == DMA_TO_DEVICE) { 654 630 cmd_pkt->control_flags = 655 631 __constant_cpu_to_le16(CF_WRITE_DATA); 656 - ha->qla_stats.output_bytes += scsi_bufflen(cmd); 632 + vha->qla_stats.output_bytes += scsi_bufflen(cmd); 657 633 } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { 658 634 cmd_pkt->control_flags = 659 635 __constant_cpu_to_le16(CF_READ_DATA); 660 - ha->qla_stats.input_bytes += scsi_bufflen(cmd); 636 + vha->qla_stats.input_bytes += scsi_bufflen(cmd); 661 637 } 662 638 663 639 cur_seg = scsi_sglist(cmd); ··· 769 745 if (cmd->sc_data_direction == DMA_TO_DEVICE) { 770 746 cmd_pkt->task_mgmt_flags = 771 747 __constant_cpu_to_le16(TMF_WRITE_DATA); 772 - sp->fcport->vha->hw->qla_stats.output_bytes += 773 - scsi_bufflen(cmd); 748 + vha->qla_stats.output_bytes += scsi_bufflen(cmd); 774 749 } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { 775 750 cmd_pkt->task_mgmt_flags = 776 751 __constant_cpu_to_le16(TMF_READ_DATA); 777 - sp->fcport->vha->hw->qla_stats.input_bytes += 778 - scsi_bufflen(cmd); 752 + vha->qla_stats.input_bytes += scsi_bufflen(cmd); 779 753 } 780 754 781 755 /* One DSD is available in the Command Type 3 IOCB */ ··· 1267 1245 return QLA_SUCCESS; 1268 1246 } 1269 1247 1270 - cmd_pkt->vp_index = sp->fcport->vp_idx; 1248 + cmd_pkt->vp_index = sp->fcport->vha->vp_idx; 1271 1249 1272 1250 /* Set transfer direction */ 1273 1251 if (cmd->sc_data_direction == DMA_TO_DEVICE) { ··· 1524 1502 else 1525 1503 req->cnt = req->length - 1526 1504 (req->ring_index - cnt); 1505 + if (req->cnt < (req_cnt + 2)) 1506 + goto queuing_error; 1527 1507 } 1528 - if (req->cnt < (req_cnt + 2)) 1529 - goto queuing_error; 1530 1508 1531 1509 /* Build command packet. */ 1532 1510 req->current_outstanding_cmd = handle; ··· 1549 1527 cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; 1550 1528 cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; 1551 1529 cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; 1552 - cmd_pkt->vp_index = sp->fcport->vp_idx; 1530 + cmd_pkt->vp_index = sp->fcport->vha->vp_idx; 1553 1531 1554 1532 int_to_scsilun(cmd->device->lun, &cmd_pkt->lun); 1555 1533 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); ··· 1739 1717 else 1740 1718 req->cnt = req->length - 1741 1719 (req->ring_index - cnt); 1720 + if (req->cnt < (req_cnt + 2)) 1721 + goto queuing_error; 1742 1722 } 1743 - 1744 - if (req->cnt < (req_cnt + 2)) 1745 - goto queuing_error; 1746 1723 1747 1724 status |= QDSS_GOT_Q_SPACE; 1748 1725 ··· 1919 1898 logio->port_id[0] = sp->fcport->d_id.b.al_pa; 1920 1899 logio->port_id[1] = sp->fcport->d_id.b.area; 1921 1900 logio->port_id[2] = sp->fcport->d_id.b.domain; 1922 - logio->vp_index = sp->fcport->vp_idx; 1901 + logio->vp_index = sp->fcport->vha->vp_idx; 1923 1902 } 1924 1903 1925 1904 static void ··· 1943 1922 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); 1944 1923 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | 1945 1924 sp->fcport->d_id.b.al_pa); 1946 - mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); 1925 + mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); 1947 1926 } 1948 1927 1949 1928 static void ··· 1956 1935 logio->port_id[0] = sp->fcport->d_id.b.al_pa; 1957 1936 logio->port_id[1] = sp->fcport->d_id.b.area; 1958 1937 logio->port_id[2] = sp->fcport->d_id.b.domain; 1959 - logio->vp_index = sp->fcport->vp_idx; 1938 + logio->vp_index = sp->fcport->vha->vp_idx; 1960 1939 } 1961 1940 1962 1941 static void ··· 1973 1952 mbx->mb2 = cpu_to_le16(sp->fcport->d_id.b.domain); 1974 1953 mbx->mb3 = cpu_to_le16(sp->fcport->d_id.b.area << 8 | 1975 1954 sp->fcport->d_id.b.al_pa); 1976 - mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); 1955 + mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); 1977 1956 /* Implicit: mbx->mbx10 = 0. */ 1978 1957 } 1979 1958 ··· 1983 1962 logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; 1984 1963 logio->control_flags = cpu_to_le16(LCF_COMMAND_ADISC); 1985 1964 logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); 1986 - logio->vp_index = sp->fcport->vp_idx; 1965 + logio->vp_index = sp->fcport->vha->vp_idx; 1987 1966 } 1988 1967 1989 1968 static void ··· 2004 1983 mbx->mb3 = cpu_to_le16(LSW(ha->async_pd_dma)); 2005 1984 mbx->mb6 = cpu_to_le16(MSW(MSD(ha->async_pd_dma))); 2006 1985 mbx->mb7 = cpu_to_le16(LSW(MSD(ha->async_pd_dma))); 2007 - mbx->mb9 = cpu_to_le16(sp->fcport->vp_idx); 1986 + mbx->mb9 = cpu_to_le16(sp->fcport->vha->vp_idx); 2008 1987 } 2009 1988 2010 1989 static void ··· 2030 2009 tsk->port_id[0] = fcport->d_id.b.al_pa; 2031 2010 tsk->port_id[1] = fcport->d_id.b.area; 2032 2011 tsk->port_id[2] = fcport->d_id.b.domain; 2033 - tsk->vp_index = fcport->vp_idx; 2012 + tsk->vp_index = fcport->vha->vp_idx; 2034 2013 2035 2014 if (flags == TCF_LUN_RESET) { 2036 2015 int_to_scsilun(lun, &tsk->lun); ··· 2051 2030 els_iocb->handle = sp->handle; 2052 2031 els_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); 2053 2032 els_iocb->tx_dsd_count = __constant_cpu_to_le16(bsg_job->request_payload.sg_cnt); 2054 - els_iocb->vp_index = sp->fcport->vp_idx; 2033 + els_iocb->vp_index = sp->fcport->vha->vp_idx; 2055 2034 els_iocb->sof_type = EST_SOFI3; 2056 2035 els_iocb->rx_dsd_count = __constant_cpu_to_le16(bsg_job->reply_payload.sg_cnt); 2057 2036 ··· 2181 2160 ct_iocb->handle = sp->handle; 2182 2161 2183 2162 ct_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id); 2184 - ct_iocb->vp_index = sp->fcport->vp_idx; 2163 + ct_iocb->vp_index = sp->fcport->vha->vp_idx; 2185 2164 ct_iocb->comp_status = __constant_cpu_to_le16(0); 2186 2165 2187 2166 ct_iocb->cmd_dsd_count = ··· 2364 2343 else 2365 2344 req->cnt = req->length - 2366 2345 (req->ring_index - cnt); 2346 + if (req->cnt < (req_cnt + 2)) 2347 + goto queuing_error; 2367 2348 } 2368 - 2369 - if (req->cnt < (req_cnt + 2)) 2370 - goto queuing_error; 2371 2349 2372 2350 ctx = sp->u.scmd.ctx = 2373 2351 mempool_alloc(ha->ctx_mempool, GFP_ATOMIC); ··· 2382 2362 if (!ctx->fcp_cmnd) { 2383 2363 ql_log(ql_log_fatal, vha, 0x3011, 2384 2364 "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd); 2385 - goto queuing_error_fcp_cmnd; 2365 + goto queuing_error; 2386 2366 } 2387 2367 2388 2368 /* Initialize the DSD list and dma handle */ ··· 2420 2400 cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; 2421 2401 cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; 2422 2402 cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; 2423 - cmd_pkt->vp_index = sp->fcport->vp_idx; 2403 + cmd_pkt->vp_index = sp->fcport->vha->vp_idx; 2424 2404 2425 2405 /* Build IOCB segments */ 2426 2406 if (qla24xx_build_scsi_type_6_iocbs(sp, cmd_pkt, tot_dsds)) ··· 2509 2489 cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa; 2510 2490 cmd_pkt->port_id[1] = sp->fcport->d_id.b.area; 2511 2491 cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain; 2512 - cmd_pkt->vp_index = sp->fcport->vp_idx; 2492 + cmd_pkt->vp_index = sp->fcport->vha->vp_idx; 2513 2493 2514 2494 int_to_scsilun(cmd->device->lun, &cmd_pkt->lun); 2515 2495 host_to_fcp_swap((uint8_t *)&cmd_pkt->lun,
+79 -15
drivers/scsi/qla2xxx/qla_isr.c
··· 5 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 6 */ 7 7 #include "qla_def.h" 8 + #include "qla_target.h" 8 9 9 10 #include <linux/delay.h> 10 11 #include <linux/slab.h> ··· 310 309 "IDC failed to post ACK.\n"); 311 310 } 312 311 312 + #define LS_UNKNOWN 2 313 + char * 314 + qla2x00_get_link_speed_str(struct qla_hw_data *ha) 315 + { 316 + static char *link_speeds[] = {"1", "2", "?", "4", "8", "16", "10"}; 317 + char *link_speed; 318 + int fw_speed = ha->link_data_rate; 319 + 320 + if (IS_QLA2100(ha) || IS_QLA2200(ha)) 321 + link_speed = link_speeds[0]; 322 + else if (fw_speed == 0x13) 323 + link_speed = link_speeds[6]; 324 + else { 325 + link_speed = link_speeds[LS_UNKNOWN]; 326 + if (fw_speed < 6) 327 + link_speed = 328 + link_speeds[fw_speed]; 329 + } 330 + 331 + return link_speed; 332 + } 333 + 313 334 /** 314 335 * qla2x00_async_event() - Process aynchronous events. 315 336 * @ha: SCSI driver HA context ··· 340 317 void 341 318 qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) 342 319 { 343 - #define LS_UNKNOWN 2 344 - static char *link_speeds[] = { "1", "2", "?", "4", "8", "16", "10" }; 345 - char *link_speed; 346 320 uint16_t handle_cnt; 347 321 uint16_t cnt, mbx; 348 322 uint32_t handles[5]; ··· 474 454 case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ 475 455 ql_dbg(ql_dbg_async, vha, 0x5008, 476 456 "Asynchronous WAKEUP_THRES.\n"); 477 - break; 478 457 458 + break; 479 459 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ 480 460 ql_dbg(ql_dbg_async, vha, 0x5009, 481 461 "LIP occurred (%x).\n", mb[1]); ··· 499 479 break; 500 480 501 481 case MBA_LOOP_UP: /* Loop Up Event */ 502 - if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 503 - link_speed = link_speeds[0]; 482 + if (IS_QLA2100(ha) || IS_QLA2200(ha)) 504 483 ha->link_data_rate = PORT_SPEED_1GB; 505 - } else { 506 - link_speed = link_speeds[LS_UNKNOWN]; 507 - if (mb[1] < 6) 508 - link_speed = link_speeds[mb[1]]; 509 - else if (mb[1] == 0x13) 510 - link_speed = link_speeds[6]; 484 + else 511 485 ha->link_data_rate = mb[1]; 512 - } 513 486 514 487 ql_dbg(ql_dbg_async, vha, 0x500a, 515 - "LOOP UP detected (%s Gbps).\n", link_speed); 488 + "LOOP UP detected (%s Gbps).\n", 489 + qla2x00_get_link_speed_str(ha)); 516 490 517 491 vha->flags.management_server_logged_in = 0; 518 492 qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate); ··· 652 638 ql_dbg(ql_dbg_async, vha, 0x5010, 653 639 "Port unavailable %04x %04x %04x.\n", 654 640 mb[1], mb[2], mb[3]); 641 + ql_log(ql_log_warn, vha, 0x505e, 642 + "Link is offline.\n"); 655 643 656 644 if (atomic_read(&vha->loop_state) != LOOP_DOWN) { 657 645 atomic_set(&vha->loop_state, LOOP_DOWN); ··· 686 670 ql_dbg(ql_dbg_async, vha, 0x5011, 687 671 "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", 688 672 mb[1], mb[2], mb[3]); 673 + 674 + qlt_async_event(mb[0], vha, mb); 689 675 break; 690 676 } 691 677 692 678 ql_dbg(ql_dbg_async, vha, 0x5012, 693 679 "Port database changed %04x %04x %04x.\n", 694 680 mb[1], mb[2], mb[3]); 681 + ql_log(ql_log_warn, vha, 0x505f, 682 + "Link is operational (%s Gbps).\n", 683 + qla2x00_get_link_speed_str(ha)); 695 684 696 685 /* 697 686 * Mark all devices as missing so we will login again. ··· 705 684 706 685 qla2x00_mark_all_devices_lost(vha, 1); 707 686 687 + if (vha->vp_idx == 0 && !qla_ini_mode_enabled(vha)) 688 + set_bit(SCR_PENDING, &vha->dpc_flags); 689 + 708 690 set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); 709 691 set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); 692 + 693 + qlt_async_event(mb[0], vha, mb); 710 694 break; 711 695 712 696 case MBA_RSCN_UPDATE: /* State Change Registration */ ··· 832 806 "Unknown AEN:%04x %04x %04x %04x\n", 833 807 mb[0], mb[1], mb[2], mb[3]); 834 808 } 809 + 810 + qlt_async_event(mb[0], vha, mb); 835 811 836 812 if (!vha->vp_idx && ha->num_vhosts) 837 813 qla2x00_alert_all_vps(rsp, mb); ··· 1199 1171 fcport->flags |= FCF_FCP2_DEVICE; 1200 1172 } else if (iop[0] & BIT_5) 1201 1173 fcport->port_type = FCT_INITIATOR; 1174 + 1175 + if (iop[0] & BIT_7) 1176 + fcport->flags |= FCF_CONF_COMP_SUPPORTED; 1202 1177 1203 1178 if (logio->io_parameter[7] || logio->io_parameter[8]) 1204 1179 fcport->supported_classes |= FC_COS_CLASS2; ··· 2017 1986 2018 1987 if (pkt->entry_status != 0) { 2019 1988 qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); 1989 + 1990 + (void)qlt_24xx_process_response_error(vha, pkt); 1991 + 2020 1992 ((response_t *)pkt)->signature = RESPONSE_PROCESSED; 2021 1993 wmb(); 2022 1994 continue; ··· 2049 2015 break; 2050 2016 case ELS_IOCB_TYPE: 2051 2017 qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); 2018 + break; 2019 + case ABTS_RECV_24XX: 2020 + /* ensure that the ATIO queue is empty */ 2021 + qlt_24xx_process_atio_queue(vha); 2022 + case ABTS_RESP_24XX: 2023 + case CTIO_TYPE7: 2024 + case NOTIFY_ACK_TYPE: 2025 + qlt_response_pkt_all_vps(vha, (response_t *)pkt); 2052 2026 break; 2053 2027 case MARKER_TYPE: 2054 2028 /* Do nothing in this case, this check is to prevent it ··· 2210 2168 case 0x14: 2211 2169 qla24xx_process_response_queue(vha, rsp); 2212 2170 break; 2171 + case 0x1C: /* ATIO queue updated */ 2172 + qlt_24xx_process_atio_queue(vha); 2173 + break; 2174 + case 0x1D: /* ATIO and response queues updated */ 2175 + qlt_24xx_process_atio_queue(vha); 2176 + qla24xx_process_response_queue(vha, rsp); 2177 + break; 2213 2178 default: 2214 2179 ql_dbg(ql_dbg_async, vha, 0x504f, 2215 2180 "Unrecognized interrupt type (%d).\n", stat * 0xff); ··· 2359 2310 break; 2360 2311 case 0x13: 2361 2312 case 0x14: 2313 + qla24xx_process_response_queue(vha, rsp); 2314 + break; 2315 + case 0x1C: /* ATIO queue updated */ 2316 + qlt_24xx_process_atio_queue(vha); 2317 + break; 2318 + case 0x1D: /* ATIO and response queues updated */ 2319 + qlt_24xx_process_atio_queue(vha); 2362 2320 qla24xx_process_response_queue(vha, rsp); 2363 2321 break; 2364 2322 default: ··· 2620 2564 qla2x00_free_irqs(scsi_qla_host_t *vha) 2621 2565 { 2622 2566 struct qla_hw_data *ha = vha->hw; 2623 - struct rsp_que *rsp = ha->rsp_q_map[0]; 2567 + struct rsp_que *rsp; 2568 + 2569 + /* 2570 + * We need to check that ha->rsp_q_map is valid in case we are called 2571 + * from a probe failure context. 2572 + */ 2573 + if (!ha->rsp_q_map || !ha->rsp_q_map[0]) 2574 + return; 2575 + rsp = ha->rsp_q_map[0]; 2624 2576 2625 2577 if (ha->flags.msix_enabled) 2626 2578 qla24xx_disable_msix(ha);
+430 -185
drivers/scsi/qla2xxx/qla_mbx.c
··· 5 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 6 */ 7 7 #include "qla_def.h" 8 + #include "qla_target.h" 8 9 9 10 #include <linux/delay.h> 10 11 #include <linux/gfp.h> ··· 271 270 ictrl = RD_REG_WORD(&reg->isp.ictrl); 272 271 } 273 272 ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, 274 - "MBX Command timeout for cmd %x.\n", command); 275 - ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111a, 276 - "iocontrol=%x jiffies=%lx.\n", ictrl, jiffies); 277 - ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111b, 278 - "mb[0] = 0x%x.\n", mb0); 273 + "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " 274 + "mb[0]=0x%x\n", command, ictrl, jiffies, mb0); 279 275 ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019); 280 276 281 277 /* ··· 318 320 CRB_NIU_XG_PAUSE_CTL_P1); 319 321 } 320 322 ql_log(ql_log_info, base_vha, 0x101c, 321 - "Mailbox cmd timeout occured, cmd=0x%x, " 323 + "Mailbox cmd timeout occurred, cmd=0x%x, " 322 324 "mb[0]=0x%x, eeh_busy=0x%x. Scheduling ISP " 323 325 "abort.\n", command, mcp->mb[0], 324 326 ha->flags.eeh_busy); ··· 343 345 CRB_NIU_XG_PAUSE_CTL_P1); 344 346 } 345 347 ql_log(ql_log_info, base_vha, 0x101e, 346 - "Mailbox cmd timeout occured, cmd=0x%x, " 348 + "Mailbox cmd timeout occurred, cmd=0x%x, " 347 349 "mb[0]=0x%x. Scheduling ISP abort ", 348 350 command, mcp->mb[0]); 349 351 set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); ··· 388 390 mbx_cmd_t mc; 389 391 mbx_cmd_t *mcp = &mc; 390 392 391 - ql_dbg(ql_dbg_mbx, vha, 0x1022, "Entered %s.\n", __func__); 393 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1022, 394 + "Entered %s.\n", __func__); 392 395 393 396 if (MSW(risc_addr) || IS_FWI2_CAPABLE(ha)) { 394 397 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; ··· 423 424 ql_dbg(ql_dbg_mbx, vha, 0x1023, 424 425 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 425 426 } else { 426 - ql_dbg(ql_dbg_mbx, vha, 0x1024, "Done %s.\n", __func__); 427 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1024, 428 + "Done %s.\n", __func__); 427 429 } 428 430 429 431 return rval; ··· 454 454 mbx_cmd_t mc; 455 455 mbx_cmd_t *mcp = &mc; 456 456 457 - ql_dbg(ql_dbg_mbx, vha, 0x1025, "Entered %s.\n", __func__); 457 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025, 458 + "Entered %s.\n", __func__); 458 459 459 460 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 460 461 mcp->out_mb = MBX_0; ··· 490 489 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 491 490 } else { 492 491 if (IS_FWI2_CAPABLE(ha)) { 493 - ql_dbg(ql_dbg_mbx, vha, 0x1027, 492 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1027, 494 493 "Done exchanges=%x.\n", mcp->mb[1]); 495 494 } else { 496 - ql_dbg(ql_dbg_mbx, vha, 0x1028, "Done %s.\n", __func__); 495 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1028, 496 + "Done %s.\n", __func__); 497 497 } 498 498 } 499 499 ··· 525 523 mbx_cmd_t *mcp = &mc; 526 524 struct qla_hw_data *ha = vha->hw; 527 525 528 - ql_dbg(ql_dbg_mbx, vha, 0x1029, "Entered %s.\n", __func__); 526 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1029, 527 + "Entered %s.\n", __func__); 529 528 530 529 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; 531 530 mcp->out_mb = MBX_0; ··· 564 561 ha->fw_attributes_h = mcp->mb[15]; 565 562 ha->fw_attributes_ext[0] = mcp->mb[16]; 566 563 ha->fw_attributes_ext[1] = mcp->mb[17]; 567 - ql_dbg(ql_dbg_mbx, vha, 0x1139, 564 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1139, 568 565 "%s: FW_attributes Upper: 0x%x, Lower: 0x%x.\n", 569 566 __func__, mcp->mb[15], mcp->mb[6]); 570 567 } else 571 - ql_dbg(ql_dbg_mbx, vha, 0x112f, 568 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x112f, 572 569 "%s: FwAttributes [Upper] invalid, MB6:%04x\n", 573 570 __func__, mcp->mb[6]); 574 571 } ··· 579 576 ql_dbg(ql_dbg_mbx, vha, 0x102a, "Failed=%x.\n", rval); 580 577 } else { 581 578 /*EMPTY*/ 582 - ql_dbg(ql_dbg_mbx, vha, 0x102b, "Done %s.\n", __func__); 579 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102b, 580 + "Done %s.\n", __func__); 583 581 } 584 582 return rval; 585 583 } ··· 606 602 mbx_cmd_t mc; 607 603 mbx_cmd_t *mcp = &mc; 608 604 609 - ql_dbg(ql_dbg_mbx, vha, 0x102c, "Entered %s.\n", __func__); 605 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102c, 606 + "Entered %s.\n", __func__); 610 607 611 608 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; 612 609 mcp->out_mb = MBX_0; ··· 625 620 fwopts[2] = mcp->mb[2]; 626 621 fwopts[3] = mcp->mb[3]; 627 622 628 - ql_dbg(ql_dbg_mbx, vha, 0x102e, "Done %s.\n", __func__); 623 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102e, 624 + "Done %s.\n", __func__); 629 625 } 630 626 631 627 return rval; ··· 654 648 mbx_cmd_t mc; 655 649 mbx_cmd_t *mcp = &mc; 656 650 657 - ql_dbg(ql_dbg_mbx, vha, 0x102f, "Entered %s.\n", __func__); 651 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x102f, 652 + "Entered %s.\n", __func__); 658 653 659 654 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION; 660 655 mcp->mb[1] = fwopts[1]; ··· 683 676 "Failed=%x (%x/%x).\n", rval, mcp->mb[0], mcp->mb[1]); 684 677 } else { 685 678 /*EMPTY*/ 686 - ql_dbg(ql_dbg_mbx, vha, 0x1031, "Done %s.\n", __func__); 679 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1031, 680 + "Done %s.\n", __func__); 687 681 } 688 682 689 683 return rval; ··· 712 704 mbx_cmd_t mc; 713 705 mbx_cmd_t *mcp = &mc; 714 706 715 - ql_dbg(ql_dbg_mbx, vha, 0x1032, "Entered %s.\n", __func__); 707 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1032, 708 + "Entered %s.\n", __func__); 716 709 717 710 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 718 711 mcp->mb[1] = 0xAAAA; ··· 743 734 ql_dbg(ql_dbg_mbx, vha, 0x1033, "Failed=%x.\n", rval); 744 735 } else { 745 736 /*EMPTY*/ 746 - ql_dbg(ql_dbg_mbx, vha, 0x1034, "Done %s.\n", __func__); 737 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1034, 738 + "Done %s.\n", __func__); 747 739 } 748 740 749 741 return rval; ··· 772 762 mbx_cmd_t mc; 773 763 mbx_cmd_t *mcp = &mc; 774 764 775 - ql_dbg(ql_dbg_mbx, vha, 0x1035, "Entered %s.\n", __func__); 765 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1035, 766 + "Entered %s.\n", __func__); 776 767 777 768 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 778 769 mcp->out_mb = MBX_0; ··· 798 787 "Failed=%x chm sum=%x.\n", rval, IS_FWI2_CAPABLE(vha->hw) ? 799 788 (mcp->mb[2] << 16) | mcp->mb[1] : mcp->mb[1]); 800 789 } else { 801 - ql_dbg(ql_dbg_mbx, vha, 0x1037, "Done %s.\n", __func__); 790 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1037, 791 + "Done %s.\n", __func__); 802 792 } 803 793 804 794 return rval; ··· 831 819 mbx_cmd_t mc; 832 820 mbx_cmd_t *mcp = &mc; 833 821 834 - ql_dbg(ql_dbg_mbx, vha, 0x1038, "Entered %s.\n", __func__); 822 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1038, 823 + "Entered %s.\n", __func__); 835 824 836 825 mcp->mb[0] = MBC_IOCB_COMMAND_A64; 837 826 mcp->mb[1] = 0; ··· 855 842 /* Mask reserved bits. */ 856 843 sts_entry->entry_status &= 857 844 IS_FWI2_CAPABLE(vha->hw) ? RF_MASK_24XX : RF_MASK; 858 - ql_dbg(ql_dbg_mbx, vha, 0x103a, "Done %s.\n", __func__); 845 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103a, 846 + "Done %s.\n", __func__); 859 847 } 860 848 861 849 return rval; ··· 898 884 struct req_que *req = vha->req; 899 885 struct scsi_cmnd *cmd = GET_CMD_SP(sp); 900 886 901 - ql_dbg(ql_dbg_mbx, vha, 0x103b, "Entered %s.\n", __func__); 887 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103b, 888 + "Entered %s.\n", __func__); 902 889 903 890 spin_lock_irqsave(&ha->hardware_lock, flags); 904 891 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { ··· 930 915 if (rval != QLA_SUCCESS) { 931 916 ql_dbg(ql_dbg_mbx, vha, 0x103c, "Failed=%x.\n", rval); 932 917 } else { 933 - ql_dbg(ql_dbg_mbx, vha, 0x103d, "Done %s.\n", __func__); 918 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103d, 919 + "Done %s.\n", __func__); 934 920 } 935 921 936 922 return rval; ··· 950 934 l = l; 951 935 vha = fcport->vha; 952 936 953 - ql_dbg(ql_dbg_mbx, vha, 0x103e, "Entered %s.\n", __func__); 937 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103e, 938 + "Entered %s.\n", __func__); 954 939 955 940 req = vha->hw->req_q_map[0]; 956 941 rsp = req->rsp; ··· 972 955 mcp->flags = 0; 973 956 rval = qla2x00_mailbox_command(vha, mcp); 974 957 if (rval != QLA_SUCCESS) { 975 - ql_dbg(ql_dbg_mbx, vha, 0x103f, "Failed=%x.\n", rval); 958 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x103f, 959 + "Failed=%x.\n", rval); 976 960 } 977 961 978 962 /* Issue marker IOCB. */ ··· 983 965 ql_dbg(ql_dbg_mbx, vha, 0x1040, 984 966 "Failed to issue marker IOCB (%x).\n", rval2); 985 967 } else { 986 - ql_dbg(ql_dbg_mbx, vha, 0x1041, "Done %s.\n", __func__); 968 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1041, 969 + "Done %s.\n", __func__); 987 970 } 988 971 989 972 return rval; ··· 1002 983 1003 984 vha = fcport->vha; 1004 985 1005 - ql_dbg(ql_dbg_mbx, vha, 0x1042, "Entered %s.\n", __func__); 986 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1042, 987 + "Entered %s.\n", __func__); 1006 988 1007 989 req = vha->hw->req_q_map[0]; 1008 990 rsp = req->rsp; ··· 1032 1012 ql_dbg(ql_dbg_mbx, vha, 0x1044, 1033 1013 "Failed to issue marker IOCB (%x).\n", rval2); 1034 1014 } else { 1035 - ql_dbg(ql_dbg_mbx, vha, 0x1045, "Done %s.\n", __func__); 1015 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1045, 1016 + "Done %s.\n", __func__); 1036 1017 } 1037 1018 1038 1019 return rval; ··· 1067 1046 mbx_cmd_t mc; 1068 1047 mbx_cmd_t *mcp = &mc; 1069 1048 1070 - ql_dbg(ql_dbg_mbx, vha, 0x1046, "Entered %s.\n", __func__); 1049 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1046, 1050 + "Entered %s.\n", __func__); 1071 1051 1072 1052 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; 1073 1053 mcp->mb[9] = vha->vp_idx; ··· 1096 1074 /*EMPTY*/ 1097 1075 ql_dbg(ql_dbg_mbx, vha, 0x1047, "Failed=%x.\n", rval); 1098 1076 } else { 1099 - ql_dbg(ql_dbg_mbx, vha, 0x1048, "Done %s.\n", __func__); 1077 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1048, 1078 + "Done %s.\n", __func__); 1100 1079 1101 1080 if (IS_CNA_CAPABLE(vha->hw)) { 1102 1081 vha->fcoe_vlan_id = mcp->mb[9] & 0xfff; ··· 1138 1115 mbx_cmd_t mc; 1139 1116 mbx_cmd_t *mcp = &mc; 1140 1117 1141 - ql_dbg(ql_dbg_mbx, vha, 0x1049, "Entered %s.\n", __func__); 1118 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1049, 1119 + "Entered %s.\n", __func__); 1142 1120 1143 1121 mcp->mb[0] = MBC_GET_RETRY_COUNT; 1144 1122 mcp->out_mb = MBX_0; ··· 1162 1138 *tov = ratov; 1163 1139 } 1164 1140 1165 - ql_dbg(ql_dbg_mbx, vha, 0x104b, 1141 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104b, 1166 1142 "Done %s mb3=%d ratov=%d.\n", __func__, mcp->mb[3], ratov); 1167 1143 } 1168 1144 ··· 1194 1170 mbx_cmd_t *mcp = &mc; 1195 1171 struct qla_hw_data *ha = vha->hw; 1196 1172 1197 - ql_dbg(ql_dbg_mbx, vha, 0x104c, "Entered %s.\n", __func__); 1173 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104c, 1174 + "Entered %s.\n", __func__); 1198 1175 1199 1176 if (IS_QLA82XX(ha) && ql2xdbwr) 1200 1177 qla82xx_wr_32(ha, ha->nxdb_wr_ptr, ··· 1238 1213 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], mcp->mb[3]); 1239 1214 } else { 1240 1215 /*EMPTY*/ 1241 - ql_dbg(ql_dbg_mbx, vha, 0x104e, "Done %s.\n", __func__); 1216 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104e, 1217 + "Done %s.\n", __func__); 1242 1218 } 1243 1219 1220 + return rval; 1221 + } 1222 + 1223 + /* 1224 + * qla2x00_get_node_name_list 1225 + * Issue get node name list mailbox command, kmalloc() 1226 + * and return the resulting list. Caller must kfree() it! 1227 + * 1228 + * Input: 1229 + * ha = adapter state pointer. 1230 + * out_data = resulting list 1231 + * out_len = length of the resulting list 1232 + * 1233 + * Returns: 1234 + * qla2x00 local function return status code. 1235 + * 1236 + * Context: 1237 + * Kernel context. 1238 + */ 1239 + int 1240 + qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len) 1241 + { 1242 + struct qla_hw_data *ha = vha->hw; 1243 + struct qla_port_24xx_data *list = NULL; 1244 + void *pmap; 1245 + mbx_cmd_t mc; 1246 + dma_addr_t pmap_dma; 1247 + ulong dma_size; 1248 + int rval, left; 1249 + 1250 + left = 1; 1251 + while (left > 0) { 1252 + dma_size = left * sizeof(*list); 1253 + pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size, 1254 + &pmap_dma, GFP_KERNEL); 1255 + if (!pmap) { 1256 + ql_log(ql_log_warn, vha, 0x113f, 1257 + "%s(%ld): DMA Alloc failed of %ld\n", 1258 + __func__, vha->host_no, dma_size); 1259 + rval = QLA_MEMORY_ALLOC_FAILED; 1260 + goto out; 1261 + } 1262 + 1263 + mc.mb[0] = MBC_PORT_NODE_NAME_LIST; 1264 + mc.mb[1] = BIT_1 | BIT_3; 1265 + mc.mb[2] = MSW(pmap_dma); 1266 + mc.mb[3] = LSW(pmap_dma); 1267 + mc.mb[6] = MSW(MSD(pmap_dma)); 1268 + mc.mb[7] = LSW(MSD(pmap_dma)); 1269 + mc.mb[8] = dma_size; 1270 + mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8; 1271 + mc.in_mb = MBX_0|MBX_1; 1272 + mc.tov = 30; 1273 + mc.flags = MBX_DMA_IN; 1274 + 1275 + rval = qla2x00_mailbox_command(vha, &mc); 1276 + if (rval != QLA_SUCCESS) { 1277 + if ((mc.mb[0] == MBS_COMMAND_ERROR) && 1278 + (mc.mb[1] == 0xA)) { 1279 + left += le16_to_cpu(mc.mb[2]) / 1280 + sizeof(struct qla_port_24xx_data); 1281 + goto restart; 1282 + } 1283 + goto out_free; 1284 + } 1285 + 1286 + left = 0; 1287 + 1288 + list = kzalloc(dma_size, GFP_KERNEL); 1289 + if (!list) { 1290 + ql_log(ql_log_warn, vha, 0x1140, 1291 + "%s(%ld): failed to allocate node names list " 1292 + "structure.\n", __func__, vha->host_no); 1293 + rval = QLA_MEMORY_ALLOC_FAILED; 1294 + goto out_free; 1295 + } 1296 + 1297 + memcpy(list, pmap, dma_size); 1298 + restart: 1299 + dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); 1300 + } 1301 + 1302 + *out_data = list; 1303 + *out_len = dma_size; 1304 + 1305 + out: 1306 + return rval; 1307 + 1308 + out_free: 1309 + dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); 1244 1310 return rval; 1245 1311 } 1246 1312 ··· 1362 1246 dma_addr_t pd_dma; 1363 1247 struct qla_hw_data *ha = vha->hw; 1364 1248 1365 - ql_dbg(ql_dbg_mbx, vha, 0x104f, "Entered %s.\n", __func__); 1249 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x104f, 1250 + "Entered %s.\n", __func__); 1366 1251 1367 1252 pd24 = NULL; 1368 1253 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); ··· 1443 1326 fcport->port_type = FCT_INITIATOR; 1444 1327 else 1445 1328 fcport->port_type = FCT_TARGET; 1329 + 1330 + /* Passback COS information. */ 1331 + fcport->supported_classes = (pd24->flags & PDF_CLASS_2) ? 1332 + FC_COS_CLASS2 : FC_COS_CLASS3; 1333 + 1334 + if (pd24->prli_svc_param_word_3[0] & BIT_7) 1335 + fcport->flags |= FCF_CONF_COMP_SUPPORTED; 1446 1336 } else { 1447 1337 uint64_t zero = 0; 1448 1338 ··· 1502 1378 "Failed=%x mb[0]=%x mb[1]=%x.\n", rval, 1503 1379 mcp->mb[0], mcp->mb[1]); 1504 1380 } else { 1505 - ql_dbg(ql_dbg_mbx, vha, 0x1053, "Done %s.\n", __func__); 1381 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1053, 1382 + "Done %s.\n", __func__); 1506 1383 } 1507 1384 1508 1385 return rval; ··· 1532 1407 mbx_cmd_t mc; 1533 1408 mbx_cmd_t *mcp = &mc; 1534 1409 1535 - ql_dbg(ql_dbg_mbx, vha, 0x1054, "Entered %s.\n", __func__); 1410 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, 1411 + "Entered %s.\n", __func__); 1536 1412 1537 1413 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 1538 1414 mcp->out_mb = MBX_0; ··· 1559 1433 ql_dbg(ql_dbg_mbx, vha, 0x1055, "Failed=%x.\n", rval); 1560 1434 } else { 1561 1435 /*EMPTY*/ 1562 - ql_dbg(ql_dbg_mbx, vha, 0x1056, "Done %s.\n", __func__); 1436 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1056, 1437 + "Done %s.\n", __func__); 1563 1438 } 1564 1439 1565 1440 return rval; ··· 1592 1465 mbx_cmd_t mc; 1593 1466 mbx_cmd_t *mcp = &mc; 1594 1467 1595 - ql_dbg(ql_dbg_mbx, vha, 0x1057, "Entered %s.\n", __func__); 1468 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1057, 1469 + "Entered %s.\n", __func__); 1596 1470 1597 1471 mcp->mb[0] = MBC_GET_PORT_NAME; 1598 1472 mcp->mb[9] = vha->vp_idx; ··· 1627 1499 name[7] = LSB(mcp->mb[7]); 1628 1500 } 1629 1501 1630 - ql_dbg(ql_dbg_mbx, vha, 0x1059, "Done %s.\n", __func__); 1502 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1059, 1503 + "Done %s.\n", __func__); 1631 1504 } 1632 1505 1633 1506 return rval; ··· 1656 1527 mbx_cmd_t mc; 1657 1528 mbx_cmd_t *mcp = &mc; 1658 1529 1659 - ql_dbg(ql_dbg_mbx, vha, 0x105a, "Entered %s.\n", __func__); 1530 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105a, 1531 + "Entered %s.\n", __func__); 1660 1532 1661 1533 if (IS_CNA_CAPABLE(vha->hw)) { 1662 1534 /* Logout across all FCFs. */ ··· 1694 1564 ql_dbg(ql_dbg_mbx, vha, 0x105b, "Failed=%x.\n", rval); 1695 1565 } else { 1696 1566 /*EMPTY*/ 1697 - ql_dbg(ql_dbg_mbx, vha, 0x105c, "Done %s.\n", __func__); 1567 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105c, 1568 + "Done %s.\n", __func__); 1698 1569 } 1699 1570 1700 1571 return rval; ··· 1727 1596 mbx_cmd_t mc; 1728 1597 mbx_cmd_t *mcp = &mc; 1729 1598 1730 - ql_dbg(ql_dbg_mbx, vha, 0x105d, "Entered %s.\n", __func__); 1599 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105d, 1600 + "Entered %s.\n", __func__); 1731 1601 1732 - ql_dbg(ql_dbg_mbx, vha, 0x105e, 1602 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x105e, 1733 1603 "Retry cnt=%d ratov=%d total tov=%d.\n", 1734 1604 vha->hw->retry_count, vha->hw->login_timeout, mcp->tov); 1735 1605 ··· 1754 1622 rval, mcp->mb[0], mcp->mb[1]); 1755 1623 } else { 1756 1624 /*EMPTY*/ 1757 - ql_dbg(ql_dbg_mbx, vha, 0x1060, "Done %s.\n", __func__); 1625 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1060, 1626 + "Done %s.\n", __func__); 1758 1627 } 1759 1628 1760 1629 return rval; ··· 1774 1641 struct req_que *req; 1775 1642 struct rsp_que *rsp; 1776 1643 1777 - ql_dbg(ql_dbg_mbx, vha, 0x1061, "Entered %s.\n", __func__); 1644 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1061, 1645 + "Entered %s.\n", __func__); 1778 1646 1779 1647 if (ha->flags.cpu_affinity_enabled) 1780 1648 req = ha->req_q_map[0]; ··· 1849 1715 break; 1850 1716 } 1851 1717 } else { 1852 - ql_dbg(ql_dbg_mbx, vha, 0x1066, "Done %s.\n", __func__); 1718 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1066, 1719 + "Done %s.\n", __func__); 1853 1720 1854 1721 iop[0] = le32_to_cpu(lg->io_parameter[0]); 1855 1722 ··· 1868 1733 mb[10] |= BIT_0; /* Class 2. */ 1869 1734 if (lg->io_parameter[9] || lg->io_parameter[10]) 1870 1735 mb[10] |= BIT_1; /* Class 3. */ 1736 + if (lg->io_parameter[0] & __constant_cpu_to_le32(BIT_7)) 1737 + mb[10] |= BIT_7; /* Confirmed Completion 1738 + * Allowed 1739 + */ 1871 1740 } 1872 1741 1873 1742 dma_pool_free(ha->s_dma_pool, lg, lg_dma); ··· 1909 1770 mbx_cmd_t *mcp = &mc; 1910 1771 struct qla_hw_data *ha = vha->hw; 1911 1772 1912 - ql_dbg(ql_dbg_mbx, vha, 0x1067, "Entered %s.\n", __func__); 1773 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1067, 1774 + "Entered %s.\n", __func__); 1913 1775 1914 1776 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1915 1777 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; ··· 1958 1818 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 1959 1819 } else { 1960 1820 /*EMPTY*/ 1961 - ql_dbg(ql_dbg_mbx, vha, 0x1069, "Done %s.\n", __func__); 1821 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1069, 1822 + "Done %s.\n", __func__); 1962 1823 } 1963 1824 1964 1825 return rval; ··· 1990 1849 mbx_cmd_t *mcp = &mc; 1991 1850 struct qla_hw_data *ha = vha->hw; 1992 1851 1993 - ql_dbg(ql_dbg_mbx, vha, 0x106a, "Entered %s.\n", __func__); 1852 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106a, 1853 + "Entered %s.\n", __func__); 1994 1854 1995 1855 if (IS_FWI2_CAPABLE(ha)) 1996 1856 return qla24xx_login_fabric(vha, fcport->loop_id, ··· 2033 1891 rval, mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]); 2034 1892 } else { 2035 1893 /*EMPTY*/ 2036 - ql_dbg(ql_dbg_mbx, vha, 0x106c, "Done %s.\n", __func__); 1894 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106c, 1895 + "Done %s.\n", __func__); 2037 1896 } 2038 1897 2039 1898 return (rval); ··· 2051 1908 struct req_que *req; 2052 1909 struct rsp_que *rsp; 2053 1910 2054 - ql_dbg(ql_dbg_mbx, vha, 0x106d, "Entered %s.\n", __func__); 1911 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x106d, 1912 + "Entered %s.\n", __func__); 2055 1913 2056 1914 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 2057 1915 if (lg == NULL) { ··· 2096 1952 le32_to_cpu(lg->io_parameter[1])); 2097 1953 } else { 2098 1954 /*EMPTY*/ 2099 - ql_dbg(ql_dbg_mbx, vha, 0x1072, "Done %s.\n", __func__); 1955 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1072, 1956 + "Done %s.\n", __func__); 2100 1957 } 2101 1958 2102 1959 dma_pool_free(ha->s_dma_pool, lg, lg_dma); ··· 2129 1984 mbx_cmd_t mc; 2130 1985 mbx_cmd_t *mcp = &mc; 2131 1986 2132 - ql_dbg(ql_dbg_mbx, vha, 0x1073, "Entered %s.\n", __func__); 1987 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1073, 1988 + "Entered %s.\n", __func__); 2133 1989 2134 1990 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 2135 1991 mcp->out_mb = MBX_1|MBX_0; ··· 2153 2007 "Failed=%x mb[1]=%x.\n", rval, mcp->mb[1]); 2154 2008 } else { 2155 2009 /*EMPTY*/ 2156 - ql_dbg(ql_dbg_mbx, vha, 0x1075, "Done %s.\n", __func__); 2010 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1075, 2011 + "Done %s.\n", __func__); 2157 2012 } 2158 2013 2159 2014 return rval; ··· 2182 2035 mbx_cmd_t mc; 2183 2036 mbx_cmd_t *mcp = &mc; 2184 2037 2185 - ql_dbg(ql_dbg_mbx, vha, 0x1076, "Entered %s.\n", __func__); 2038 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1076, 2039 + "Entered %s.\n", __func__); 2186 2040 2187 2041 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 2188 2042 mcp->mb[1] = IS_FWI2_CAPABLE(vha->hw) ? BIT_3 : 0; ··· 2200 2052 ql_dbg(ql_dbg_mbx, vha, 0x1077, "Failed=%x.\n", rval); 2201 2053 } else { 2202 2054 /*EMPTY*/ 2203 - ql_dbg(ql_dbg_mbx, vha, 0x1078, "Done %s.\n", __func__); 2055 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1078, 2056 + "Done %s.\n", __func__); 2204 2057 } 2205 2058 2206 2059 return rval; ··· 2227 2078 mbx_cmd_t mc; 2228 2079 mbx_cmd_t *mcp = &mc; 2229 2080 2230 - ql_dbg(ql_dbg_mbx, vha, 0x1079, "Entered %s.\n", __func__); 2081 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1079, 2082 + "Entered %s.\n", __func__); 2231 2083 2232 2084 if (id_list == NULL) 2233 2085 return QLA_FUNCTION_FAILED; ··· 2260 2110 ql_dbg(ql_dbg_mbx, vha, 0x107a, "Failed=%x.\n", rval); 2261 2111 } else { 2262 2112 *entries = mcp->mb[1]; 2263 - ql_dbg(ql_dbg_mbx, vha, 0x107b, "Done %s.\n", __func__); 2113 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107b, 2114 + "Done %s.\n", __func__); 2264 2115 } 2265 2116 2266 2117 return rval; ··· 2289 2138 mbx_cmd_t mc; 2290 2139 mbx_cmd_t *mcp = &mc; 2291 2140 2292 - ql_dbg(ql_dbg_mbx, vha, 0x107c, "Entered %s.\n", __func__); 2141 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107c, 2142 + "Entered %s.\n", __func__); 2293 2143 2294 2144 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; 2295 2145 mcp->out_mb = MBX_0; ··· 2306 2154 ql_dbg(ql_dbg_mbx, vha, 0x107d, 2307 2155 "Failed mb[0]=%x.\n", mcp->mb[0]); 2308 2156 } else { 2309 - ql_dbg(ql_dbg_mbx, vha, 0x107e, 2157 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107e, 2310 2158 "Done %s mb1=%x mb2=%x mb3=%x mb6=%x mb7=%x mb10=%x " 2311 2159 "mb11=%x mb12=%x.\n", __func__, mcp->mb[1], mcp->mb[2], 2312 2160 mcp->mb[3], mcp->mb[6], mcp->mb[7], mcp->mb[10], ··· 2353 2201 dma_addr_t pmap_dma; 2354 2202 struct qla_hw_data *ha = vha->hw; 2355 2203 2356 - ql_dbg(ql_dbg_mbx, vha, 0x107f, "Entered %s.\n", __func__); 2204 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x107f, 2205 + "Entered %s.\n", __func__); 2357 2206 2358 2207 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pmap_dma); 2359 2208 if (pmap == NULL) { ··· 2377 2224 rval = qla2x00_mailbox_command(vha, mcp); 2378 2225 2379 2226 if (rval == QLA_SUCCESS) { 2380 - ql_dbg(ql_dbg_mbx, vha, 0x1081, 2227 + ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1081, 2381 2228 "mb0/mb1=%x/%X FC/AL position map size (%x).\n", 2382 2229 mcp->mb[0], mcp->mb[1], (unsigned)pmap[0]); 2383 2230 ql_dump_buffer(ql_dbg_mbx + ql_dbg_buffer, vha, 0x111d, ··· 2391 2238 if (rval != QLA_SUCCESS) { 2392 2239 ql_dbg(ql_dbg_mbx, vha, 0x1082, "Failed=%x.\n", rval); 2393 2240 } else { 2394 - ql_dbg(ql_dbg_mbx, vha, 0x1083, "Done %s.\n", __func__); 2241 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1083, 2242 + "Done %s.\n", __func__); 2395 2243 } 2396 2244 2397 2245 return rval; ··· 2421 2267 uint32_t *siter, *diter, dwords; 2422 2268 struct qla_hw_data *ha = vha->hw; 2423 2269 2424 - ql_dbg(ql_dbg_mbx, vha, 0x1084, "Entered %s.\n", __func__); 2270 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1084, 2271 + "Entered %s.\n", __func__); 2425 2272 2426 2273 mcp->mb[0] = MBC_GET_LINK_STATUS; 2427 2274 mcp->mb[2] = MSW(stats_dma); ··· 2456 2301 rval = QLA_FUNCTION_FAILED; 2457 2302 } else { 2458 2303 /* Copy over data -- firmware data is LE. */ 2459 - ql_dbg(ql_dbg_mbx, vha, 0x1086, "Done %s.\n", __func__); 2304 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1086, 2305 + "Done %s.\n", __func__); 2460 2306 dwords = offsetof(struct link_statistics, unused1) / 4; 2461 2307 siter = diter = &stats->link_fail_cnt; 2462 2308 while (dwords--) ··· 2480 2324 mbx_cmd_t *mcp = &mc; 2481 2325 uint32_t *siter, *diter, dwords; 2482 2326 2483 - ql_dbg(ql_dbg_mbx, vha, 0x1088, "Entered %s.\n", __func__); 2327 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1088, 2328 + "Entered %s.\n", __func__); 2484 2329 2485 2330 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; 2486 2331 mcp->mb[2] = MSW(stats_dma); ··· 2503 2346 "Failed mb[0]=%x.\n", mcp->mb[0]); 2504 2347 rval = QLA_FUNCTION_FAILED; 2505 2348 } else { 2506 - ql_dbg(ql_dbg_mbx, vha, 0x108a, "Done %s.\n", __func__); 2349 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108a, 2350 + "Done %s.\n", __func__); 2507 2351 /* Copy over data -- firmware data is LE. */ 2508 2352 dwords = sizeof(struct link_statistics) / 4; 2509 2353 siter = diter = &stats->link_fail_cnt; ··· 2533 2375 struct qla_hw_data *ha = vha->hw; 2534 2376 struct req_que *req = vha->req; 2535 2377 2536 - ql_dbg(ql_dbg_mbx, vha, 0x108c, "Entered %s.\n", __func__); 2378 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x108c, 2379 + "Entered %s.\n", __func__); 2537 2380 2538 2381 spin_lock_irqsave(&ha->hardware_lock, flags); 2539 2382 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { ··· 2563 2404 abt->port_id[0] = fcport->d_id.b.al_pa; 2564 2405 abt->port_id[1] = fcport->d_id.b.area; 2565 2406 abt->port_id[2] = fcport->d_id.b.domain; 2566 - abt->vp_index = fcport->vp_idx; 2407 + abt->vp_index = fcport->vha->vp_idx; 2567 2408 2568 2409 abt->req_que_no = cpu_to_le16(req->id); 2569 2410 ··· 2582 2423 le16_to_cpu(abt->nport_handle)); 2583 2424 rval = QLA_FUNCTION_FAILED; 2584 2425 } else { 2585 - ql_dbg(ql_dbg_mbx, vha, 0x1091, "Done %s.\n", __func__); 2426 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, 2427 + "Done %s.\n", __func__); 2586 2428 } 2587 2429 2588 2430 dma_pool_free(ha->s_dma_pool, abt, abt_dma); ··· 2615 2455 ha = vha->hw; 2616 2456 req = vha->req; 2617 2457 2618 - ql_dbg(ql_dbg_mbx, vha, 0x1092, "Entered %s.\n", __func__); 2458 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1092, 2459 + "Entered %s.\n", __func__); 2619 2460 2620 2461 if (ha->flags.cpu_affinity_enabled) 2621 2462 rsp = ha->rsp_q_map[tag + 1]; ··· 2639 2478 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; 2640 2479 tsk->p.tsk.port_id[1] = fcport->d_id.b.area; 2641 2480 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; 2642 - tsk->p.tsk.vp_index = fcport->vp_idx; 2481 + tsk->p.tsk.vp_index = fcport->vha->vp_idx; 2643 2482 if (type == TCF_LUN_RESET) { 2644 2483 int_to_scsilun(l, &tsk->p.tsk.lun); 2645 2484 host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun, ··· 2665 2504 } else if (le16_to_cpu(sts->scsi_status) & 2666 2505 SS_RESPONSE_INFO_LEN_VALID) { 2667 2506 if (le32_to_cpu(sts->rsp_data_len) < 4) { 2668 - ql_dbg(ql_dbg_mbx, vha, 0x1097, 2507 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1097, 2669 2508 "Ignoring inconsistent data length -- not enough " 2670 2509 "response info (%d).\n", 2671 2510 le32_to_cpu(sts->rsp_data_len)); ··· 2684 2523 ql_dbg(ql_dbg_mbx, vha, 0x1099, 2685 2524 "Failed to issue marker IOCB (%x).\n", rval2); 2686 2525 } else { 2687 - ql_dbg(ql_dbg_mbx, vha, 0x109a, "Done %s.\n", __func__); 2526 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109a, 2527 + "Done %s.\n", __func__); 2688 2528 } 2689 2529 2690 2530 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); ··· 2726 2564 if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) 2727 2565 return QLA_FUNCTION_FAILED; 2728 2566 2729 - ql_dbg(ql_dbg_mbx, vha, 0x109b, "Entered %s.\n", __func__); 2567 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109b, 2568 + "Entered %s.\n", __func__); 2730 2569 2731 2570 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; 2732 2571 mcp->out_mb = MBX_0; ··· 2739 2576 if (rval != QLA_SUCCESS) { 2740 2577 ql_dbg(ql_dbg_mbx, vha, 0x109c, "Failed=%x.\n", rval); 2741 2578 } else { 2742 - ql_dbg(ql_dbg_mbx, vha, 0x109d, "Done %s.\n", __func__); 2579 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109d, 2580 + "Done %s.\n", __func__); 2743 2581 } 2744 2582 2745 2583 return rval; ··· 2760 2596 mbx_cmd_t mc; 2761 2597 mbx_cmd_t *mcp = &mc; 2762 2598 2763 - ql_dbg(ql_dbg_mbx, vha, 0x109e, "Entered %s.\n", __func__); 2599 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x109e, 2600 + "Entered %s.\n", __func__); 2764 2601 2765 2602 mcp->mb[0] = MBC_SERDES_PARAMS; 2766 2603 mcp->mb[1] = BIT_0; ··· 2780 2615 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 2781 2616 } else { 2782 2617 /*EMPTY*/ 2783 - ql_dbg(ql_dbg_mbx, vha, 0x10a0, "Done %s.\n", __func__); 2618 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a0, 2619 + "Done %s.\n", __func__); 2784 2620 } 2785 2621 2786 2622 return rval; ··· 2797 2631 if (!IS_FWI2_CAPABLE(vha->hw)) 2798 2632 return QLA_FUNCTION_FAILED; 2799 2633 2800 - ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__); 2634 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a1, 2635 + "Entered %s.\n", __func__); 2801 2636 2802 2637 mcp->mb[0] = MBC_STOP_FIRMWARE; 2803 2638 mcp->mb[1] = 0; ··· 2813 2646 if (mcp->mb[0] == MBS_INVALID_COMMAND) 2814 2647 rval = QLA_INVALID_COMMAND; 2815 2648 } else { 2816 - ql_dbg(ql_dbg_mbx, vha, 0x10a3, "Done %s.\n", __func__); 2649 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a3, 2650 + "Done %s.\n", __func__); 2817 2651 } 2818 2652 2819 2653 return rval; ··· 2828 2660 mbx_cmd_t mc; 2829 2661 mbx_cmd_t *mcp = &mc; 2830 2662 2831 - ql_dbg(ql_dbg_mbx, vha, 0x10a4, "Entered %s.\n", __func__); 2663 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a4, 2664 + "Entered %s.\n", __func__); 2832 2665 2833 2666 if (!IS_FWI2_CAPABLE(vha->hw)) 2834 2667 return QLA_FUNCTION_FAILED; ··· 2855 2686 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2856 2687 rval, mcp->mb[0], mcp->mb[1]); 2857 2688 } else { 2858 - ql_dbg(ql_dbg_mbx, vha, 0x10a6, "Done %s.\n", __func__); 2689 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a6, 2690 + "Done %s.\n", __func__); 2859 2691 } 2860 2692 2861 2693 return rval; ··· 2869 2699 mbx_cmd_t mc; 2870 2700 mbx_cmd_t *mcp = &mc; 2871 2701 2872 - ql_dbg(ql_dbg_mbx, vha, 0x10a7, "Entered %s.\n", __func__); 2702 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a7, 2703 + "Entered %s.\n", __func__); 2873 2704 2874 2705 if (!IS_FWI2_CAPABLE(vha->hw)) 2875 2706 return QLA_FUNCTION_FAILED; ··· 2890 2719 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2891 2720 rval, mcp->mb[0], mcp->mb[1]); 2892 2721 } else { 2893 - ql_dbg(ql_dbg_mbx, vha, 0x10a9, "Done %s.\n", __func__); 2722 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10a9, 2723 + "Done %s.\n", __func__); 2894 2724 } 2895 2725 2896 2726 return rval; ··· 2905 2733 mbx_cmd_t mc; 2906 2734 mbx_cmd_t *mcp = &mc; 2907 2735 2908 - ql_dbg(ql_dbg_mbx, vha, 0x10aa, "Entered %s.\n", __func__); 2736 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10aa, 2737 + "Entered %s.\n", __func__); 2909 2738 2910 2739 if (!IS_QLA25XX(vha->hw) && !IS_QLA81XX(vha->hw) && 2911 2740 !IS_QLA83XX(vha->hw)) ··· 2937 2764 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2938 2765 rval, mcp->mb[0], mcp->mb[1]); 2939 2766 } else { 2940 - ql_dbg(ql_dbg_mbx, vha, 0x10ac, "Done %s.\n", __func__); 2767 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ac, 2768 + "Done %s.\n", __func__); 2941 2769 2942 2770 if (mb) 2943 2771 memcpy(mb, mcp->mb, 8 * sizeof(*mb)); ··· 2956 2782 mbx_cmd_t mc; 2957 2783 mbx_cmd_t *mcp = &mc; 2958 2784 2959 - ql_dbg(ql_dbg_mbx, vha, 0x10ad, "Entered %s.\n", __func__); 2785 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ad, 2786 + "Entered %s.\n", __func__); 2960 2787 2961 2788 if (!IS_FWI2_CAPABLE(vha->hw)) 2962 2789 return QLA_FUNCTION_FAILED; ··· 2979 2804 "Failed=%x mb[0]=%x mb[1]=%x.\n", 2980 2805 rval, mcp->mb[0], mcp->mb[1]); 2981 2806 } else { 2982 - ql_dbg(ql_dbg_mbx, vha, 0x10af, "Done %s.\n", __func__); 2807 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10af, 2808 + "Done %s.\n", __func__); 2983 2809 2984 2810 if (wr) 2985 2811 *wr = (uint64_t) mcp->mb[5] << 48 | ··· 3005 2829 mbx_cmd_t mc; 3006 2830 mbx_cmd_t *mcp = &mc; 3007 2831 3008 - ql_dbg(ql_dbg_mbx, vha, 0x10b0, "Entered %s.\n", __func__); 2832 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b0, 2833 + "Entered %s.\n", __func__); 3009 2834 3010 2835 if (!IS_IIDMA_CAPABLE(vha->hw)) 3011 2836 return QLA_FUNCTION_FAILED; ··· 3031 2854 if (rval != QLA_SUCCESS) { 3032 2855 ql_dbg(ql_dbg_mbx, vha, 0x10b1, "Failed=%x.\n", rval); 3033 2856 } else { 3034 - ql_dbg(ql_dbg_mbx, vha, 0x10b2, "Done %s.\n", __func__); 2857 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b2, 2858 + "Done %s.\n", __func__); 3035 2859 if (port_speed) 3036 2860 *port_speed = mcp->mb[3]; 3037 2861 } ··· 3048 2870 mbx_cmd_t mc; 3049 2871 mbx_cmd_t *mcp = &mc; 3050 2872 3051 - ql_dbg(ql_dbg_mbx, vha, 0x10b3, "Entered %s.\n", __func__); 2873 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b3, 2874 + "Entered %s.\n", __func__); 3052 2875 3053 2876 if (!IS_IIDMA_CAPABLE(vha->hw)) 3054 2877 return QLA_FUNCTION_FAILED; ··· 3076 2897 } 3077 2898 3078 2899 if (rval != QLA_SUCCESS) { 3079 - ql_dbg(ql_dbg_mbx, vha, 0x10b4, "Failed=%x.\n", rval); 2900 + ql_dbg(ql_dbg_mbx, vha, 0x10b4, 2901 + "Failed=%x.\n", rval); 3080 2902 } else { 3081 - ql_dbg(ql_dbg_mbx, vha, 0x10b5, "Done %s.\n", __func__); 2903 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b5, 2904 + "Done %s.\n", __func__); 3082 2905 } 3083 2906 3084 2907 return rval; ··· 3096 2915 scsi_qla_host_t *vp; 3097 2916 unsigned long flags; 3098 2917 3099 - ql_dbg(ql_dbg_mbx, vha, 0x10b6, "Entered %s.\n", __func__); 2918 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, 2919 + "Entered %s.\n", __func__); 3100 2920 3101 2921 if (rptid_entry->entry_status != 0) 3102 2922 return; 3103 2923 3104 2924 if (rptid_entry->format == 0) { 3105 - ql_dbg(ql_dbg_mbx, vha, 0x10b7, 2925 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7, 3106 2926 "Format 0 : Number of VPs setup %d, number of " 3107 2927 "VPs acquired %d.\n", 3108 2928 MSB(le16_to_cpu(rptid_entry->vp_count)), 3109 2929 LSB(le16_to_cpu(rptid_entry->vp_count))); 3110 - ql_dbg(ql_dbg_mbx, vha, 0x10b8, 2930 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b8, 3111 2931 "Primary port id %02x%02x%02x.\n", 3112 2932 rptid_entry->port_id[2], rptid_entry->port_id[1], 3113 2933 rptid_entry->port_id[0]); 3114 2934 } else if (rptid_entry->format == 1) { 3115 2935 vp_idx = LSB(stat); 3116 - ql_dbg(ql_dbg_mbx, vha, 0x10b9, 2936 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b9, 3117 2937 "Format 1: VP[%d] enabled - status %d - with " 3118 2938 "port id %02x%02x%02x.\n", vp_idx, MSB(stat), 3119 2939 rptid_entry->port_id[2], rptid_entry->port_id[1], ··· 3181 2999 3182 3000 /* This can be called by the parent */ 3183 3001 3184 - ql_dbg(ql_dbg_mbx, vha, 0x10bb, "Entered %s.\n", __func__); 3002 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10bb, 3003 + "Entered %s.\n", __func__); 3185 3004 3186 3005 vpmod = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &vpmod_dma); 3187 3006 if (!vpmod) { ··· 3198 3015 vpmod->vp_count = 1; 3199 3016 vpmod->vp_index1 = vha->vp_idx; 3200 3017 vpmod->options_idx1 = BIT_3|BIT_4|BIT_5; 3018 + 3019 + qlt_modify_vp_config(vha, vpmod); 3020 + 3201 3021 memcpy(vpmod->node_name_idx1, vha->node_name, WWN_SIZE); 3202 3022 memcpy(vpmod->port_name_idx1, vha->port_name, WWN_SIZE); 3203 3023 vpmod->entry_count = 1; ··· 3221 3035 rval = QLA_FUNCTION_FAILED; 3222 3036 } else { 3223 3037 /* EMPTY */ 3224 - ql_dbg(ql_dbg_mbx, vha, 0x10c0, "Done %s.\n", __func__); 3038 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c0, 3039 + "Done %s.\n", __func__); 3225 3040 fc_vport_set_state(vha->fc_vport, FC_VPORT_INITIALIZING); 3226 3041 } 3227 3042 dma_pool_free(ha->s_dma_pool, vpmod, vpmod_dma); ··· 3256 3069 int vp_index = vha->vp_idx; 3257 3070 struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); 3258 3071 3259 - ql_dbg(ql_dbg_mbx, vha, 0x10c1, 3072 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c1, 3260 3073 "Entered %s enabling index %d.\n", __func__, vp_index); 3261 3074 3262 3075 if (vp_index == 0 || vp_index >= ha->max_npiv_vports) ··· 3299 3112 le16_to_cpu(vce->comp_status)); 3300 3113 rval = QLA_FUNCTION_FAILED; 3301 3114 } else { 3302 - ql_dbg(ql_dbg_mbx, vha, 0x10c6, "Done %s.\n", __func__); 3115 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c6, 3116 + "Done %s.\n", __func__); 3303 3117 } 3304 3118 3305 3119 dma_pool_free(ha->s_dma_pool, vce, vce_dma); ··· 3337 3149 mbx_cmd_t mc; 3338 3150 mbx_cmd_t *mcp = &mc; 3339 3151 3340 - ql_dbg(ql_dbg_mbx, vha, 0x10c7, "Entered %s.\n", __func__); 3341 - 3342 - /* 3343 - * This command is implicitly executed by firmware during login for the 3344 - * physical hosts 3345 - */ 3346 - if (vp_idx == 0) 3347 - return QLA_FUNCTION_FAILED; 3152 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c7, 3153 + "Entered %s.\n", __func__); 3348 3154 3349 3155 mcp->mb[0] = MBC_SEND_CHANGE_REQUEST; 3350 3156 mcp->mb[1] = format; ··· 3367 3185 mbx_cmd_t mc; 3368 3186 mbx_cmd_t *mcp = &mc; 3369 3187 3370 - ql_dbg(ql_dbg_mbx, vha, 0x1009, "Entered %s.\n", __func__); 3188 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1009, 3189 + "Entered %s.\n", __func__); 3371 3190 3372 3191 if (MSW(addr) || IS_FWI2_CAPABLE(vha->hw)) { 3373 3192 mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; ··· 3402 3219 ql_dbg(ql_dbg_mbx, vha, 0x1008, 3403 3220 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3404 3221 } else { 3405 - ql_dbg(ql_dbg_mbx, vha, 0x1007, "Done %s.\n", __func__); 3222 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1007, 3223 + "Done %s.\n", __func__); 3406 3224 } 3407 3225 3408 3226 return rval; ··· 3428 3244 unsigned long flags; 3429 3245 struct qla_hw_data *ha = vha->hw; 3430 3246 3431 - ql_dbg(ql_dbg_mbx, vha, 0x10c8, "Entered %s.\n", __func__); 3247 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10c8, 3248 + "Entered %s.\n", __func__); 3432 3249 3433 3250 mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); 3434 3251 if (mn == NULL) { ··· 3470 3285 status[0] = le16_to_cpu(mn->p.rsp.comp_status); 3471 3286 status[1] = status[0] == CS_VCS_CHIP_FAILURE ? 3472 3287 le16_to_cpu(mn->p.rsp.failure_code) : 0; 3473 - ql_dbg(ql_dbg_mbx, vha, 0x10ce, 3288 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ce, 3474 3289 "cs=%x fc=%x.\n", status[0], status[1]); 3475 3290 3476 3291 if (status[0] != CS_COMPLETE) { ··· 3484 3299 retry = 1; 3485 3300 } 3486 3301 } else { 3487 - ql_dbg(ql_dbg_mbx, vha, 0x10d0, 3302 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d0, 3488 3303 "Firmware updated to %x.\n", 3489 3304 le32_to_cpu(mn->p.rsp.fw_ver)); 3490 3305 ··· 3501 3316 dma_pool_free(ha->s_dma_pool, mn, mn_dma); 3502 3317 3503 3318 if (rval != QLA_SUCCESS) { 3504 - ql_dbg(ql_dbg_mbx, vha, 0x10d1, "Failed=%x.\n", rval); 3319 + ql_dbg(ql_dbg_mbx, vha, 0x10d1, 3320 + "Failed=%x.\n", rval); 3505 3321 } else { 3506 - ql_dbg(ql_dbg_mbx, vha, 0x10d2, "Done %s.\n", __func__); 3322 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d2, 3323 + "Done %s.\n", __func__); 3507 3324 } 3508 3325 3509 3326 return rval; ··· 3521 3334 struct device_reg_25xxmq __iomem *reg; 3522 3335 struct qla_hw_data *ha = vha->hw; 3523 3336 3524 - ql_dbg(ql_dbg_mbx, vha, 0x10d3, "Entered %s.\n", __func__); 3337 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, 3338 + "Entered %s.\n", __func__); 3525 3339 3526 3340 mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 3527 3341 mcp->mb[1] = req->options; ··· 3576 3388 ql_dbg(ql_dbg_mbx, vha, 0x10d4, 3577 3389 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3578 3390 } else { 3579 - ql_dbg(ql_dbg_mbx, vha, 0x10d5, "Done %s.\n", __func__); 3391 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d5, 3392 + "Done %s.\n", __func__); 3580 3393 } 3581 3394 3582 3395 return rval; ··· 3593 3404 struct device_reg_25xxmq __iomem *reg; 3594 3405 struct qla_hw_data *ha = vha->hw; 3595 3406 3596 - ql_dbg(ql_dbg_mbx, vha, 0x10d6, "Entered %s.\n", __func__); 3407 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, 3408 + "Entered %s.\n", __func__); 3597 3409 3598 3410 mcp->mb[0] = MBC_INITIALIZE_MULTIQ; 3599 3411 mcp->mb[1] = rsp->options; ··· 3646 3456 ql_dbg(ql_dbg_mbx, vha, 0x10d7, 3647 3457 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3648 3458 } else { 3649 - ql_dbg(ql_dbg_mbx, vha, 0x10d8, "Done %s.\n", __func__); 3459 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d8, 3460 + "Done %s.\n", __func__); 3650 3461 } 3651 3462 3652 3463 return rval; ··· 3660 3469 mbx_cmd_t mc; 3661 3470 mbx_cmd_t *mcp = &mc; 3662 3471 3663 - ql_dbg(ql_dbg_mbx, vha, 0x10d9, "Entered %s.\n", __func__); 3472 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d9, 3473 + "Entered %s.\n", __func__); 3664 3474 3665 3475 mcp->mb[0] = MBC_IDC_ACK; 3666 3476 memcpy(&mcp->mb[1], mb, QLA_IDC_ACK_REGS * sizeof(uint16_t)); ··· 3675 3483 ql_dbg(ql_dbg_mbx, vha, 0x10da, 3676 3484 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3677 3485 } else { 3678 - ql_dbg(ql_dbg_mbx, vha, 0x10db, "Done %s.\n", __func__); 3486 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10db, 3487 + "Done %s.\n", __func__); 3679 3488 } 3680 3489 3681 3490 return rval; ··· 3689 3496 mbx_cmd_t mc; 3690 3497 mbx_cmd_t *mcp = &mc; 3691 3498 3692 - ql_dbg(ql_dbg_mbx, vha, 0x10dc, "Entered %s.\n", __func__); 3499 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10dc, 3500 + "Entered %s.\n", __func__); 3693 3501 3694 3502 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) 3695 3503 return QLA_FUNCTION_FAILED; ··· 3708 3514 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3709 3515 rval, mcp->mb[0], mcp->mb[1]); 3710 3516 } else { 3711 - ql_dbg(ql_dbg_mbx, vha, 0x10de, "Done %s.\n", __func__); 3517 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10de, 3518 + "Done %s.\n", __func__); 3712 3519 *sector_size = mcp->mb[1]; 3713 3520 } 3714 3521 ··· 3726 3531 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) 3727 3532 return QLA_FUNCTION_FAILED; 3728 3533 3729 - ql_dbg(ql_dbg_mbx, vha, 0x10df, "Entered %s.\n", __func__); 3534 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10df, 3535 + "Entered %s.\n", __func__); 3730 3536 3731 3537 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 3732 3538 mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE : ··· 3743 3547 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3744 3548 rval, mcp->mb[0], mcp->mb[1]); 3745 3549 } else { 3746 - ql_dbg(ql_dbg_mbx, vha, 0x10e1, "Done %s.\n", __func__); 3550 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e1, 3551 + "Done %s.\n", __func__); 3747 3552 } 3748 3553 3749 3554 return rval; ··· 3760 3563 if (!IS_QLA81XX(vha->hw) && !IS_QLA83XX(vha->hw)) 3761 3564 return QLA_FUNCTION_FAILED; 3762 3565 3763 - ql_dbg(ql_dbg_mbx, vha, 0x10e2, "Entered %s.\n", __func__); 3566 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e2, 3567 + "Entered %s.\n", __func__); 3764 3568 3765 3569 mcp->mb[0] = MBC_FLASH_ACCESS_CTRL; 3766 3570 mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR; ··· 3780 3582 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 3781 3583 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 3782 3584 } else { 3783 - ql_dbg(ql_dbg_mbx, vha, 0x10e4, "Done %s.\n", __func__); 3585 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e4, 3586 + "Done %s.\n", __func__); 3784 3587 } 3785 3588 3786 3589 return rval; ··· 3794 3595 mbx_cmd_t mc; 3795 3596 mbx_cmd_t *mcp = &mc; 3796 3597 3797 - ql_dbg(ql_dbg_mbx, vha, 0x10e5, "Entered %s.\n", __func__); 3598 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e5, 3599 + "Entered %s.\n", __func__); 3798 3600 3799 3601 mcp->mb[0] = MBC_RESTART_MPI_FW; 3800 3602 mcp->out_mb = MBX_0; ··· 3809 3609 "Failed=%x mb[0]=%x mb[1]=%x.\n", 3810 3610 rval, mcp->mb[0], mcp->mb[1]); 3811 3611 } else { 3812 - ql_dbg(ql_dbg_mbx, vha, 0x10e7, "Done %s.\n", __func__); 3612 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e7, 3613 + "Done %s.\n", __func__); 3813 3614 } 3814 3615 3815 3616 return rval; ··· 3825 3624 mbx_cmd_t *mcp = &mc; 3826 3625 struct qla_hw_data *ha = vha->hw; 3827 3626 3828 - ql_dbg(ql_dbg_mbx, vha, 0x10e8, "Entered %s.\n", __func__); 3627 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10e8, 3628 + "Entered %s.\n", __func__); 3829 3629 3830 3630 if (!IS_FWI2_CAPABLE(ha)) 3831 3631 return QLA_FUNCTION_FAILED; ··· 3856 3654 ql_dbg(ql_dbg_mbx, vha, 0x10e9, 3857 3655 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3858 3656 } else { 3859 - ql_dbg(ql_dbg_mbx, vha, 0x10ea, "Done %s.\n", __func__); 3657 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ea, 3658 + "Done %s.\n", __func__); 3860 3659 } 3861 3660 3862 3661 return rval; ··· 3872 3669 mbx_cmd_t *mcp = &mc; 3873 3670 struct qla_hw_data *ha = vha->hw; 3874 3671 3875 - ql_dbg(ql_dbg_mbx, vha, 0x10eb, "Entered %s.\n", __func__); 3672 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10eb, 3673 + "Entered %s.\n", __func__); 3876 3674 3877 3675 if (!IS_FWI2_CAPABLE(ha)) 3878 3676 return QLA_FUNCTION_FAILED; ··· 3903 3699 ql_dbg(ql_dbg_mbx, vha, 0x10ec, 3904 3700 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 3905 3701 } else { 3906 - ql_dbg(ql_dbg_mbx, vha, 0x10ed, "Done %s.\n", __func__); 3702 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ed, 3703 + "Done %s.\n", __func__); 3907 3704 } 3908 3705 3909 3706 return rval; ··· 3918 3713 mbx_cmd_t mc; 3919 3714 mbx_cmd_t *mcp = &mc; 3920 3715 3921 - ql_dbg(ql_dbg_mbx, vha, 0x10ee, "Entered %s.\n", __func__); 3716 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ee, 3717 + "Entered %s.\n", __func__); 3922 3718 3923 3719 if (!IS_CNA_CAPABLE(vha->hw)) 3924 3720 return QLA_FUNCTION_FAILED; ··· 3941 3735 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 3942 3736 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 3943 3737 } else { 3944 - ql_dbg(ql_dbg_mbx, vha, 0x10f0, "Done %s.\n", __func__); 3738 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f0, 3739 + "Done %s.\n", __func__); 3945 3740 3946 3741 3947 3742 *actual_size = mcp->mb[2] << 2; ··· 3959 3752 mbx_cmd_t mc; 3960 3753 mbx_cmd_t *mcp = &mc; 3961 3754 3962 - ql_dbg(ql_dbg_mbx, vha, 0x10f1, "Entered %s.\n", __func__); 3755 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f1, 3756 + "Entered %s.\n", __func__); 3963 3757 3964 3758 if (!IS_CNA_CAPABLE(vha->hw)) 3965 3759 return QLA_FUNCTION_FAILED; ··· 3983 3775 "Failed=%x mb[0]=%x mb[1]=%x mb[2]=%x.\n", 3984 3776 rval, mcp->mb[0], mcp->mb[1], mcp->mb[2]); 3985 3777 } else { 3986 - ql_dbg(ql_dbg_mbx, vha, 0x10f3, "Done %s.\n", __func__); 3778 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f3, 3779 + "Done %s.\n", __func__); 3987 3780 } 3988 3781 3989 3782 return rval; ··· 3997 3788 mbx_cmd_t mc; 3998 3789 mbx_cmd_t *mcp = &mc; 3999 3790 4000 - ql_dbg(ql_dbg_mbx, vha, 0x10f4, "Entered %s.\n", __func__); 3791 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f4, 3792 + "Entered %s.\n", __func__); 4001 3793 4002 3794 if (!IS_FWI2_CAPABLE(vha->hw)) 4003 3795 return QLA_FUNCTION_FAILED; ··· 4015 3805 ql_dbg(ql_dbg_mbx, vha, 0x10f5, 4016 3806 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4017 3807 } else { 4018 - ql_dbg(ql_dbg_mbx, vha, 0x10f6, "Done %s.\n", __func__); 3808 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f6, 3809 + "Done %s.\n", __func__); 4019 3810 *data = mcp->mb[3] << 16 | mcp->mb[2]; 4020 3811 } 4021 3812 ··· 4032 3821 mbx_cmd_t *mcp = &mc; 4033 3822 uint32_t iter_cnt = 0x1; 4034 3823 4035 - ql_dbg(ql_dbg_mbx, vha, 0x10f7, "Entered %s.\n", __func__); 3824 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f7, 3825 + "Entered %s.\n", __func__); 4036 3826 4037 3827 memset(mcp->mb, 0 , sizeof(mcp->mb)); 4038 3828 mcp->mb[0] = MBC_DIAGNOSTIC_LOOP_BACK; ··· 4077 3865 "mb[19]=%x.\n", rval, mcp->mb[0], mcp->mb[1], mcp->mb[2], 4078 3866 mcp->mb[3], mcp->mb[18], mcp->mb[19]); 4079 3867 } else { 4080 - ql_dbg(ql_dbg_mbx, vha, 0x10f9, "Done %s.\n", __func__); 3868 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10f9, 3869 + "Done %s.\n", __func__); 4081 3870 } 4082 3871 4083 3872 /* Copy mailbox information */ ··· 4095 3882 mbx_cmd_t *mcp = &mc; 4096 3883 struct qla_hw_data *ha = vha->hw; 4097 3884 4098 - ql_dbg(ql_dbg_mbx, vha, 0x10fa, "Entered %s.\n", __func__); 3885 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fa, 3886 + "Entered %s.\n", __func__); 4099 3887 4100 3888 memset(mcp->mb, 0 , sizeof(mcp->mb)); 4101 3889 mcp->mb[0] = MBC_DIAGNOSTIC_ECHO; ··· 4140 3926 "Failed=%x mb[0]=%x mb[1]=%x.\n", 4141 3927 rval, mcp->mb[0], mcp->mb[1]); 4142 3928 } else { 4143 - ql_dbg(ql_dbg_mbx, vha, 0x10fc, "Done %s.\n", __func__); 3929 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fc, 3930 + "Done %s.\n", __func__); 4144 3931 } 4145 3932 4146 3933 /* Copy mailbox information */ ··· 4156 3941 mbx_cmd_t mc; 4157 3942 mbx_cmd_t *mcp = &mc; 4158 3943 4159 - ql_dbg(ql_dbg_mbx, vha, 0x10fd, 3944 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10fd, 4160 3945 "Entered %s enable_diag=%d.\n", __func__, enable_diagnostic); 4161 3946 4162 3947 mcp->mb[0] = MBC_ISP84XX_RESET; ··· 4170 3955 if (rval != QLA_SUCCESS) 4171 3956 ql_dbg(ql_dbg_mbx, vha, 0x10fe, "Failed=%x.\n", rval); 4172 3957 else 4173 - ql_dbg(ql_dbg_mbx, vha, 0x10ff, "Done %s.\n", __func__); 3958 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ff, 3959 + "Done %s.\n", __func__); 4174 3960 4175 3961 return rval; 4176 3962 } ··· 4183 3967 mbx_cmd_t mc; 4184 3968 mbx_cmd_t *mcp = &mc; 4185 3969 4186 - ql_dbg(ql_dbg_mbx, vha, 0x1100, "Entered %s.\n", __func__); 3970 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1100, 3971 + "Entered %s.\n", __func__); 4187 3972 4188 3973 if (!IS_FWI2_CAPABLE(vha->hw)) 4189 3974 return QLA_FUNCTION_FAILED; ··· 4203 3986 ql_dbg(ql_dbg_mbx, vha, 0x1101, 4204 3987 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4205 3988 } else { 4206 - ql_dbg(ql_dbg_mbx, vha, 0x1102, "Done %s.\n", __func__); 3989 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1102, 3990 + "Done %s.\n", __func__); 4207 3991 } 4208 3992 4209 3993 return rval; ··· 4221 4003 4222 4004 rval = QLA_SUCCESS; 4223 4005 4224 - ql_dbg(ql_dbg_mbx, vha, 0x1103, "Entered %s.\n", __func__); 4006 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1103, 4007 + "Entered %s.\n", __func__); 4225 4008 4226 4009 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 4227 4010 ··· 4265 4046 ql_dbg(ql_dbg_mbx, vha, 0x1104, 4266 4047 "Failed=%x mb[0]=%x.\n", rval, mb[0]); 4267 4048 } else { 4268 - ql_dbg(ql_dbg_mbx, vha, 0x1105, "Done %s.\n", __func__); 4049 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1105, 4050 + "Done %s.\n", __func__); 4269 4051 } 4270 4052 4271 4053 return rval; ··· 4280 4060 mbx_cmd_t *mcp = &mc; 4281 4061 struct qla_hw_data *ha = vha->hw; 4282 4062 4283 - ql_dbg(ql_dbg_mbx, vha, 0x1106, "Entered %s.\n", __func__); 4063 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1106, 4064 + "Entered %s.\n", __func__); 4284 4065 4285 4066 if (!IS_FWI2_CAPABLE(ha)) 4286 4067 return QLA_FUNCTION_FAILED; ··· 4299 4078 ql_dbg(ql_dbg_mbx, vha, 0x1107, 4300 4079 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4301 4080 } else { 4302 - ql_dbg(ql_dbg_mbx, vha, 0x1108, "Done %s.\n", __func__); 4081 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108, 4082 + "Done %s.\n", __func__); 4303 4083 if (mcp->mb[1] != 0x7) 4304 4084 ha->link_data_rate = mcp->mb[1]; 4305 4085 } ··· 4316 4094 mbx_cmd_t *mcp = &mc; 4317 4095 struct qla_hw_data *ha = vha->hw; 4318 4096 4319 - ql_dbg(ql_dbg_mbx, vha, 0x1109, "Entered %s.\n", __func__); 4097 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1109, 4098 + "Entered %s.\n", __func__); 4320 4099 4321 4100 if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha)) 4322 4101 return QLA_FUNCTION_FAILED; ··· 4336 4113 /* Copy all bits to preserve original value */ 4337 4114 memcpy(mb, &mcp->mb[1], sizeof(uint16_t) * 4); 4338 4115 4339 - ql_dbg(ql_dbg_mbx, vha, 0x110b, "Done %s.\n", __func__); 4116 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110b, 4117 + "Done %s.\n", __func__); 4340 4118 } 4341 4119 return rval; 4342 4120 } ··· 4349 4125 mbx_cmd_t mc; 4350 4126 mbx_cmd_t *mcp = &mc; 4351 4127 4352 - ql_dbg(ql_dbg_mbx, vha, 0x110c, "Entered %s.\n", __func__); 4128 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110c, 4129 + "Entered %s.\n", __func__); 4353 4130 4354 4131 mcp->mb[0] = MBC_SET_PORT_CONFIG; 4355 4132 /* Copy all bits to preserve original setting */ ··· 4365 4140 ql_dbg(ql_dbg_mbx, vha, 0x110d, 4366 4141 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4367 4142 } else 4368 - ql_dbg(ql_dbg_mbx, vha, 0x110e, "Done %s.\n", __func__); 4143 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110e, 4144 + "Done %s.\n", __func__); 4369 4145 4370 4146 return rval; 4371 4147 } ··· 4381 4155 mbx_cmd_t *mcp = &mc; 4382 4156 struct qla_hw_data *ha = vha->hw; 4383 4157 4384 - ql_dbg(ql_dbg_mbx, vha, 0x110f, "Entered %s.\n", __func__); 4158 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x110f, 4159 + "Entered %s.\n", __func__); 4385 4160 4386 4161 if (!IS_QLA24XX_TYPE(ha) && !IS_QLA25XX(ha)) 4387 4162 return QLA_FUNCTION_FAILED; ··· 4410 4183 if (rval != QLA_SUCCESS) { 4411 4184 ql_dbg(ql_dbg_mbx, vha, 0x10cd, "Failed=%x.\n", rval); 4412 4185 } else { 4413 - ql_dbg(ql_dbg_mbx, vha, 0x10cc, "Done %s.\n", __func__); 4186 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10cc, 4187 + "Done %s.\n", __func__); 4414 4188 } 4415 4189 4416 4190 return rval; ··· 4424 4196 uint8_t byte; 4425 4197 struct qla_hw_data *ha = vha->hw; 4426 4198 4427 - ql_dbg(ql_dbg_mbx, vha, 0x10ca, "Entered %s.\n", __func__); 4199 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10ca, 4200 + "Entered %s.\n", __func__); 4428 4201 4429 4202 /* Integer part */ 4430 4203 rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0); ··· 4445 4216 } 4446 4217 *frac = (byte >> 6) * 25; 4447 4218 4448 - ql_dbg(ql_dbg_mbx, vha, 0x1018, "Done %s.\n", __func__); 4219 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1018, 4220 + "Done %s.\n", __func__); 4449 4221 fail: 4450 4222 return rval; 4451 4223 } ··· 4459 4229 mbx_cmd_t mc; 4460 4230 mbx_cmd_t *mcp = &mc; 4461 4231 4462 - ql_dbg(ql_dbg_mbx, vha, 0x1017, "Entered %s.\n", __func__); 4232 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1017, 4233 + "Entered %s.\n", __func__); 4463 4234 4464 4235 if (!IS_FWI2_CAPABLE(ha)) 4465 4236 return QLA_FUNCTION_FAILED; ··· 4479 4248 ql_dbg(ql_dbg_mbx, vha, 0x1016, 4480 4249 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4481 4250 } else { 4482 - ql_dbg(ql_dbg_mbx, vha, 0x100e, "Done %s.\n", __func__); 4251 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100e, 4252 + "Done %s.\n", __func__); 4483 4253 } 4484 4254 4485 4255 return rval; ··· 4494 4262 mbx_cmd_t mc; 4495 4263 mbx_cmd_t *mcp = &mc; 4496 4264 4497 - ql_dbg(ql_dbg_mbx, vha, 0x100d, "Entered %s.\n", __func__); 4265 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100d, 4266 + "Entered %s.\n", __func__); 4498 4267 4499 4268 if (!IS_QLA82XX(ha)) 4500 4269 return QLA_FUNCTION_FAILED; ··· 4514 4281 ql_dbg(ql_dbg_mbx, vha, 0x100c, 4515 4282 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4516 4283 } else { 4517 - ql_dbg(ql_dbg_mbx, vha, 0x100b, "Done %s.\n", __func__); 4284 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x100b, 4285 + "Done %s.\n", __func__); 4518 4286 } 4519 4287 4520 4288 return rval; ··· 4529 4295 mbx_cmd_t *mcp = &mc; 4530 4296 int rval = QLA_FUNCTION_FAILED; 4531 4297 4532 - ql_dbg(ql_dbg_mbx, vha, 0x111f, "Entered %s.\n", __func__); 4298 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x111f, 4299 + "Entered %s.\n", __func__); 4533 4300 4534 4301 memset(mcp->mb, 0 , sizeof(mcp->mb)); 4535 4302 mcp->mb[0] = LSW(MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE); ··· 4553 4318 (mcp->mb[1] << 16) | mcp->mb[0], 4554 4319 (mcp->mb[3] << 16) | mcp->mb[2]); 4555 4320 } else { 4556 - ql_dbg(ql_dbg_mbx, vha, 0x1121, "Done %s.\n", __func__); 4321 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1121, 4322 + "Done %s.\n", __func__); 4557 4323 ha->md_template_size = ((mcp->mb[3] << 16) | mcp->mb[2]); 4558 4324 if (!ha->md_template_size) { 4559 4325 ql_dbg(ql_dbg_mbx, vha, 0x1122, ··· 4573 4337 mbx_cmd_t *mcp = &mc; 4574 4338 int rval = QLA_FUNCTION_FAILED; 4575 4339 4576 - ql_dbg(ql_dbg_mbx, vha, 0x1123, "Entered %s.\n", __func__); 4340 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1123, 4341 + "Entered %s.\n", __func__); 4577 4342 4578 4343 ha->md_tmplt_hdr = dma_alloc_coherent(&ha->pdev->dev, 4579 4344 ha->md_template_size, &ha->md_tmplt_hdr_dma, GFP_KERNEL); ··· 4609 4372 ((mcp->mb[1] << 16) | mcp->mb[0]), 4610 4373 ((mcp->mb[3] << 16) | mcp->mb[2])); 4611 4374 } else 4612 - ql_dbg(ql_dbg_mbx, vha, 0x1126, "Done %s.\n", __func__); 4375 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1126, 4376 + "Done %s.\n", __func__); 4613 4377 return rval; 4614 4378 } 4615 4379 ··· 4625 4387 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 4626 4388 return QLA_FUNCTION_FAILED; 4627 4389 4628 - ql_dbg(ql_dbg_mbx, vha, 0x1133, "Entered %s.\n", __func__); 4390 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1133, 4391 + "Entered %s.\n", __func__); 4629 4392 4630 4393 memset(mcp, 0, sizeof(mbx_cmd_t)); 4631 4394 mcp->mb[0] = MBC_SET_LED_CONFIG; ··· 4651 4412 ql_dbg(ql_dbg_mbx, vha, 0x1134, 4652 4413 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4653 4414 } else { 4654 - ql_dbg(ql_dbg_mbx, vha, 0x1135, "Done %s.\n", __func__); 4415 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1135, 4416 + "Done %s.\n", __func__); 4655 4417 } 4656 4418 4657 4419 return rval; ··· 4669 4429 if (!IS_QLA81XX(ha) && !IS_QLA8031(ha)) 4670 4430 return QLA_FUNCTION_FAILED; 4671 4431 4672 - ql_dbg(ql_dbg_mbx, vha, 0x1136, "Entered %s.\n", __func__); 4432 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1136, 4433 + "Entered %s.\n", __func__); 4673 4434 4674 4435 memset(mcp, 0, sizeof(mbx_cmd_t)); 4675 4436 mcp->mb[0] = MBC_GET_LED_CONFIG; ··· 4695 4454 led_cfg[4] = mcp->mb[5]; 4696 4455 led_cfg[5] = mcp->mb[6]; 4697 4456 } 4698 - ql_dbg(ql_dbg_mbx, vha, 0x1138, "Done %s.\n", __func__); 4457 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1138, 4458 + "Done %s.\n", __func__); 4699 4459 } 4700 4460 4701 4461 return rval; ··· 4713 4471 if (!IS_QLA82XX(ha)) 4714 4472 return QLA_FUNCTION_FAILED; 4715 4473 4716 - ql_dbg(ql_dbg_mbx, vha, 0x1127, 4474 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1127, 4717 4475 "Entered %s.\n", __func__); 4718 4476 4719 4477 memset(mcp, 0, sizeof(mbx_cmd_t)); ··· 4733 4491 ql_dbg(ql_dbg_mbx, vha, 0x1128, 4734 4492 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4735 4493 } else { 4736 - ql_dbg(ql_dbg_mbx, vha, 0x1129, 4494 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1129, 4737 4495 "Done %s.\n", __func__); 4738 4496 } 4739 4497 ··· 4751 4509 if (!IS_QLA83XX(ha)) 4752 4510 return QLA_FUNCTION_FAILED; 4753 4511 4754 - ql_dbg(ql_dbg_mbx, vha, 0x1130, "Entered %s.\n", __func__); 4512 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1130, 4513 + "Entered %s.\n", __func__); 4755 4514 4756 4515 mcp->mb[0] = MBC_WRITE_REMOTE_REG; 4757 4516 mcp->mb[1] = LSW(reg); ··· 4770 4527 ql_dbg(ql_dbg_mbx, vha, 0x1131, 4771 4528 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4772 4529 } else { 4773 - ql_dbg(ql_dbg_mbx, vha, 0x1132, 4530 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1132, 4774 4531 "Done %s.\n", __func__); 4775 4532 } 4776 4533 ··· 4786 4543 mbx_cmd_t *mcp = &mc; 4787 4544 4788 4545 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 4789 - ql_dbg(ql_dbg_mbx, vha, 0x113b, 4546 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113b, 4790 4547 "Implicit LOGO Unsupported.\n"); 4791 4548 return QLA_FUNCTION_FAILED; 4792 4549 } 4793 4550 4794 4551 4795 - ql_dbg(ql_dbg_mbx, vha, 0x113c, "Done %s.\n", __func__); 4552 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113c, 4553 + "Entering %s.\n", __func__); 4796 4554 4797 4555 /* Perform Implicit LOGO. */ 4798 4556 mcp->mb[0] = MBC_PORT_LOGOUT; ··· 4808 4564 ql_dbg(ql_dbg_mbx, vha, 0x113d, 4809 4565 "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); 4810 4566 else 4811 - ql_dbg(ql_dbg_mbx, vha, 0x113e, "Done %s.\n", __func__); 4567 + ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x113e, 4568 + "Done %s.\n", __func__); 4812 4569 4813 4570 return rval; 4814 4571 }
+12 -6
drivers/scsi/qla2xxx/qla_mid.c
··· 6 6 */ 7 7 #include "qla_def.h" 8 8 #include "qla_gbl.h" 9 + #include "qla_target.h" 9 10 10 11 #include <linux/moduleparam.h> 11 12 #include <linux/vmalloc.h> ··· 50 49 51 50 spin_lock_irqsave(&ha->vport_slock, flags); 52 51 list_add_tail(&vha->list, &ha->vp_list); 52 + 53 + qlt_update_vp_map(vha, SET_VP_IDX); 54 + 53 55 spin_unlock_irqrestore(&ha->vport_slock, flags); 54 56 55 57 mutex_unlock(&ha->vport_lock); ··· 83 79 spin_lock_irqsave(&ha->vport_slock, flags); 84 80 } 85 81 list_del(&vha->list); 82 + qlt_update_vp_map(vha, RESET_VP_IDX); 86 83 spin_unlock_irqrestore(&ha->vport_slock, flags); 87 84 88 85 vp_id = vha->vp_idx; ··· 139 134 list_for_each_entry(fcport, &vha->vp_fcports, list) { 140 135 ql_dbg(ql_dbg_vport, vha, 0xa001, 141 136 "Marking port dead, loop_id=0x%04x : %x.\n", 142 - fcport->loop_id, fcport->vp_idx); 137 + fcport->loop_id, fcport->vha->vp_idx); 143 138 144 139 qla2x00_mark_device_lost(vha, fcport, 0, 0); 145 140 qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); ··· 154 149 ret = qla24xx_control_vp(vha, VCE_COMMAND_DISABLE_VPS_LOGO_ALL); 155 150 atomic_set(&vha->loop_state, LOOP_DOWN); 156 151 atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); 152 + 153 + /* Remove port id from vp target map */ 154 + qlt_update_vp_map(vha, RESET_AL_PA); 157 155 158 156 qla2x00_mark_vp_devices_dead(vha); 159 157 atomic_set(&vha->vp_state, VP_FAILED); ··· 303 295 static int 304 296 qla2x00_do_dpc_vp(scsi_qla_host_t *vha) 305 297 { 306 - ql_dbg(ql_dbg_dpc, vha, 0x4012, 307 - "Entering %s.\n", __func__); 308 - ql_dbg(ql_dbg_dpc, vha, 0x4013, 309 - "vp_flags: 0x%lx.\n", vha->vp_flags); 298 + ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x4012, 299 + "Entering %s vp_flags: 0x%lx.\n", __func__, vha->vp_flags); 310 300 311 301 qla2x00_do_work(vha); 312 302 ··· 354 348 } 355 349 } 356 350 357 - ql_dbg(ql_dbg_dpc, vha, 0x401c, 351 + ql_dbg(ql_dbg_dpc + ql_dbg_verbose, vha, 0x401c, 358 352 "Exiting %s.\n", __func__); 359 353 return 0; 360 354 }
+49 -17
drivers/scsi/qla2xxx/qla_nx.c
··· 1190 1190 } 1191 1191 1192 1192 /* Offset in flash = lower 16 bits 1193 - * Number of enteries = upper 16 bits 1193 + * Number of entries = upper 16 bits 1194 1194 */ 1195 1195 offset = n & 0xffffU; 1196 1196 n = (n >> 16) & 0xffffU; 1197 1197 1198 - /* number of addr/value pair should not exceed 1024 enteries */ 1198 + /* number of addr/value pair should not exceed 1024 entries */ 1199 1199 if (n >= 1024) { 1200 1200 ql_log(ql_log_fatal, vha, 0x0071, 1201 1201 "Card flash not initialized:n=0x%x.\n", n); ··· 2050 2050 2051 2051 rsp = (struct rsp_que *) dev_id; 2052 2052 if (!rsp) { 2053 - ql_log(ql_log_info, NULL, 0xb054, 2053 + ql_log(ql_log_info, NULL, 0xb053, 2054 2054 "%s: NULL response queue pointer.\n", __func__); 2055 2055 return IRQ_NONE; 2056 2056 } ··· 2446 2446 2447 2447 if (qla82xx_fw_load_from_flash(ha) == QLA_SUCCESS) { 2448 2448 ql_log(ql_log_info, vha, 0x00a1, 2449 - "Firmware loaded successully from flash.\n"); 2449 + "Firmware loaded successfully from flash.\n"); 2450 2450 return QLA_SUCCESS; 2451 2451 } else { 2452 2452 ql_log(ql_log_warn, vha, 0x0108, ··· 2461 2461 blob = ha->hablob = qla2x00_request_firmware(vha); 2462 2462 if (!blob) { 2463 2463 ql_log(ql_log_fatal, vha, 0x00a3, 2464 - "Firmware image not preset.\n"); 2464 + "Firmware image not present.\n"); 2465 2465 goto fw_load_failed; 2466 2466 } 2467 2467 ··· 2689 2689 if (!optrom) { 2690 2690 ql_log(ql_log_warn, vha, 0xb01b, 2691 2691 "Unable to allocate memory " 2692 - "for optron burst write (%x KB).\n", 2692 + "for optrom burst write (%x KB).\n", 2693 2693 OPTROM_BURST_SIZE / 1024); 2694 2694 } 2695 2695 } ··· 2960 2960 * changing the state to DEV_READY 2961 2961 */ 2962 2962 ql_log(ql_log_info, vha, 0xb023, 2963 - "%s : QUIESCENT TIMEOUT.\n", QLA2XXX_DRIVER_NAME); 2964 - ql_log(ql_log_info, vha, 0xb024, 2965 - "DRV_ACTIVE:%d DRV_STATE:%d.\n", 2963 + "%s : QUIESCENT TIMEOUT DRV_ACTIVE:%d " 2964 + "DRV_STATE:%d.\n", QLA2XXX_DRIVER_NAME, 2966 2965 drv_active, drv_state); 2967 2966 qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2968 2967 QLA82XX_DEV_READY); ··· 3128 3129 if (ql2xmdenable) { 3129 3130 if (qla82xx_md_collect(vha)) 3130 3131 ql_log(ql_log_warn, vha, 0xb02c, 3131 - "Not able to collect minidump.\n"); 3132 + "Minidump not collected.\n"); 3132 3133 } else 3133 3134 ql_log(ql_log_warn, vha, 0xb04f, 3134 3135 "Minidump disabled.\n"); ··· 3159 3160 "Firmware version differs " 3160 3161 "Previous version: %d:%d:%d - " 3161 3162 "New version: %d:%d:%d\n", 3163 + fw_major_version, fw_minor_version, 3164 + fw_subminor_version, 3162 3165 ha->fw_major_version, 3163 3166 ha->fw_minor_version, 3164 - ha->fw_subminor_version, 3165 - fw_major_version, fw_minor_version, 3166 - fw_subminor_version); 3167 + ha->fw_subminor_version); 3167 3168 /* Release MiniDump resources */ 3168 3169 qla82xx_md_free(vha); 3169 3170 /* ALlocate MiniDump resources */ ··· 3324 3325 return rval; 3325 3326 } 3326 3327 3328 + static int qla82xx_check_temp(scsi_qla_host_t *vha) 3329 + { 3330 + uint32_t temp, temp_state, temp_val; 3331 + struct qla_hw_data *ha = vha->hw; 3332 + 3333 + temp = qla82xx_rd_32(ha, CRB_TEMP_STATE); 3334 + temp_state = qla82xx_get_temp_state(temp); 3335 + temp_val = qla82xx_get_temp_val(temp); 3336 + 3337 + if (temp_state == QLA82XX_TEMP_PANIC) { 3338 + ql_log(ql_log_warn, vha, 0x600e, 3339 + "Device temperature %d degrees C exceeds " 3340 + " maximum allowed. Hardware has been shut down.\n", 3341 + temp_val); 3342 + return 1; 3343 + } else if (temp_state == QLA82XX_TEMP_WARN) { 3344 + ql_log(ql_log_warn, vha, 0x600f, 3345 + "Device temperature %d degrees C exceeds " 3346 + "operating range. Immediate action needed.\n", 3347 + temp_val); 3348 + } 3349 + return 0; 3350 + } 3351 + 3327 3352 void qla82xx_clear_pending_mbx(scsi_qla_host_t *vha) 3328 3353 { 3329 3354 struct qla_hw_data *ha = vha->hw; ··· 3370 3347 /* don't poll if reset is going on */ 3371 3348 if (!ha->flags.isp82xx_reset_hdlr_active) { 3372 3349 dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 3373 - if (dev_state == QLA82XX_DEV_NEED_RESET && 3350 + if (qla82xx_check_temp(vha)) { 3351 + set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); 3352 + ha->flags.isp82xx_fw_hung = 1; 3353 + qla82xx_clear_pending_mbx(vha); 3354 + } else if (dev_state == QLA82XX_DEV_NEED_RESET && 3374 3355 !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) { 3375 3356 ql_log(ql_log_warn, vha, 0x6001, 3376 3357 "Adapter reset needed.\n"); 3377 3358 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 3378 - qla2xxx_wake_dpc(vha); 3379 3359 } else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT && 3380 3360 !test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags)) { 3381 3361 ql_log(ql_log_warn, vha, 0x6002, 3382 3362 "Quiescent needed.\n"); 3383 3363 set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags); 3384 - qla2xxx_wake_dpc(vha); 3385 3364 } else { 3386 3365 if (qla82xx_check_fw_alive(vha)) { 3387 3366 ql_dbg(ql_dbg_timer, vha, 0x6011, ··· 3423 3398 set_bit(ISP_ABORT_NEEDED, 3424 3399 &vha->dpc_flags); 3425 3400 } 3426 - qla2xxx_wake_dpc(vha); 3427 3401 ha->flags.isp82xx_fw_hung = 1; 3428 3402 ql_log(ql_log_warn, vha, 0x6007, "Firmware hung.\n"); 3429 3403 qla82xx_clear_pending_mbx(vha); ··· 4134 4110 if (!ha->md_tmplt_hdr || !ha->md_dump) { 4135 4111 ql_log(ql_log_warn, vha, 0xb038, 4136 4112 "Memory not allocated for minidump capture\n"); 4113 + goto md_failed; 4114 + } 4115 + 4116 + if (ha->flags.isp82xx_no_md_cap) { 4117 + ql_log(ql_log_warn, vha, 0xb054, 4118 + "Forced reset from application, " 4119 + "ignore minidump capture\n"); 4120 + ha->flags.isp82xx_no_md_cap = 0; 4137 4121 goto md_failed; 4138 4122 } 4139 4123
+13 -1
drivers/scsi/qla2xxx/qla_nx.h
··· 26 26 #define CRB_RCVPEG_STATE QLA82XX_REG(0x13c) 27 27 #define BOOT_LOADER_DIMM_STATUS QLA82XX_REG(0x54) 28 28 #define CRB_DMA_SHIFT QLA82XX_REG(0xcc) 29 + #define CRB_TEMP_STATE QLA82XX_REG(0x1b4) 29 30 #define QLA82XX_DMA_SHIFT_VALUE 0x55555555 30 31 31 32 #define QLA82XX_HW_H0_CH_HUB_ADR 0x05 ··· 562 561 #define QLA82XX_FW_VERSION_SUB (QLA82XX_CAM_RAM(0x158)) 563 562 #define QLA82XX_PCIE_REG(reg) (QLA82XX_CRB_PCIE + (reg)) 564 563 565 - #define PCIE_CHICKEN3 (0x120c8) 566 564 #define PCIE_SETUP_FUNCTION (0x12040) 567 565 #define PCIE_SETUP_FUNCTION2 (0x12048) 568 566 ··· 1178 1178 #define CRB_NIU_XG_PAUSE_CTL_P0 0x1 1179 1179 #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 1180 1180 1181 + #define qla82xx_get_temp_val(x) ((x) >> 16) 1182 + #define qla82xx_get_temp_state(x) ((x) & 0xffff) 1183 + #define qla82xx_encode_temp(val, state) (((val) << 16) | (state)) 1184 + 1185 + /* 1186 + * Temperature control. 1187 + */ 1188 + enum { 1189 + QLA82XX_TEMP_NORMAL = 0x1, /* Normal operating range */ 1190 + QLA82XX_TEMP_WARN, /* Sound alert, temperature getting high */ 1191 + QLA82XX_TEMP_PANIC /* Fatal error, hardware has shut down. */ 1192 + }; 1181 1193 #endif
+134 -39
drivers/scsi/qla2xxx/qla_os.c
··· 13 13 #include <linux/mutex.h> 14 14 #include <linux/kobject.h> 15 15 #include <linux/slab.h> 16 - 17 16 #include <scsi/scsi_tcq.h> 18 17 #include <scsi/scsicam.h> 19 18 #include <scsi/scsi_transport.h> 20 19 #include <scsi/scsi_transport_fc.h> 20 + 21 + #include "qla_target.h" 21 22 22 23 /* 23 24 * Driver version ··· 40 39 * error level for logging 41 40 */ 42 41 int ql_errlev = ql_log_all; 42 + 43 + int ql2xenableclass2; 44 + module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR); 45 + MODULE_PARM_DESC(ql2xenableclass2, 46 + "Specify if Class 2 operations are supported from the very " 47 + "beginning. Default is 0 - class 2 not supported."); 43 48 44 49 int ql2xlogintimeout = 20; 45 50 module_param(ql2xlogintimeout, int, S_IRUGO); ··· 262 255 263 256 .max_sectors = 0xFFFF, 264 257 .shost_attrs = qla2x00_host_attrs, 258 + 259 + .supported_mode = MODE_INITIATOR, 265 260 }; 266 261 267 262 static struct scsi_transport_template *qla2xxx_transport_template = NULL; ··· 315 306 static void qla2x00_mem_free(struct qla_hw_data *); 316 307 317 308 /* -------------------------------------------------------------------------- */ 318 - static int qla2x00_alloc_queues(struct qla_hw_data *ha) 309 + static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, 310 + struct rsp_que *rsp) 319 311 { 320 312 scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); 321 313 ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues, ··· 334 324 "Unable to allocate memory for response queue ptrs.\n"); 335 325 goto fail_rsp_map; 336 326 } 327 + /* 328 + * Make sure we record at least the request and response queue zero in 329 + * case we need to free them if part of the probe fails. 330 + */ 331 + ha->rsp_q_map[0] = rsp; 332 + ha->req_q_map[0] = req; 337 333 set_bit(0, ha->rsp_qid_map); 338 334 set_bit(0, ha->req_qid_map); 339 335 return 1; ··· 658 642 659 643 if (ha->flags.eeh_busy) { 660 644 if (ha->flags.pci_channel_io_perm_failure) { 661 - ql_dbg(ql_dbg_io, vha, 0x3001, 645 + ql_dbg(ql_dbg_aer, vha, 0x9010, 662 646 "PCI Channel IO permanent failure, exiting " 663 647 "cmd=%p.\n", cmd); 664 648 cmd->result = DID_NO_CONNECT << 16; 665 649 } else { 666 - ql_dbg(ql_dbg_io, vha, 0x3002, 650 + ql_dbg(ql_dbg_aer, vha, 0x9011, 667 651 "EEH_Busy, Requeuing the cmd=%p.\n", cmd); 668 652 cmd->result = DID_REQUEUE << 16; 669 653 } ··· 673 657 rval = fc_remote_port_chkready(rport); 674 658 if (rval) { 675 659 cmd->result = rval; 676 - ql_dbg(ql_dbg_io, vha, 0x3003, 660 + ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3003, 677 661 "fc_remote_port_chkready failed for cmd=%p, rval=0x%x.\n", 678 662 cmd, rval); 679 663 goto qc24_fail_command; ··· 1152 1136 ret = FAILED; 1153 1137 1154 1138 ql_log(ql_log_info, vha, 0x8012, 1155 - "BUS RESET ISSUED nexus=%ld:%d%d.\n", vha->host_no, id, lun); 1139 + "BUS RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun); 1156 1140 1157 1141 if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) { 1158 1142 ql_log(ql_log_fatal, vha, 0x8013, ··· 2196 2180 ql_dbg_pci(ql_dbg_init, pdev, 0x000a, 2197 2181 "Memory allocated for ha=%p.\n", ha); 2198 2182 ha->pdev = pdev; 2183 + ha->tgt.enable_class_2 = ql2xenableclass2; 2199 2184 2200 2185 /* Clear our data area */ 2201 2186 ha->bars = bars; ··· 2260 2243 ha->mbx_count = MAILBOX_REGISTER_COUNT; 2261 2244 req_length = REQUEST_ENTRY_CNT_24XX; 2262 2245 rsp_length = RESPONSE_ENTRY_CNT_2300; 2246 + ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; 2263 2247 ha->max_loop_id = SNS_LAST_LOOP_ID_2300; 2264 2248 ha->init_cb_size = sizeof(struct mid_init_cb_24xx); 2265 2249 ha->gid_list_info_size = 8; ··· 2276 2258 ha->mbx_count = MAILBOX_REGISTER_COUNT; 2277 2259 req_length = REQUEST_ENTRY_CNT_24XX; 2278 2260 rsp_length = RESPONSE_ENTRY_CNT_2300; 2261 + ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; 2279 2262 ha->max_loop_id = SNS_LAST_LOOP_ID_2300; 2280 2263 ha->init_cb_size = sizeof(struct mid_init_cb_24xx); 2281 2264 ha->gid_list_info_size = 8; ··· 2436 2417 host->max_cmd_len, host->max_channel, host->max_lun, 2437 2418 host->transportt, sht->vendor_id); 2438 2419 2420 + que_init: 2421 + /* Alloc arrays of request and response ring ptrs */ 2422 + if (!qla2x00_alloc_queues(ha, req, rsp)) { 2423 + ql_log(ql_log_fatal, base_vha, 0x003d, 2424 + "Failed to allocate memory for queue pointers..." 2425 + "aborting.\n"); 2426 + goto probe_init_failed; 2427 + } 2428 + 2429 + qlt_probe_one_stage1(base_vha, ha); 2430 + 2439 2431 /* Set up the irqs */ 2440 2432 ret = qla2x00_request_irqs(ha, rsp); 2441 2433 if (ret) ··· 2454 2424 2455 2425 pci_save_state(pdev); 2456 2426 2457 - /* Alloc arrays of request and response ring ptrs */ 2458 - que_init: 2459 - if (!qla2x00_alloc_queues(ha)) { 2460 - ql_log(ql_log_fatal, base_vha, 0x003d, 2461 - "Failed to allocate memory for queue pointers.. aborting.\n"); 2462 - goto probe_init_failed; 2463 - } 2464 - 2465 - ha->rsp_q_map[0] = rsp; 2466 - ha->req_q_map[0] = req; 2427 + /* Assign back pointers */ 2467 2428 rsp->req = req; 2468 2429 req->rsp = rsp; 2469 - set_bit(0, ha->req_qid_map); 2470 - set_bit(0, ha->rsp_qid_map); 2430 + 2471 2431 /* FWI2-capable only. */ 2472 2432 req->req_q_in = &ha->iobase->isp24.req_q_in; 2473 2433 req->req_q_out = &ha->iobase->isp24.req_q_out; ··· 2534 2514 ql_dbg(ql_dbg_init, base_vha, 0x00ee, 2535 2515 "DPC thread started successfully.\n"); 2536 2516 2517 + /* 2518 + * If we're not coming up in initiator mode, we might sit for 2519 + * a while without waking up the dpc thread, which leads to a 2520 + * stuck process warning. So just kick the dpc once here and 2521 + * let the kthread start (and go back to sleep in qla2x00_do_dpc). 2522 + */ 2523 + qla2xxx_wake_dpc(base_vha); 2524 + 2537 2525 skip_dpc: 2538 2526 list_add_tail(&base_vha->list, &ha->vp_list); 2539 2527 base_vha->host->irq = ha->pdev->irq; ··· 2587 2559 ql_dbg(ql_dbg_init, base_vha, 0x00f2, 2588 2560 "Init done and hba is online.\n"); 2589 2561 2590 - scsi_scan_host(host); 2562 + if (qla_ini_mode_enabled(base_vha)) 2563 + scsi_scan_host(host); 2564 + else 2565 + ql_dbg(ql_dbg_init, base_vha, 0x0122, 2566 + "skipping scsi_scan_host() for non-initiator port\n"); 2591 2567 2592 2568 qla2x00_alloc_sysfs_attr(base_vha); 2593 2569 ··· 2609 2577 base_vha->host_no, 2610 2578 ha->isp_ops->fw_version_str(base_vha, fw_str)); 2611 2579 2580 + qlt_add_target(ha, base_vha); 2581 + 2612 2582 return 0; 2613 2583 2614 2584 probe_init_failed: 2615 2585 qla2x00_free_req_que(ha, req); 2586 + ha->req_q_map[0] = NULL; 2587 + clear_bit(0, ha->req_qid_map); 2616 2588 qla2x00_free_rsp_que(ha, rsp); 2589 + ha->rsp_q_map[0] = NULL; 2590 + clear_bit(0, ha->rsp_qid_map); 2617 2591 ha->max_req_queues = ha->max_rsp_queues = 0; 2618 2592 2619 2593 probe_failed: ··· 2656 2618 probe_out: 2657 2619 pci_disable_device(pdev); 2658 2620 return ret; 2621 + } 2622 + 2623 + static void 2624 + qla2x00_stop_dpc_thread(scsi_qla_host_t *vha) 2625 + { 2626 + struct qla_hw_data *ha = vha->hw; 2627 + struct task_struct *t = ha->dpc_thread; 2628 + 2629 + if (ha->dpc_thread == NULL) 2630 + return; 2631 + /* 2632 + * qla2xxx_wake_dpc checks for ->dpc_thread 2633 + * so we need to zero it out. 2634 + */ 2635 + ha->dpc_thread = NULL; 2636 + kthread_stop(t); 2659 2637 } 2660 2638 2661 2639 static void ··· 2717 2663 struct qla_hw_data *ha; 2718 2664 unsigned long flags; 2719 2665 2666 + /* 2667 + * If the PCI device is disabled that means that probe failed and any 2668 + * resources should be have cleaned up on probe exit. 2669 + */ 2670 + if (!atomic_read(&pdev->enable_cnt)) 2671 + return; 2672 + 2720 2673 base_vha = pci_get_drvdata(pdev); 2721 2674 ha = base_vha->hw; 2675 + 2676 + ha->flags.host_shutting_down = 1; 2722 2677 2723 2678 mutex_lock(&ha->vport_lock); 2724 2679 while (ha->cur_vport_count) { ··· 2782 2719 ha->dpc_thread = NULL; 2783 2720 kthread_stop(t); 2784 2721 } 2722 + qlt_remove_target(ha, base_vha); 2785 2723 2786 2724 qla2x00_free_sysfs_attr(base_vha); 2787 2725 ··· 2834 2770 if (vha->timer_active) 2835 2771 qla2x00_stop_timer(vha); 2836 2772 2837 - /* Kill the kernel thread for this host */ 2838 - if (ha->dpc_thread) { 2839 - struct task_struct *t = ha->dpc_thread; 2840 - 2841 - /* 2842 - * qla2xxx_wake_dpc checks for ->dpc_thread 2843 - * so we need to zero it out. 2844 - */ 2845 - ha->dpc_thread = NULL; 2846 - kthread_stop(t); 2847 - } 2773 + qla2x00_stop_dpc_thread(vha); 2848 2774 2849 2775 qla25xx_delete_queues(vha); 2850 2776 ··· 2896 2842 spin_unlock_irqrestore(vha->host->host_lock, flags); 2897 2843 set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); 2898 2844 qla2xxx_wake_dpc(base_vha); 2899 - } else 2845 + } else { 2900 2846 fc_remote_port_delete(rport); 2847 + qlt_fc_port_deleted(vha, fcport); 2848 + } 2901 2849 } 2902 2850 2903 2851 /* ··· 2915 2859 int do_login, int defer) 2916 2860 { 2917 2861 if (atomic_read(&fcport->state) == FCS_ONLINE && 2918 - vha->vp_idx == fcport->vp_idx) { 2862 + vha->vp_idx == fcport->vha->vp_idx) { 2919 2863 qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); 2920 2864 qla2x00_schedule_rport_del(vha, fcport, defer); 2921 2865 } ··· 2964 2908 fc_port_t *fcport; 2965 2909 2966 2910 list_for_each_entry(fcport, &vha->vp_fcports, list) { 2967 - if (vha->vp_idx != 0 && vha->vp_idx != fcport->vp_idx) 2911 + if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx) 2968 2912 continue; 2969 2913 2970 2914 /* ··· 2977 2921 qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); 2978 2922 if (defer) 2979 2923 qla2x00_schedule_rport_del(vha, fcport, defer); 2980 - else if (vha->vp_idx == fcport->vp_idx) 2924 + else if (vha->vp_idx == fcport->vha->vp_idx) 2981 2925 qla2x00_schedule_rport_del(vha, fcport, defer); 2982 2926 } 2983 2927 } ··· 3002 2946 if (!ha->init_cb) 3003 2947 goto fail; 3004 2948 2949 + if (qlt_mem_alloc(ha) < 0) 2950 + goto fail_free_init_cb; 2951 + 3005 2952 ha->gid_list = dma_alloc_coherent(&ha->pdev->dev, 3006 2953 qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL); 3007 2954 if (!ha->gid_list) 3008 - goto fail_free_init_cb; 2955 + goto fail_free_tgt_mem; 3009 2956 3010 2957 ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep); 3011 2958 if (!ha->srb_mempool) ··· 3226 3167 ha->gid_list_dma); 3227 3168 ha->gid_list = NULL; 3228 3169 ha->gid_list_dma = 0; 3170 + fail_free_tgt_mem: 3171 + qlt_mem_free(ha); 3229 3172 fail_free_init_cb: 3230 3173 dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb, 3231 3174 ha->init_cb_dma); ··· 3343 3282 if (ha->ctx_mempool) 3344 3283 mempool_destroy(ha->ctx_mempool); 3345 3284 3285 + qlt_mem_free(ha); 3286 + 3346 3287 if (ha->init_cb) 3347 3288 dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, 3348 3289 ha->init_cb, ha->init_cb_dma); ··· 3374 3311 3375 3312 ha->gid_list = NULL; 3376 3313 ha->gid_list_dma = 0; 3314 + 3315 + ha->tgt.atio_ring = NULL; 3316 + ha->tgt.atio_dma = 0; 3317 + ha->tgt.tgt_vp_map = NULL; 3377 3318 } 3378 3319 3379 3320 struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, ··· 3738 3671 3739 3672 ha->dpc_active = 1; 3740 3673 3741 - ql_dbg(ql_dbg_dpc, base_vha, 0x4001, 3742 - "DPC handler waking up.\n"); 3743 - ql_dbg(ql_dbg_dpc, base_vha, 0x4002, 3744 - "dpc_flags=0x%lx.\n", base_vha->dpc_flags); 3674 + ql_dbg(ql_dbg_dpc + ql_dbg_verbose, base_vha, 0x4001, 3675 + "DPC handler waking up, dpc_flags=0x%lx.\n", 3676 + base_vha->dpc_flags); 3745 3677 3746 3678 qla2x00_do_work(base_vha); 3747 3679 ··· 3804 3738 if (test_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags)) { 3805 3739 qla2x00_update_fcports(base_vha); 3806 3740 clear_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); 3741 + } 3742 + 3743 + if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) { 3744 + int ret; 3745 + ret = qla2x00_send_change_request(base_vha, 0x3, 0); 3746 + if (ret != QLA_SUCCESS) 3747 + ql_log(ql_log_warn, base_vha, 0x121, 3748 + "Failed to enable receiving of RSCN " 3749 + "requests: 0x%x.\n", ret); 3750 + clear_bit(SCR_PENDING, &base_vha->dpc_flags); 3807 3751 } 3808 3752 3809 3753 if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) { ··· 4533 4457 return -ENOMEM; 4534 4458 } 4535 4459 4460 + /* Initialize target kmem_cache and mem_pools */ 4461 + ret = qlt_init(); 4462 + if (ret < 0) { 4463 + kmem_cache_destroy(srb_cachep); 4464 + return ret; 4465 + } else if (ret > 0) { 4466 + /* 4467 + * If initiator mode is explictly disabled by qlt_init(), 4468 + * prevent scsi_transport_fc.c:fc_scsi_scan_rport() from 4469 + * performing scsi_scan_target() during LOOP UP event. 4470 + */ 4471 + qla2xxx_transport_functions.disable_target_scan = 1; 4472 + qla2xxx_transport_vport_functions.disable_target_scan = 1; 4473 + } 4474 + 4536 4475 /* Derive version string. */ 4537 4476 strcpy(qla2x00_version_str, QLA2XXX_VERSION); 4538 4477 if (ql2xextended_error_logging) ··· 4559 4468 kmem_cache_destroy(srb_cachep); 4560 4469 ql_log(ql_log_fatal, NULL, 0x0002, 4561 4470 "fc_attach_transport failed...Failing load!.\n"); 4471 + qlt_exit(); 4562 4472 return -ENODEV; 4563 4473 } 4564 4474 ··· 4573 4481 fc_attach_transport(&qla2xxx_transport_vport_functions); 4574 4482 if (!qla2xxx_transport_vport_template) { 4575 4483 kmem_cache_destroy(srb_cachep); 4484 + qlt_exit(); 4576 4485 fc_release_transport(qla2xxx_transport_template); 4577 4486 ql_log(ql_log_fatal, NULL, 0x0004, 4578 4487 "fc_attach_transport vport failed...Failing load!.\n"); ··· 4585 4492 ret = pci_register_driver(&qla2xxx_pci_driver); 4586 4493 if (ret) { 4587 4494 kmem_cache_destroy(srb_cachep); 4495 + qlt_exit(); 4588 4496 fc_release_transport(qla2xxx_transport_template); 4589 4497 fc_release_transport(qla2xxx_transport_vport_template); 4590 4498 ql_log(ql_log_fatal, NULL, 0x0006, ··· 4605 4511 pci_unregister_driver(&qla2xxx_pci_driver); 4606 4512 qla2x00_release_firmware(); 4607 4513 kmem_cache_destroy(srb_cachep); 4514 + qlt_exit(); 4608 4515 if (ctx_cachep) 4609 4516 kmem_cache_destroy(ctx_cachep); 4610 4517 fc_release_transport(qla2xxx_transport_template);
+4973
drivers/scsi/qla2xxx/qla_target.c
··· 1 + /* 2 + * qla_target.c SCSI LLD infrastructure for QLogic 22xx/23xx/24xx/25xx 3 + * 4 + * based on qla2x00t.c code: 5 + * 6 + * Copyright (C) 2004 - 2010 Vladislav Bolkhovitin <vst@vlnb.net> 7 + * Copyright (C) 2004 - 2005 Leonid Stoljar 8 + * Copyright (C) 2006 Nathaniel Clark <nate@misrule.us> 9 + * Copyright (C) 2006 - 2010 ID7 Ltd. 10 + * 11 + * Forward port and refactoring to modern qla2xxx and target/configfs 12 + * 13 + * Copyright (C) 2010-2011 Nicholas A. Bellinger <nab@kernel.org> 14 + * 15 + * This program is free software; you can redistribute it and/or 16 + * modify it under the terms of the GNU General Public License 17 + * as published by the Free Software Foundation, version 2 18 + * of the License. 19 + * 20 + * This program is distributed in the hope that it will be useful, 21 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 22 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 + * GNU General Public License for more details. 24 + */ 25 + 26 + #include <linux/module.h> 27 + #include <linux/init.h> 28 + #include <linux/types.h> 29 + #include <linux/version.h> 30 + #include <linux/blkdev.h> 31 + #include <linux/interrupt.h> 32 + #include <linux/pci.h> 33 + #include <linux/delay.h> 34 + #include <linux/list.h> 35 + #include <linux/workqueue.h> 36 + #include <asm/unaligned.h> 37 + #include <scsi/scsi.h> 38 + #include <scsi/scsi_host.h> 39 + #include <scsi/scsi_tcq.h> 40 + #include <target/target_core_base.h> 41 + #include <target/target_core_fabric.h> 42 + 43 + #include "qla_def.h" 44 + #include "qla_target.h" 45 + 46 + static char *qlini_mode = QLA2XXX_INI_MODE_STR_ENABLED; 47 + module_param(qlini_mode, charp, S_IRUGO); 48 + MODULE_PARM_DESC(qlini_mode, 49 + "Determines when initiator mode will be enabled. Possible values: " 50 + "\"exclusive\" - initiator mode will be enabled on load, " 51 + "disabled on enabling target mode and then on disabling target mode " 52 + "enabled back; " 53 + "\"disabled\" - initiator mode will never be enabled; " 54 + "\"enabled\" (default) - initiator mode will always stay enabled."); 55 + 56 + static int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE; 57 + 58 + /* 59 + * From scsi/fc/fc_fcp.h 60 + */ 61 + enum fcp_resp_rsp_codes { 62 + FCP_TMF_CMPL = 0, 63 + FCP_DATA_LEN_INVALID = 1, 64 + FCP_CMND_FIELDS_INVALID = 2, 65 + FCP_DATA_PARAM_MISMATCH = 3, 66 + FCP_TMF_REJECTED = 4, 67 + FCP_TMF_FAILED = 5, 68 + FCP_TMF_INVALID_LUN = 9, 69 + }; 70 + 71 + /* 72 + * fc_pri_ta from scsi/fc/fc_fcp.h 73 + */ 74 + #define FCP_PTA_SIMPLE 0 /* simple task attribute */ 75 + #define FCP_PTA_HEADQ 1 /* head of queue task attribute */ 76 + #define FCP_PTA_ORDERED 2 /* ordered task attribute */ 77 + #define FCP_PTA_ACA 4 /* auto. contigent allegiance */ 78 + #define FCP_PTA_MASK 7 /* mask for task attribute field */ 79 + #define FCP_PRI_SHIFT 3 /* priority field starts in bit 3 */ 80 + #define FCP_PRI_RESVD_MASK 0x80 /* reserved bits in priority field */ 81 + 82 + /* 83 + * This driver calls qla2x00_alloc_iocbs() and qla2x00_issue_marker(), which 84 + * must be called under HW lock and could unlock/lock it inside. 85 + * It isn't an issue, since in the current implementation on the time when 86 + * those functions are called: 87 + * 88 + * - Either context is IRQ and only IRQ handler can modify HW data, 89 + * including rings related fields, 90 + * 91 + * - Or access to target mode variables from struct qla_tgt doesn't 92 + * cross those functions boundaries, except tgt_stop, which 93 + * additionally protected by irq_cmd_count. 94 + */ 95 + /* Predefs for callbacks handed to qla2xxx LLD */ 96 + static void qlt_24xx_atio_pkt(struct scsi_qla_host *ha, 97 + struct atio_from_isp *pkt); 98 + static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt); 99 + static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, 100 + int fn, void *iocb, int flags); 101 + static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd 102 + *cmd, struct atio_from_isp *atio, int ha_locked); 103 + static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha, 104 + struct qla_tgt_srr_imm *imm, int ha_lock); 105 + /* 106 + * Global Variables 107 + */ 108 + static struct kmem_cache *qla_tgt_cmd_cachep; 109 + static struct kmem_cache *qla_tgt_mgmt_cmd_cachep; 110 + static mempool_t *qla_tgt_mgmt_cmd_mempool; 111 + static struct workqueue_struct *qla_tgt_wq; 112 + static DEFINE_MUTEX(qla_tgt_mutex); 113 + static LIST_HEAD(qla_tgt_glist); 114 + 115 + /* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */ 116 + static struct qla_tgt_sess *qlt_find_sess_by_port_name( 117 + struct qla_tgt *tgt, 118 + const uint8_t *port_name) 119 + { 120 + struct qla_tgt_sess *sess; 121 + 122 + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) { 123 + if (!memcmp(sess->port_name, port_name, WWN_SIZE)) 124 + return sess; 125 + } 126 + 127 + return NULL; 128 + } 129 + 130 + /* Might release hw lock, then reaquire!! */ 131 + static inline int qlt_issue_marker(struct scsi_qla_host *vha, int vha_locked) 132 + { 133 + /* Send marker if required */ 134 + if (unlikely(vha->marker_needed != 0)) { 135 + int rc = qla2x00_issue_marker(vha, vha_locked); 136 + if (rc != QLA_SUCCESS) { 137 + ql_dbg(ql_dbg_tgt, vha, 0xe03d, 138 + "qla_target(%d): issue_marker() failed\n", 139 + vha->vp_idx); 140 + } 141 + return rc; 142 + } 143 + return QLA_SUCCESS; 144 + } 145 + 146 + static inline 147 + struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, 148 + uint8_t *d_id) 149 + { 150 + struct qla_hw_data *ha = vha->hw; 151 + uint8_t vp_idx; 152 + 153 + if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0])) 154 + return NULL; 155 + 156 + if (vha->d_id.b.al_pa == d_id[2]) 157 + return vha; 158 + 159 + BUG_ON(ha->tgt.tgt_vp_map == NULL); 160 + vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx; 161 + if (likely(test_bit(vp_idx, ha->vp_idx_map))) 162 + return ha->tgt.tgt_vp_map[vp_idx].vha; 163 + 164 + return NULL; 165 + } 166 + 167 + static inline 168 + struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha, 169 + uint16_t vp_idx) 170 + { 171 + struct qla_hw_data *ha = vha->hw; 172 + 173 + if (vha->vp_idx == vp_idx) 174 + return vha; 175 + 176 + BUG_ON(ha->tgt.tgt_vp_map == NULL); 177 + if (likely(test_bit(vp_idx, ha->vp_idx_map))) 178 + return ha->tgt.tgt_vp_map[vp_idx].vha; 179 + 180 + return NULL; 181 + } 182 + 183 + void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, 184 + struct atio_from_isp *atio) 185 + { 186 + switch (atio->u.raw.entry_type) { 187 + case ATIO_TYPE7: 188 + { 189 + struct scsi_qla_host *host = qlt_find_host_by_d_id(vha, 190 + atio->u.isp24.fcp_hdr.d_id); 191 + if (unlikely(NULL == host)) { 192 + ql_dbg(ql_dbg_tgt, vha, 0xe03e, 193 + "qla_target(%d): Received ATIO_TYPE7 " 194 + "with unknown d_id %x:%x:%x\n", vha->vp_idx, 195 + atio->u.isp24.fcp_hdr.d_id[0], 196 + atio->u.isp24.fcp_hdr.d_id[1], 197 + atio->u.isp24.fcp_hdr.d_id[2]); 198 + break; 199 + } 200 + qlt_24xx_atio_pkt(host, atio); 201 + break; 202 + } 203 + 204 + case IMMED_NOTIFY_TYPE: 205 + { 206 + struct scsi_qla_host *host = vha; 207 + struct imm_ntfy_from_isp *entry = 208 + (struct imm_ntfy_from_isp *)atio; 209 + 210 + if ((entry->u.isp24.vp_index != 0xFF) && 211 + (entry->u.isp24.nport_handle != 0xFFFF)) { 212 + host = qlt_find_host_by_vp_idx(vha, 213 + entry->u.isp24.vp_index); 214 + if (unlikely(!host)) { 215 + ql_dbg(ql_dbg_tgt, vha, 0xe03f, 216 + "qla_target(%d): Received " 217 + "ATIO (IMMED_NOTIFY_TYPE) " 218 + "with unknown vp_index %d\n", 219 + vha->vp_idx, entry->u.isp24.vp_index); 220 + break; 221 + } 222 + } 223 + qlt_24xx_atio_pkt(host, atio); 224 + break; 225 + } 226 + 227 + default: 228 + ql_dbg(ql_dbg_tgt, vha, 0xe040, 229 + "qla_target(%d): Received unknown ATIO atio " 230 + "type %x\n", vha->vp_idx, atio->u.raw.entry_type); 231 + break; 232 + } 233 + 234 + return; 235 + } 236 + 237 + void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) 238 + { 239 + switch (pkt->entry_type) { 240 + case CTIO_TYPE7: 241 + { 242 + struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; 243 + struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, 244 + entry->vp_index); 245 + if (unlikely(!host)) { 246 + ql_dbg(ql_dbg_tgt, vha, 0xe041, 247 + "qla_target(%d): Response pkt (CTIO_TYPE7) " 248 + "received, with unknown vp_index %d\n", 249 + vha->vp_idx, entry->vp_index); 250 + break; 251 + } 252 + qlt_response_pkt(host, pkt); 253 + break; 254 + } 255 + 256 + case IMMED_NOTIFY_TYPE: 257 + { 258 + struct scsi_qla_host *host = vha; 259 + struct imm_ntfy_from_isp *entry = 260 + (struct imm_ntfy_from_isp *)pkt; 261 + 262 + host = qlt_find_host_by_vp_idx(vha, entry->u.isp24.vp_index); 263 + if (unlikely(!host)) { 264 + ql_dbg(ql_dbg_tgt, vha, 0xe042, 265 + "qla_target(%d): Response pkt (IMMED_NOTIFY_TYPE) " 266 + "received, with unknown vp_index %d\n", 267 + vha->vp_idx, entry->u.isp24.vp_index); 268 + break; 269 + } 270 + qlt_response_pkt(host, pkt); 271 + break; 272 + } 273 + 274 + case NOTIFY_ACK_TYPE: 275 + { 276 + struct scsi_qla_host *host = vha; 277 + struct nack_to_isp *entry = (struct nack_to_isp *)pkt; 278 + 279 + if (0xFF != entry->u.isp24.vp_index) { 280 + host = qlt_find_host_by_vp_idx(vha, 281 + entry->u.isp24.vp_index); 282 + if (unlikely(!host)) { 283 + ql_dbg(ql_dbg_tgt, vha, 0xe043, 284 + "qla_target(%d): Response " 285 + "pkt (NOTIFY_ACK_TYPE) " 286 + "received, with unknown " 287 + "vp_index %d\n", vha->vp_idx, 288 + entry->u.isp24.vp_index); 289 + break; 290 + } 291 + } 292 + qlt_response_pkt(host, pkt); 293 + break; 294 + } 295 + 296 + case ABTS_RECV_24XX: 297 + { 298 + struct abts_recv_from_24xx *entry = 299 + (struct abts_recv_from_24xx *)pkt; 300 + struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, 301 + entry->vp_index); 302 + if (unlikely(!host)) { 303 + ql_dbg(ql_dbg_tgt, vha, 0xe044, 304 + "qla_target(%d): Response pkt " 305 + "(ABTS_RECV_24XX) received, with unknown " 306 + "vp_index %d\n", vha->vp_idx, entry->vp_index); 307 + break; 308 + } 309 + qlt_response_pkt(host, pkt); 310 + break; 311 + } 312 + 313 + case ABTS_RESP_24XX: 314 + { 315 + struct abts_resp_to_24xx *entry = 316 + (struct abts_resp_to_24xx *)pkt; 317 + struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha, 318 + entry->vp_index); 319 + if (unlikely(!host)) { 320 + ql_dbg(ql_dbg_tgt, vha, 0xe045, 321 + "qla_target(%d): Response pkt " 322 + "(ABTS_RECV_24XX) received, with unknown " 323 + "vp_index %d\n", vha->vp_idx, entry->vp_index); 324 + break; 325 + } 326 + qlt_response_pkt(host, pkt); 327 + break; 328 + } 329 + 330 + default: 331 + qlt_response_pkt(vha, pkt); 332 + break; 333 + } 334 + 335 + } 336 + 337 + static void qlt_free_session_done(struct work_struct *work) 338 + { 339 + struct qla_tgt_sess *sess = container_of(work, struct qla_tgt_sess, 340 + free_work); 341 + struct qla_tgt *tgt = sess->tgt; 342 + struct scsi_qla_host *vha = sess->vha; 343 + struct qla_hw_data *ha = vha->hw; 344 + 345 + BUG_ON(!tgt); 346 + /* 347 + * Release the target session for FC Nexus from fabric module code. 348 + */ 349 + if (sess->se_sess != NULL) 350 + ha->tgt.tgt_ops->free_session(sess); 351 + 352 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, 353 + "Unregistration of sess %p finished\n", sess); 354 + 355 + kfree(sess); 356 + /* 357 + * We need to protect against race, when tgt is freed before or 358 + * inside wake_up() 359 + */ 360 + tgt->sess_count--; 361 + if (tgt->sess_count == 0) 362 + wake_up_all(&tgt->waitQ); 363 + } 364 + 365 + /* ha->hardware_lock supposed to be held on entry */ 366 + void qlt_unreg_sess(struct qla_tgt_sess *sess) 367 + { 368 + struct scsi_qla_host *vha = sess->vha; 369 + 370 + vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); 371 + 372 + list_del(&sess->sess_list_entry); 373 + if (sess->deleted) 374 + list_del(&sess->del_list_entry); 375 + 376 + INIT_WORK(&sess->free_work, qlt_free_session_done); 377 + schedule_work(&sess->free_work); 378 + } 379 + EXPORT_SYMBOL(qlt_unreg_sess); 380 + 381 + /* ha->hardware_lock supposed to be held on entry */ 382 + static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd) 383 + { 384 + struct qla_hw_data *ha = vha->hw; 385 + struct qla_tgt_sess *sess = NULL; 386 + uint32_t unpacked_lun, lun = 0; 387 + uint16_t loop_id; 388 + int res = 0; 389 + struct imm_ntfy_from_isp *n = (struct imm_ntfy_from_isp *)iocb; 390 + struct atio_from_isp *a = (struct atio_from_isp *)iocb; 391 + 392 + loop_id = le16_to_cpu(n->u.isp24.nport_handle); 393 + if (loop_id == 0xFFFF) { 394 + #if 0 /* FIXME: Re-enable Global event handling.. */ 395 + /* Global event */ 396 + atomic_inc(&ha->tgt.qla_tgt->tgt_global_resets_count); 397 + qlt_clear_tgt_db(ha->tgt.qla_tgt, 1); 398 + if (!list_empty(&ha->tgt.qla_tgt->sess_list)) { 399 + sess = list_entry(ha->tgt.qla_tgt->sess_list.next, 400 + typeof(*sess), sess_list_entry); 401 + switch (mcmd) { 402 + case QLA_TGT_NEXUS_LOSS_SESS: 403 + mcmd = QLA_TGT_NEXUS_LOSS; 404 + break; 405 + case QLA_TGT_ABORT_ALL_SESS: 406 + mcmd = QLA_TGT_ABORT_ALL; 407 + break; 408 + case QLA_TGT_NEXUS_LOSS: 409 + case QLA_TGT_ABORT_ALL: 410 + break; 411 + default: 412 + ql_dbg(ql_dbg_tgt, vha, 0xe046, 413 + "qla_target(%d): Not allowed " 414 + "command %x in %s", vha->vp_idx, 415 + mcmd, __func__); 416 + sess = NULL; 417 + break; 418 + } 419 + } else 420 + sess = NULL; 421 + #endif 422 + } else { 423 + sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id); 424 + } 425 + 426 + ql_dbg(ql_dbg_tgt, vha, 0xe000, 427 + "Using sess for qla_tgt_reset: %p\n", sess); 428 + if (!sess) { 429 + res = -ESRCH; 430 + return res; 431 + } 432 + 433 + ql_dbg(ql_dbg_tgt, vha, 0xe047, 434 + "scsi(%ld): resetting (session %p from port " 435 + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, " 436 + "mcmd %x, loop_id %d)\n", vha->host_no, sess, 437 + sess->port_name[0], sess->port_name[1], 438 + sess->port_name[2], sess->port_name[3], 439 + sess->port_name[4], sess->port_name[5], 440 + sess->port_name[6], sess->port_name[7], 441 + mcmd, loop_id); 442 + 443 + lun = a->u.isp24.fcp_cmnd.lun; 444 + unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); 445 + 446 + return qlt_issue_task_mgmt(sess, unpacked_lun, mcmd, 447 + iocb, QLA24XX_MGMT_SEND_NACK); 448 + } 449 + 450 + /* ha->hardware_lock supposed to be held on entry */ 451 + static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess, 452 + bool immediate) 453 + { 454 + struct qla_tgt *tgt = sess->tgt; 455 + uint32_t dev_loss_tmo = tgt->ha->port_down_retry_count + 5; 456 + 457 + if (sess->deleted) 458 + return; 459 + 460 + ql_dbg(ql_dbg_tgt, sess->vha, 0xe001, 461 + "Scheduling sess %p for deletion\n", sess); 462 + list_add_tail(&sess->del_list_entry, &tgt->del_sess_list); 463 + sess->deleted = 1; 464 + 465 + if (immediate) 466 + dev_loss_tmo = 0; 467 + 468 + sess->expires = jiffies + dev_loss_tmo * HZ; 469 + 470 + ql_dbg(ql_dbg_tgt, sess->vha, 0xe048, 471 + "qla_target(%d): session for port %02x:%02x:%02x:" 472 + "%02x:%02x:%02x:%02x:%02x (loop ID %d) scheduled for " 473 + "deletion in %u secs (expires: %lu) immed: %d\n", 474 + sess->vha->vp_idx, 475 + sess->port_name[0], sess->port_name[1], 476 + sess->port_name[2], sess->port_name[3], 477 + sess->port_name[4], sess->port_name[5], 478 + sess->port_name[6], sess->port_name[7], 479 + sess->loop_id, dev_loss_tmo, sess->expires, immediate); 480 + 481 + if (immediate) 482 + schedule_delayed_work(&tgt->sess_del_work, 0); 483 + else 484 + schedule_delayed_work(&tgt->sess_del_work, 485 + jiffies - sess->expires); 486 + } 487 + 488 + /* ha->hardware_lock supposed to be held on entry */ 489 + static void qlt_clear_tgt_db(struct qla_tgt *tgt, bool local_only) 490 + { 491 + struct qla_tgt_sess *sess; 492 + 493 + list_for_each_entry(sess, &tgt->sess_list, sess_list_entry) 494 + qlt_schedule_sess_for_deletion(sess, true); 495 + 496 + /* At this point tgt could be already dead */ 497 + } 498 + 499 + static int qla24xx_get_loop_id(struct scsi_qla_host *vha, const uint8_t *s_id, 500 + uint16_t *loop_id) 501 + { 502 + struct qla_hw_data *ha = vha->hw; 503 + dma_addr_t gid_list_dma; 504 + struct gid_list_info *gid_list; 505 + char *id_iter; 506 + int res, rc, i; 507 + uint16_t entries; 508 + 509 + gid_list = dma_alloc_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 510 + &gid_list_dma, GFP_KERNEL); 511 + if (!gid_list) { 512 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf044, 513 + "qla_target(%d): DMA Alloc failed of %u\n", 514 + vha->vp_idx, qla2x00_gid_list_size(ha)); 515 + return -ENOMEM; 516 + } 517 + 518 + /* Get list of logged in devices */ 519 + rc = qla2x00_get_id_list(vha, gid_list, gid_list_dma, &entries); 520 + if (rc != QLA_SUCCESS) { 521 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf045, 522 + "qla_target(%d): get_id_list() failed: %x\n", 523 + vha->vp_idx, rc); 524 + res = -1; 525 + goto out_free_id_list; 526 + } 527 + 528 + id_iter = (char *)gid_list; 529 + res = -1; 530 + for (i = 0; i < entries; i++) { 531 + struct gid_list_info *gid = (struct gid_list_info *)id_iter; 532 + if ((gid->al_pa == s_id[2]) && 533 + (gid->area == s_id[1]) && 534 + (gid->domain == s_id[0])) { 535 + *loop_id = le16_to_cpu(gid->loop_id); 536 + res = 0; 537 + break; 538 + } 539 + id_iter += ha->gid_list_info_size; 540 + } 541 + 542 + out_free_id_list: 543 + dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), 544 + gid_list, gid_list_dma); 545 + return res; 546 + } 547 + 548 + static bool qlt_check_fcport_exist(struct scsi_qla_host *vha, 549 + struct qla_tgt_sess *sess) 550 + { 551 + struct qla_hw_data *ha = vha->hw; 552 + struct qla_port_24xx_data *pmap24; 553 + bool res, found = false; 554 + int rc, i; 555 + uint16_t loop_id = 0xFFFF; /* to eliminate compiler's warning */ 556 + uint16_t entries; 557 + void *pmap; 558 + int pmap_len; 559 + fc_port_t *fcport; 560 + int global_resets; 561 + 562 + retry: 563 + global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); 564 + 565 + rc = qla2x00_get_node_name_list(vha, &pmap, &pmap_len); 566 + if (rc != QLA_SUCCESS) { 567 + res = false; 568 + goto out; 569 + } 570 + 571 + pmap24 = pmap; 572 + entries = pmap_len/sizeof(*pmap24); 573 + 574 + for (i = 0; i < entries; ++i) { 575 + if (!memcmp(sess->port_name, pmap24[i].port_name, WWN_SIZE)) { 576 + loop_id = le16_to_cpu(pmap24[i].loop_id); 577 + found = true; 578 + break; 579 + } 580 + } 581 + 582 + kfree(pmap); 583 + 584 + if (!found) { 585 + res = false; 586 + goto out; 587 + } 588 + 589 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf046, 590 + "qlt_check_fcport_exist(): loop_id %d", loop_id); 591 + 592 + fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); 593 + if (fcport == NULL) { 594 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf047, 595 + "qla_target(%d): Allocation of tmp FC port failed", 596 + vha->vp_idx); 597 + res = false; 598 + goto out; 599 + } 600 + 601 + fcport->loop_id = loop_id; 602 + 603 + rc = qla2x00_get_port_database(vha, fcport, 0); 604 + if (rc != QLA_SUCCESS) { 605 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf048, 606 + "qla_target(%d): Failed to retrieve fcport " 607 + "information -- get_port_database() returned %x " 608 + "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); 609 + res = false; 610 + goto out_free_fcport; 611 + } 612 + 613 + if (global_resets != 614 + atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { 615 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf002, 616 + "qla_target(%d): global reset during session discovery" 617 + " (counter was %d, new %d), retrying", 618 + vha->vp_idx, global_resets, 619 + atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); 620 + goto retry; 621 + } 622 + 623 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf003, 624 + "Updating sess %p s_id %x:%x:%x, loop_id %d) to d_id %x:%x:%x, " 625 + "loop_id %d", sess, sess->s_id.b.domain, sess->s_id.b.al_pa, 626 + sess->s_id.b.area, sess->loop_id, fcport->d_id.b.domain, 627 + fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->loop_id); 628 + 629 + sess->s_id = fcport->d_id; 630 + sess->loop_id = fcport->loop_id; 631 + sess->conf_compl_supported = !!(fcport->flags & 632 + FCF_CONF_COMP_SUPPORTED); 633 + 634 + res = true; 635 + 636 + out_free_fcport: 637 + kfree(fcport); 638 + 639 + out: 640 + return res; 641 + } 642 + 643 + /* ha->hardware_lock supposed to be held on entry */ 644 + static void qlt_undelete_sess(struct qla_tgt_sess *sess) 645 + { 646 + BUG_ON(!sess->deleted); 647 + 648 + list_del(&sess->del_list_entry); 649 + sess->deleted = 0; 650 + } 651 + 652 + static void qlt_del_sess_work_fn(struct delayed_work *work) 653 + { 654 + struct qla_tgt *tgt = container_of(work, struct qla_tgt, 655 + sess_del_work); 656 + struct scsi_qla_host *vha = tgt->vha; 657 + struct qla_hw_data *ha = vha->hw; 658 + struct qla_tgt_sess *sess; 659 + unsigned long flags; 660 + 661 + spin_lock_irqsave(&ha->hardware_lock, flags); 662 + while (!list_empty(&tgt->del_sess_list)) { 663 + sess = list_entry(tgt->del_sess_list.next, typeof(*sess), 664 + del_list_entry); 665 + if (time_after_eq(jiffies, sess->expires)) { 666 + bool cancel; 667 + 668 + qlt_undelete_sess(sess); 669 + 670 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 671 + cancel = qlt_check_fcport_exist(vha, sess); 672 + 673 + if (cancel) { 674 + if (sess->deleted) { 675 + /* 676 + * sess was again deleted while we were 677 + * discovering it 678 + */ 679 + spin_lock_irqsave(&ha->hardware_lock, 680 + flags); 681 + continue; 682 + } 683 + 684 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf049, 685 + "qla_target(%d): cancel deletion of " 686 + "session for port %02x:%02x:%02x:%02x:%02x:" 687 + "%02x:%02x:%02x (loop ID %d), because " 688 + " it isn't deleted by firmware", 689 + vha->vp_idx, sess->port_name[0], 690 + sess->port_name[1], sess->port_name[2], 691 + sess->port_name[3], sess->port_name[4], 692 + sess->port_name[5], sess->port_name[6], 693 + sess->port_name[7], sess->loop_id); 694 + } else { 695 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004, 696 + "Timeout: sess %p about to be deleted\n", 697 + sess); 698 + ha->tgt.tgt_ops->shutdown_sess(sess); 699 + ha->tgt.tgt_ops->put_sess(sess); 700 + } 701 + 702 + spin_lock_irqsave(&ha->hardware_lock, flags); 703 + } else { 704 + schedule_delayed_work(&tgt->sess_del_work, 705 + jiffies - sess->expires); 706 + break; 707 + } 708 + } 709 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 710 + } 711 + 712 + /* 713 + * Adds an extra ref to allow to drop hw lock after adding sess to the list. 714 + * Caller must put it. 715 + */ 716 + static struct qla_tgt_sess *qlt_create_sess( 717 + struct scsi_qla_host *vha, 718 + fc_port_t *fcport, 719 + bool local) 720 + { 721 + struct qla_hw_data *ha = vha->hw; 722 + struct qla_tgt_sess *sess; 723 + unsigned long flags; 724 + unsigned char be_sid[3]; 725 + 726 + /* Check to avoid double sessions */ 727 + spin_lock_irqsave(&ha->hardware_lock, flags); 728 + list_for_each_entry(sess, &ha->tgt.qla_tgt->sess_list, 729 + sess_list_entry) { 730 + if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) { 731 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005, 732 + "Double sess %p found (s_id %x:%x:%x, " 733 + "loop_id %d), updating to d_id %x:%x:%x, " 734 + "loop_id %d", sess, sess->s_id.b.domain, 735 + sess->s_id.b.al_pa, sess->s_id.b.area, 736 + sess->loop_id, fcport->d_id.b.domain, 737 + fcport->d_id.b.al_pa, fcport->d_id.b.area, 738 + fcport->loop_id); 739 + 740 + if (sess->deleted) 741 + qlt_undelete_sess(sess); 742 + 743 + kref_get(&sess->se_sess->sess_kref); 744 + sess->s_id = fcport->d_id; 745 + sess->loop_id = fcport->loop_id; 746 + sess->conf_compl_supported = !!(fcport->flags & 747 + FCF_CONF_COMP_SUPPORTED); 748 + if (sess->local && !local) 749 + sess->local = 0; 750 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 751 + 752 + return sess; 753 + } 754 + } 755 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 756 + 757 + sess = kzalloc(sizeof(*sess), GFP_KERNEL); 758 + if (!sess) { 759 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04a, 760 + "qla_target(%u): session allocation failed, " 761 + "all commands from port %02x:%02x:%02x:%02x:" 762 + "%02x:%02x:%02x:%02x will be refused", vha->vp_idx, 763 + fcport->port_name[0], fcport->port_name[1], 764 + fcport->port_name[2], fcport->port_name[3], 765 + fcport->port_name[4], fcport->port_name[5], 766 + fcport->port_name[6], fcport->port_name[7]); 767 + 768 + return NULL; 769 + } 770 + sess->tgt = ha->tgt.qla_tgt; 771 + sess->vha = vha; 772 + sess->s_id = fcport->d_id; 773 + sess->loop_id = fcport->loop_id; 774 + sess->local = local; 775 + 776 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006, 777 + "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n", 778 + sess, ha->tgt.qla_tgt); 779 + 780 + be_sid[0] = sess->s_id.b.domain; 781 + be_sid[1] = sess->s_id.b.area; 782 + be_sid[2] = sess->s_id.b.al_pa; 783 + /* 784 + * Determine if this fc_port->port_name is allowed to access 785 + * target mode using explict NodeACLs+MappedLUNs, or using 786 + * TPG demo mode. If this is successful a target mode FC nexus 787 + * is created. 788 + */ 789 + if (ha->tgt.tgt_ops->check_initiator_node_acl(vha, 790 + &fcport->port_name[0], sess, &be_sid[0], fcport->loop_id) < 0) { 791 + kfree(sess); 792 + return NULL; 793 + } 794 + /* 795 + * Take an extra reference to ->sess_kref here to handle qla_tgt_sess 796 + * access across ->hardware_lock reaquire. 797 + */ 798 + kref_get(&sess->se_sess->sess_kref); 799 + 800 + sess->conf_compl_supported = !!(fcport->flags & 801 + FCF_CONF_COMP_SUPPORTED); 802 + BUILD_BUG_ON(sizeof(sess->port_name) != sizeof(fcport->port_name)); 803 + memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); 804 + 805 + spin_lock_irqsave(&ha->hardware_lock, flags); 806 + list_add_tail(&sess->sess_list_entry, &ha->tgt.qla_tgt->sess_list); 807 + ha->tgt.qla_tgt->sess_count++; 808 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 809 + 810 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b, 811 + "qla_target(%d): %ssession for wwn %02x:%02x:%02x:%02x:" 812 + "%02x:%02x:%02x:%02x (loop_id %d, s_id %x:%x:%x, confirmed" 813 + " completion %ssupported) added\n", 814 + vha->vp_idx, local ? "local " : "", fcport->port_name[0], 815 + fcport->port_name[1], fcport->port_name[2], fcport->port_name[3], 816 + fcport->port_name[4], fcport->port_name[5], fcport->port_name[6], 817 + fcport->port_name[7], fcport->loop_id, sess->s_id.b.domain, 818 + sess->s_id.b.area, sess->s_id.b.al_pa, sess->conf_compl_supported ? 819 + "" : "not "); 820 + 821 + return sess; 822 + } 823 + 824 + /* 825 + * Called from drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() 826 + */ 827 + void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) 828 + { 829 + struct qla_hw_data *ha = vha->hw; 830 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 831 + struct qla_tgt_sess *sess; 832 + unsigned long flags; 833 + 834 + if (!vha->hw->tgt.tgt_ops) 835 + return; 836 + 837 + if (!tgt || (fcport->port_type != FCT_INITIATOR)) 838 + return; 839 + 840 + spin_lock_irqsave(&ha->hardware_lock, flags); 841 + if (tgt->tgt_stop) { 842 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 843 + return; 844 + } 845 + sess = qlt_find_sess_by_port_name(tgt, fcport->port_name); 846 + if (!sess) { 847 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 848 + 849 + mutex_lock(&ha->tgt.tgt_mutex); 850 + sess = qlt_create_sess(vha, fcport, false); 851 + mutex_unlock(&ha->tgt.tgt_mutex); 852 + 853 + spin_lock_irqsave(&ha->hardware_lock, flags); 854 + } else { 855 + kref_get(&sess->se_sess->sess_kref); 856 + 857 + if (sess->deleted) { 858 + qlt_undelete_sess(sess); 859 + 860 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04c, 861 + "qla_target(%u): %ssession for port %02x:" 862 + "%02x:%02x:%02x:%02x:%02x:%02x:%02x (loop ID %d) " 863 + "reappeared\n", vha->vp_idx, sess->local ? "local " 864 + : "", sess->port_name[0], sess->port_name[1], 865 + sess->port_name[2], sess->port_name[3], 866 + sess->port_name[4], sess->port_name[5], 867 + sess->port_name[6], sess->port_name[7], 868 + sess->loop_id); 869 + 870 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf007, 871 + "Reappeared sess %p\n", sess); 872 + } 873 + sess->s_id = fcport->d_id; 874 + sess->loop_id = fcport->loop_id; 875 + sess->conf_compl_supported = !!(fcport->flags & 876 + FCF_CONF_COMP_SUPPORTED); 877 + } 878 + 879 + if (sess && sess->local) { 880 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04d, 881 + "qla_target(%u): local session for " 882 + "port %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x " 883 + "(loop ID %d) became global\n", vha->vp_idx, 884 + fcport->port_name[0], fcport->port_name[1], 885 + fcport->port_name[2], fcport->port_name[3], 886 + fcport->port_name[4], fcport->port_name[5], 887 + fcport->port_name[6], fcport->port_name[7], 888 + sess->loop_id); 889 + sess->local = 0; 890 + } 891 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 892 + 893 + ha->tgt.tgt_ops->put_sess(sess); 894 + } 895 + 896 + void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) 897 + { 898 + struct qla_hw_data *ha = vha->hw; 899 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 900 + struct qla_tgt_sess *sess; 901 + unsigned long flags; 902 + 903 + if (!vha->hw->tgt.tgt_ops) 904 + return; 905 + 906 + if (!tgt || (fcport->port_type != FCT_INITIATOR)) 907 + return; 908 + 909 + spin_lock_irqsave(&ha->hardware_lock, flags); 910 + if (tgt->tgt_stop) { 911 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 912 + return; 913 + } 914 + sess = qlt_find_sess_by_port_name(tgt, fcport->port_name); 915 + if (!sess) { 916 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 917 + return; 918 + } 919 + 920 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess); 921 + 922 + sess->local = 1; 923 + qlt_schedule_sess_for_deletion(sess, false); 924 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 925 + } 926 + 927 + static inline int test_tgt_sess_count(struct qla_tgt *tgt) 928 + { 929 + struct qla_hw_data *ha = tgt->ha; 930 + unsigned long flags; 931 + int res; 932 + /* 933 + * We need to protect against race, when tgt is freed before or 934 + * inside wake_up() 935 + */ 936 + spin_lock_irqsave(&ha->hardware_lock, flags); 937 + ql_dbg(ql_dbg_tgt, tgt->vha, 0xe002, 938 + "tgt %p, empty(sess_list)=%d sess_count=%d\n", 939 + tgt, list_empty(&tgt->sess_list), tgt->sess_count); 940 + res = (tgt->sess_count == 0); 941 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 942 + 943 + return res; 944 + } 945 + 946 + /* Called by tcm_qla2xxx configfs code */ 947 + void qlt_stop_phase1(struct qla_tgt *tgt) 948 + { 949 + struct scsi_qla_host *vha = tgt->vha; 950 + struct qla_hw_data *ha = tgt->ha; 951 + unsigned long flags; 952 + 953 + if (tgt->tgt_stop || tgt->tgt_stopped) { 954 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, 955 + "Already in tgt->tgt_stop or tgt_stopped state\n"); 956 + dump_stack(); 957 + return; 958 + } 959 + 960 + ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", 961 + vha->host_no, vha); 962 + /* 963 + * Mutex needed to sync with qla_tgt_fc_port_[added,deleted]. 964 + * Lock is needed, because we still can get an incoming packet. 965 + */ 966 + mutex_lock(&ha->tgt.tgt_mutex); 967 + spin_lock_irqsave(&ha->hardware_lock, flags); 968 + tgt->tgt_stop = 1; 969 + qlt_clear_tgt_db(tgt, true); 970 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 971 + mutex_unlock(&ha->tgt.tgt_mutex); 972 + 973 + flush_delayed_work_sync(&tgt->sess_del_work); 974 + 975 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf009, 976 + "Waiting for sess works (tgt %p)", tgt); 977 + spin_lock_irqsave(&tgt->sess_work_lock, flags); 978 + while (!list_empty(&tgt->sess_works_list)) { 979 + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 980 + flush_scheduled_work(); 981 + spin_lock_irqsave(&tgt->sess_work_lock, flags); 982 + } 983 + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 984 + 985 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00a, 986 + "Waiting for tgt %p: list_empty(sess_list)=%d " 987 + "sess_count=%d\n", tgt, list_empty(&tgt->sess_list), 988 + tgt->sess_count); 989 + 990 + wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); 991 + 992 + /* Big hammer */ 993 + if (!ha->flags.host_shutting_down && qla_tgt_mode_enabled(vha)) 994 + qlt_disable_vha(vha); 995 + 996 + /* Wait for sessions to clear out (just in case) */ 997 + wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); 998 + } 999 + EXPORT_SYMBOL(qlt_stop_phase1); 1000 + 1001 + /* Called by tcm_qla2xxx configfs code */ 1002 + void qlt_stop_phase2(struct qla_tgt *tgt) 1003 + { 1004 + struct qla_hw_data *ha = tgt->ha; 1005 + unsigned long flags; 1006 + 1007 + if (tgt->tgt_stopped) { 1008 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf04f, 1009 + "Already in tgt->tgt_stopped state\n"); 1010 + dump_stack(); 1011 + return; 1012 + } 1013 + 1014 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00b, 1015 + "Waiting for %d IRQ commands to complete (tgt %p)", 1016 + tgt->irq_cmd_count, tgt); 1017 + 1018 + mutex_lock(&ha->tgt.tgt_mutex); 1019 + spin_lock_irqsave(&ha->hardware_lock, flags); 1020 + while (tgt->irq_cmd_count != 0) { 1021 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 1022 + udelay(2); 1023 + spin_lock_irqsave(&ha->hardware_lock, flags); 1024 + } 1025 + tgt->tgt_stop = 0; 1026 + tgt->tgt_stopped = 1; 1027 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 1028 + mutex_unlock(&ha->tgt.tgt_mutex); 1029 + 1030 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00c, "Stop of tgt %p finished", 1031 + tgt); 1032 + } 1033 + EXPORT_SYMBOL(qlt_stop_phase2); 1034 + 1035 + /* Called from qlt_remove_target() -> qla2x00_remove_one() */ 1036 + void qlt_release(struct qla_tgt *tgt) 1037 + { 1038 + struct qla_hw_data *ha = tgt->ha; 1039 + 1040 + if ((ha->tgt.qla_tgt != NULL) && !tgt->tgt_stopped) 1041 + qlt_stop_phase2(tgt); 1042 + 1043 + ha->tgt.qla_tgt = NULL; 1044 + 1045 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00d, 1046 + "Release of tgt %p finished\n", tgt); 1047 + 1048 + kfree(tgt); 1049 + } 1050 + 1051 + /* ha->hardware_lock supposed to be held on entry */ 1052 + static int qlt_sched_sess_work(struct qla_tgt *tgt, int type, 1053 + const void *param, unsigned int param_size) 1054 + { 1055 + struct qla_tgt_sess_work_param *prm; 1056 + unsigned long flags; 1057 + 1058 + prm = kzalloc(sizeof(*prm), GFP_ATOMIC); 1059 + if (!prm) { 1060 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf050, 1061 + "qla_target(%d): Unable to create session " 1062 + "work, command will be refused", 0); 1063 + return -ENOMEM; 1064 + } 1065 + 1066 + ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00e, 1067 + "Scheduling work (type %d, prm %p)" 1068 + " to find session for param %p (size %d, tgt %p)\n", 1069 + type, prm, param, param_size, tgt); 1070 + 1071 + prm->type = type; 1072 + memcpy(&prm->tm_iocb, param, param_size); 1073 + 1074 + spin_lock_irqsave(&tgt->sess_work_lock, flags); 1075 + list_add_tail(&prm->sess_works_list_entry, &tgt->sess_works_list); 1076 + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 1077 + 1078 + schedule_work(&tgt->sess_work); 1079 + 1080 + return 0; 1081 + } 1082 + 1083 + /* 1084 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1085 + */ 1086 + static void qlt_send_notify_ack(struct scsi_qla_host *vha, 1087 + struct imm_ntfy_from_isp *ntfy, 1088 + uint32_t add_flags, uint16_t resp_code, int resp_code_valid, 1089 + uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan) 1090 + { 1091 + struct qla_hw_data *ha = vha->hw; 1092 + request_t *pkt; 1093 + struct nack_to_isp *nack; 1094 + 1095 + ql_dbg(ql_dbg_tgt, vha, 0xe004, "Sending NOTIFY_ACK (ha=%p)\n", ha); 1096 + 1097 + /* Send marker if required */ 1098 + if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) 1099 + return; 1100 + 1101 + pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); 1102 + if (!pkt) { 1103 + ql_dbg(ql_dbg_tgt, vha, 0xe049, 1104 + "qla_target(%d): %s failed: unable to allocate " 1105 + "request packet\n", vha->vp_idx, __func__); 1106 + return; 1107 + } 1108 + 1109 + if (ha->tgt.qla_tgt != NULL) 1110 + ha->tgt.qla_tgt->notify_ack_expected++; 1111 + 1112 + pkt->entry_type = NOTIFY_ACK_TYPE; 1113 + pkt->entry_count = 1; 1114 + 1115 + nack = (struct nack_to_isp *)pkt; 1116 + nack->ox_id = ntfy->ox_id; 1117 + 1118 + nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle; 1119 + if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) { 1120 + nack->u.isp24.flags = ntfy->u.isp24.flags & 1121 + __constant_cpu_to_le32(NOTIFY24XX_FLAGS_PUREX_IOCB); 1122 + } 1123 + nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id; 1124 + nack->u.isp24.status = ntfy->u.isp24.status; 1125 + nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode; 1126 + nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address; 1127 + nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs; 1128 + nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui; 1129 + nack->u.isp24.srr_flags = cpu_to_le16(srr_flags); 1130 + nack->u.isp24.srr_reject_code = srr_reject_code; 1131 + nack->u.isp24.srr_reject_code_expl = srr_explan; 1132 + nack->u.isp24.vp_index = ntfy->u.isp24.vp_index; 1133 + 1134 + ql_dbg(ql_dbg_tgt, vha, 0xe005, 1135 + "qla_target(%d): Sending 24xx Notify Ack %d\n", 1136 + vha->vp_idx, nack->u.isp24.status); 1137 + 1138 + qla2x00_start_iocbs(vha, vha->req); 1139 + } 1140 + 1141 + /* 1142 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1143 + */ 1144 + static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, 1145 + struct abts_recv_from_24xx *abts, uint32_t status, 1146 + bool ids_reversed) 1147 + { 1148 + struct qla_hw_data *ha = vha->hw; 1149 + struct abts_resp_to_24xx *resp; 1150 + uint32_t f_ctl; 1151 + uint8_t *p; 1152 + 1153 + ql_dbg(ql_dbg_tgt, vha, 0xe006, 1154 + "Sending task mgmt ABTS response (ha=%p, atio=%p, status=%x\n", 1155 + ha, abts, status); 1156 + 1157 + /* Send marker if required */ 1158 + if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) 1159 + return; 1160 + 1161 + resp = (struct abts_resp_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); 1162 + if (!resp) { 1163 + ql_dbg(ql_dbg_tgt, vha, 0xe04a, 1164 + "qla_target(%d): %s failed: unable to allocate " 1165 + "request packet", vha->vp_idx, __func__); 1166 + return; 1167 + } 1168 + 1169 + resp->entry_type = ABTS_RESP_24XX; 1170 + resp->entry_count = 1; 1171 + resp->nport_handle = abts->nport_handle; 1172 + resp->vp_index = vha->vp_idx; 1173 + resp->sof_type = abts->sof_type; 1174 + resp->exchange_address = abts->exchange_address; 1175 + resp->fcp_hdr_le = abts->fcp_hdr_le; 1176 + f_ctl = __constant_cpu_to_le32(F_CTL_EXCH_CONTEXT_RESP | 1177 + F_CTL_LAST_SEQ | F_CTL_END_SEQ | 1178 + F_CTL_SEQ_INITIATIVE); 1179 + p = (uint8_t *)&f_ctl; 1180 + resp->fcp_hdr_le.f_ctl[0] = *p++; 1181 + resp->fcp_hdr_le.f_ctl[1] = *p++; 1182 + resp->fcp_hdr_le.f_ctl[2] = *p; 1183 + if (ids_reversed) { 1184 + resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.d_id[0]; 1185 + resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.d_id[1]; 1186 + resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.d_id[2]; 1187 + resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.s_id[0]; 1188 + resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.s_id[1]; 1189 + resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.s_id[2]; 1190 + } else { 1191 + resp->fcp_hdr_le.d_id[0] = abts->fcp_hdr_le.s_id[0]; 1192 + resp->fcp_hdr_le.d_id[1] = abts->fcp_hdr_le.s_id[1]; 1193 + resp->fcp_hdr_le.d_id[2] = abts->fcp_hdr_le.s_id[2]; 1194 + resp->fcp_hdr_le.s_id[0] = abts->fcp_hdr_le.d_id[0]; 1195 + resp->fcp_hdr_le.s_id[1] = abts->fcp_hdr_le.d_id[1]; 1196 + resp->fcp_hdr_le.s_id[2] = abts->fcp_hdr_le.d_id[2]; 1197 + } 1198 + resp->exchange_addr_to_abort = abts->exchange_addr_to_abort; 1199 + if (status == FCP_TMF_CMPL) { 1200 + resp->fcp_hdr_le.r_ctl = R_CTL_BASIC_LINK_SERV | R_CTL_B_ACC; 1201 + resp->payload.ba_acct.seq_id_valid = SEQ_ID_INVALID; 1202 + resp->payload.ba_acct.low_seq_cnt = 0x0000; 1203 + resp->payload.ba_acct.high_seq_cnt = 0xFFFF; 1204 + resp->payload.ba_acct.ox_id = abts->fcp_hdr_le.ox_id; 1205 + resp->payload.ba_acct.rx_id = abts->fcp_hdr_le.rx_id; 1206 + } else { 1207 + resp->fcp_hdr_le.r_ctl = R_CTL_BASIC_LINK_SERV | R_CTL_B_RJT; 1208 + resp->payload.ba_rjt.reason_code = 1209 + BA_RJT_REASON_CODE_UNABLE_TO_PERFORM; 1210 + /* Other bytes are zero */ 1211 + } 1212 + 1213 + ha->tgt.qla_tgt->abts_resp_expected++; 1214 + 1215 + qla2x00_start_iocbs(vha, vha->req); 1216 + } 1217 + 1218 + /* 1219 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1220 + */ 1221 + static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha, 1222 + struct abts_resp_from_24xx_fw *entry) 1223 + { 1224 + struct ctio7_to_24xx *ctio; 1225 + 1226 + ql_dbg(ql_dbg_tgt, vha, 0xe007, 1227 + "Sending retry TERM EXCH CTIO7 (ha=%p)\n", vha->hw); 1228 + /* Send marker if required */ 1229 + if (qlt_issue_marker(vha, 1) != QLA_SUCCESS) 1230 + return; 1231 + 1232 + ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); 1233 + if (ctio == NULL) { 1234 + ql_dbg(ql_dbg_tgt, vha, 0xe04b, 1235 + "qla_target(%d): %s failed: unable to allocate " 1236 + "request packet\n", vha->vp_idx, __func__); 1237 + return; 1238 + } 1239 + 1240 + /* 1241 + * We've got on entrance firmware's response on by us generated 1242 + * ABTS response. So, in it ID fields are reversed. 1243 + */ 1244 + 1245 + ctio->entry_type = CTIO_TYPE7; 1246 + ctio->entry_count = 1; 1247 + ctio->nport_handle = entry->nport_handle; 1248 + ctio->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 1249 + ctio->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); 1250 + ctio->vp_index = vha->vp_idx; 1251 + ctio->initiator_id[0] = entry->fcp_hdr_le.d_id[0]; 1252 + ctio->initiator_id[1] = entry->fcp_hdr_le.d_id[1]; 1253 + ctio->initiator_id[2] = entry->fcp_hdr_le.d_id[2]; 1254 + ctio->exchange_addr = entry->exchange_addr_to_abort; 1255 + ctio->u.status1.flags = 1256 + __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | 1257 + CTIO7_FLAGS_TERMINATE); 1258 + ctio->u.status1.ox_id = entry->fcp_hdr_le.ox_id; 1259 + 1260 + qla2x00_start_iocbs(vha, vha->req); 1261 + 1262 + qlt_24xx_send_abts_resp(vha, (struct abts_recv_from_24xx *)entry, 1263 + FCP_TMF_CMPL, true); 1264 + } 1265 + 1266 + /* ha->hardware_lock supposed to be held on entry */ 1267 + static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, 1268 + struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess) 1269 + { 1270 + struct qla_hw_data *ha = vha->hw; 1271 + struct qla_tgt_mgmt_cmd *mcmd; 1272 + int rc; 1273 + 1274 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f, 1275 + "qla_target(%d): task abort (tag=%d)\n", 1276 + vha->vp_idx, abts->exchange_addr_to_abort); 1277 + 1278 + mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); 1279 + if (mcmd == NULL) { 1280 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf051, 1281 + "qla_target(%d): %s: Allocation of ABORT cmd failed", 1282 + vha->vp_idx, __func__); 1283 + return -ENOMEM; 1284 + } 1285 + memset(mcmd, 0, sizeof(*mcmd)); 1286 + 1287 + mcmd->sess = sess; 1288 + memcpy(&mcmd->orig_iocb.abts, abts, sizeof(mcmd->orig_iocb.abts)); 1289 + 1290 + rc = ha->tgt.tgt_ops->handle_tmr(mcmd, 0, TMR_ABORT_TASK, 1291 + abts->exchange_addr_to_abort); 1292 + if (rc != 0) { 1293 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf052, 1294 + "qla_target(%d): tgt_ops->handle_tmr()" 1295 + " failed: %d", vha->vp_idx, rc); 1296 + mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 1297 + return -EFAULT; 1298 + } 1299 + 1300 + return 0; 1301 + } 1302 + 1303 + /* 1304 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1305 + */ 1306 + static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, 1307 + struct abts_recv_from_24xx *abts) 1308 + { 1309 + struct qla_hw_data *ha = vha->hw; 1310 + struct qla_tgt_sess *sess; 1311 + uint32_t tag = abts->exchange_addr_to_abort; 1312 + uint8_t s_id[3]; 1313 + int rc; 1314 + 1315 + if (le32_to_cpu(abts->fcp_hdr_le.parameter) & ABTS_PARAM_ABORT_SEQ) { 1316 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf053, 1317 + "qla_target(%d): ABTS: Abort Sequence not " 1318 + "supported\n", vha->vp_idx); 1319 + qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); 1320 + return; 1321 + } 1322 + 1323 + if (tag == ATIO_EXCHANGE_ADDRESS_UNKNOWN) { 1324 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf010, 1325 + "qla_target(%d): ABTS: Unknown Exchange " 1326 + "Address received\n", vha->vp_idx); 1327 + qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); 1328 + return; 1329 + } 1330 + 1331 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf011, 1332 + "qla_target(%d): task abort (s_id=%x:%x:%x, " 1333 + "tag=%d, param=%x)\n", vha->vp_idx, abts->fcp_hdr_le.s_id[2], 1334 + abts->fcp_hdr_le.s_id[1], abts->fcp_hdr_le.s_id[0], tag, 1335 + le32_to_cpu(abts->fcp_hdr_le.parameter)); 1336 + 1337 + s_id[0] = abts->fcp_hdr_le.s_id[2]; 1338 + s_id[1] = abts->fcp_hdr_le.s_id[1]; 1339 + s_id[2] = abts->fcp_hdr_le.s_id[0]; 1340 + 1341 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); 1342 + if (!sess) { 1343 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, 1344 + "qla_target(%d): task abort for non-existant session\n", 1345 + vha->vp_idx); 1346 + rc = qlt_sched_sess_work(ha->tgt.qla_tgt, 1347 + QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts)); 1348 + if (rc != 0) { 1349 + qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, 1350 + false); 1351 + } 1352 + return; 1353 + } 1354 + 1355 + rc = __qlt_24xx_handle_abts(vha, abts, sess); 1356 + if (rc != 0) { 1357 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054, 1358 + "qla_target(%d): __qlt_24xx_handle_abts() failed: %d\n", 1359 + vha->vp_idx, rc); 1360 + qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false); 1361 + return; 1362 + } 1363 + } 1364 + 1365 + /* 1366 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1367 + */ 1368 + static void qlt_24xx_send_task_mgmt_ctio(struct scsi_qla_host *ha, 1369 + struct qla_tgt_mgmt_cmd *mcmd, uint32_t resp_code) 1370 + { 1371 + struct atio_from_isp *atio = &mcmd->orig_iocb.atio; 1372 + struct ctio7_to_24xx *ctio; 1373 + 1374 + ql_dbg(ql_dbg_tgt, ha, 0xe008, 1375 + "Sending task mgmt CTIO7 (ha=%p, atio=%p, resp_code=%x\n", 1376 + ha, atio, resp_code); 1377 + 1378 + /* Send marker if required */ 1379 + if (qlt_issue_marker(ha, 1) != QLA_SUCCESS) 1380 + return; 1381 + 1382 + ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(ha, NULL); 1383 + if (ctio == NULL) { 1384 + ql_dbg(ql_dbg_tgt, ha, 0xe04c, 1385 + "qla_target(%d): %s failed: unable to allocate " 1386 + "request packet\n", ha->vp_idx, __func__); 1387 + return; 1388 + } 1389 + 1390 + ctio->entry_type = CTIO_TYPE7; 1391 + ctio->entry_count = 1; 1392 + ctio->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 1393 + ctio->nport_handle = mcmd->sess->loop_id; 1394 + ctio->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); 1395 + ctio->vp_index = ha->vp_idx; 1396 + ctio->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 1397 + ctio->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; 1398 + ctio->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; 1399 + ctio->exchange_addr = atio->u.isp24.exchange_addr; 1400 + ctio->u.status1.flags = (atio->u.isp24.attr << 9) | 1401 + __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | 1402 + CTIO7_FLAGS_SEND_STATUS); 1403 + ctio->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); 1404 + ctio->u.status1.scsi_status = 1405 + __constant_cpu_to_le16(SS_RESPONSE_INFO_LEN_VALID); 1406 + ctio->u.status1.response_len = __constant_cpu_to_le16(8); 1407 + ((uint32_t *)ctio->u.status1.sense_data)[0] = cpu_to_be32(resp_code); 1408 + 1409 + qla2x00_start_iocbs(ha, ha->req); 1410 + } 1411 + 1412 + void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) 1413 + { 1414 + mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 1415 + } 1416 + EXPORT_SYMBOL(qlt_free_mcmd); 1417 + 1418 + /* callback from target fabric module code */ 1419 + void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *mcmd) 1420 + { 1421 + struct scsi_qla_host *vha = mcmd->sess->vha; 1422 + struct qla_hw_data *ha = vha->hw; 1423 + unsigned long flags; 1424 + 1425 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf013, 1426 + "TM response mcmd (%p) status %#x state %#x", 1427 + mcmd, mcmd->fc_tm_rsp, mcmd->flags); 1428 + 1429 + spin_lock_irqsave(&ha->hardware_lock, flags); 1430 + if (mcmd->flags == QLA24XX_MGMT_SEND_NACK) 1431 + qlt_send_notify_ack(vha, &mcmd->orig_iocb.imm_ntfy, 1432 + 0, 0, 0, 0, 0, 0); 1433 + else { 1434 + if (mcmd->se_cmd.se_tmr_req->function == TMR_ABORT_TASK) 1435 + qlt_24xx_send_abts_resp(vha, &mcmd->orig_iocb.abts, 1436 + mcmd->fc_tm_rsp, false); 1437 + else 1438 + qlt_24xx_send_task_mgmt_ctio(vha, mcmd, 1439 + mcmd->fc_tm_rsp); 1440 + } 1441 + /* 1442 + * Make the callback for ->free_mcmd() to queue_work() and invoke 1443 + * target_put_sess_cmd() to drop cmd_kref to 1. The final 1444 + * target_put_sess_cmd() call will be made from TFO->check_stop_free() 1445 + * -> tcm_qla2xxx_check_stop_free() to release the TMR associated se_cmd 1446 + * descriptor after TFO->queue_tm_rsp() -> tcm_qla2xxx_queue_tm_rsp() -> 1447 + * qlt_xmit_tm_rsp() returns here.. 1448 + */ 1449 + ha->tgt.tgt_ops->free_mcmd(mcmd); 1450 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 1451 + } 1452 + EXPORT_SYMBOL(qlt_xmit_tm_rsp); 1453 + 1454 + /* No locks */ 1455 + static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm) 1456 + { 1457 + struct qla_tgt_cmd *cmd = prm->cmd; 1458 + 1459 + BUG_ON(cmd->sg_cnt == 0); 1460 + 1461 + prm->sg = (struct scatterlist *)cmd->sg; 1462 + prm->seg_cnt = pci_map_sg(prm->tgt->ha->pdev, cmd->sg, 1463 + cmd->sg_cnt, cmd->dma_data_direction); 1464 + if (unlikely(prm->seg_cnt == 0)) 1465 + goto out_err; 1466 + 1467 + prm->cmd->sg_mapped = 1; 1468 + 1469 + /* 1470 + * If greater than four sg entries then we need to allocate 1471 + * the continuation entries 1472 + */ 1473 + if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) 1474 + prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt - 1475 + prm->tgt->datasegs_per_cmd, prm->tgt->datasegs_per_cont); 1476 + 1477 + ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n", 1478 + prm->seg_cnt, prm->req_cnt); 1479 + return 0; 1480 + 1481 + out_err: 1482 + ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe04d, 1483 + "qla_target(%d): PCI mapping failed: sg_cnt=%d", 1484 + 0, prm->cmd->sg_cnt); 1485 + return -1; 1486 + } 1487 + 1488 + static inline void qlt_unmap_sg(struct scsi_qla_host *vha, 1489 + struct qla_tgt_cmd *cmd) 1490 + { 1491 + struct qla_hw_data *ha = vha->hw; 1492 + 1493 + BUG_ON(!cmd->sg_mapped); 1494 + pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); 1495 + cmd->sg_mapped = 0; 1496 + } 1497 + 1498 + static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, 1499 + uint32_t req_cnt) 1500 + { 1501 + struct qla_hw_data *ha = vha->hw; 1502 + device_reg_t __iomem *reg = ha->iobase; 1503 + uint32_t cnt; 1504 + 1505 + if (vha->req->cnt < (req_cnt + 2)) { 1506 + cnt = (uint16_t)RD_REG_DWORD(&reg->isp24.req_q_out); 1507 + 1508 + ql_dbg(ql_dbg_tgt, vha, 0xe00a, 1509 + "Request ring circled: cnt=%d, vha->->ring_index=%d, " 1510 + "vha->req->cnt=%d, req_cnt=%d\n", cnt, 1511 + vha->req->ring_index, vha->req->cnt, req_cnt); 1512 + if (vha->req->ring_index < cnt) 1513 + vha->req->cnt = cnt - vha->req->ring_index; 1514 + else 1515 + vha->req->cnt = vha->req->length - 1516 + (vha->req->ring_index - cnt); 1517 + } 1518 + 1519 + if (unlikely(vha->req->cnt < (req_cnt + 2))) { 1520 + ql_dbg(ql_dbg_tgt, vha, 0xe00b, 1521 + "qla_target(%d): There is no room in the " 1522 + "request ring: vha->req->ring_index=%d, vha->req->cnt=%d, " 1523 + "req_cnt=%d\n", vha->vp_idx, vha->req->ring_index, 1524 + vha->req->cnt, req_cnt); 1525 + return -EAGAIN; 1526 + } 1527 + vha->req->cnt -= req_cnt; 1528 + 1529 + return 0; 1530 + } 1531 + 1532 + /* 1533 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 1534 + */ 1535 + static inline void *qlt_get_req_pkt(struct scsi_qla_host *vha) 1536 + { 1537 + /* Adjust ring index. */ 1538 + vha->req->ring_index++; 1539 + if (vha->req->ring_index == vha->req->length) { 1540 + vha->req->ring_index = 0; 1541 + vha->req->ring_ptr = vha->req->ring; 1542 + } else { 1543 + vha->req->ring_ptr++; 1544 + } 1545 + return (cont_entry_t *)vha->req->ring_ptr; 1546 + } 1547 + 1548 + /* ha->hardware_lock supposed to be held on entry */ 1549 + static inline uint32_t qlt_make_handle(struct scsi_qla_host *vha) 1550 + { 1551 + struct qla_hw_data *ha = vha->hw; 1552 + uint32_t h; 1553 + 1554 + h = ha->tgt.current_handle; 1555 + /* always increment cmd handle */ 1556 + do { 1557 + ++h; 1558 + if (h > MAX_OUTSTANDING_COMMANDS) 1559 + h = 1; /* 0 is QLA_TGT_NULL_HANDLE */ 1560 + if (h == ha->tgt.current_handle) { 1561 + ql_dbg(ql_dbg_tgt, vha, 0xe04e, 1562 + "qla_target(%d): Ran out of " 1563 + "empty cmd slots in ha %p\n", vha->vp_idx, ha); 1564 + h = QLA_TGT_NULL_HANDLE; 1565 + break; 1566 + } 1567 + } while ((h == QLA_TGT_NULL_HANDLE) || 1568 + (h == QLA_TGT_SKIP_HANDLE) || 1569 + (ha->tgt.cmds[h-1] != NULL)); 1570 + 1571 + if (h != QLA_TGT_NULL_HANDLE) 1572 + ha->tgt.current_handle = h; 1573 + 1574 + return h; 1575 + } 1576 + 1577 + /* ha->hardware_lock supposed to be held on entry */ 1578 + static int qlt_24xx_build_ctio_pkt(struct qla_tgt_prm *prm, 1579 + struct scsi_qla_host *vha) 1580 + { 1581 + uint32_t h; 1582 + struct ctio7_to_24xx *pkt; 1583 + struct qla_hw_data *ha = vha->hw; 1584 + struct atio_from_isp *atio = &prm->cmd->atio; 1585 + 1586 + pkt = (struct ctio7_to_24xx *)vha->req->ring_ptr; 1587 + prm->pkt = pkt; 1588 + memset(pkt, 0, sizeof(*pkt)); 1589 + 1590 + pkt->entry_type = CTIO_TYPE7; 1591 + pkt->entry_count = (uint8_t)prm->req_cnt; 1592 + pkt->vp_index = vha->vp_idx; 1593 + 1594 + h = qlt_make_handle(vha); 1595 + if (unlikely(h == QLA_TGT_NULL_HANDLE)) { 1596 + /* 1597 + * CTIO type 7 from the firmware doesn't provide a way to 1598 + * know the initiator's LOOP ID, hence we can't find 1599 + * the session and, so, the command. 1600 + */ 1601 + return -EAGAIN; 1602 + } else 1603 + ha->tgt.cmds[h-1] = prm->cmd; 1604 + 1605 + pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; 1606 + pkt->nport_handle = prm->cmd->loop_id; 1607 + pkt->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); 1608 + pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 1609 + pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; 1610 + pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; 1611 + pkt->exchange_addr = atio->u.isp24.exchange_addr; 1612 + pkt->u.status0.flags |= (atio->u.isp24.attr << 9); 1613 + pkt->u.status0.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); 1614 + pkt->u.status0.relative_offset = cpu_to_le32(prm->cmd->offset); 1615 + 1616 + ql_dbg(ql_dbg_tgt, vha, 0xe00c, 1617 + "qla_target(%d): handle(cmd) -> %08x, timeout %d, ox_id %#x\n", 1618 + vha->vp_idx, pkt->handle, QLA_TGT_TIMEOUT, 1619 + le16_to_cpu(pkt->u.status0.ox_id)); 1620 + return 0; 1621 + } 1622 + 1623 + /* 1624 + * ha->hardware_lock supposed to be held on entry. We have already made sure 1625 + * that there is sufficient amount of request entries to not drop it. 1626 + */ 1627 + static void qlt_load_cont_data_segments(struct qla_tgt_prm *prm, 1628 + struct scsi_qla_host *vha) 1629 + { 1630 + int cnt; 1631 + uint32_t *dword_ptr; 1632 + int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr; 1633 + 1634 + /* Build continuation packets */ 1635 + while (prm->seg_cnt > 0) { 1636 + cont_a64_entry_t *cont_pkt64 = 1637 + (cont_a64_entry_t *)qlt_get_req_pkt(vha); 1638 + 1639 + /* 1640 + * Make sure that from cont_pkt64 none of 1641 + * 64-bit specific fields used for 32-bit 1642 + * addressing. Cast to (cont_entry_t *) for 1643 + * that. 1644 + */ 1645 + 1646 + memset(cont_pkt64, 0, sizeof(*cont_pkt64)); 1647 + 1648 + cont_pkt64->entry_count = 1; 1649 + cont_pkt64->sys_define = 0; 1650 + 1651 + if (enable_64bit_addressing) { 1652 + cont_pkt64->entry_type = CONTINUE_A64_TYPE; 1653 + dword_ptr = 1654 + (uint32_t *)&cont_pkt64->dseg_0_address; 1655 + } else { 1656 + cont_pkt64->entry_type = CONTINUE_TYPE; 1657 + dword_ptr = 1658 + (uint32_t *)&((cont_entry_t *) 1659 + cont_pkt64)->dseg_0_address; 1660 + } 1661 + 1662 + /* Load continuation entry data segments */ 1663 + for (cnt = 0; 1664 + cnt < prm->tgt->datasegs_per_cont && prm->seg_cnt; 1665 + cnt++, prm->seg_cnt--) { 1666 + *dword_ptr++ = 1667 + cpu_to_le32(pci_dma_lo32 1668 + (sg_dma_address(prm->sg))); 1669 + if (enable_64bit_addressing) { 1670 + *dword_ptr++ = 1671 + cpu_to_le32(pci_dma_hi32 1672 + (sg_dma_address 1673 + (prm->sg))); 1674 + } 1675 + *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); 1676 + 1677 + ql_dbg(ql_dbg_tgt, vha, 0xe00d, 1678 + "S/G Segment Cont. phys_addr=%llx:%llx, len=%d\n", 1679 + (long long unsigned int) 1680 + pci_dma_hi32(sg_dma_address(prm->sg)), 1681 + (long long unsigned int) 1682 + pci_dma_lo32(sg_dma_address(prm->sg)), 1683 + (int)sg_dma_len(prm->sg)); 1684 + 1685 + prm->sg = sg_next(prm->sg); 1686 + } 1687 + } 1688 + } 1689 + 1690 + /* 1691 + * ha->hardware_lock supposed to be held on entry. We have already made sure 1692 + * that there is sufficient amount of request entries to not drop it. 1693 + */ 1694 + static void qlt_load_data_segments(struct qla_tgt_prm *prm, 1695 + struct scsi_qla_host *vha) 1696 + { 1697 + int cnt; 1698 + uint32_t *dword_ptr; 1699 + int enable_64bit_addressing = prm->tgt->tgt_enable_64bit_addr; 1700 + struct ctio7_to_24xx *pkt24 = (struct ctio7_to_24xx *)prm->pkt; 1701 + 1702 + ql_dbg(ql_dbg_tgt, vha, 0xe00e, 1703 + "iocb->scsi_status=%x, iocb->flags=%x\n", 1704 + le16_to_cpu(pkt24->u.status0.scsi_status), 1705 + le16_to_cpu(pkt24->u.status0.flags)); 1706 + 1707 + pkt24->u.status0.transfer_length = cpu_to_le32(prm->cmd->bufflen); 1708 + 1709 + /* Setup packet address segment pointer */ 1710 + dword_ptr = pkt24->u.status0.dseg_0_address; 1711 + 1712 + /* Set total data segment count */ 1713 + if (prm->seg_cnt) 1714 + pkt24->dseg_count = cpu_to_le16(prm->seg_cnt); 1715 + 1716 + if (prm->seg_cnt == 0) { 1717 + /* No data transfer */ 1718 + *dword_ptr++ = 0; 1719 + *dword_ptr = 0; 1720 + return; 1721 + } 1722 + 1723 + /* If scatter gather */ 1724 + ql_dbg(ql_dbg_tgt, vha, 0xe00f, "%s", "Building S/G data segments..."); 1725 + 1726 + /* Load command entry data segments */ 1727 + for (cnt = 0; 1728 + (cnt < prm->tgt->datasegs_per_cmd) && prm->seg_cnt; 1729 + cnt++, prm->seg_cnt--) { 1730 + *dword_ptr++ = 1731 + cpu_to_le32(pci_dma_lo32(sg_dma_address(prm->sg))); 1732 + if (enable_64bit_addressing) { 1733 + *dword_ptr++ = 1734 + cpu_to_le32(pci_dma_hi32( 1735 + sg_dma_address(prm->sg))); 1736 + } 1737 + *dword_ptr++ = cpu_to_le32(sg_dma_len(prm->sg)); 1738 + 1739 + ql_dbg(ql_dbg_tgt, vha, 0xe010, 1740 + "S/G Segment phys_addr=%llx:%llx, len=%d\n", 1741 + (long long unsigned int)pci_dma_hi32(sg_dma_address( 1742 + prm->sg)), 1743 + (long long unsigned int)pci_dma_lo32(sg_dma_address( 1744 + prm->sg)), 1745 + (int)sg_dma_len(prm->sg)); 1746 + 1747 + prm->sg = sg_next(prm->sg); 1748 + } 1749 + 1750 + qlt_load_cont_data_segments(prm, vha); 1751 + } 1752 + 1753 + static inline int qlt_has_data(struct qla_tgt_cmd *cmd) 1754 + { 1755 + return cmd->bufflen > 0; 1756 + } 1757 + 1758 + /* 1759 + * Called without ha->hardware_lock held 1760 + */ 1761 + static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd, 1762 + struct qla_tgt_prm *prm, int xmit_type, uint8_t scsi_status, 1763 + uint32_t *full_req_cnt) 1764 + { 1765 + struct qla_tgt *tgt = cmd->tgt; 1766 + struct scsi_qla_host *vha = tgt->vha; 1767 + struct qla_hw_data *ha = vha->hw; 1768 + struct se_cmd *se_cmd = &cmd->se_cmd; 1769 + 1770 + if (unlikely(cmd->aborted)) { 1771 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, 1772 + "qla_target(%d): terminating exchange " 1773 + "for aborted cmd=%p (se_cmd=%p, tag=%d)", vha->vp_idx, cmd, 1774 + se_cmd, cmd->tag); 1775 + 1776 + cmd->state = QLA_TGT_STATE_ABORTED; 1777 + 1778 + qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); 1779 + 1780 + /* !! At this point cmd could be already freed !! */ 1781 + return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED; 1782 + } 1783 + 1784 + ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u\n", 1785 + vha->vp_idx, cmd->tag); 1786 + 1787 + prm->cmd = cmd; 1788 + prm->tgt = tgt; 1789 + prm->rq_result = scsi_status; 1790 + prm->sense_buffer = &cmd->sense_buffer[0]; 1791 + prm->sense_buffer_len = TRANSPORT_SENSE_BUFFER; 1792 + prm->sg = NULL; 1793 + prm->seg_cnt = -1; 1794 + prm->req_cnt = 1; 1795 + prm->add_status_pkt = 0; 1796 + 1797 + ql_dbg(ql_dbg_tgt, vha, 0xe012, "rq_result=%x, xmit_type=%x\n", 1798 + prm->rq_result, xmit_type); 1799 + 1800 + /* Send marker if required */ 1801 + if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) 1802 + return -EFAULT; 1803 + 1804 + ql_dbg(ql_dbg_tgt, vha, 0xe013, "CTIO start: vha(%d)\n", vha->vp_idx); 1805 + 1806 + if ((xmit_type & QLA_TGT_XMIT_DATA) && qlt_has_data(cmd)) { 1807 + if (qlt_pci_map_calc_cnt(prm) != 0) 1808 + return -EAGAIN; 1809 + } 1810 + 1811 + *full_req_cnt = prm->req_cnt; 1812 + 1813 + if (se_cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) { 1814 + prm->residual = se_cmd->residual_count; 1815 + ql_dbg(ql_dbg_tgt, vha, 0xe014, 1816 + "Residual underflow: %d (tag %d, " 1817 + "op %x, bufflen %d, rq_result %x)\n", prm->residual, 1818 + cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, 1819 + cmd->bufflen, prm->rq_result); 1820 + prm->rq_result |= SS_RESIDUAL_UNDER; 1821 + } else if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT) { 1822 + prm->residual = se_cmd->residual_count; 1823 + ql_dbg(ql_dbg_tgt, vha, 0xe015, 1824 + "Residual overflow: %d (tag %d, " 1825 + "op %x, bufflen %d, rq_result %x)\n", prm->residual, 1826 + cmd->tag, se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0, 1827 + cmd->bufflen, prm->rq_result); 1828 + prm->rq_result |= SS_RESIDUAL_OVER; 1829 + } 1830 + 1831 + if (xmit_type & QLA_TGT_XMIT_STATUS) { 1832 + /* 1833 + * If QLA_TGT_XMIT_DATA is not set, add_status_pkt will be 1834 + * ignored in *xmit_response() below 1835 + */ 1836 + if (qlt_has_data(cmd)) { 1837 + if (QLA_TGT_SENSE_VALID(prm->sense_buffer) || 1838 + (IS_FWI2_CAPABLE(ha) && 1839 + (prm->rq_result != 0))) { 1840 + prm->add_status_pkt = 1; 1841 + (*full_req_cnt)++; 1842 + } 1843 + } 1844 + } 1845 + 1846 + ql_dbg(ql_dbg_tgt, vha, 0xe016, 1847 + "req_cnt=%d, full_req_cnt=%d, add_status_pkt=%d\n", 1848 + prm->req_cnt, *full_req_cnt, prm->add_status_pkt); 1849 + 1850 + return 0; 1851 + } 1852 + 1853 + static inline int qlt_need_explicit_conf(struct qla_hw_data *ha, 1854 + struct qla_tgt_cmd *cmd, int sending_sense) 1855 + { 1856 + if (ha->tgt.enable_class_2) 1857 + return 0; 1858 + 1859 + if (sending_sense) 1860 + return cmd->conf_compl_supported; 1861 + else 1862 + return ha->tgt.enable_explicit_conf && 1863 + cmd->conf_compl_supported; 1864 + } 1865 + 1866 + #ifdef CONFIG_QLA_TGT_DEBUG_SRR 1867 + /* 1868 + * Original taken from the XFS code 1869 + */ 1870 + static unsigned long qlt_srr_random(void) 1871 + { 1872 + static int Inited; 1873 + static unsigned long RandomValue; 1874 + static DEFINE_SPINLOCK(lock); 1875 + /* cycles pseudo-randomly through all values between 1 and 2^31 - 2 */ 1876 + register long rv; 1877 + register long lo; 1878 + register long hi; 1879 + unsigned long flags; 1880 + 1881 + spin_lock_irqsave(&lock, flags); 1882 + if (!Inited) { 1883 + RandomValue = jiffies; 1884 + Inited = 1; 1885 + } 1886 + rv = RandomValue; 1887 + hi = rv / 127773; 1888 + lo = rv % 127773; 1889 + rv = 16807 * lo - 2836 * hi; 1890 + if (rv <= 0) 1891 + rv += 2147483647; 1892 + RandomValue = rv; 1893 + spin_unlock_irqrestore(&lock, flags); 1894 + return rv; 1895 + } 1896 + 1897 + static void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type) 1898 + { 1899 + #if 0 /* This is not a real status packets lost, so it won't lead to SRR */ 1900 + if ((*xmit_type & QLA_TGT_XMIT_STATUS) && (qlt_srr_random() % 200) 1901 + == 50) { 1902 + *xmit_type &= ~QLA_TGT_XMIT_STATUS; 1903 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf015, 1904 + "Dropping cmd %p (tag %d) status", cmd, cmd->tag); 1905 + } 1906 + #endif 1907 + /* 1908 + * It's currently not possible to simulate SRRs for FCP_WRITE without 1909 + * a physical link layer failure, so don't even try here.. 1910 + */ 1911 + if (cmd->dma_data_direction != DMA_FROM_DEVICE) 1912 + return; 1913 + 1914 + if (qlt_has_data(cmd) && (cmd->sg_cnt > 1) && 1915 + ((qlt_srr_random() % 100) == 20)) { 1916 + int i, leave = 0; 1917 + unsigned int tot_len = 0; 1918 + 1919 + while (leave == 0) 1920 + leave = qlt_srr_random() % cmd->sg_cnt; 1921 + 1922 + for (i = 0; i < leave; i++) 1923 + tot_len += cmd->sg[i].length; 1924 + 1925 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf016, 1926 + "Cutting cmd %p (tag %d) buffer" 1927 + " tail to len %d, sg_cnt %d (cmd->bufflen %d," 1928 + " cmd->sg_cnt %d)", cmd, cmd->tag, tot_len, leave, 1929 + cmd->bufflen, cmd->sg_cnt); 1930 + 1931 + cmd->bufflen = tot_len; 1932 + cmd->sg_cnt = leave; 1933 + } 1934 + 1935 + if (qlt_has_data(cmd) && ((qlt_srr_random() % 100) == 70)) { 1936 + unsigned int offset = qlt_srr_random() % cmd->bufflen; 1937 + 1938 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf017, 1939 + "Cutting cmd %p (tag %d) buffer head " 1940 + "to offset %d (cmd->bufflen %d)", cmd, cmd->tag, offset, 1941 + cmd->bufflen); 1942 + if (offset == 0) 1943 + *xmit_type &= ~QLA_TGT_XMIT_DATA; 1944 + else if (qlt_set_data_offset(cmd, offset)) { 1945 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf018, 1946 + "qlt_set_data_offset() failed (tag %d)", cmd->tag); 1947 + } 1948 + } 1949 + } 1950 + #else 1951 + static inline void qlt_check_srr_debug(struct qla_tgt_cmd *cmd, int *xmit_type) 1952 + {} 1953 + #endif 1954 + 1955 + static void qlt_24xx_init_ctio_to_isp(struct ctio7_to_24xx *ctio, 1956 + struct qla_tgt_prm *prm) 1957 + { 1958 + prm->sense_buffer_len = min_t(uint32_t, prm->sense_buffer_len, 1959 + (uint32_t)sizeof(ctio->u.status1.sense_data)); 1960 + ctio->u.status0.flags |= 1961 + __constant_cpu_to_le16(CTIO7_FLAGS_SEND_STATUS); 1962 + if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 0)) { 1963 + ctio->u.status0.flags |= __constant_cpu_to_le16( 1964 + CTIO7_FLAGS_EXPLICIT_CONFORM | 1965 + CTIO7_FLAGS_CONFORM_REQ); 1966 + } 1967 + ctio->u.status0.residual = cpu_to_le32(prm->residual); 1968 + ctio->u.status0.scsi_status = cpu_to_le16(prm->rq_result); 1969 + if (QLA_TGT_SENSE_VALID(prm->sense_buffer)) { 1970 + int i; 1971 + 1972 + if (qlt_need_explicit_conf(prm->tgt->ha, prm->cmd, 1)) { 1973 + if (prm->cmd->se_cmd.scsi_status != 0) { 1974 + ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe017, 1975 + "Skipping EXPLICIT_CONFORM and " 1976 + "CTIO7_FLAGS_CONFORM_REQ for FCP READ w/ " 1977 + "non GOOD status\n"); 1978 + goto skip_explict_conf; 1979 + } 1980 + ctio->u.status1.flags |= __constant_cpu_to_le16( 1981 + CTIO7_FLAGS_EXPLICIT_CONFORM | 1982 + CTIO7_FLAGS_CONFORM_REQ); 1983 + } 1984 + skip_explict_conf: 1985 + ctio->u.status1.flags &= 1986 + ~__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); 1987 + ctio->u.status1.flags |= 1988 + __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1); 1989 + ctio->u.status1.scsi_status |= 1990 + __constant_cpu_to_le16(SS_SENSE_LEN_VALID); 1991 + ctio->u.status1.sense_length = 1992 + cpu_to_le16(prm->sense_buffer_len); 1993 + for (i = 0; i < prm->sense_buffer_len/4; i++) 1994 + ((uint32_t *)ctio->u.status1.sense_data)[i] = 1995 + cpu_to_be32(((uint32_t *)prm->sense_buffer)[i]); 1996 + #if 0 1997 + if (unlikely((prm->sense_buffer_len % 4) != 0)) { 1998 + static int q; 1999 + if (q < 10) { 2000 + ql_dbg(ql_dbg_tgt, vha, 0xe04f, 2001 + "qla_target(%d): %d bytes of sense " 2002 + "lost", prm->tgt->ha->vp_idx, 2003 + prm->sense_buffer_len % 4); 2004 + q++; 2005 + } 2006 + } 2007 + #endif 2008 + } else { 2009 + ctio->u.status1.flags &= 2010 + ~__constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_0); 2011 + ctio->u.status1.flags |= 2012 + __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1); 2013 + ctio->u.status1.sense_length = 0; 2014 + memset(ctio->u.status1.sense_data, 0, 2015 + sizeof(ctio->u.status1.sense_data)); 2016 + } 2017 + 2018 + /* Sense with len > 24, is it possible ??? */ 2019 + } 2020 + 2021 + /* 2022 + * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * 2023 + * QLA_TGT_XMIT_STATUS for >= 24xx silicon 2024 + */ 2025 + int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, 2026 + uint8_t scsi_status) 2027 + { 2028 + struct scsi_qla_host *vha = cmd->vha; 2029 + struct qla_hw_data *ha = vha->hw; 2030 + struct ctio7_to_24xx *pkt; 2031 + struct qla_tgt_prm prm; 2032 + uint32_t full_req_cnt = 0; 2033 + unsigned long flags = 0; 2034 + int res; 2035 + 2036 + memset(&prm, 0, sizeof(prm)); 2037 + qlt_check_srr_debug(cmd, &xmit_type); 2038 + 2039 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018, 2040 + "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, " 2041 + "cmd->dma_data_direction=%d\n", (xmit_type & QLA_TGT_XMIT_STATUS) ? 2042 + 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction); 2043 + 2044 + res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, 2045 + &full_req_cnt); 2046 + if (unlikely(res != 0)) { 2047 + if (res == QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED) 2048 + return 0; 2049 + 2050 + return res; 2051 + } 2052 + 2053 + spin_lock_irqsave(&ha->hardware_lock, flags); 2054 + 2055 + /* Does F/W have an IOCBs for this request */ 2056 + res = qlt_check_reserve_free_req(vha, full_req_cnt); 2057 + if (unlikely(res)) 2058 + goto out_unmap_unlock; 2059 + 2060 + res = qlt_24xx_build_ctio_pkt(&prm, vha); 2061 + if (unlikely(res != 0)) 2062 + goto out_unmap_unlock; 2063 + 2064 + 2065 + pkt = (struct ctio7_to_24xx *)prm.pkt; 2066 + 2067 + if (qlt_has_data(cmd) && (xmit_type & QLA_TGT_XMIT_DATA)) { 2068 + pkt->u.status0.flags |= 2069 + __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN | 2070 + CTIO7_FLAGS_STATUS_MODE_0); 2071 + 2072 + qlt_load_data_segments(&prm, vha); 2073 + 2074 + if (prm.add_status_pkt == 0) { 2075 + if (xmit_type & QLA_TGT_XMIT_STATUS) { 2076 + pkt->u.status0.scsi_status = 2077 + cpu_to_le16(prm.rq_result); 2078 + pkt->u.status0.residual = 2079 + cpu_to_le32(prm.residual); 2080 + pkt->u.status0.flags |= __constant_cpu_to_le16( 2081 + CTIO7_FLAGS_SEND_STATUS); 2082 + if (qlt_need_explicit_conf(ha, cmd, 0)) { 2083 + pkt->u.status0.flags |= 2084 + __constant_cpu_to_le16( 2085 + CTIO7_FLAGS_EXPLICIT_CONFORM | 2086 + CTIO7_FLAGS_CONFORM_REQ); 2087 + } 2088 + } 2089 + 2090 + } else { 2091 + /* 2092 + * We have already made sure that there is sufficient 2093 + * amount of request entries to not drop HW lock in 2094 + * req_pkt(). 2095 + */ 2096 + struct ctio7_to_24xx *ctio = 2097 + (struct ctio7_to_24xx *)qlt_get_req_pkt(vha); 2098 + 2099 + ql_dbg(ql_dbg_tgt, vha, 0xe019, 2100 + "Building additional status packet\n"); 2101 + 2102 + memcpy(ctio, pkt, sizeof(*ctio)); 2103 + ctio->entry_count = 1; 2104 + ctio->dseg_count = 0; 2105 + ctio->u.status1.flags &= ~__constant_cpu_to_le16( 2106 + CTIO7_FLAGS_DATA_IN); 2107 + 2108 + /* Real finish is ctio_m1's finish */ 2109 + pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK; 2110 + pkt->u.status0.flags |= __constant_cpu_to_le16( 2111 + CTIO7_FLAGS_DONT_RET_CTIO); 2112 + qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio, 2113 + &prm); 2114 + pr_debug("Status CTIO7: %p\n", ctio); 2115 + } 2116 + } else 2117 + qlt_24xx_init_ctio_to_isp(pkt, &prm); 2118 + 2119 + 2120 + cmd->state = QLA_TGT_STATE_PROCESSED; /* Mid-level is done processing */ 2121 + 2122 + ql_dbg(ql_dbg_tgt, vha, 0xe01a, 2123 + "Xmitting CTIO7 response pkt for 24xx: %p scsi_status: 0x%02x\n", 2124 + pkt, scsi_status); 2125 + 2126 + qla2x00_start_iocbs(vha, vha->req); 2127 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2128 + 2129 + return 0; 2130 + 2131 + out_unmap_unlock: 2132 + if (cmd->sg_mapped) 2133 + qlt_unmap_sg(vha, cmd); 2134 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2135 + 2136 + return res; 2137 + } 2138 + EXPORT_SYMBOL(qlt_xmit_response); 2139 + 2140 + int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) 2141 + { 2142 + struct ctio7_to_24xx *pkt; 2143 + struct scsi_qla_host *vha = cmd->vha; 2144 + struct qla_hw_data *ha = vha->hw; 2145 + struct qla_tgt *tgt = cmd->tgt; 2146 + struct qla_tgt_prm prm; 2147 + unsigned long flags; 2148 + int res = 0; 2149 + 2150 + memset(&prm, 0, sizeof(prm)); 2151 + prm.cmd = cmd; 2152 + prm.tgt = tgt; 2153 + prm.sg = NULL; 2154 + prm.req_cnt = 1; 2155 + 2156 + /* Send marker if required */ 2157 + if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) 2158 + return -EIO; 2159 + 2160 + ql_dbg(ql_dbg_tgt, vha, 0xe01b, "CTIO_start: vha(%d)", 2161 + (int)vha->vp_idx); 2162 + 2163 + /* Calculate number of entries and segments required */ 2164 + if (qlt_pci_map_calc_cnt(&prm) != 0) 2165 + return -EAGAIN; 2166 + 2167 + spin_lock_irqsave(&ha->hardware_lock, flags); 2168 + 2169 + /* Does F/W have an IOCBs for this request */ 2170 + res = qlt_check_reserve_free_req(vha, prm.req_cnt); 2171 + if (res != 0) 2172 + goto out_unlock_free_unmap; 2173 + 2174 + res = qlt_24xx_build_ctio_pkt(&prm, vha); 2175 + if (unlikely(res != 0)) 2176 + goto out_unlock_free_unmap; 2177 + pkt = (struct ctio7_to_24xx *)prm.pkt; 2178 + pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT | 2179 + CTIO7_FLAGS_STATUS_MODE_0); 2180 + qlt_load_data_segments(&prm, vha); 2181 + 2182 + cmd->state = QLA_TGT_STATE_NEED_DATA; 2183 + 2184 + qla2x00_start_iocbs(vha, vha->req); 2185 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2186 + 2187 + return res; 2188 + 2189 + out_unlock_free_unmap: 2190 + if (cmd->sg_mapped) 2191 + qlt_unmap_sg(vha, cmd); 2192 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2193 + 2194 + return res; 2195 + } 2196 + EXPORT_SYMBOL(qlt_rdy_to_xfer); 2197 + 2198 + /* If hardware_lock held on entry, might drop it, then reaquire */ 2199 + /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ 2200 + static int __qlt_send_term_exchange(struct scsi_qla_host *vha, 2201 + struct qla_tgt_cmd *cmd, 2202 + struct atio_from_isp *atio) 2203 + { 2204 + struct ctio7_to_24xx *ctio24; 2205 + struct qla_hw_data *ha = vha->hw; 2206 + request_t *pkt; 2207 + int ret = 0; 2208 + 2209 + ql_dbg(ql_dbg_tgt, vha, 0xe01c, "Sending TERM EXCH CTIO (ha=%p)\n", ha); 2210 + 2211 + pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); 2212 + if (pkt == NULL) { 2213 + ql_dbg(ql_dbg_tgt, vha, 0xe050, 2214 + "qla_target(%d): %s failed: unable to allocate " 2215 + "request packet\n", vha->vp_idx, __func__); 2216 + return -ENOMEM; 2217 + } 2218 + 2219 + if (cmd != NULL) { 2220 + if (cmd->state < QLA_TGT_STATE_PROCESSED) { 2221 + ql_dbg(ql_dbg_tgt, vha, 0xe051, 2222 + "qla_target(%d): Terminating cmd %p with " 2223 + "incorrect state %d\n", vha->vp_idx, cmd, 2224 + cmd->state); 2225 + } else 2226 + ret = 1; 2227 + } 2228 + 2229 + pkt->entry_count = 1; 2230 + pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 2231 + 2232 + ctio24 = (struct ctio7_to_24xx *)pkt; 2233 + ctio24->entry_type = CTIO_TYPE7; 2234 + ctio24->nport_handle = cmd ? cmd->loop_id : CTIO7_NHANDLE_UNRECOGNIZED; 2235 + ctio24->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); 2236 + ctio24->vp_index = vha->vp_idx; 2237 + ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 2238 + ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; 2239 + ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; 2240 + ctio24->exchange_addr = atio->u.isp24.exchange_addr; 2241 + ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | 2242 + __constant_cpu_to_le16(CTIO7_FLAGS_STATUS_MODE_1 | 2243 + CTIO7_FLAGS_TERMINATE); 2244 + ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); 2245 + 2246 + /* Most likely, it isn't needed */ 2247 + ctio24->u.status1.residual = get_unaligned((uint32_t *) 2248 + &atio->u.isp24.fcp_cmnd.add_cdb[ 2249 + atio->u.isp24.fcp_cmnd.add_cdb_len]); 2250 + if (ctio24->u.status1.residual != 0) 2251 + ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER; 2252 + 2253 + qla2x00_start_iocbs(vha, vha->req); 2254 + return ret; 2255 + } 2256 + 2257 + static void qlt_send_term_exchange(struct scsi_qla_host *vha, 2258 + struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) 2259 + { 2260 + unsigned long flags; 2261 + int rc; 2262 + 2263 + if (qlt_issue_marker(vha, ha_locked) < 0) 2264 + return; 2265 + 2266 + if (ha_locked) { 2267 + rc = __qlt_send_term_exchange(vha, cmd, atio); 2268 + goto done; 2269 + } 2270 + spin_lock_irqsave(&vha->hw->hardware_lock, flags); 2271 + rc = __qlt_send_term_exchange(vha, cmd, atio); 2272 + spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 2273 + done: 2274 + if (rc == 1) { 2275 + if (!ha_locked && !in_interrupt()) 2276 + msleep(250); /* just in case */ 2277 + 2278 + vha->hw->tgt.tgt_ops->free_cmd(cmd); 2279 + } 2280 + } 2281 + 2282 + void qlt_free_cmd(struct qla_tgt_cmd *cmd) 2283 + { 2284 + BUG_ON(cmd->sg_mapped); 2285 + 2286 + if (unlikely(cmd->free_sg)) 2287 + kfree(cmd->sg); 2288 + kmem_cache_free(qla_tgt_cmd_cachep, cmd); 2289 + } 2290 + EXPORT_SYMBOL(qlt_free_cmd); 2291 + 2292 + /* ha->hardware_lock supposed to be held on entry */ 2293 + static int qlt_prepare_srr_ctio(struct scsi_qla_host *vha, 2294 + struct qla_tgt_cmd *cmd, void *ctio) 2295 + { 2296 + struct qla_tgt_srr_ctio *sc; 2297 + struct qla_hw_data *ha = vha->hw; 2298 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 2299 + struct qla_tgt_srr_imm *imm; 2300 + 2301 + tgt->ctio_srr_id++; 2302 + 2303 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019, 2304 + "qla_target(%d): CTIO with SRR status received\n", vha->vp_idx); 2305 + 2306 + if (!ctio) { 2307 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf055, 2308 + "qla_target(%d): SRR CTIO, but ctio is NULL\n", 2309 + vha->vp_idx); 2310 + return -EINVAL; 2311 + } 2312 + 2313 + sc = kzalloc(sizeof(*sc), GFP_ATOMIC); 2314 + if (sc != NULL) { 2315 + sc->cmd = cmd; 2316 + /* IRQ is already OFF */ 2317 + spin_lock(&tgt->srr_lock); 2318 + sc->srr_id = tgt->ctio_srr_id; 2319 + list_add_tail(&sc->srr_list_entry, 2320 + &tgt->srr_ctio_list); 2321 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a, 2322 + "CTIO SRR %p added (id %d)\n", sc, sc->srr_id); 2323 + if (tgt->imm_srr_id == tgt->ctio_srr_id) { 2324 + int found = 0; 2325 + list_for_each_entry(imm, &tgt->srr_imm_list, 2326 + srr_list_entry) { 2327 + if (imm->srr_id == sc->srr_id) { 2328 + found = 1; 2329 + break; 2330 + } 2331 + } 2332 + if (found) { 2333 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01b, 2334 + "Scheduling srr work\n"); 2335 + schedule_work(&tgt->srr_work); 2336 + } else { 2337 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf056, 2338 + "qla_target(%d): imm_srr_id " 2339 + "== ctio_srr_id (%d), but there is no " 2340 + "corresponding SRR IMM, deleting CTIO " 2341 + "SRR %p\n", vha->vp_idx, 2342 + tgt->ctio_srr_id, sc); 2343 + list_del(&sc->srr_list_entry); 2344 + spin_unlock(&tgt->srr_lock); 2345 + 2346 + kfree(sc); 2347 + return -EINVAL; 2348 + } 2349 + } 2350 + spin_unlock(&tgt->srr_lock); 2351 + } else { 2352 + struct qla_tgt_srr_imm *ti; 2353 + 2354 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf057, 2355 + "qla_target(%d): Unable to allocate SRR CTIO entry\n", 2356 + vha->vp_idx); 2357 + spin_lock(&tgt->srr_lock); 2358 + list_for_each_entry_safe(imm, ti, &tgt->srr_imm_list, 2359 + srr_list_entry) { 2360 + if (imm->srr_id == tgt->ctio_srr_id) { 2361 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01c, 2362 + "IMM SRR %p deleted (id %d)\n", 2363 + imm, imm->srr_id); 2364 + list_del(&imm->srr_list_entry); 2365 + qlt_reject_free_srr_imm(vha, imm, 1); 2366 + } 2367 + } 2368 + spin_unlock(&tgt->srr_lock); 2369 + 2370 + return -ENOMEM; 2371 + } 2372 + 2373 + return 0; 2374 + } 2375 + 2376 + /* 2377 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 2378 + */ 2379 + static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio, 2380 + struct qla_tgt_cmd *cmd, uint32_t status) 2381 + { 2382 + int term = 0; 2383 + 2384 + if (ctio != NULL) { 2385 + struct ctio7_from_24xx *c = (struct ctio7_from_24xx *)ctio; 2386 + term = !(c->flags & 2387 + __constant_cpu_to_le16(OF_TERM_EXCH)); 2388 + } else 2389 + term = 1; 2390 + 2391 + if (term) 2392 + qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 2393 + 2394 + return term; 2395 + } 2396 + 2397 + /* ha->hardware_lock supposed to be held on entry */ 2398 + static inline struct qla_tgt_cmd *qlt_get_cmd(struct scsi_qla_host *vha, 2399 + uint32_t handle) 2400 + { 2401 + struct qla_hw_data *ha = vha->hw; 2402 + 2403 + handle--; 2404 + if (ha->tgt.cmds[handle] != NULL) { 2405 + struct qla_tgt_cmd *cmd = ha->tgt.cmds[handle]; 2406 + ha->tgt.cmds[handle] = NULL; 2407 + return cmd; 2408 + } else 2409 + return NULL; 2410 + } 2411 + 2412 + /* ha->hardware_lock supposed to be held on entry */ 2413 + static struct qla_tgt_cmd *qlt_ctio_to_cmd(struct scsi_qla_host *vha, 2414 + uint32_t handle, void *ctio) 2415 + { 2416 + struct qla_tgt_cmd *cmd = NULL; 2417 + 2418 + /* Clear out internal marks */ 2419 + handle &= ~(CTIO_COMPLETION_HANDLE_MARK | 2420 + CTIO_INTERMEDIATE_HANDLE_MARK); 2421 + 2422 + if (handle != QLA_TGT_NULL_HANDLE) { 2423 + if (unlikely(handle == QLA_TGT_SKIP_HANDLE)) { 2424 + ql_dbg(ql_dbg_tgt, vha, 0xe01d, "%s", 2425 + "SKIP_HANDLE CTIO\n"); 2426 + return NULL; 2427 + } 2428 + /* handle-1 is actually used */ 2429 + if (unlikely(handle > MAX_OUTSTANDING_COMMANDS)) { 2430 + ql_dbg(ql_dbg_tgt, vha, 0xe052, 2431 + "qla_target(%d): Wrong handle %x received\n", 2432 + vha->vp_idx, handle); 2433 + return NULL; 2434 + } 2435 + cmd = qlt_get_cmd(vha, handle); 2436 + if (unlikely(cmd == NULL)) { 2437 + ql_dbg(ql_dbg_tgt, vha, 0xe053, 2438 + "qla_target(%d): Suspicious: unable to " 2439 + "find the command with handle %x\n", vha->vp_idx, 2440 + handle); 2441 + return NULL; 2442 + } 2443 + } else if (ctio != NULL) { 2444 + /* We can't get loop ID from CTIO7 */ 2445 + ql_dbg(ql_dbg_tgt, vha, 0xe054, 2446 + "qla_target(%d): Wrong CTIO received: QLA24xx doesn't " 2447 + "support NULL handles\n", vha->vp_idx); 2448 + return NULL; 2449 + } 2450 + 2451 + return cmd; 2452 + } 2453 + 2454 + /* 2455 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 2456 + */ 2457 + static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, 2458 + uint32_t status, void *ctio) 2459 + { 2460 + struct qla_hw_data *ha = vha->hw; 2461 + struct se_cmd *se_cmd; 2462 + struct target_core_fabric_ops *tfo; 2463 + struct qla_tgt_cmd *cmd; 2464 + 2465 + ql_dbg(ql_dbg_tgt, vha, 0xe01e, 2466 + "qla_target(%d): handle(ctio %p status %#x) <- %08x\n", 2467 + vha->vp_idx, ctio, status, handle); 2468 + 2469 + if (handle & CTIO_INTERMEDIATE_HANDLE_MARK) { 2470 + /* That could happen only in case of an error/reset/abort */ 2471 + if (status != CTIO_SUCCESS) { 2472 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01d, 2473 + "Intermediate CTIO received" 2474 + " (status %x)\n", status); 2475 + } 2476 + return; 2477 + } 2478 + 2479 + cmd = qlt_ctio_to_cmd(vha, handle, ctio); 2480 + if (cmd == NULL) { 2481 + if (status != CTIO_SUCCESS) 2482 + qlt_term_ctio_exchange(vha, ctio, NULL, status); 2483 + return; 2484 + } 2485 + se_cmd = &cmd->se_cmd; 2486 + tfo = se_cmd->se_tfo; 2487 + 2488 + if (cmd->sg_mapped) 2489 + qlt_unmap_sg(vha, cmd); 2490 + 2491 + if (unlikely(status != CTIO_SUCCESS)) { 2492 + switch (status & 0xFFFF) { 2493 + case CTIO_LIP_RESET: 2494 + case CTIO_TARGET_RESET: 2495 + case CTIO_ABORTED: 2496 + case CTIO_TIMEOUT: 2497 + case CTIO_INVALID_RX_ID: 2498 + /* They are OK */ 2499 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf058, 2500 + "qla_target(%d): CTIO with " 2501 + "status %#x received, state %x, se_cmd %p, " 2502 + "(LIP_RESET=e, ABORTED=2, TARGET_RESET=17, " 2503 + "TIMEOUT=b, INVALID_RX_ID=8)\n", vha->vp_idx, 2504 + status, cmd->state, se_cmd); 2505 + break; 2506 + 2507 + case CTIO_PORT_LOGGED_OUT: 2508 + case CTIO_PORT_UNAVAILABLE: 2509 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf059, 2510 + "qla_target(%d): CTIO with PORT LOGGED " 2511 + "OUT (29) or PORT UNAVAILABLE (28) status %x " 2512 + "received (state %x, se_cmd %p)\n", vha->vp_idx, 2513 + status, cmd->state, se_cmd); 2514 + break; 2515 + 2516 + case CTIO_SRR_RECEIVED: 2517 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05a, 2518 + "qla_target(%d): CTIO with SRR_RECEIVED" 2519 + " status %x received (state %x, se_cmd %p)\n", 2520 + vha->vp_idx, status, cmd->state, se_cmd); 2521 + if (qlt_prepare_srr_ctio(vha, cmd, ctio) != 0) 2522 + break; 2523 + else 2524 + return; 2525 + 2526 + default: 2527 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, 2528 + "qla_target(%d): CTIO with error status " 2529 + "0x%x received (state %x, se_cmd %p\n", 2530 + vha->vp_idx, status, cmd->state, se_cmd); 2531 + break; 2532 + } 2533 + 2534 + if (cmd->state != QLA_TGT_STATE_NEED_DATA) 2535 + if (qlt_term_ctio_exchange(vha, ctio, cmd, status)) 2536 + return; 2537 + } 2538 + 2539 + if (cmd->state == QLA_TGT_STATE_PROCESSED) { 2540 + ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd); 2541 + } else if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 2542 + int rx_status = 0; 2543 + 2544 + cmd->state = QLA_TGT_STATE_DATA_IN; 2545 + 2546 + if (unlikely(status != CTIO_SUCCESS)) 2547 + rx_status = -EIO; 2548 + else 2549 + cmd->write_data_transferred = 1; 2550 + 2551 + ql_dbg(ql_dbg_tgt, vha, 0xe020, 2552 + "Data received, context %x, rx_status %d\n", 2553 + 0x0, rx_status); 2554 + 2555 + ha->tgt.tgt_ops->handle_data(cmd); 2556 + return; 2557 + } else if (cmd->state == QLA_TGT_STATE_ABORTED) { 2558 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01e, 2559 + "Aborted command %p (tag %d) finished\n", cmd, cmd->tag); 2560 + } else { 2561 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05c, 2562 + "qla_target(%d): A command in state (%d) should " 2563 + "not return a CTIO complete\n", vha->vp_idx, cmd->state); 2564 + } 2565 + 2566 + if (unlikely(status != CTIO_SUCCESS)) { 2567 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n"); 2568 + dump_stack(); 2569 + } 2570 + 2571 + ha->tgt.tgt_ops->free_cmd(cmd); 2572 + } 2573 + 2574 + /* ha->hardware_lock supposed to be held on entry */ 2575 + /* called via callback from qla2xxx */ 2576 + void qlt_ctio_completion(struct scsi_qla_host *vha, uint32_t handle) 2577 + { 2578 + struct qla_hw_data *ha = vha->hw; 2579 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 2580 + 2581 + if (likely(tgt == NULL)) { 2582 + ql_dbg(ql_dbg_tgt, vha, 0xe021, 2583 + "CTIO, but target mode not enabled" 2584 + " (ha %d %p handle %#x)", vha->vp_idx, ha, handle); 2585 + return; 2586 + } 2587 + 2588 + tgt->irq_cmd_count++; 2589 + qlt_do_ctio_completion(vha, handle, CTIO_SUCCESS, NULL); 2590 + tgt->irq_cmd_count--; 2591 + } 2592 + 2593 + static inline int qlt_get_fcp_task_attr(struct scsi_qla_host *vha, 2594 + uint8_t task_codes) 2595 + { 2596 + int fcp_task_attr; 2597 + 2598 + switch (task_codes) { 2599 + case ATIO_SIMPLE_QUEUE: 2600 + fcp_task_attr = MSG_SIMPLE_TAG; 2601 + break; 2602 + case ATIO_HEAD_OF_QUEUE: 2603 + fcp_task_attr = MSG_HEAD_TAG; 2604 + break; 2605 + case ATIO_ORDERED_QUEUE: 2606 + fcp_task_attr = MSG_ORDERED_TAG; 2607 + break; 2608 + case ATIO_ACA_QUEUE: 2609 + fcp_task_attr = MSG_ACA_TAG; 2610 + break; 2611 + case ATIO_UNTAGGED: 2612 + fcp_task_attr = MSG_SIMPLE_TAG; 2613 + break; 2614 + default: 2615 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05d, 2616 + "qla_target: unknown task code %x, use ORDERED instead\n", 2617 + task_codes); 2618 + fcp_task_attr = MSG_ORDERED_TAG; 2619 + break; 2620 + } 2621 + 2622 + return fcp_task_attr; 2623 + } 2624 + 2625 + static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *, 2626 + uint8_t *); 2627 + /* 2628 + * Process context for I/O path into tcm_qla2xxx code 2629 + */ 2630 + static void qlt_do_work(struct work_struct *work) 2631 + { 2632 + struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 2633 + scsi_qla_host_t *vha = cmd->vha; 2634 + struct qla_hw_data *ha = vha->hw; 2635 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 2636 + struct qla_tgt_sess *sess = NULL; 2637 + struct atio_from_isp *atio = &cmd->atio; 2638 + unsigned char *cdb; 2639 + unsigned long flags; 2640 + uint32_t data_length; 2641 + int ret, fcp_task_attr, data_dir, bidi = 0; 2642 + 2643 + if (tgt->tgt_stop) 2644 + goto out_term; 2645 + 2646 + spin_lock_irqsave(&ha->hardware_lock, flags); 2647 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, 2648 + atio->u.isp24.fcp_hdr.s_id); 2649 + if (sess) { 2650 + if (unlikely(sess->tearing_down)) { 2651 + sess = NULL; 2652 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2653 + goto out_term; 2654 + } else { 2655 + /* 2656 + * Do the extra kref_get() before dropping 2657 + * qla_hw_data->hardware_lock. 2658 + */ 2659 + kref_get(&sess->se_sess->sess_kref); 2660 + } 2661 + } 2662 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2663 + 2664 + if (unlikely(!sess)) { 2665 + uint8_t *s_id = atio->u.isp24.fcp_hdr.s_id; 2666 + 2667 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022, 2668 + "qla_target(%d): Unable to find wwn login" 2669 + " (s_id %x:%x:%x), trying to create it manually\n", 2670 + vha->vp_idx, s_id[0], s_id[1], s_id[2]); 2671 + 2672 + if (atio->u.raw.entry_count > 1) { 2673 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023, 2674 + "Dropping multy entry cmd %p\n", cmd); 2675 + goto out_term; 2676 + } 2677 + 2678 + mutex_lock(&ha->tgt.tgt_mutex); 2679 + sess = qlt_make_local_sess(vha, s_id); 2680 + /* sess has an extra creation ref. */ 2681 + mutex_unlock(&ha->tgt.tgt_mutex); 2682 + 2683 + if (!sess) 2684 + goto out_term; 2685 + } 2686 + 2687 + cmd->sess = sess; 2688 + cmd->loop_id = sess->loop_id; 2689 + cmd->conf_compl_supported = sess->conf_compl_supported; 2690 + 2691 + cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; 2692 + cmd->tag = atio->u.isp24.exchange_addr; 2693 + cmd->unpacked_lun = scsilun_to_int( 2694 + (struct scsi_lun *)&atio->u.isp24.fcp_cmnd.lun); 2695 + 2696 + if (atio->u.isp24.fcp_cmnd.rddata && 2697 + atio->u.isp24.fcp_cmnd.wrdata) { 2698 + bidi = 1; 2699 + data_dir = DMA_TO_DEVICE; 2700 + } else if (atio->u.isp24.fcp_cmnd.rddata) 2701 + data_dir = DMA_FROM_DEVICE; 2702 + else if (atio->u.isp24.fcp_cmnd.wrdata) 2703 + data_dir = DMA_TO_DEVICE; 2704 + else 2705 + data_dir = DMA_NONE; 2706 + 2707 + fcp_task_attr = qlt_get_fcp_task_attr(vha, 2708 + atio->u.isp24.fcp_cmnd.task_attr); 2709 + data_length = be32_to_cpu(get_unaligned((uint32_t *) 2710 + &atio->u.isp24.fcp_cmnd.add_cdb[ 2711 + atio->u.isp24.fcp_cmnd.add_cdb_len])); 2712 + 2713 + ql_dbg(ql_dbg_tgt, vha, 0xe022, 2714 + "qla_target: START qla command: %p lun: 0x%04x (tag %d)\n", 2715 + cmd, cmd->unpacked_lun, cmd->tag); 2716 + 2717 + ret = vha->hw->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length, 2718 + fcp_task_attr, data_dir, bidi); 2719 + if (ret != 0) 2720 + goto out_term; 2721 + /* 2722 + * Drop extra session reference from qla_tgt_handle_cmd_for_atio*( 2723 + */ 2724 + ha->tgt.tgt_ops->put_sess(sess); 2725 + return; 2726 + 2727 + out_term: 2728 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf020, "Terminating work cmd %p", cmd); 2729 + /* 2730 + * cmd has not sent to target yet, so pass NULL as the second argument 2731 + */ 2732 + spin_lock_irqsave(&ha->hardware_lock, flags); 2733 + qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); 2734 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 2735 + if (sess) 2736 + ha->tgt.tgt_ops->put_sess(sess); 2737 + } 2738 + 2739 + /* ha->hardware_lock supposed to be held on entry */ 2740 + static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, 2741 + struct atio_from_isp *atio) 2742 + { 2743 + struct qla_hw_data *ha = vha->hw; 2744 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 2745 + struct qla_tgt_cmd *cmd; 2746 + 2747 + if (unlikely(tgt->tgt_stop)) { 2748 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf021, 2749 + "New command while device %p is shutting down\n", tgt); 2750 + return -EFAULT; 2751 + } 2752 + 2753 + cmd = kmem_cache_zalloc(qla_tgt_cmd_cachep, GFP_ATOMIC); 2754 + if (!cmd) { 2755 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05e, 2756 + "qla_target(%d): Allocation of cmd failed\n", vha->vp_idx); 2757 + return -ENOMEM; 2758 + } 2759 + 2760 + INIT_LIST_HEAD(&cmd->cmd_list); 2761 + 2762 + memcpy(&cmd->atio, atio, sizeof(*atio)); 2763 + cmd->state = QLA_TGT_STATE_NEW; 2764 + cmd->tgt = ha->tgt.qla_tgt; 2765 + cmd->vha = vha; 2766 + 2767 + INIT_WORK(&cmd->work, qlt_do_work); 2768 + queue_work(qla_tgt_wq, &cmd->work); 2769 + return 0; 2770 + 2771 + } 2772 + 2773 + /* ha->hardware_lock supposed to be held on entry */ 2774 + static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, 2775 + int fn, void *iocb, int flags) 2776 + { 2777 + struct scsi_qla_host *vha = sess->vha; 2778 + struct qla_hw_data *ha = vha->hw; 2779 + struct qla_tgt_mgmt_cmd *mcmd; 2780 + int res; 2781 + uint8_t tmr_func; 2782 + 2783 + mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); 2784 + if (!mcmd) { 2785 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10009, 2786 + "qla_target(%d): Allocation of management " 2787 + "command failed, some commands and their data could " 2788 + "leak\n", vha->vp_idx); 2789 + return -ENOMEM; 2790 + } 2791 + memset(mcmd, 0, sizeof(*mcmd)); 2792 + mcmd->sess = sess; 2793 + 2794 + if (iocb) { 2795 + memcpy(&mcmd->orig_iocb.imm_ntfy, iocb, 2796 + sizeof(mcmd->orig_iocb.imm_ntfy)); 2797 + } 2798 + mcmd->tmr_func = fn; 2799 + mcmd->flags = flags; 2800 + 2801 + switch (fn) { 2802 + case QLA_TGT_CLEAR_ACA: 2803 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10000, 2804 + "qla_target(%d): CLEAR_ACA received\n", sess->vha->vp_idx); 2805 + tmr_func = TMR_CLEAR_ACA; 2806 + break; 2807 + 2808 + case QLA_TGT_TARGET_RESET: 2809 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10001, 2810 + "qla_target(%d): TARGET_RESET received\n", 2811 + sess->vha->vp_idx); 2812 + tmr_func = TMR_TARGET_WARM_RESET; 2813 + break; 2814 + 2815 + case QLA_TGT_LUN_RESET: 2816 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10002, 2817 + "qla_target(%d): LUN_RESET received\n", sess->vha->vp_idx); 2818 + tmr_func = TMR_LUN_RESET; 2819 + break; 2820 + 2821 + case QLA_TGT_CLEAR_TS: 2822 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10003, 2823 + "qla_target(%d): CLEAR_TS received\n", sess->vha->vp_idx); 2824 + tmr_func = TMR_CLEAR_TASK_SET; 2825 + break; 2826 + 2827 + case QLA_TGT_ABORT_TS: 2828 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10004, 2829 + "qla_target(%d): ABORT_TS received\n", sess->vha->vp_idx); 2830 + tmr_func = TMR_ABORT_TASK_SET; 2831 + break; 2832 + #if 0 2833 + case QLA_TGT_ABORT_ALL: 2834 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10005, 2835 + "qla_target(%d): Doing ABORT_ALL_TASKS\n", 2836 + sess->vha->vp_idx); 2837 + tmr_func = 0; 2838 + break; 2839 + 2840 + case QLA_TGT_ABORT_ALL_SESS: 2841 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10006, 2842 + "qla_target(%d): Doing ABORT_ALL_TASKS_SESS\n", 2843 + sess->vha->vp_idx); 2844 + tmr_func = 0; 2845 + break; 2846 + 2847 + case QLA_TGT_NEXUS_LOSS_SESS: 2848 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10007, 2849 + "qla_target(%d): Doing NEXUS_LOSS_SESS\n", 2850 + sess->vha->vp_idx); 2851 + tmr_func = 0; 2852 + break; 2853 + 2854 + case QLA_TGT_NEXUS_LOSS: 2855 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x10008, 2856 + "qla_target(%d): Doing NEXUS_LOSS\n", sess->vha->vp_idx); 2857 + tmr_func = 0; 2858 + break; 2859 + #endif 2860 + default: 2861 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000a, 2862 + "qla_target(%d): Unknown task mgmt fn 0x%x\n", 2863 + sess->vha->vp_idx, fn); 2864 + mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 2865 + return -ENOSYS; 2866 + } 2867 + 2868 + res = ha->tgt.tgt_ops->handle_tmr(mcmd, lun, tmr_func, 0); 2869 + if (res != 0) { 2870 + ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000b, 2871 + "qla_target(%d): tgt.tgt_ops->handle_tmr() failed: %d\n", 2872 + sess->vha->vp_idx, res); 2873 + mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 2874 + return -EFAULT; 2875 + } 2876 + 2877 + return 0; 2878 + } 2879 + 2880 + /* ha->hardware_lock supposed to be held on entry */ 2881 + static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb) 2882 + { 2883 + struct atio_from_isp *a = (struct atio_from_isp *)iocb; 2884 + struct qla_hw_data *ha = vha->hw; 2885 + struct qla_tgt *tgt; 2886 + struct qla_tgt_sess *sess; 2887 + uint32_t lun, unpacked_lun; 2888 + int lun_size, fn; 2889 + 2890 + tgt = ha->tgt.qla_tgt; 2891 + 2892 + lun = a->u.isp24.fcp_cmnd.lun; 2893 + lun_size = sizeof(a->u.isp24.fcp_cmnd.lun); 2894 + fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; 2895 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, 2896 + a->u.isp24.fcp_hdr.s_id); 2897 + unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); 2898 + 2899 + if (!sess) { 2900 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf024, 2901 + "qla_target(%d): task mgmt fn 0x%x for " 2902 + "non-existant session\n", vha->vp_idx, fn); 2903 + return qlt_sched_sess_work(tgt, QLA_TGT_SESS_WORK_TM, iocb, 2904 + sizeof(struct atio_from_isp)); 2905 + } 2906 + 2907 + return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); 2908 + } 2909 + 2910 + /* ha->hardware_lock supposed to be held on entry */ 2911 + static int __qlt_abort_task(struct scsi_qla_host *vha, 2912 + struct imm_ntfy_from_isp *iocb, struct qla_tgt_sess *sess) 2913 + { 2914 + struct atio_from_isp *a = (struct atio_from_isp *)iocb; 2915 + struct qla_hw_data *ha = vha->hw; 2916 + struct qla_tgt_mgmt_cmd *mcmd; 2917 + uint32_t lun, unpacked_lun; 2918 + int rc; 2919 + 2920 + mcmd = mempool_alloc(qla_tgt_mgmt_cmd_mempool, GFP_ATOMIC); 2921 + if (mcmd == NULL) { 2922 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05f, 2923 + "qla_target(%d): %s: Allocation of ABORT cmd failed\n", 2924 + vha->vp_idx, __func__); 2925 + return -ENOMEM; 2926 + } 2927 + memset(mcmd, 0, sizeof(*mcmd)); 2928 + 2929 + mcmd->sess = sess; 2930 + memcpy(&mcmd->orig_iocb.imm_ntfy, iocb, 2931 + sizeof(mcmd->orig_iocb.imm_ntfy)); 2932 + 2933 + lun = a->u.isp24.fcp_cmnd.lun; 2934 + unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); 2935 + 2936 + rc = ha->tgt.tgt_ops->handle_tmr(mcmd, unpacked_lun, TMR_ABORT_TASK, 2937 + le16_to_cpu(iocb->u.isp2x.seq_id)); 2938 + if (rc != 0) { 2939 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf060, 2940 + "qla_target(%d): tgt_ops->handle_tmr() failed: %d\n", 2941 + vha->vp_idx, rc); 2942 + mempool_free(mcmd, qla_tgt_mgmt_cmd_mempool); 2943 + return -EFAULT; 2944 + } 2945 + 2946 + return 0; 2947 + } 2948 + 2949 + /* ha->hardware_lock supposed to be held on entry */ 2950 + static int qlt_abort_task(struct scsi_qla_host *vha, 2951 + struct imm_ntfy_from_isp *iocb) 2952 + { 2953 + struct qla_hw_data *ha = vha->hw; 2954 + struct qla_tgt_sess *sess; 2955 + int loop_id; 2956 + 2957 + loop_id = GET_TARGET_ID(ha, (struct atio_from_isp *)iocb); 2958 + 2959 + sess = ha->tgt.tgt_ops->find_sess_by_loop_id(vha, loop_id); 2960 + if (sess == NULL) { 2961 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025, 2962 + "qla_target(%d): task abort for unexisting " 2963 + "session\n", vha->vp_idx); 2964 + return qlt_sched_sess_work(ha->tgt.qla_tgt, 2965 + QLA_TGT_SESS_WORK_ABORT, iocb, sizeof(*iocb)); 2966 + } 2967 + 2968 + return __qlt_abort_task(vha, iocb, sess); 2969 + } 2970 + 2971 + /* 2972 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 2973 + */ 2974 + static int qlt_24xx_handle_els(struct scsi_qla_host *vha, 2975 + struct imm_ntfy_from_isp *iocb) 2976 + { 2977 + struct qla_hw_data *ha = vha->hw; 2978 + int res = 0; 2979 + 2980 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026, 2981 + "qla_target(%d): Port ID: 0x%02x:%02x:%02x" 2982 + " ELS opcode: 0x%02x\n", vha->vp_idx, iocb->u.isp24.port_id[0], 2983 + iocb->u.isp24.port_id[1], iocb->u.isp24.port_id[2], 2984 + iocb->u.isp24.status_subcode); 2985 + 2986 + switch (iocb->u.isp24.status_subcode) { 2987 + case ELS_PLOGI: 2988 + case ELS_FLOGI: 2989 + case ELS_PRLI: 2990 + case ELS_LOGO: 2991 + case ELS_PRLO: 2992 + res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS); 2993 + break; 2994 + case ELS_PDISC: 2995 + case ELS_ADISC: 2996 + { 2997 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 2998 + if (tgt->link_reinit_iocb_pending) { 2999 + qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, 3000 + 0, 0, 0, 0, 0, 0); 3001 + tgt->link_reinit_iocb_pending = 0; 3002 + } 3003 + res = 1; /* send notify ack */ 3004 + break; 3005 + } 3006 + 3007 + default: 3008 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf061, 3009 + "qla_target(%d): Unsupported ELS command %x " 3010 + "received\n", vha->vp_idx, iocb->u.isp24.status_subcode); 3011 + res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS); 3012 + break; 3013 + } 3014 + 3015 + return res; 3016 + } 3017 + 3018 + static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset) 3019 + { 3020 + struct scatterlist *sg, *sgp, *sg_srr, *sg_srr_start = NULL; 3021 + size_t first_offset = 0, rem_offset = offset, tmp = 0; 3022 + int i, sg_srr_cnt, bufflen = 0; 3023 + 3024 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe023, 3025 + "Entering qla_tgt_set_data_offset: cmd: %p, cmd->sg: %p, " 3026 + "cmd->sg_cnt: %u, direction: %d\n", 3027 + cmd, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); 3028 + 3029 + /* 3030 + * FIXME: Reject non zero SRR relative offset until we can test 3031 + * this code properly. 3032 + */ 3033 + pr_debug("Rejecting non zero SRR rel_offs: %u\n", offset); 3034 + return -1; 3035 + 3036 + if (!cmd->sg || !cmd->sg_cnt) { 3037 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe055, 3038 + "Missing cmd->sg or zero cmd->sg_cnt in" 3039 + " qla_tgt_set_data_offset\n"); 3040 + return -EINVAL; 3041 + } 3042 + /* 3043 + * Walk the current cmd->sg list until we locate the new sg_srr_start 3044 + */ 3045 + for_each_sg(cmd->sg, sg, cmd->sg_cnt, i) { 3046 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe024, 3047 + "sg[%d]: %p page: %p, length: %d, offset: %d\n", 3048 + i, sg, sg_page(sg), sg->length, sg->offset); 3049 + 3050 + if ((sg->length + tmp) > offset) { 3051 + first_offset = rem_offset; 3052 + sg_srr_start = sg; 3053 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe025, 3054 + "Found matching sg[%d], using %p as sg_srr_start, " 3055 + "and using first_offset: %zu\n", i, sg, 3056 + first_offset); 3057 + break; 3058 + } 3059 + tmp += sg->length; 3060 + rem_offset -= sg->length; 3061 + } 3062 + 3063 + if (!sg_srr_start) { 3064 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe056, 3065 + "Unable to locate sg_srr_start for offset: %u\n", offset); 3066 + return -EINVAL; 3067 + } 3068 + sg_srr_cnt = (cmd->sg_cnt - i); 3069 + 3070 + sg_srr = kzalloc(sizeof(struct scatterlist) * sg_srr_cnt, GFP_KERNEL); 3071 + if (!sg_srr) { 3072 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe057, 3073 + "Unable to allocate sgp\n"); 3074 + return -ENOMEM; 3075 + } 3076 + sg_init_table(sg_srr, sg_srr_cnt); 3077 + sgp = &sg_srr[0]; 3078 + /* 3079 + * Walk the remaining list for sg_srr_start, mapping to the newly 3080 + * allocated sg_srr taking first_offset into account. 3081 + */ 3082 + for_each_sg(sg_srr_start, sg, sg_srr_cnt, i) { 3083 + if (first_offset) { 3084 + sg_set_page(sgp, sg_page(sg), 3085 + (sg->length - first_offset), first_offset); 3086 + first_offset = 0; 3087 + } else { 3088 + sg_set_page(sgp, sg_page(sg), sg->length, 0); 3089 + } 3090 + bufflen += sgp->length; 3091 + 3092 + sgp = sg_next(sgp); 3093 + if (!sgp) 3094 + break; 3095 + } 3096 + 3097 + cmd->sg = sg_srr; 3098 + cmd->sg_cnt = sg_srr_cnt; 3099 + cmd->bufflen = bufflen; 3100 + cmd->offset += offset; 3101 + cmd->free_sg = 1; 3102 + 3103 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe026, "New cmd->sg: %p\n", cmd->sg); 3104 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe027, "New cmd->sg_cnt: %u\n", 3105 + cmd->sg_cnt); 3106 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe028, "New cmd->bufflen: %u\n", 3107 + cmd->bufflen); 3108 + ql_dbg(ql_dbg_tgt, cmd->vha, 0xe029, "New cmd->offset: %u\n", 3109 + cmd->offset); 3110 + 3111 + if (cmd->sg_cnt < 0) 3112 + BUG(); 3113 + 3114 + if (cmd->bufflen < 0) 3115 + BUG(); 3116 + 3117 + return 0; 3118 + } 3119 + 3120 + static inline int qlt_srr_adjust_data(struct qla_tgt_cmd *cmd, 3121 + uint32_t srr_rel_offs, int *xmit_type) 3122 + { 3123 + int res = 0, rel_offs; 3124 + 3125 + rel_offs = srr_rel_offs - cmd->offset; 3126 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf027, "srr_rel_offs=%d, rel_offs=%d", 3127 + srr_rel_offs, rel_offs); 3128 + 3129 + *xmit_type = QLA_TGT_XMIT_ALL; 3130 + 3131 + if (rel_offs < 0) { 3132 + ql_dbg(ql_dbg_tgt_mgt, cmd->vha, 0xf062, 3133 + "qla_target(%d): SRR rel_offs (%d) < 0", 3134 + cmd->vha->vp_idx, rel_offs); 3135 + res = -1; 3136 + } else if (rel_offs == cmd->bufflen) 3137 + *xmit_type = QLA_TGT_XMIT_STATUS; 3138 + else if (rel_offs > 0) 3139 + res = qlt_set_data_offset(cmd, rel_offs); 3140 + 3141 + return res; 3142 + } 3143 + 3144 + /* No locks, thread context */ 3145 + static void qlt_handle_srr(struct scsi_qla_host *vha, 3146 + struct qla_tgt_srr_ctio *sctio, struct qla_tgt_srr_imm *imm) 3147 + { 3148 + struct imm_ntfy_from_isp *ntfy = 3149 + (struct imm_ntfy_from_isp *)&imm->imm_ntfy; 3150 + struct qla_hw_data *ha = vha->hw; 3151 + struct qla_tgt_cmd *cmd = sctio->cmd; 3152 + struct se_cmd *se_cmd = &cmd->se_cmd; 3153 + unsigned long flags; 3154 + int xmit_type = 0, resp = 0; 3155 + uint32_t offset; 3156 + uint16_t srr_ui; 3157 + 3158 + offset = le32_to_cpu(ntfy->u.isp24.srr_rel_offs); 3159 + srr_ui = ntfy->u.isp24.srr_ui; 3160 + 3161 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf028, "SRR cmd %p, srr_ui %x\n", 3162 + cmd, srr_ui); 3163 + 3164 + switch (srr_ui) { 3165 + case SRR_IU_STATUS: 3166 + spin_lock_irqsave(&ha->hardware_lock, flags); 3167 + qlt_send_notify_ack(vha, ntfy, 3168 + 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); 3169 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 3170 + xmit_type = QLA_TGT_XMIT_STATUS; 3171 + resp = 1; 3172 + break; 3173 + case SRR_IU_DATA_IN: 3174 + if (!cmd->sg || !cmd->sg_cnt) { 3175 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf063, 3176 + "Unable to process SRR_IU_DATA_IN due to" 3177 + " missing cmd->sg, state: %d\n", cmd->state); 3178 + dump_stack(); 3179 + goto out_reject; 3180 + } 3181 + if (se_cmd->scsi_status != 0) { 3182 + ql_dbg(ql_dbg_tgt, vha, 0xe02a, 3183 + "Rejecting SRR_IU_DATA_IN with non GOOD " 3184 + "scsi_status\n"); 3185 + goto out_reject; 3186 + } 3187 + cmd->bufflen = se_cmd->data_length; 3188 + 3189 + if (qlt_has_data(cmd)) { 3190 + if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0) 3191 + goto out_reject; 3192 + spin_lock_irqsave(&ha->hardware_lock, flags); 3193 + qlt_send_notify_ack(vha, ntfy, 3194 + 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); 3195 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 3196 + resp = 1; 3197 + } else { 3198 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf064, 3199 + "qla_target(%d): SRR for in data for cmd " 3200 + "without them (tag %d, SCSI status %d), " 3201 + "reject", vha->vp_idx, cmd->tag, 3202 + cmd->se_cmd.scsi_status); 3203 + goto out_reject; 3204 + } 3205 + break; 3206 + case SRR_IU_DATA_OUT: 3207 + if (!cmd->sg || !cmd->sg_cnt) { 3208 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf065, 3209 + "Unable to process SRR_IU_DATA_OUT due to" 3210 + " missing cmd->sg\n"); 3211 + dump_stack(); 3212 + goto out_reject; 3213 + } 3214 + if (se_cmd->scsi_status != 0) { 3215 + ql_dbg(ql_dbg_tgt, vha, 0xe02b, 3216 + "Rejecting SRR_IU_DATA_OUT" 3217 + " with non GOOD scsi_status\n"); 3218 + goto out_reject; 3219 + } 3220 + cmd->bufflen = se_cmd->data_length; 3221 + 3222 + if (qlt_has_data(cmd)) { 3223 + if (qlt_srr_adjust_data(cmd, offset, &xmit_type) != 0) 3224 + goto out_reject; 3225 + spin_lock_irqsave(&ha->hardware_lock, flags); 3226 + qlt_send_notify_ack(vha, ntfy, 3227 + 0, 0, 0, NOTIFY_ACK_SRR_FLAGS_ACCEPT, 0, 0); 3228 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 3229 + if (xmit_type & QLA_TGT_XMIT_DATA) 3230 + qlt_rdy_to_xfer(cmd); 3231 + } else { 3232 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf066, 3233 + "qla_target(%d): SRR for out data for cmd " 3234 + "without them (tag %d, SCSI status %d), " 3235 + "reject", vha->vp_idx, cmd->tag, 3236 + cmd->se_cmd.scsi_status); 3237 + goto out_reject; 3238 + } 3239 + break; 3240 + default: 3241 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf067, 3242 + "qla_target(%d): Unknown srr_ui value %x", 3243 + vha->vp_idx, srr_ui); 3244 + goto out_reject; 3245 + } 3246 + 3247 + /* Transmit response in case of status and data-in cases */ 3248 + if (resp) 3249 + qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); 3250 + 3251 + return; 3252 + 3253 + out_reject: 3254 + spin_lock_irqsave(&ha->hardware_lock, flags); 3255 + qlt_send_notify_ack(vha, ntfy, 0, 0, 0, 3256 + NOTIFY_ACK_SRR_FLAGS_REJECT, 3257 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 3258 + NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); 3259 + if (cmd->state == QLA_TGT_STATE_NEED_DATA) { 3260 + cmd->state = QLA_TGT_STATE_DATA_IN; 3261 + dump_stack(); 3262 + } else 3263 + qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 3264 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 3265 + } 3266 + 3267 + static void qlt_reject_free_srr_imm(struct scsi_qla_host *vha, 3268 + struct qla_tgt_srr_imm *imm, int ha_locked) 3269 + { 3270 + struct qla_hw_data *ha = vha->hw; 3271 + unsigned long flags = 0; 3272 + 3273 + if (!ha_locked) 3274 + spin_lock_irqsave(&ha->hardware_lock, flags); 3275 + 3276 + qlt_send_notify_ack(vha, (void *)&imm->imm_ntfy, 0, 0, 0, 3277 + NOTIFY_ACK_SRR_FLAGS_REJECT, 3278 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 3279 + NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); 3280 + 3281 + if (!ha_locked) 3282 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 3283 + 3284 + kfree(imm); 3285 + } 3286 + 3287 + static void qlt_handle_srr_work(struct work_struct *work) 3288 + { 3289 + struct qla_tgt *tgt = container_of(work, struct qla_tgt, srr_work); 3290 + struct scsi_qla_host *vha = tgt->vha; 3291 + struct qla_tgt_srr_ctio *sctio; 3292 + unsigned long flags; 3293 + 3294 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf029, "Entering SRR work (tgt %p)\n", 3295 + tgt); 3296 + 3297 + restart: 3298 + spin_lock_irqsave(&tgt->srr_lock, flags); 3299 + list_for_each_entry(sctio, &tgt->srr_ctio_list, srr_list_entry) { 3300 + struct qla_tgt_srr_imm *imm, *i, *ti; 3301 + struct qla_tgt_cmd *cmd; 3302 + struct se_cmd *se_cmd; 3303 + 3304 + imm = NULL; 3305 + list_for_each_entry_safe(i, ti, &tgt->srr_imm_list, 3306 + srr_list_entry) { 3307 + if (i->srr_id == sctio->srr_id) { 3308 + list_del(&i->srr_list_entry); 3309 + if (imm) { 3310 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf068, 3311 + "qla_target(%d): There must be " 3312 + "only one IMM SRR per CTIO SRR " 3313 + "(IMM SRR %p, id %d, CTIO %p\n", 3314 + vha->vp_idx, i, i->srr_id, sctio); 3315 + qlt_reject_free_srr_imm(tgt->vha, i, 0); 3316 + } else 3317 + imm = i; 3318 + } 3319 + } 3320 + 3321 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02a, 3322 + "IMM SRR %p, CTIO SRR %p (id %d)\n", imm, sctio, 3323 + sctio->srr_id); 3324 + 3325 + if (imm == NULL) { 3326 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02b, 3327 + "Not found matching IMM for SRR CTIO (id %d)\n", 3328 + sctio->srr_id); 3329 + continue; 3330 + } else 3331 + list_del(&sctio->srr_list_entry); 3332 + 3333 + spin_unlock_irqrestore(&tgt->srr_lock, flags); 3334 + 3335 + cmd = sctio->cmd; 3336 + /* 3337 + * Reset qla_tgt_cmd SRR values and SGL pointer+count to follow 3338 + * tcm_qla2xxx_write_pending() and tcm_qla2xxx_queue_data_in() 3339 + * logic.. 3340 + */ 3341 + cmd->offset = 0; 3342 + if (cmd->free_sg) { 3343 + kfree(cmd->sg); 3344 + cmd->sg = NULL; 3345 + cmd->free_sg = 0; 3346 + } 3347 + se_cmd = &cmd->se_cmd; 3348 + 3349 + cmd->sg_cnt = se_cmd->t_data_nents; 3350 + cmd->sg = se_cmd->t_data_sg; 3351 + 3352 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, 3353 + "SRR cmd %p (se_cmd %p, tag %d, op %x), " 3354 + "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, 3355 + se_cmd->t_task_cdb[0], cmd->sg_cnt, cmd->offset); 3356 + 3357 + qlt_handle_srr(vha, sctio, imm); 3358 + 3359 + kfree(imm); 3360 + kfree(sctio); 3361 + goto restart; 3362 + } 3363 + spin_unlock_irqrestore(&tgt->srr_lock, flags); 3364 + } 3365 + 3366 + /* ha->hardware_lock supposed to be held on entry */ 3367 + static void qlt_prepare_srr_imm(struct scsi_qla_host *vha, 3368 + struct imm_ntfy_from_isp *iocb) 3369 + { 3370 + struct qla_tgt_srr_imm *imm; 3371 + struct qla_hw_data *ha = vha->hw; 3372 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 3373 + struct qla_tgt_srr_ctio *sctio; 3374 + 3375 + tgt->imm_srr_id++; 3376 + 3377 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02d, "qla_target(%d): SRR received\n", 3378 + vha->vp_idx); 3379 + 3380 + imm = kzalloc(sizeof(*imm), GFP_ATOMIC); 3381 + if (imm != NULL) { 3382 + memcpy(&imm->imm_ntfy, iocb, sizeof(imm->imm_ntfy)); 3383 + 3384 + /* IRQ is already OFF */ 3385 + spin_lock(&tgt->srr_lock); 3386 + imm->srr_id = tgt->imm_srr_id; 3387 + list_add_tail(&imm->srr_list_entry, 3388 + &tgt->srr_imm_list); 3389 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02e, 3390 + "IMM NTFY SRR %p added (id %d, ui %x)\n", 3391 + imm, imm->srr_id, iocb->u.isp24.srr_ui); 3392 + if (tgt->imm_srr_id == tgt->ctio_srr_id) { 3393 + int found = 0; 3394 + list_for_each_entry(sctio, &tgt->srr_ctio_list, 3395 + srr_list_entry) { 3396 + if (sctio->srr_id == imm->srr_id) { 3397 + found = 1; 3398 + break; 3399 + } 3400 + } 3401 + if (found) { 3402 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02f, "%s", 3403 + "Scheduling srr work\n"); 3404 + schedule_work(&tgt->srr_work); 3405 + } else { 3406 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf030, 3407 + "qla_target(%d): imm_srr_id " 3408 + "== ctio_srr_id (%d), but there is no " 3409 + "corresponding SRR CTIO, deleting IMM " 3410 + "SRR %p\n", vha->vp_idx, tgt->ctio_srr_id, 3411 + imm); 3412 + list_del(&imm->srr_list_entry); 3413 + 3414 + kfree(imm); 3415 + 3416 + spin_unlock(&tgt->srr_lock); 3417 + goto out_reject; 3418 + } 3419 + } 3420 + spin_unlock(&tgt->srr_lock); 3421 + } else { 3422 + struct qla_tgt_srr_ctio *ts; 3423 + 3424 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf069, 3425 + "qla_target(%d): Unable to allocate SRR IMM " 3426 + "entry, SRR request will be rejected\n", vha->vp_idx); 3427 + 3428 + /* IRQ is already OFF */ 3429 + spin_lock(&tgt->srr_lock); 3430 + list_for_each_entry_safe(sctio, ts, &tgt->srr_ctio_list, 3431 + srr_list_entry) { 3432 + if (sctio->srr_id == tgt->imm_srr_id) { 3433 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf031, 3434 + "CTIO SRR %p deleted (id %d)\n", 3435 + sctio, sctio->srr_id); 3436 + list_del(&sctio->srr_list_entry); 3437 + qlt_send_term_exchange(vha, sctio->cmd, 3438 + &sctio->cmd->atio, 1); 3439 + kfree(sctio); 3440 + } 3441 + } 3442 + spin_unlock(&tgt->srr_lock); 3443 + goto out_reject; 3444 + } 3445 + 3446 + return; 3447 + 3448 + out_reject: 3449 + qlt_send_notify_ack(vha, iocb, 0, 0, 0, 3450 + NOTIFY_ACK_SRR_FLAGS_REJECT, 3451 + NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM, 3452 + NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL); 3453 + } 3454 + 3455 + /* 3456 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 3457 + */ 3458 + static void qlt_handle_imm_notify(struct scsi_qla_host *vha, 3459 + struct imm_ntfy_from_isp *iocb) 3460 + { 3461 + struct qla_hw_data *ha = vha->hw; 3462 + uint32_t add_flags = 0; 3463 + int send_notify_ack = 1; 3464 + uint16_t status; 3465 + 3466 + status = le16_to_cpu(iocb->u.isp2x.status); 3467 + switch (status) { 3468 + case IMM_NTFY_LIP_RESET: 3469 + { 3470 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf032, 3471 + "qla_target(%d): LIP reset (loop %#x), subcode %x\n", 3472 + vha->vp_idx, le16_to_cpu(iocb->u.isp24.nport_handle), 3473 + iocb->u.isp24.status_subcode); 3474 + 3475 + if (qlt_reset(vha, iocb, QLA_TGT_ABORT_ALL) == 0) 3476 + send_notify_ack = 0; 3477 + break; 3478 + } 3479 + 3480 + case IMM_NTFY_LIP_LINK_REINIT: 3481 + { 3482 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 3483 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, 3484 + "qla_target(%d): LINK REINIT (loop %#x, " 3485 + "subcode %x)\n", vha->vp_idx, 3486 + le16_to_cpu(iocb->u.isp24.nport_handle), 3487 + iocb->u.isp24.status_subcode); 3488 + if (tgt->link_reinit_iocb_pending) { 3489 + qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, 3490 + 0, 0, 0, 0, 0, 0); 3491 + } 3492 + memcpy(&tgt->link_reinit_iocb, iocb, sizeof(*iocb)); 3493 + tgt->link_reinit_iocb_pending = 1; 3494 + /* 3495 + * QLogic requires to wait after LINK REINIT for possible 3496 + * PDISC or ADISC ELS commands 3497 + */ 3498 + send_notify_ack = 0; 3499 + break; 3500 + } 3501 + 3502 + case IMM_NTFY_PORT_LOGOUT: 3503 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf034, 3504 + "qla_target(%d): Port logout (loop " 3505 + "%#x, subcode %x)\n", vha->vp_idx, 3506 + le16_to_cpu(iocb->u.isp24.nport_handle), 3507 + iocb->u.isp24.status_subcode); 3508 + 3509 + if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS) == 0) 3510 + send_notify_ack = 0; 3511 + /* The sessions will be cleared in the callback, if needed */ 3512 + break; 3513 + 3514 + case IMM_NTFY_GLBL_TPRLO: 3515 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf035, 3516 + "qla_target(%d): Global TPRLO (%x)\n", vha->vp_idx, status); 3517 + if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS) == 0) 3518 + send_notify_ack = 0; 3519 + /* The sessions will be cleared in the callback, if needed */ 3520 + break; 3521 + 3522 + case IMM_NTFY_PORT_CONFIG: 3523 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf036, 3524 + "qla_target(%d): Port config changed (%x)\n", vha->vp_idx, 3525 + status); 3526 + if (qlt_reset(vha, iocb, QLA_TGT_ABORT_ALL) == 0) 3527 + send_notify_ack = 0; 3528 + /* The sessions will be cleared in the callback, if needed */ 3529 + break; 3530 + 3531 + case IMM_NTFY_GLBL_LOGO: 3532 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06a, 3533 + "qla_target(%d): Link failure detected\n", 3534 + vha->vp_idx); 3535 + /* I_T nexus loss */ 3536 + if (qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS) == 0) 3537 + send_notify_ack = 0; 3538 + break; 3539 + 3540 + case IMM_NTFY_IOCB_OVERFLOW: 3541 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06b, 3542 + "qla_target(%d): Cannot provide requested " 3543 + "capability (IOCB overflowed the immediate notify " 3544 + "resource count)\n", vha->vp_idx); 3545 + break; 3546 + 3547 + case IMM_NTFY_ABORT_TASK: 3548 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf037, 3549 + "qla_target(%d): Abort Task (S %08x I %#x -> " 3550 + "L %#x)\n", vha->vp_idx, 3551 + le16_to_cpu(iocb->u.isp2x.seq_id), 3552 + GET_TARGET_ID(ha, (struct atio_from_isp *)iocb), 3553 + le16_to_cpu(iocb->u.isp2x.lun)); 3554 + if (qlt_abort_task(vha, iocb) == 0) 3555 + send_notify_ack = 0; 3556 + break; 3557 + 3558 + case IMM_NTFY_RESOURCE: 3559 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06c, 3560 + "qla_target(%d): Out of resources, host %ld\n", 3561 + vha->vp_idx, vha->host_no); 3562 + break; 3563 + 3564 + case IMM_NTFY_MSG_RX: 3565 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf038, 3566 + "qla_target(%d): Immediate notify task %x\n", 3567 + vha->vp_idx, iocb->u.isp2x.task_flags); 3568 + if (qlt_handle_task_mgmt(vha, iocb) == 0) 3569 + send_notify_ack = 0; 3570 + break; 3571 + 3572 + case IMM_NTFY_ELS: 3573 + if (qlt_24xx_handle_els(vha, iocb) == 0) 3574 + send_notify_ack = 0; 3575 + break; 3576 + 3577 + case IMM_NTFY_SRR: 3578 + qlt_prepare_srr_imm(vha, iocb); 3579 + send_notify_ack = 0; 3580 + break; 3581 + 3582 + default: 3583 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06d, 3584 + "qla_target(%d): Received unknown immediate " 3585 + "notify status %x\n", vha->vp_idx, status); 3586 + break; 3587 + } 3588 + 3589 + if (send_notify_ack) 3590 + qlt_send_notify_ack(vha, iocb, add_flags, 0, 0, 0, 0, 0); 3591 + } 3592 + 3593 + /* 3594 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 3595 + * This function sends busy to ISP 2xxx or 24xx. 3596 + */ 3597 + static void qlt_send_busy(struct scsi_qla_host *vha, 3598 + struct atio_from_isp *atio, uint16_t status) 3599 + { 3600 + struct ctio7_to_24xx *ctio24; 3601 + struct qla_hw_data *ha = vha->hw; 3602 + request_t *pkt; 3603 + struct qla_tgt_sess *sess = NULL; 3604 + 3605 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, 3606 + atio->u.isp24.fcp_hdr.s_id); 3607 + if (!sess) { 3608 + qlt_send_term_exchange(vha, NULL, atio, 1); 3609 + return; 3610 + } 3611 + /* Sending marker isn't necessary, since we called from ISR */ 3612 + 3613 + pkt = (request_t *)qla2x00_alloc_iocbs(vha, NULL); 3614 + if (!pkt) { 3615 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06e, 3616 + "qla_target(%d): %s failed: unable to allocate " 3617 + "request packet", vha->vp_idx, __func__); 3618 + return; 3619 + } 3620 + 3621 + pkt->entry_count = 1; 3622 + pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; 3623 + 3624 + ctio24 = (struct ctio7_to_24xx *)pkt; 3625 + ctio24->entry_type = CTIO_TYPE7; 3626 + ctio24->nport_handle = sess->loop_id; 3627 + ctio24->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); 3628 + ctio24->vp_index = vha->vp_idx; 3629 + ctio24->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; 3630 + ctio24->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; 3631 + ctio24->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; 3632 + ctio24->exchange_addr = atio->u.isp24.exchange_addr; 3633 + ctio24->u.status1.flags = (atio->u.isp24.attr << 9) | 3634 + __constant_cpu_to_le16( 3635 + CTIO7_FLAGS_STATUS_MODE_1 | CTIO7_FLAGS_SEND_STATUS | 3636 + CTIO7_FLAGS_DONT_RET_CTIO); 3637 + /* 3638 + * CTIO from fw w/o se_cmd doesn't provide enough info to retry it, 3639 + * if the explicit conformation is used. 3640 + */ 3641 + ctio24->u.status1.ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); 3642 + ctio24->u.status1.scsi_status = cpu_to_le16(status); 3643 + ctio24->u.status1.residual = get_unaligned((uint32_t *) 3644 + &atio->u.isp24.fcp_cmnd.add_cdb[ 3645 + atio->u.isp24.fcp_cmnd.add_cdb_len]); 3646 + if (ctio24->u.status1.residual != 0) 3647 + ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER; 3648 + 3649 + qla2x00_start_iocbs(vha, vha->req); 3650 + } 3651 + 3652 + /* ha->hardware_lock supposed to be held on entry */ 3653 + /* called via callback from qla2xxx */ 3654 + static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, 3655 + struct atio_from_isp *atio) 3656 + { 3657 + struct qla_hw_data *ha = vha->hw; 3658 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 3659 + int rc; 3660 + 3661 + if (unlikely(tgt == NULL)) { 3662 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf039, 3663 + "ATIO pkt, but no tgt (ha %p)", ha); 3664 + return; 3665 + } 3666 + ql_dbg(ql_dbg_tgt, vha, 0xe02c, 3667 + "qla_target(%d): ATIO pkt %p: type %02x count %02x", 3668 + vha->vp_idx, atio, atio->u.raw.entry_type, 3669 + atio->u.raw.entry_count); 3670 + /* 3671 + * In tgt_stop mode we also should allow all requests to pass. 3672 + * Otherwise, some commands can stuck. 3673 + */ 3674 + 3675 + tgt->irq_cmd_count++; 3676 + 3677 + switch (atio->u.raw.entry_type) { 3678 + case ATIO_TYPE7: 3679 + ql_dbg(ql_dbg_tgt, vha, 0xe02d, 3680 + "ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, " 3681 + "add_cdb_len %d, data_length %04x, s_id %x:%x:%x\n", 3682 + vha->vp_idx, atio->u.isp24.fcp_cmnd.lun, 3683 + atio->u.isp24.fcp_cmnd.rddata, 3684 + atio->u.isp24.fcp_cmnd.wrdata, 3685 + atio->u.isp24.fcp_cmnd.add_cdb_len, 3686 + be32_to_cpu(get_unaligned((uint32_t *) 3687 + &atio->u.isp24.fcp_cmnd.add_cdb[ 3688 + atio->u.isp24.fcp_cmnd.add_cdb_len])), 3689 + atio->u.isp24.fcp_hdr.s_id[0], 3690 + atio->u.isp24.fcp_hdr.s_id[1], 3691 + atio->u.isp24.fcp_hdr.s_id[2]); 3692 + 3693 + if (unlikely(atio->u.isp24.exchange_addr == 3694 + ATIO_EXCHANGE_ADDRESS_UNKNOWN)) { 3695 + ql_dbg(ql_dbg_tgt, vha, 0xe058, 3696 + "qla_target(%d): ATIO_TYPE7 " 3697 + "received with UNKNOWN exchange address, " 3698 + "sending QUEUE_FULL\n", vha->vp_idx); 3699 + qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL); 3700 + break; 3701 + } 3702 + if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) 3703 + rc = qlt_handle_cmd_for_atio(vha, atio); 3704 + else 3705 + rc = qlt_handle_task_mgmt(vha, atio); 3706 + if (unlikely(rc != 0)) { 3707 + if (rc == -ESRCH) { 3708 + #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 3709 + qlt_send_busy(vha, atio, SAM_STAT_BUSY); 3710 + #else 3711 + qlt_send_term_exchange(vha, NULL, atio, 1); 3712 + #endif 3713 + } else { 3714 + if (tgt->tgt_stop) { 3715 + ql_dbg(ql_dbg_tgt, vha, 0xe059, 3716 + "qla_target: Unable to send " 3717 + "command to target for req, " 3718 + "ignoring.\n"); 3719 + } else { 3720 + ql_dbg(ql_dbg_tgt, vha, 0xe05a, 3721 + "qla_target(%d): Unable to send " 3722 + "command to target, sending BUSY " 3723 + "status.\n", vha->vp_idx); 3724 + qlt_send_busy(vha, atio, SAM_STAT_BUSY); 3725 + } 3726 + } 3727 + } 3728 + break; 3729 + 3730 + case IMMED_NOTIFY_TYPE: 3731 + { 3732 + if (unlikely(atio->u.isp2x.entry_status != 0)) { 3733 + ql_dbg(ql_dbg_tgt, vha, 0xe05b, 3734 + "qla_target(%d): Received ATIO packet %x " 3735 + "with error status %x\n", vha->vp_idx, 3736 + atio->u.raw.entry_type, 3737 + atio->u.isp2x.entry_status); 3738 + break; 3739 + } 3740 + ql_dbg(ql_dbg_tgt, vha, 0xe02e, "%s", "IMMED_NOTIFY ATIO"); 3741 + qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)atio); 3742 + break; 3743 + } 3744 + 3745 + default: 3746 + ql_dbg(ql_dbg_tgt, vha, 0xe05c, 3747 + "qla_target(%d): Received unknown ATIO atio " 3748 + "type %x\n", vha->vp_idx, atio->u.raw.entry_type); 3749 + break; 3750 + } 3751 + 3752 + tgt->irq_cmd_count--; 3753 + } 3754 + 3755 + /* ha->hardware_lock supposed to be held on entry */ 3756 + /* called via callback from qla2xxx */ 3757 + static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) 3758 + { 3759 + struct qla_hw_data *ha = vha->hw; 3760 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 3761 + 3762 + if (unlikely(tgt == NULL)) { 3763 + ql_dbg(ql_dbg_tgt, vha, 0xe05d, 3764 + "qla_target(%d): Response pkt %x received, but no " 3765 + "tgt (ha %p)\n", vha->vp_idx, pkt->entry_type, ha); 3766 + return; 3767 + } 3768 + 3769 + ql_dbg(ql_dbg_tgt, vha, 0xe02f, 3770 + "qla_target(%d): response pkt %p: T %02x C %02x S %02x " 3771 + "handle %#x\n", vha->vp_idx, pkt, pkt->entry_type, 3772 + pkt->entry_count, pkt->entry_status, pkt->handle); 3773 + 3774 + /* 3775 + * In tgt_stop mode we also should allow all requests to pass. 3776 + * Otherwise, some commands can stuck. 3777 + */ 3778 + 3779 + tgt->irq_cmd_count++; 3780 + 3781 + switch (pkt->entry_type) { 3782 + case CTIO_TYPE7: 3783 + { 3784 + struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; 3785 + ql_dbg(ql_dbg_tgt, vha, 0xe030, "CTIO_TYPE7: instance %d\n", 3786 + vha->vp_idx); 3787 + qlt_do_ctio_completion(vha, entry->handle, 3788 + le16_to_cpu(entry->status)|(pkt->entry_status << 16), 3789 + entry); 3790 + break; 3791 + } 3792 + 3793 + case ACCEPT_TGT_IO_TYPE: 3794 + { 3795 + struct atio_from_isp *atio = (struct atio_from_isp *)pkt; 3796 + int rc; 3797 + ql_dbg(ql_dbg_tgt, vha, 0xe031, 3798 + "ACCEPT_TGT_IO instance %d status %04x " 3799 + "lun %04x read/write %d data_length %04x " 3800 + "target_id %02x rx_id %04x\n ", vha->vp_idx, 3801 + le16_to_cpu(atio->u.isp2x.status), 3802 + le16_to_cpu(atio->u.isp2x.lun), 3803 + atio->u.isp2x.execution_codes, 3804 + le32_to_cpu(atio->u.isp2x.data_length), GET_TARGET_ID(ha, 3805 + atio), atio->u.isp2x.rx_id); 3806 + if (atio->u.isp2x.status != 3807 + __constant_cpu_to_le16(ATIO_CDB_VALID)) { 3808 + ql_dbg(ql_dbg_tgt, vha, 0xe05e, 3809 + "qla_target(%d): ATIO with error " 3810 + "status %x received\n", vha->vp_idx, 3811 + le16_to_cpu(atio->u.isp2x.status)); 3812 + break; 3813 + } 3814 + ql_dbg(ql_dbg_tgt, vha, 0xe032, 3815 + "FCP CDB: 0x%02x, sizeof(cdb): %lu", 3816 + atio->u.isp2x.cdb[0], (unsigned long 3817 + int)sizeof(atio->u.isp2x.cdb)); 3818 + 3819 + rc = qlt_handle_cmd_for_atio(vha, atio); 3820 + if (unlikely(rc != 0)) { 3821 + if (rc == -ESRCH) { 3822 + #if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 3823 + qlt_send_busy(vha, atio, 0); 3824 + #else 3825 + qlt_send_term_exchange(vha, NULL, atio, 1); 3826 + #endif 3827 + } else { 3828 + if (tgt->tgt_stop) { 3829 + ql_dbg(ql_dbg_tgt, vha, 0xe05f, 3830 + "qla_target: Unable to send " 3831 + "command to target, sending TERM " 3832 + "EXCHANGE for rsp\n"); 3833 + qlt_send_term_exchange(vha, NULL, 3834 + atio, 1); 3835 + } else { 3836 + ql_dbg(ql_dbg_tgt, vha, 0xe060, 3837 + "qla_target(%d): Unable to send " 3838 + "command to target, sending BUSY " 3839 + "status\n", vha->vp_idx); 3840 + qlt_send_busy(vha, atio, 0); 3841 + } 3842 + } 3843 + } 3844 + } 3845 + break; 3846 + 3847 + case CONTINUE_TGT_IO_TYPE: 3848 + { 3849 + struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; 3850 + ql_dbg(ql_dbg_tgt, vha, 0xe033, 3851 + "CONTINUE_TGT_IO: instance %d\n", vha->vp_idx); 3852 + qlt_do_ctio_completion(vha, entry->handle, 3853 + le16_to_cpu(entry->status)|(pkt->entry_status << 16), 3854 + entry); 3855 + break; 3856 + } 3857 + 3858 + case CTIO_A64_TYPE: 3859 + { 3860 + struct ctio_to_2xxx *entry = (struct ctio_to_2xxx *)pkt; 3861 + ql_dbg(ql_dbg_tgt, vha, 0xe034, "CTIO_A64: instance %d\n", 3862 + vha->vp_idx); 3863 + qlt_do_ctio_completion(vha, entry->handle, 3864 + le16_to_cpu(entry->status)|(pkt->entry_status << 16), 3865 + entry); 3866 + break; 3867 + } 3868 + 3869 + case IMMED_NOTIFY_TYPE: 3870 + ql_dbg(ql_dbg_tgt, vha, 0xe035, "%s", "IMMED_NOTIFY\n"); 3871 + qlt_handle_imm_notify(vha, (struct imm_ntfy_from_isp *)pkt); 3872 + break; 3873 + 3874 + case NOTIFY_ACK_TYPE: 3875 + if (tgt->notify_ack_expected > 0) { 3876 + struct nack_to_isp *entry = (struct nack_to_isp *)pkt; 3877 + ql_dbg(ql_dbg_tgt, vha, 0xe036, 3878 + "NOTIFY_ACK seq %08x status %x\n", 3879 + le16_to_cpu(entry->u.isp2x.seq_id), 3880 + le16_to_cpu(entry->u.isp2x.status)); 3881 + tgt->notify_ack_expected--; 3882 + if (entry->u.isp2x.status != 3883 + __constant_cpu_to_le16(NOTIFY_ACK_SUCCESS)) { 3884 + ql_dbg(ql_dbg_tgt, vha, 0xe061, 3885 + "qla_target(%d): NOTIFY_ACK " 3886 + "failed %x\n", vha->vp_idx, 3887 + le16_to_cpu(entry->u.isp2x.status)); 3888 + } 3889 + } else { 3890 + ql_dbg(ql_dbg_tgt, vha, 0xe062, 3891 + "qla_target(%d): Unexpected NOTIFY_ACK received\n", 3892 + vha->vp_idx); 3893 + } 3894 + break; 3895 + 3896 + case ABTS_RECV_24XX: 3897 + ql_dbg(ql_dbg_tgt, vha, 0xe037, 3898 + "ABTS_RECV_24XX: instance %d\n", vha->vp_idx); 3899 + qlt_24xx_handle_abts(vha, (struct abts_recv_from_24xx *)pkt); 3900 + break; 3901 + 3902 + case ABTS_RESP_24XX: 3903 + if (tgt->abts_resp_expected > 0) { 3904 + struct abts_resp_from_24xx_fw *entry = 3905 + (struct abts_resp_from_24xx_fw *)pkt; 3906 + ql_dbg(ql_dbg_tgt, vha, 0xe038, 3907 + "ABTS_RESP_24XX: compl_status %x\n", 3908 + entry->compl_status); 3909 + tgt->abts_resp_expected--; 3910 + if (le16_to_cpu(entry->compl_status) != 3911 + ABTS_RESP_COMPL_SUCCESS) { 3912 + if ((entry->error_subcode1 == 0x1E) && 3913 + (entry->error_subcode2 == 0)) { 3914 + /* 3915 + * We've got a race here: aborted 3916 + * exchange not terminated, i.e. 3917 + * response for the aborted command was 3918 + * sent between the abort request was 3919 + * received and processed. 3920 + * Unfortunately, the firmware has a 3921 + * silly requirement that all aborted 3922 + * exchanges must be explicitely 3923 + * terminated, otherwise it refuses to 3924 + * send responses for the abort 3925 + * requests. So, we have to 3926 + * (re)terminate the exchange and retry 3927 + * the abort response. 3928 + */ 3929 + qlt_24xx_retry_term_exchange(vha, 3930 + entry); 3931 + } else 3932 + ql_dbg(ql_dbg_tgt, vha, 0xe063, 3933 + "qla_target(%d): ABTS_RESP_24XX " 3934 + "failed %x (subcode %x:%x)", 3935 + vha->vp_idx, entry->compl_status, 3936 + entry->error_subcode1, 3937 + entry->error_subcode2); 3938 + } 3939 + } else { 3940 + ql_dbg(ql_dbg_tgt, vha, 0xe064, 3941 + "qla_target(%d): Unexpected ABTS_RESP_24XX " 3942 + "received\n", vha->vp_idx); 3943 + } 3944 + break; 3945 + 3946 + default: 3947 + ql_dbg(ql_dbg_tgt, vha, 0xe065, 3948 + "qla_target(%d): Received unknown response pkt " 3949 + "type %x\n", vha->vp_idx, pkt->entry_type); 3950 + break; 3951 + } 3952 + 3953 + tgt->irq_cmd_count--; 3954 + } 3955 + 3956 + /* 3957 + * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire 3958 + */ 3959 + void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, 3960 + uint16_t *mailbox) 3961 + { 3962 + struct qla_hw_data *ha = vha->hw; 3963 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 3964 + int reason_code; 3965 + 3966 + ql_dbg(ql_dbg_tgt, vha, 0xe039, 3967 + "scsi(%ld): ha state %d init_done %d oper_mode %d topo %d\n", 3968 + vha->host_no, atomic_read(&vha->loop_state), vha->flags.init_done, 3969 + ha->operating_mode, ha->current_topology); 3970 + 3971 + if (!ha->tgt.tgt_ops) 3972 + return; 3973 + 3974 + if (unlikely(tgt == NULL)) { 3975 + ql_dbg(ql_dbg_tgt, vha, 0xe03a, 3976 + "ASYNC EVENT %#x, but no tgt (ha %p)\n", code, ha); 3977 + return; 3978 + } 3979 + 3980 + if (((code == MBA_POINT_TO_POINT) || (code == MBA_CHG_IN_CONNECTION)) && 3981 + IS_QLA2100(ha)) 3982 + return; 3983 + /* 3984 + * In tgt_stop mode we also should allow all requests to pass. 3985 + * Otherwise, some commands can stuck. 3986 + */ 3987 + 3988 + tgt->irq_cmd_count++; 3989 + 3990 + switch (code) { 3991 + case MBA_RESET: /* Reset */ 3992 + case MBA_SYSTEM_ERR: /* System Error */ 3993 + case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ 3994 + case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ 3995 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03a, 3996 + "qla_target(%d): System error async event %#x " 3997 + "occured", vha->vp_idx, code); 3998 + break; 3999 + case MBA_WAKEUP_THRES: /* Request Queue Wake-up. */ 4000 + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 4001 + break; 4002 + 4003 + case MBA_LOOP_UP: 4004 + { 4005 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03b, 4006 + "qla_target(%d): Async LOOP_UP occured " 4007 + "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, 4008 + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), 4009 + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); 4010 + if (tgt->link_reinit_iocb_pending) { 4011 + qlt_send_notify_ack(vha, (void *)&tgt->link_reinit_iocb, 4012 + 0, 0, 0, 0, 0, 0); 4013 + tgt->link_reinit_iocb_pending = 0; 4014 + } 4015 + break; 4016 + } 4017 + 4018 + case MBA_LIP_OCCURRED: 4019 + case MBA_LOOP_DOWN: 4020 + case MBA_LIP_RESET: 4021 + case MBA_RSCN_UPDATE: 4022 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03c, 4023 + "qla_target(%d): Async event %#x occured " 4024 + "(m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, code, 4025 + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), 4026 + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); 4027 + break; 4028 + 4029 + case MBA_PORT_UPDATE: 4030 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03d, 4031 + "qla_target(%d): Port update async event %#x " 4032 + "occured: updating the ports database (m[1]=%x, m[2]=%x, " 4033 + "m[3]=%x, m[4]=%x)", vha->vp_idx, code, 4034 + le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), 4035 + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); 4036 + reason_code = le16_to_cpu(mailbox[2]); 4037 + if (reason_code == 0x4) 4038 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03e, 4039 + "Async MB 2: Got PLOGI Complete\n"); 4040 + else if (reason_code == 0x7) 4041 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf03f, 4042 + "Async MB 2: Port Logged Out\n"); 4043 + break; 4044 + 4045 + default: 4046 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf040, 4047 + "qla_target(%d): Async event %#x occured: " 4048 + "ignore (m[1]=%x, m[2]=%x, m[3]=%x, m[4]=%x)", vha->vp_idx, 4049 + code, le16_to_cpu(mailbox[1]), le16_to_cpu(mailbox[2]), 4050 + le16_to_cpu(mailbox[3]), le16_to_cpu(mailbox[4])); 4051 + break; 4052 + } 4053 + 4054 + tgt->irq_cmd_count--; 4055 + } 4056 + 4057 + static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, 4058 + uint16_t loop_id) 4059 + { 4060 + fc_port_t *fcport; 4061 + int rc; 4062 + 4063 + fcport = kzalloc(sizeof(*fcport), GFP_KERNEL); 4064 + if (!fcport) { 4065 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf06f, 4066 + "qla_target(%d): Allocation of tmp FC port failed", 4067 + vha->vp_idx); 4068 + return NULL; 4069 + } 4070 + 4071 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf041, "loop_id %d", loop_id); 4072 + 4073 + fcport->loop_id = loop_id; 4074 + 4075 + rc = qla2x00_get_port_database(vha, fcport, 0); 4076 + if (rc != QLA_SUCCESS) { 4077 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf070, 4078 + "qla_target(%d): Failed to retrieve fcport " 4079 + "information -- get_port_database() returned %x " 4080 + "(loop_id=0x%04x)", vha->vp_idx, rc, loop_id); 4081 + kfree(fcport); 4082 + return NULL; 4083 + } 4084 + 4085 + return fcport; 4086 + } 4087 + 4088 + /* Must be called under tgt_mutex */ 4089 + static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha, 4090 + uint8_t *s_id) 4091 + { 4092 + struct qla_hw_data *ha = vha->hw; 4093 + struct qla_tgt_sess *sess = NULL; 4094 + fc_port_t *fcport = NULL; 4095 + int rc, global_resets; 4096 + uint16_t loop_id = 0; 4097 + 4098 + retry: 4099 + global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); 4100 + 4101 + rc = qla24xx_get_loop_id(vha, s_id, &loop_id); 4102 + if (rc != 0) { 4103 + if ((s_id[0] == 0xFF) && 4104 + (s_id[1] == 0xFC)) { 4105 + /* 4106 + * This is Domain Controller, so it should be 4107 + * OK to drop SCSI commands from it. 4108 + */ 4109 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf042, 4110 + "Unable to find initiator with S_ID %x:%x:%x", 4111 + s_id[0], s_id[1], s_id[2]); 4112 + } else 4113 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf071, 4114 + "qla_target(%d): Unable to find " 4115 + "initiator with S_ID %x:%x:%x", 4116 + vha->vp_idx, s_id[0], s_id[1], 4117 + s_id[2]); 4118 + return NULL; 4119 + } 4120 + 4121 + fcport = qlt_get_port_database(vha, loop_id); 4122 + if (!fcport) 4123 + return NULL; 4124 + 4125 + if (global_resets != 4126 + atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { 4127 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf043, 4128 + "qla_target(%d): global reset during session discovery " 4129 + "(counter was %d, new %d), retrying", vha->vp_idx, 4130 + global_resets, 4131 + atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); 4132 + goto retry; 4133 + } 4134 + 4135 + sess = qlt_create_sess(vha, fcport, true); 4136 + 4137 + kfree(fcport); 4138 + return sess; 4139 + } 4140 + 4141 + static void qlt_abort_work(struct qla_tgt *tgt, 4142 + struct qla_tgt_sess_work_param *prm) 4143 + { 4144 + struct scsi_qla_host *vha = tgt->vha; 4145 + struct qla_hw_data *ha = vha->hw; 4146 + struct qla_tgt_sess *sess = NULL; 4147 + unsigned long flags; 4148 + uint32_t be_s_id; 4149 + uint8_t s_id[3]; 4150 + int rc; 4151 + 4152 + spin_lock_irqsave(&ha->hardware_lock, flags); 4153 + 4154 + if (tgt->tgt_stop) 4155 + goto out_term; 4156 + 4157 + s_id[0] = prm->abts.fcp_hdr_le.s_id[2]; 4158 + s_id[1] = prm->abts.fcp_hdr_le.s_id[1]; 4159 + s_id[2] = prm->abts.fcp_hdr_le.s_id[0]; 4160 + 4161 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, 4162 + (unsigned char *)&be_s_id); 4163 + if (!sess) { 4164 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4165 + 4166 + mutex_lock(&ha->tgt.tgt_mutex); 4167 + sess = qlt_make_local_sess(vha, s_id); 4168 + /* sess has got an extra creation ref */ 4169 + mutex_unlock(&ha->tgt.tgt_mutex); 4170 + 4171 + spin_lock_irqsave(&ha->hardware_lock, flags); 4172 + if (!sess) 4173 + goto out_term; 4174 + } else { 4175 + kref_get(&sess->se_sess->sess_kref); 4176 + } 4177 + 4178 + if (tgt->tgt_stop) 4179 + goto out_term; 4180 + 4181 + rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess); 4182 + if (rc != 0) 4183 + goto out_term; 4184 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4185 + 4186 + ha->tgt.tgt_ops->put_sess(sess); 4187 + return; 4188 + 4189 + out_term: 4190 + qlt_24xx_send_abts_resp(vha, &prm->abts, FCP_TMF_REJECTED, false); 4191 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4192 + if (sess) 4193 + ha->tgt.tgt_ops->put_sess(sess); 4194 + } 4195 + 4196 + static void qlt_tmr_work(struct qla_tgt *tgt, 4197 + struct qla_tgt_sess_work_param *prm) 4198 + { 4199 + struct atio_from_isp *a = &prm->tm_iocb2; 4200 + struct scsi_qla_host *vha = tgt->vha; 4201 + struct qla_hw_data *ha = vha->hw; 4202 + struct qla_tgt_sess *sess = NULL; 4203 + unsigned long flags; 4204 + uint8_t *s_id = NULL; /* to hide compiler warnings */ 4205 + int rc; 4206 + uint32_t lun, unpacked_lun; 4207 + int lun_size, fn; 4208 + void *iocb; 4209 + 4210 + spin_lock_irqsave(&ha->hardware_lock, flags); 4211 + 4212 + if (tgt->tgt_stop) 4213 + goto out_term; 4214 + 4215 + s_id = prm->tm_iocb2.u.isp24.fcp_hdr.s_id; 4216 + sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); 4217 + if (!sess) { 4218 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4219 + 4220 + mutex_lock(&ha->tgt.tgt_mutex); 4221 + sess = qlt_make_local_sess(vha, s_id); 4222 + /* sess has got an extra creation ref */ 4223 + mutex_unlock(&ha->tgt.tgt_mutex); 4224 + 4225 + spin_lock_irqsave(&ha->hardware_lock, flags); 4226 + if (!sess) 4227 + goto out_term; 4228 + } else { 4229 + kref_get(&sess->se_sess->sess_kref); 4230 + } 4231 + 4232 + iocb = a; 4233 + lun = a->u.isp24.fcp_cmnd.lun; 4234 + lun_size = sizeof(lun); 4235 + fn = a->u.isp24.fcp_cmnd.task_mgmt_flags; 4236 + unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); 4237 + 4238 + rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0); 4239 + if (rc != 0) 4240 + goto out_term; 4241 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4242 + 4243 + ha->tgt.tgt_ops->put_sess(sess); 4244 + return; 4245 + 4246 + out_term: 4247 + qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1); 4248 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4249 + if (sess) 4250 + ha->tgt.tgt_ops->put_sess(sess); 4251 + } 4252 + 4253 + static void qlt_sess_work_fn(struct work_struct *work) 4254 + { 4255 + struct qla_tgt *tgt = container_of(work, struct qla_tgt, sess_work); 4256 + struct scsi_qla_host *vha = tgt->vha; 4257 + unsigned long flags; 4258 + 4259 + ql_dbg(ql_dbg_tgt_mgt, vha, 0xf000, "Sess work (tgt %p)", tgt); 4260 + 4261 + spin_lock_irqsave(&tgt->sess_work_lock, flags); 4262 + while (!list_empty(&tgt->sess_works_list)) { 4263 + struct qla_tgt_sess_work_param *prm = list_entry( 4264 + tgt->sess_works_list.next, typeof(*prm), 4265 + sess_works_list_entry); 4266 + 4267 + /* 4268 + * This work can be scheduled on several CPUs at time, so we 4269 + * must delete the entry to eliminate double processing 4270 + */ 4271 + list_del(&prm->sess_works_list_entry); 4272 + 4273 + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 4274 + 4275 + switch (prm->type) { 4276 + case QLA_TGT_SESS_WORK_ABORT: 4277 + qlt_abort_work(tgt, prm); 4278 + break; 4279 + case QLA_TGT_SESS_WORK_TM: 4280 + qlt_tmr_work(tgt, prm); 4281 + break; 4282 + default: 4283 + BUG_ON(1); 4284 + break; 4285 + } 4286 + 4287 + spin_lock_irqsave(&tgt->sess_work_lock, flags); 4288 + 4289 + kfree(prm); 4290 + } 4291 + spin_unlock_irqrestore(&tgt->sess_work_lock, flags); 4292 + } 4293 + 4294 + /* Must be called under tgt_host_action_mutex */ 4295 + int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) 4296 + { 4297 + struct qla_tgt *tgt; 4298 + 4299 + if (!QLA_TGT_MODE_ENABLED()) 4300 + return 0; 4301 + 4302 + ql_dbg(ql_dbg_tgt, base_vha, 0xe03b, 4303 + "Registering target for host %ld(%p)", base_vha->host_no, ha); 4304 + 4305 + BUG_ON((ha->tgt.qla_tgt != NULL) || (ha->tgt.tgt_ops != NULL)); 4306 + 4307 + tgt = kzalloc(sizeof(struct qla_tgt), GFP_KERNEL); 4308 + if (!tgt) { 4309 + ql_dbg(ql_dbg_tgt, base_vha, 0xe066, 4310 + "Unable to allocate struct qla_tgt\n"); 4311 + return -ENOMEM; 4312 + } 4313 + 4314 + if (!(base_vha->host->hostt->supported_mode & MODE_TARGET)) 4315 + base_vha->host->hostt->supported_mode |= MODE_TARGET; 4316 + 4317 + tgt->ha = ha; 4318 + tgt->vha = base_vha; 4319 + init_waitqueue_head(&tgt->waitQ); 4320 + INIT_LIST_HEAD(&tgt->sess_list); 4321 + INIT_LIST_HEAD(&tgt->del_sess_list); 4322 + INIT_DELAYED_WORK(&tgt->sess_del_work, 4323 + (void (*)(struct work_struct *))qlt_del_sess_work_fn); 4324 + spin_lock_init(&tgt->sess_work_lock); 4325 + INIT_WORK(&tgt->sess_work, qlt_sess_work_fn); 4326 + INIT_LIST_HEAD(&tgt->sess_works_list); 4327 + spin_lock_init(&tgt->srr_lock); 4328 + INIT_LIST_HEAD(&tgt->srr_ctio_list); 4329 + INIT_LIST_HEAD(&tgt->srr_imm_list); 4330 + INIT_WORK(&tgt->srr_work, qlt_handle_srr_work); 4331 + atomic_set(&tgt->tgt_global_resets_count, 0); 4332 + 4333 + ha->tgt.qla_tgt = tgt; 4334 + 4335 + ql_dbg(ql_dbg_tgt, base_vha, 0xe067, 4336 + "qla_target(%d): using 64 Bit PCI addressing", 4337 + base_vha->vp_idx); 4338 + tgt->tgt_enable_64bit_addr = 1; 4339 + /* 3 is reserved */ 4340 + tgt->sg_tablesize = QLA_TGT_MAX_SG_24XX(base_vha->req->length - 3); 4341 + tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; 4342 + tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; 4343 + 4344 + mutex_lock(&qla_tgt_mutex); 4345 + list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); 4346 + mutex_unlock(&qla_tgt_mutex); 4347 + 4348 + return 0; 4349 + } 4350 + 4351 + /* Must be called under tgt_host_action_mutex */ 4352 + int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) 4353 + { 4354 + if (!ha->tgt.qla_tgt) 4355 + return 0; 4356 + 4357 + mutex_lock(&qla_tgt_mutex); 4358 + list_del(&ha->tgt.qla_tgt->tgt_list_entry); 4359 + mutex_unlock(&qla_tgt_mutex); 4360 + 4361 + ql_dbg(ql_dbg_tgt, vha, 0xe03c, "Unregistering target for host %ld(%p)", 4362 + vha->host_no, ha); 4363 + qlt_release(ha->tgt.qla_tgt); 4364 + 4365 + return 0; 4366 + } 4367 + 4368 + static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, 4369 + unsigned char *b) 4370 + { 4371 + int i; 4372 + 4373 + pr_debug("qla2xxx HW vha->node_name: "); 4374 + for (i = 0; i < WWN_SIZE; i++) 4375 + pr_debug("%02x ", vha->node_name[i]); 4376 + pr_debug("\n"); 4377 + pr_debug("qla2xxx HW vha->port_name: "); 4378 + for (i = 0; i < WWN_SIZE; i++) 4379 + pr_debug("%02x ", vha->port_name[i]); 4380 + pr_debug("\n"); 4381 + 4382 + pr_debug("qla2xxx passed configfs WWPN: "); 4383 + put_unaligned_be64(wwpn, b); 4384 + for (i = 0; i < WWN_SIZE; i++) 4385 + pr_debug("%02x ", b[i]); 4386 + pr_debug("\n"); 4387 + } 4388 + 4389 + /** 4390 + * qla_tgt_lport_register - register lport with external module 4391 + * 4392 + * @qla_tgt_ops: Pointer for tcm_qla2xxx qla_tgt_ops 4393 + * @wwpn: Passwd FC target WWPN 4394 + * @callback: lport initialization callback for tcm_qla2xxx code 4395 + * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data 4396 + */ 4397 + int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn, 4398 + int (*callback)(struct scsi_qla_host *), void *target_lport_ptr) 4399 + { 4400 + struct qla_tgt *tgt; 4401 + struct scsi_qla_host *vha; 4402 + struct qla_hw_data *ha; 4403 + struct Scsi_Host *host; 4404 + unsigned long flags; 4405 + int rc; 4406 + u8 b[WWN_SIZE]; 4407 + 4408 + mutex_lock(&qla_tgt_mutex); 4409 + list_for_each_entry(tgt, &qla_tgt_glist, tgt_list_entry) { 4410 + vha = tgt->vha; 4411 + ha = vha->hw; 4412 + 4413 + host = vha->host; 4414 + if (!host) 4415 + continue; 4416 + 4417 + if (ha->tgt.tgt_ops != NULL) 4418 + continue; 4419 + 4420 + if (!(host->hostt->supported_mode & MODE_TARGET)) 4421 + continue; 4422 + 4423 + spin_lock_irqsave(&ha->hardware_lock, flags); 4424 + if (host->active_mode & MODE_TARGET) { 4425 + pr_debug("MODE_TARGET already active on qla2xxx(%d)\n", 4426 + host->host_no); 4427 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4428 + continue; 4429 + } 4430 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4431 + 4432 + if (!scsi_host_get(host)) { 4433 + ql_dbg(ql_dbg_tgt, vha, 0xe068, 4434 + "Unable to scsi_host_get() for" 4435 + " qla2xxx scsi_host\n"); 4436 + continue; 4437 + } 4438 + qlt_lport_dump(vha, wwpn, b); 4439 + 4440 + if (memcmp(vha->port_name, b, WWN_SIZE)) { 4441 + scsi_host_put(host); 4442 + continue; 4443 + } 4444 + /* 4445 + * Setup passed parameters ahead of invoking callback 4446 + */ 4447 + ha->tgt.tgt_ops = qla_tgt_ops; 4448 + ha->tgt.target_lport_ptr = target_lport_ptr; 4449 + rc = (*callback)(vha); 4450 + if (rc != 0) { 4451 + ha->tgt.tgt_ops = NULL; 4452 + ha->tgt.target_lport_ptr = NULL; 4453 + } 4454 + mutex_unlock(&qla_tgt_mutex); 4455 + return rc; 4456 + } 4457 + mutex_unlock(&qla_tgt_mutex); 4458 + 4459 + return -ENODEV; 4460 + } 4461 + EXPORT_SYMBOL(qlt_lport_register); 4462 + 4463 + /** 4464 + * qla_tgt_lport_deregister - Degister lport 4465 + * 4466 + * @vha: Registered scsi_qla_host pointer 4467 + */ 4468 + void qlt_lport_deregister(struct scsi_qla_host *vha) 4469 + { 4470 + struct qla_hw_data *ha = vha->hw; 4471 + struct Scsi_Host *sh = vha->host; 4472 + /* 4473 + * Clear the target_lport_ptr qla_target_template pointer in qla_hw_data 4474 + */ 4475 + ha->tgt.target_lport_ptr = NULL; 4476 + ha->tgt.tgt_ops = NULL; 4477 + /* 4478 + * Release the Scsi_Host reference for the underlying qla2xxx host 4479 + */ 4480 + scsi_host_put(sh); 4481 + } 4482 + EXPORT_SYMBOL(qlt_lport_deregister); 4483 + 4484 + /* Must be called under HW lock */ 4485 + void qlt_set_mode(struct scsi_qla_host *vha) 4486 + { 4487 + struct qla_hw_data *ha = vha->hw; 4488 + 4489 + switch (ql2x_ini_mode) { 4490 + case QLA2XXX_INI_MODE_DISABLED: 4491 + case QLA2XXX_INI_MODE_EXCLUSIVE: 4492 + vha->host->active_mode = MODE_TARGET; 4493 + break; 4494 + case QLA2XXX_INI_MODE_ENABLED: 4495 + vha->host->active_mode |= MODE_TARGET; 4496 + break; 4497 + default: 4498 + break; 4499 + } 4500 + 4501 + if (ha->tgt.ini_mode_force_reverse) 4502 + qla_reverse_ini_mode(vha); 4503 + } 4504 + 4505 + /* Must be called under HW lock */ 4506 + void qlt_clear_mode(struct scsi_qla_host *vha) 4507 + { 4508 + struct qla_hw_data *ha = vha->hw; 4509 + 4510 + switch (ql2x_ini_mode) { 4511 + case QLA2XXX_INI_MODE_DISABLED: 4512 + vha->host->active_mode = MODE_UNKNOWN; 4513 + break; 4514 + case QLA2XXX_INI_MODE_EXCLUSIVE: 4515 + vha->host->active_mode = MODE_INITIATOR; 4516 + break; 4517 + case QLA2XXX_INI_MODE_ENABLED: 4518 + vha->host->active_mode &= ~MODE_TARGET; 4519 + break; 4520 + default: 4521 + break; 4522 + } 4523 + 4524 + if (ha->tgt.ini_mode_force_reverse) 4525 + qla_reverse_ini_mode(vha); 4526 + } 4527 + 4528 + /* 4529 + * qla_tgt_enable_vha - NO LOCK HELD 4530 + * 4531 + * host_reset, bring up w/ Target Mode Enabled 4532 + */ 4533 + void 4534 + qlt_enable_vha(struct scsi_qla_host *vha) 4535 + { 4536 + struct qla_hw_data *ha = vha->hw; 4537 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 4538 + unsigned long flags; 4539 + 4540 + if (!tgt) { 4541 + ql_dbg(ql_dbg_tgt, vha, 0xe069, 4542 + "Unable to locate qla_tgt pointer from" 4543 + " struct qla_hw_data\n"); 4544 + dump_stack(); 4545 + return; 4546 + } 4547 + 4548 + spin_lock_irqsave(&ha->hardware_lock, flags); 4549 + tgt->tgt_stopped = 0; 4550 + qlt_set_mode(vha); 4551 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4552 + 4553 + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 4554 + qla2xxx_wake_dpc(vha); 4555 + qla2x00_wait_for_hba_online(vha); 4556 + } 4557 + EXPORT_SYMBOL(qlt_enable_vha); 4558 + 4559 + /* 4560 + * qla_tgt_disable_vha - NO LOCK HELD 4561 + * 4562 + * Disable Target Mode and reset the adapter 4563 + */ 4564 + void 4565 + qlt_disable_vha(struct scsi_qla_host *vha) 4566 + { 4567 + struct qla_hw_data *ha = vha->hw; 4568 + struct qla_tgt *tgt = ha->tgt.qla_tgt; 4569 + unsigned long flags; 4570 + 4571 + if (!tgt) { 4572 + ql_dbg(ql_dbg_tgt, vha, 0xe06a, 4573 + "Unable to locate qla_tgt pointer from" 4574 + " struct qla_hw_data\n"); 4575 + dump_stack(); 4576 + return; 4577 + } 4578 + 4579 + spin_lock_irqsave(&ha->hardware_lock, flags); 4580 + qlt_clear_mode(vha); 4581 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 4582 + 4583 + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); 4584 + qla2xxx_wake_dpc(vha); 4585 + qla2x00_wait_for_hba_online(vha); 4586 + } 4587 + 4588 + /* 4589 + * Called from qla_init.c:qla24xx_vport_create() contex to setup 4590 + * the target mode specific struct scsi_qla_host and struct qla_hw_data 4591 + * members. 4592 + */ 4593 + void 4594 + qlt_vport_create(struct scsi_qla_host *vha, struct qla_hw_data *ha) 4595 + { 4596 + if (!qla_tgt_mode_enabled(vha)) 4597 + return; 4598 + 4599 + mutex_init(&ha->tgt.tgt_mutex); 4600 + mutex_init(&ha->tgt.tgt_host_action_mutex); 4601 + 4602 + qlt_clear_mode(vha); 4603 + 4604 + /* 4605 + * NOTE: Currently the value is kept the same for <24xx and 4606 + * >=24xx ISPs. If it is necessary to change it, 4607 + * the check should be added for specific ISPs, 4608 + * assigning the value appropriately. 4609 + */ 4610 + ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; 4611 + } 4612 + 4613 + void 4614 + qlt_rff_id(struct scsi_qla_host *vha, struct ct_sns_req *ct_req) 4615 + { 4616 + /* 4617 + * FC-4 Feature bit 0 indicates target functionality to the name server. 4618 + */ 4619 + if (qla_tgt_mode_enabled(vha)) { 4620 + if (qla_ini_mode_enabled(vha)) 4621 + ct_req->req.rff_id.fc4_feature = BIT_0 | BIT_1; 4622 + else 4623 + ct_req->req.rff_id.fc4_feature = BIT_0; 4624 + } else if (qla_ini_mode_enabled(vha)) { 4625 + ct_req->req.rff_id.fc4_feature = BIT_1; 4626 + } 4627 + } 4628 + 4629 + /* 4630 + * qlt_init_atio_q_entries() - Initializes ATIO queue entries. 4631 + * @ha: HA context 4632 + * 4633 + * Beginning of ATIO ring has initialization control block already built 4634 + * by nvram config routine. 4635 + * 4636 + * Returns 0 on success. 4637 + */ 4638 + void 4639 + qlt_init_atio_q_entries(struct scsi_qla_host *vha) 4640 + { 4641 + struct qla_hw_data *ha = vha->hw; 4642 + uint16_t cnt; 4643 + struct atio_from_isp *pkt = (struct atio_from_isp *)ha->tgt.atio_ring; 4644 + 4645 + if (!qla_tgt_mode_enabled(vha)) 4646 + return; 4647 + 4648 + for (cnt = 0; cnt < ha->tgt.atio_q_length; cnt++) { 4649 + pkt->u.raw.signature = ATIO_PROCESSED; 4650 + pkt++; 4651 + } 4652 + 4653 + } 4654 + 4655 + /* 4656 + * qlt_24xx_process_atio_queue() - Process ATIO queue entries. 4657 + * @ha: SCSI driver HA context 4658 + */ 4659 + void 4660 + qlt_24xx_process_atio_queue(struct scsi_qla_host *vha) 4661 + { 4662 + struct qla_hw_data *ha = vha->hw; 4663 + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; 4664 + struct atio_from_isp *pkt; 4665 + int cnt, i; 4666 + 4667 + if (!vha->flags.online) 4668 + return; 4669 + 4670 + while (ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) { 4671 + pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; 4672 + cnt = pkt->u.raw.entry_count; 4673 + 4674 + qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt); 4675 + 4676 + for (i = 0; i < cnt; i++) { 4677 + ha->tgt.atio_ring_index++; 4678 + if (ha->tgt.atio_ring_index == ha->tgt.atio_q_length) { 4679 + ha->tgt.atio_ring_index = 0; 4680 + ha->tgt.atio_ring_ptr = ha->tgt.atio_ring; 4681 + } else 4682 + ha->tgt.atio_ring_ptr++; 4683 + 4684 + pkt->u.raw.signature = ATIO_PROCESSED; 4685 + pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; 4686 + } 4687 + wmb(); 4688 + } 4689 + 4690 + /* Adjust ring index */ 4691 + WRT_REG_DWORD(&reg->atio_q_out, ha->tgt.atio_ring_index); 4692 + } 4693 + 4694 + void 4695 + qlt_24xx_config_rings(struct scsi_qla_host *vha, device_reg_t __iomem *reg) 4696 + { 4697 + struct qla_hw_data *ha = vha->hw; 4698 + 4699 + /* FIXME: atio_q in/out for ha->mqenable=1..? */ 4700 + if (ha->mqenable) { 4701 + #if 0 4702 + WRT_REG_DWORD(&reg->isp25mq.atio_q_in, 0); 4703 + WRT_REG_DWORD(&reg->isp25mq.atio_q_out, 0); 4704 + RD_REG_DWORD(&reg->isp25mq.atio_q_out); 4705 + #endif 4706 + } else { 4707 + /* Setup APTIO registers for target mode */ 4708 + WRT_REG_DWORD(&reg->isp24.atio_q_in, 0); 4709 + WRT_REG_DWORD(&reg->isp24.atio_q_out, 0); 4710 + RD_REG_DWORD(&reg->isp24.atio_q_out); 4711 + } 4712 + } 4713 + 4714 + void 4715 + qlt_24xx_config_nvram_stage1(struct scsi_qla_host *vha, struct nvram_24xx *nv) 4716 + { 4717 + struct qla_hw_data *ha = vha->hw; 4718 + 4719 + if (qla_tgt_mode_enabled(vha)) { 4720 + if (!ha->tgt.saved_set) { 4721 + /* We save only once */ 4722 + ha->tgt.saved_exchange_count = nv->exchange_count; 4723 + ha->tgt.saved_firmware_options_1 = 4724 + nv->firmware_options_1; 4725 + ha->tgt.saved_firmware_options_2 = 4726 + nv->firmware_options_2; 4727 + ha->tgt.saved_firmware_options_3 = 4728 + nv->firmware_options_3; 4729 + ha->tgt.saved_set = 1; 4730 + } 4731 + 4732 + nv->exchange_count = __constant_cpu_to_le16(0xFFFF); 4733 + 4734 + /* Enable target mode */ 4735 + nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_4); 4736 + 4737 + /* Disable ini mode, if requested */ 4738 + if (!qla_ini_mode_enabled(vha)) 4739 + nv->firmware_options_1 |= __constant_cpu_to_le32(BIT_5); 4740 + 4741 + /* Disable Full Login after LIP */ 4742 + nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_13); 4743 + /* Enable initial LIP */ 4744 + nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_9); 4745 + /* Enable FC tapes support */ 4746 + nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_12); 4747 + /* Disable Full Login after LIP */ 4748 + nv->host_p &= __constant_cpu_to_le32(~BIT_10); 4749 + /* Enable target PRLI control */ 4750 + nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_14); 4751 + } else { 4752 + if (ha->tgt.saved_set) { 4753 + nv->exchange_count = ha->tgt.saved_exchange_count; 4754 + nv->firmware_options_1 = 4755 + ha->tgt.saved_firmware_options_1; 4756 + nv->firmware_options_2 = 4757 + ha->tgt.saved_firmware_options_2; 4758 + nv->firmware_options_3 = 4759 + ha->tgt.saved_firmware_options_3; 4760 + } 4761 + return; 4762 + } 4763 + 4764 + /* out-of-order frames reassembly */ 4765 + nv->firmware_options_3 |= BIT_6|BIT_9; 4766 + 4767 + if (ha->tgt.enable_class_2) { 4768 + if (vha->flags.init_done) 4769 + fc_host_supported_classes(vha->host) = 4770 + FC_COS_CLASS2 | FC_COS_CLASS3; 4771 + 4772 + nv->firmware_options_2 |= __constant_cpu_to_le32(BIT_8); 4773 + } else { 4774 + if (vha->flags.init_done) 4775 + fc_host_supported_classes(vha->host) = FC_COS_CLASS3; 4776 + 4777 + nv->firmware_options_2 &= ~__constant_cpu_to_le32(BIT_8); 4778 + } 4779 + } 4780 + 4781 + void 4782 + qlt_24xx_config_nvram_stage2(struct scsi_qla_host *vha, 4783 + struct init_cb_24xx *icb) 4784 + { 4785 + struct qla_hw_data *ha = vha->hw; 4786 + 4787 + if (ha->tgt.node_name_set) { 4788 + memcpy(icb->node_name, ha->tgt.tgt_node_name, WWN_SIZE); 4789 + icb->firmware_options_1 |= __constant_cpu_to_le32(BIT_14); 4790 + } 4791 + } 4792 + 4793 + int 4794 + qlt_24xx_process_response_error(struct scsi_qla_host *vha, 4795 + struct sts_entry_24xx *pkt) 4796 + { 4797 + switch (pkt->entry_type) { 4798 + case ABTS_RECV_24XX: 4799 + case ABTS_RESP_24XX: 4800 + case CTIO_TYPE7: 4801 + case NOTIFY_ACK_TYPE: 4802 + return 1; 4803 + default: 4804 + return 0; 4805 + } 4806 + } 4807 + 4808 + void 4809 + qlt_modify_vp_config(struct scsi_qla_host *vha, 4810 + struct vp_config_entry_24xx *vpmod) 4811 + { 4812 + if (qla_tgt_mode_enabled(vha)) 4813 + vpmod->options_idx1 &= ~BIT_5; 4814 + /* Disable ini mode, if requested */ 4815 + if (!qla_ini_mode_enabled(vha)) 4816 + vpmod->options_idx1 &= ~BIT_4; 4817 + } 4818 + 4819 + void 4820 + qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) 4821 + { 4822 + if (!QLA_TGT_MODE_ENABLED()) 4823 + return; 4824 + 4825 + mutex_init(&ha->tgt.tgt_mutex); 4826 + mutex_init(&ha->tgt.tgt_host_action_mutex); 4827 + qlt_clear_mode(base_vha); 4828 + } 4829 + 4830 + int 4831 + qlt_mem_alloc(struct qla_hw_data *ha) 4832 + { 4833 + if (!QLA_TGT_MODE_ENABLED()) 4834 + return 0; 4835 + 4836 + ha->tgt.tgt_vp_map = kzalloc(sizeof(struct qla_tgt_vp_map) * 4837 + MAX_MULTI_ID_FABRIC, GFP_KERNEL); 4838 + if (!ha->tgt.tgt_vp_map) 4839 + return -ENOMEM; 4840 + 4841 + ha->tgt.atio_ring = dma_alloc_coherent(&ha->pdev->dev, 4842 + (ha->tgt.atio_q_length + 1) * sizeof(struct atio_from_isp), 4843 + &ha->tgt.atio_dma, GFP_KERNEL); 4844 + if (!ha->tgt.atio_ring) { 4845 + kfree(ha->tgt.tgt_vp_map); 4846 + return -ENOMEM; 4847 + } 4848 + return 0; 4849 + } 4850 + 4851 + void 4852 + qlt_mem_free(struct qla_hw_data *ha) 4853 + { 4854 + if (!QLA_TGT_MODE_ENABLED()) 4855 + return; 4856 + 4857 + if (ha->tgt.atio_ring) { 4858 + dma_free_coherent(&ha->pdev->dev, (ha->tgt.atio_q_length + 1) * 4859 + sizeof(struct atio_from_isp), ha->tgt.atio_ring, 4860 + ha->tgt.atio_dma); 4861 + } 4862 + kfree(ha->tgt.tgt_vp_map); 4863 + } 4864 + 4865 + /* vport_slock to be held by the caller */ 4866 + void 4867 + qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) 4868 + { 4869 + if (!QLA_TGT_MODE_ENABLED()) 4870 + return; 4871 + 4872 + switch (cmd) { 4873 + case SET_VP_IDX: 4874 + vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; 4875 + break; 4876 + case SET_AL_PA: 4877 + vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx; 4878 + break; 4879 + case RESET_VP_IDX: 4880 + vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; 4881 + break; 4882 + case RESET_AL_PA: 4883 + vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0; 4884 + break; 4885 + } 4886 + } 4887 + 4888 + static int __init qlt_parse_ini_mode(void) 4889 + { 4890 + if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0) 4891 + ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE; 4892 + else if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_DISABLED) == 0) 4893 + ql2x_ini_mode = QLA2XXX_INI_MODE_DISABLED; 4894 + else if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_ENABLED) == 0) 4895 + ql2x_ini_mode = QLA2XXX_INI_MODE_ENABLED; 4896 + else 4897 + return false; 4898 + 4899 + return true; 4900 + } 4901 + 4902 + int __init qlt_init(void) 4903 + { 4904 + int ret; 4905 + 4906 + if (!qlt_parse_ini_mode()) { 4907 + ql_log(ql_log_fatal, NULL, 0xe06b, 4908 + "qlt_parse_ini_mode() failed\n"); 4909 + return -EINVAL; 4910 + } 4911 + 4912 + if (!QLA_TGT_MODE_ENABLED()) 4913 + return 0; 4914 + 4915 + qla_tgt_cmd_cachep = kmem_cache_create("qla_tgt_cmd_cachep", 4916 + sizeof(struct qla_tgt_cmd), __alignof__(struct qla_tgt_cmd), 0, 4917 + NULL); 4918 + if (!qla_tgt_cmd_cachep) { 4919 + ql_log(ql_log_fatal, NULL, 0xe06c, 4920 + "kmem_cache_create for qla_tgt_cmd_cachep failed\n"); 4921 + return -ENOMEM; 4922 + } 4923 + 4924 + qla_tgt_mgmt_cmd_cachep = kmem_cache_create("qla_tgt_mgmt_cmd_cachep", 4925 + sizeof(struct qla_tgt_mgmt_cmd), __alignof__(struct 4926 + qla_tgt_mgmt_cmd), 0, NULL); 4927 + if (!qla_tgt_mgmt_cmd_cachep) { 4928 + ql_log(ql_log_fatal, NULL, 0xe06d, 4929 + "kmem_cache_create for qla_tgt_mgmt_cmd_cachep failed\n"); 4930 + ret = -ENOMEM; 4931 + goto out; 4932 + } 4933 + 4934 + qla_tgt_mgmt_cmd_mempool = mempool_create(25, mempool_alloc_slab, 4935 + mempool_free_slab, qla_tgt_mgmt_cmd_cachep); 4936 + if (!qla_tgt_mgmt_cmd_mempool) { 4937 + ql_log(ql_log_fatal, NULL, 0xe06e, 4938 + "mempool_create for qla_tgt_mgmt_cmd_mempool failed\n"); 4939 + ret = -ENOMEM; 4940 + goto out_mgmt_cmd_cachep; 4941 + } 4942 + 4943 + qla_tgt_wq = alloc_workqueue("qla_tgt_wq", 0, 0); 4944 + if (!qla_tgt_wq) { 4945 + ql_log(ql_log_fatal, NULL, 0xe06f, 4946 + "alloc_workqueue for qla_tgt_wq failed\n"); 4947 + ret = -ENOMEM; 4948 + goto out_cmd_mempool; 4949 + } 4950 + /* 4951 + * Return 1 to signal that initiator-mode is being disabled 4952 + */ 4953 + return (ql2x_ini_mode == QLA2XXX_INI_MODE_DISABLED) ? 1 : 0; 4954 + 4955 + out_cmd_mempool: 4956 + mempool_destroy(qla_tgt_mgmt_cmd_mempool); 4957 + out_mgmt_cmd_cachep: 4958 + kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep); 4959 + out: 4960 + kmem_cache_destroy(qla_tgt_cmd_cachep); 4961 + return ret; 4962 + } 4963 + 4964 + void qlt_exit(void) 4965 + { 4966 + if (!QLA_TGT_MODE_ENABLED()) 4967 + return; 4968 + 4969 + destroy_workqueue(qla_tgt_wq); 4970 + mempool_destroy(qla_tgt_mgmt_cmd_mempool); 4971 + kmem_cache_destroy(qla_tgt_mgmt_cmd_cachep); 4972 + kmem_cache_destroy(qla_tgt_cmd_cachep); 4973 + }
+1005
drivers/scsi/qla2xxx/qla_target.h
··· 1 + /* 2 + * Copyright (C) 2004 - 2010 Vladislav Bolkhovitin <vst@vlnb.net> 3 + * Copyright (C) 2004 - 2005 Leonid Stoljar 4 + * Copyright (C) 2006 Nathaniel Clark <nate@misrule.us> 5 + * Copyright (C) 2007 - 2010 ID7 Ltd. 6 + * 7 + * Forward port and refactoring to modern qla2xxx and target/configfs 8 + * 9 + * Copyright (C) 2010-2011 Nicholas A. Bellinger <nab@kernel.org> 10 + * 11 + * Additional file for the target driver support. 12 + * 13 + * This program is free software; you can redistribute it and/or 14 + * modify it under the terms of the GNU General Public License 15 + * as published by the Free Software Foundation; either version 2 16 + * of the License, or (at your option) any later version. 17 + * 18 + * This program is distributed in the hope that it will be useful, 19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 + * GNU General Public License for more details. 22 + */ 23 + /* 24 + * This is the global def file that is useful for including from the 25 + * target portion. 26 + */ 27 + 28 + #ifndef __QLA_TARGET_H 29 + #define __QLA_TARGET_H 30 + 31 + #include "qla_def.h" 32 + 33 + /* 34 + * Must be changed on any change in any initiator visible interfaces or 35 + * data in the target add-on 36 + */ 37 + #define QLA2XXX_TARGET_MAGIC 269 38 + 39 + /* 40 + * Must be changed on any change in any target visible interfaces or 41 + * data in the initiator 42 + */ 43 + #define QLA2XXX_INITIATOR_MAGIC 57222 44 + 45 + #define QLA2XXX_INI_MODE_STR_EXCLUSIVE "exclusive" 46 + #define QLA2XXX_INI_MODE_STR_DISABLED "disabled" 47 + #define QLA2XXX_INI_MODE_STR_ENABLED "enabled" 48 + 49 + #define QLA2XXX_INI_MODE_EXCLUSIVE 0 50 + #define QLA2XXX_INI_MODE_DISABLED 1 51 + #define QLA2XXX_INI_MODE_ENABLED 2 52 + 53 + #define QLA2XXX_COMMAND_COUNT_INIT 250 54 + #define QLA2XXX_IMMED_NOTIFY_COUNT_INIT 250 55 + 56 + /* 57 + * Used to mark which completion handles (for RIO Status's) are for CTIO's 58 + * vs. regular (non-target) info. This is checked for in 59 + * qla2x00_process_response_queue() to see if a handle coming back in a 60 + * multi-complete should come to the tgt driver or be handled there by qla2xxx 61 + */ 62 + #define CTIO_COMPLETION_HANDLE_MARK BIT_29 63 + #if (CTIO_COMPLETION_HANDLE_MARK <= MAX_OUTSTANDING_COMMANDS) 64 + #error "CTIO_COMPLETION_HANDLE_MARK not larger than MAX_OUTSTANDING_COMMANDS" 65 + #endif 66 + #define HANDLE_IS_CTIO_COMP(h) (h & CTIO_COMPLETION_HANDLE_MARK) 67 + 68 + /* Used to mark CTIO as intermediate */ 69 + #define CTIO_INTERMEDIATE_HANDLE_MARK BIT_30 70 + 71 + #ifndef OF_SS_MODE_0 72 + /* 73 + * ISP target entries - Flags bit definitions. 74 + */ 75 + #define OF_SS_MODE_0 0 76 + #define OF_SS_MODE_1 1 77 + #define OF_SS_MODE_2 2 78 + #define OF_SS_MODE_3 3 79 + 80 + #define OF_EXPL_CONF BIT_5 /* Explicit Confirmation Requested */ 81 + #define OF_DATA_IN BIT_6 /* Data in to initiator */ 82 + /* (data from target to initiator) */ 83 + #define OF_DATA_OUT BIT_7 /* Data out from initiator */ 84 + /* (data from initiator to target) */ 85 + #define OF_NO_DATA (BIT_7 | BIT_6) 86 + #define OF_INC_RC BIT_8 /* Increment command resource count */ 87 + #define OF_FAST_POST BIT_9 /* Enable mailbox fast posting. */ 88 + #define OF_CONF_REQ BIT_13 /* Confirmation Requested */ 89 + #define OF_TERM_EXCH BIT_14 /* Terminate exchange */ 90 + #define OF_SSTS BIT_15 /* Send SCSI status */ 91 + #endif 92 + 93 + #ifndef QLA_TGT_DATASEGS_PER_CMD32 94 + #define QLA_TGT_DATASEGS_PER_CMD32 3 95 + #define QLA_TGT_DATASEGS_PER_CONT32 7 96 + #define QLA_TGT_MAX_SG32(ql) \ 97 + (((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD32 + \ 98 + QLA_TGT_DATASEGS_PER_CONT32*((ql) - 1)) : 0) 99 + 100 + #define QLA_TGT_DATASEGS_PER_CMD64 2 101 + #define QLA_TGT_DATASEGS_PER_CONT64 5 102 + #define QLA_TGT_MAX_SG64(ql) \ 103 + (((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD64 + \ 104 + QLA_TGT_DATASEGS_PER_CONT64*((ql) - 1)) : 0) 105 + #endif 106 + 107 + #ifndef QLA_TGT_DATASEGS_PER_CMD_24XX 108 + #define QLA_TGT_DATASEGS_PER_CMD_24XX 1 109 + #define QLA_TGT_DATASEGS_PER_CONT_24XX 5 110 + #define QLA_TGT_MAX_SG_24XX(ql) \ 111 + (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ 112 + QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) 113 + #endif 114 + #endif 115 + 116 + #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ 117 + ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ 118 + : (uint16_t)(iocb)->u.isp2x.target.id.standard) 119 + 120 + #ifndef IMMED_NOTIFY_TYPE 121 + #define IMMED_NOTIFY_TYPE 0x0D /* Immediate notify entry. */ 122 + /* 123 + * ISP queue - immediate notify entry structure definition. 124 + * This is sent by the ISP to the Target driver. 125 + * This IOCB would have report of events sent by the 126 + * initiator, that needs to be handled by the target 127 + * driver immediately. 128 + */ 129 + struct imm_ntfy_from_isp { 130 + uint8_t entry_type; /* Entry type. */ 131 + uint8_t entry_count; /* Entry count. */ 132 + uint8_t sys_define; /* System defined. */ 133 + uint8_t entry_status; /* Entry Status. */ 134 + union { 135 + struct { 136 + uint32_t sys_define_2; /* System defined. */ 137 + target_id_t target; 138 + uint16_t lun; 139 + uint8_t target_id; 140 + uint8_t reserved_1; 141 + uint16_t status_modifier; 142 + uint16_t status; 143 + uint16_t task_flags; 144 + uint16_t seq_id; 145 + uint16_t srr_rx_id; 146 + uint32_t srr_rel_offs; 147 + uint16_t srr_ui; 148 + #define SRR_IU_DATA_IN 0x1 149 + #define SRR_IU_DATA_OUT 0x5 150 + #define SRR_IU_STATUS 0x7 151 + uint16_t srr_ox_id; 152 + uint8_t reserved_2[28]; 153 + } isp2x; 154 + struct { 155 + uint32_t reserved; 156 + uint16_t nport_handle; 157 + uint16_t reserved_2; 158 + uint16_t flags; 159 + #define NOTIFY24XX_FLAGS_GLOBAL_TPRLO BIT_1 160 + #define NOTIFY24XX_FLAGS_PUREX_IOCB BIT_0 161 + uint16_t srr_rx_id; 162 + uint16_t status; 163 + uint8_t status_subcode; 164 + uint8_t reserved_3; 165 + uint32_t exchange_address; 166 + uint32_t srr_rel_offs; 167 + uint16_t srr_ui; 168 + uint16_t srr_ox_id; 169 + uint8_t reserved_4[19]; 170 + uint8_t vp_index; 171 + uint32_t reserved_5; 172 + uint8_t port_id[3]; 173 + uint8_t reserved_6; 174 + } isp24; 175 + } u; 176 + uint16_t reserved_7; 177 + uint16_t ox_id; 178 + } __packed; 179 + #endif 180 + 181 + #ifndef NOTIFY_ACK_TYPE 182 + #define NOTIFY_ACK_TYPE 0x0E /* Notify acknowledge entry. */ 183 + /* 184 + * ISP queue - notify acknowledge entry structure definition. 185 + * This is sent to the ISP from the target driver. 186 + */ 187 + struct nack_to_isp { 188 + uint8_t entry_type; /* Entry type. */ 189 + uint8_t entry_count; /* Entry count. */ 190 + uint8_t sys_define; /* System defined. */ 191 + uint8_t entry_status; /* Entry Status. */ 192 + union { 193 + struct { 194 + uint32_t sys_define_2; /* System defined. */ 195 + target_id_t target; 196 + uint8_t target_id; 197 + uint8_t reserved_1; 198 + uint16_t flags; 199 + uint16_t resp_code; 200 + uint16_t status; 201 + uint16_t task_flags; 202 + uint16_t seq_id; 203 + uint16_t srr_rx_id; 204 + uint32_t srr_rel_offs; 205 + uint16_t srr_ui; 206 + uint16_t srr_flags; 207 + uint16_t srr_reject_code; 208 + uint8_t srr_reject_vendor_uniq; 209 + uint8_t srr_reject_code_expl; 210 + uint8_t reserved_2[24]; 211 + } isp2x; 212 + struct { 213 + uint32_t handle; 214 + uint16_t nport_handle; 215 + uint16_t reserved_1; 216 + uint16_t flags; 217 + uint16_t srr_rx_id; 218 + uint16_t status; 219 + uint8_t status_subcode; 220 + uint8_t reserved_3; 221 + uint32_t exchange_address; 222 + uint32_t srr_rel_offs; 223 + uint16_t srr_ui; 224 + uint16_t srr_flags; 225 + uint8_t reserved_4[19]; 226 + uint8_t vp_index; 227 + uint8_t srr_reject_vendor_uniq; 228 + uint8_t srr_reject_code_expl; 229 + uint8_t srr_reject_code; 230 + uint8_t reserved_5[5]; 231 + } isp24; 232 + } u; 233 + uint8_t reserved[2]; 234 + uint16_t ox_id; 235 + } __packed; 236 + #define NOTIFY_ACK_SRR_FLAGS_ACCEPT 0 237 + #define NOTIFY_ACK_SRR_FLAGS_REJECT 1 238 + 239 + #define NOTIFY_ACK_SRR_REJECT_REASON_UNABLE_TO_PERFORM 0x9 240 + 241 + #define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_NO_EXPL 0 242 + #define NOTIFY_ACK_SRR_FLAGS_REJECT_EXPL_UNABLE_TO_SUPPLY_DATA 0x2a 243 + 244 + #define NOTIFY_ACK_SUCCESS 0x01 245 + #endif 246 + 247 + #ifndef ACCEPT_TGT_IO_TYPE 248 + #define ACCEPT_TGT_IO_TYPE 0x16 /* Accept target I/O entry. */ 249 + #endif 250 + 251 + #ifndef CONTINUE_TGT_IO_TYPE 252 + #define CONTINUE_TGT_IO_TYPE 0x17 253 + /* 254 + * ISP queue - Continue Target I/O (CTIO) entry for status mode 0 structure. 255 + * This structure is sent to the ISP 2xxx from target driver. 256 + */ 257 + struct ctio_to_2xxx { 258 + uint8_t entry_type; /* Entry type. */ 259 + uint8_t entry_count; /* Entry count. */ 260 + uint8_t sys_define; /* System defined. */ 261 + uint8_t entry_status; /* Entry Status. */ 262 + uint32_t handle; /* System defined handle */ 263 + target_id_t target; 264 + uint16_t rx_id; 265 + uint16_t flags; 266 + uint16_t status; 267 + uint16_t timeout; /* 0 = 30 seconds, 0xFFFF = disable */ 268 + uint16_t dseg_count; /* Data segment count. */ 269 + uint32_t relative_offset; 270 + uint32_t residual; 271 + uint16_t reserved_1[3]; 272 + uint16_t scsi_status; 273 + uint32_t transfer_length; 274 + uint32_t dseg_0_address; /* Data segment 0 address. */ 275 + uint32_t dseg_0_length; /* Data segment 0 length. */ 276 + uint32_t dseg_1_address; /* Data segment 1 address. */ 277 + uint32_t dseg_1_length; /* Data segment 1 length. */ 278 + uint32_t dseg_2_address; /* Data segment 2 address. */ 279 + uint32_t dseg_2_length; /* Data segment 2 length. */ 280 + } __packed; 281 + #define ATIO_PATH_INVALID 0x07 282 + #define ATIO_CANT_PROV_CAP 0x16 283 + #define ATIO_CDB_VALID 0x3D 284 + 285 + #define ATIO_EXEC_READ BIT_1 286 + #define ATIO_EXEC_WRITE BIT_0 287 + #endif 288 + 289 + #ifndef CTIO_A64_TYPE 290 + #define CTIO_A64_TYPE 0x1F 291 + #define CTIO_SUCCESS 0x01 292 + #define CTIO_ABORTED 0x02 293 + #define CTIO_INVALID_RX_ID 0x08 294 + #define CTIO_TIMEOUT 0x0B 295 + #define CTIO_LIP_RESET 0x0E 296 + #define CTIO_TARGET_RESET 0x17 297 + #define CTIO_PORT_UNAVAILABLE 0x28 298 + #define CTIO_PORT_LOGGED_OUT 0x29 299 + #define CTIO_PORT_CONF_CHANGED 0x2A 300 + #define CTIO_SRR_RECEIVED 0x45 301 + #endif 302 + 303 + #ifndef CTIO_RET_TYPE 304 + #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ 305 + #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ 306 + 307 + struct fcp_hdr { 308 + uint8_t r_ctl; 309 + uint8_t d_id[3]; 310 + uint8_t cs_ctl; 311 + uint8_t s_id[3]; 312 + uint8_t type; 313 + uint8_t f_ctl[3]; 314 + uint8_t seq_id; 315 + uint8_t df_ctl; 316 + uint16_t seq_cnt; 317 + uint16_t ox_id; 318 + uint16_t rx_id; 319 + uint32_t parameter; 320 + } __packed; 321 + 322 + struct fcp_hdr_le { 323 + uint8_t d_id[3]; 324 + uint8_t r_ctl; 325 + uint8_t s_id[3]; 326 + uint8_t cs_ctl; 327 + uint8_t f_ctl[3]; 328 + uint8_t type; 329 + uint16_t seq_cnt; 330 + uint8_t df_ctl; 331 + uint8_t seq_id; 332 + uint16_t rx_id; 333 + uint16_t ox_id; 334 + uint32_t parameter; 335 + } __packed; 336 + 337 + #define F_CTL_EXCH_CONTEXT_RESP BIT_23 338 + #define F_CTL_SEQ_CONTEXT_RESIP BIT_22 339 + #define F_CTL_LAST_SEQ BIT_20 340 + #define F_CTL_END_SEQ BIT_19 341 + #define F_CTL_SEQ_INITIATIVE BIT_16 342 + 343 + #define R_CTL_BASIC_LINK_SERV 0x80 344 + #define R_CTL_B_ACC 0x4 345 + #define R_CTL_B_RJT 0x5 346 + 347 + struct atio7_fcp_cmnd { 348 + uint64_t lun; 349 + uint8_t cmnd_ref; 350 + uint8_t task_attr:3; 351 + uint8_t reserved:5; 352 + uint8_t task_mgmt_flags; 353 + #define FCP_CMND_TASK_MGMT_CLEAR_ACA 6 354 + #define FCP_CMND_TASK_MGMT_TARGET_RESET 5 355 + #define FCP_CMND_TASK_MGMT_LU_RESET 4 356 + #define FCP_CMND_TASK_MGMT_CLEAR_TASK_SET 2 357 + #define FCP_CMND_TASK_MGMT_ABORT_TASK_SET 1 358 + uint8_t wrdata:1; 359 + uint8_t rddata:1; 360 + uint8_t add_cdb_len:6; 361 + uint8_t cdb[16]; 362 + /* 363 + * add_cdb is optional and can absent from struct atio7_fcp_cmnd. Size 4 364 + * only to make sizeof(struct atio7_fcp_cmnd) be as expected by 365 + * BUILD_BUG_ON in qlt_init(). 366 + */ 367 + uint8_t add_cdb[4]; 368 + /* uint32_t data_length; */ 369 + } __packed; 370 + 371 + /* 372 + * ISP queue - Accept Target I/O (ATIO) type entry IOCB structure. 373 + * This is sent from the ISP to the target driver. 374 + */ 375 + struct atio_from_isp { 376 + union { 377 + struct { 378 + uint16_t entry_hdr; 379 + uint8_t sys_define; /* System defined. */ 380 + uint8_t entry_status; /* Entry Status. */ 381 + uint32_t sys_define_2; /* System defined. */ 382 + target_id_t target; 383 + uint16_t rx_id; 384 + uint16_t flags; 385 + uint16_t status; 386 + uint8_t command_ref; 387 + uint8_t task_codes; 388 + uint8_t task_flags; 389 + uint8_t execution_codes; 390 + uint8_t cdb[MAX_CMDSZ]; 391 + uint32_t data_length; 392 + uint16_t lun; 393 + uint8_t initiator_port_name[WWN_SIZE]; /* on qla23xx */ 394 + uint16_t reserved_32[6]; 395 + uint16_t ox_id; 396 + } isp2x; 397 + struct { 398 + uint16_t entry_hdr; 399 + uint8_t fcp_cmnd_len_low; 400 + uint8_t fcp_cmnd_len_high:4; 401 + uint8_t attr:4; 402 + uint32_t exchange_addr; 403 + #define ATIO_EXCHANGE_ADDRESS_UNKNOWN 0xFFFFFFFF 404 + struct fcp_hdr fcp_hdr; 405 + struct atio7_fcp_cmnd fcp_cmnd; 406 + } isp24; 407 + struct { 408 + uint8_t entry_type; /* Entry type. */ 409 + uint8_t entry_count; /* Entry count. */ 410 + uint8_t data[58]; 411 + uint32_t signature; 412 + #define ATIO_PROCESSED 0xDEADDEAD /* Signature */ 413 + } raw; 414 + } u; 415 + } __packed; 416 + 417 + #define CTIO_TYPE7 0x12 /* Continue target I/O entry (for 24xx) */ 418 + 419 + /* 420 + * ISP queue - Continue Target I/O (ATIO) type 7 entry (for 24xx) structure. 421 + * This structure is sent to the ISP 24xx from the target driver. 422 + */ 423 + 424 + struct ctio7_to_24xx { 425 + uint8_t entry_type; /* Entry type. */ 426 + uint8_t entry_count; /* Entry count. */ 427 + uint8_t sys_define; /* System defined. */ 428 + uint8_t entry_status; /* Entry Status. */ 429 + uint32_t handle; /* System defined handle */ 430 + uint16_t nport_handle; 431 + #define CTIO7_NHANDLE_UNRECOGNIZED 0xFFFF 432 + uint16_t timeout; 433 + uint16_t dseg_count; /* Data segment count. */ 434 + uint8_t vp_index; 435 + uint8_t add_flags; 436 + uint8_t initiator_id[3]; 437 + uint8_t reserved; 438 + uint32_t exchange_addr; 439 + union { 440 + struct { 441 + uint16_t reserved1; 442 + uint16_t flags; 443 + uint32_t residual; 444 + uint16_t ox_id; 445 + uint16_t scsi_status; 446 + uint32_t relative_offset; 447 + uint32_t reserved2; 448 + uint32_t transfer_length; 449 + uint32_t reserved3; 450 + /* Data segment 0 address. */ 451 + uint32_t dseg_0_address[2]; 452 + /* Data segment 0 length. */ 453 + uint32_t dseg_0_length; 454 + } status0; 455 + struct { 456 + uint16_t sense_length; 457 + uint16_t flags; 458 + uint32_t residual; 459 + uint16_t ox_id; 460 + uint16_t scsi_status; 461 + uint16_t response_len; 462 + uint16_t reserved; 463 + uint8_t sense_data[24]; 464 + } status1; 465 + } u; 466 + } __packed; 467 + 468 + /* 469 + * ISP queue - CTIO type 7 from ISP 24xx to target driver 470 + * returned entry structure. 471 + */ 472 + struct ctio7_from_24xx { 473 + uint8_t entry_type; /* Entry type. */ 474 + uint8_t entry_count; /* Entry count. */ 475 + uint8_t sys_define; /* System defined. */ 476 + uint8_t entry_status; /* Entry Status. */ 477 + uint32_t handle; /* System defined handle */ 478 + uint16_t status; 479 + uint16_t timeout; 480 + uint16_t dseg_count; /* Data segment count. */ 481 + uint8_t vp_index; 482 + uint8_t reserved1[5]; 483 + uint32_t exchange_address; 484 + uint16_t reserved2; 485 + uint16_t flags; 486 + uint32_t residual; 487 + uint16_t ox_id; 488 + uint16_t reserved3; 489 + uint32_t relative_offset; 490 + uint8_t reserved4[24]; 491 + } __packed; 492 + 493 + /* CTIO7 flags values */ 494 + #define CTIO7_FLAGS_SEND_STATUS BIT_15 495 + #define CTIO7_FLAGS_TERMINATE BIT_14 496 + #define CTIO7_FLAGS_CONFORM_REQ BIT_13 497 + #define CTIO7_FLAGS_DONT_RET_CTIO BIT_8 498 + #define CTIO7_FLAGS_STATUS_MODE_0 0 499 + #define CTIO7_FLAGS_STATUS_MODE_1 BIT_6 500 + #define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5 501 + #define CTIO7_FLAGS_CONFIRM_SATISF BIT_4 502 + #define CTIO7_FLAGS_DSD_PTR BIT_2 503 + #define CTIO7_FLAGS_DATA_IN BIT_1 504 + #define CTIO7_FLAGS_DATA_OUT BIT_0 505 + 506 + #define ELS_PLOGI 0x3 507 + #define ELS_FLOGI 0x4 508 + #define ELS_LOGO 0x5 509 + #define ELS_PRLI 0x20 510 + #define ELS_PRLO 0x21 511 + #define ELS_TPRLO 0x24 512 + #define ELS_PDISC 0x50 513 + #define ELS_ADISC 0x52 514 + 515 + /* 516 + * ISP queue - ABTS received/response entries structure definition for 24xx. 517 + */ 518 + #define ABTS_RECV_24XX 0x54 /* ABTS received (for 24xx) */ 519 + #define ABTS_RESP_24XX 0x55 /* ABTS responce (for 24xx) */ 520 + 521 + /* 522 + * ISP queue - ABTS received IOCB entry structure definition for 24xx. 523 + * The ABTS BLS received from the wire is sent to the 524 + * target driver by the ISP 24xx. 525 + * The IOCB is placed on the response queue. 526 + */ 527 + struct abts_recv_from_24xx { 528 + uint8_t entry_type; /* Entry type. */ 529 + uint8_t entry_count; /* Entry count. */ 530 + uint8_t sys_define; /* System defined. */ 531 + uint8_t entry_status; /* Entry Status. */ 532 + uint8_t reserved_1[6]; 533 + uint16_t nport_handle; 534 + uint8_t reserved_2[2]; 535 + uint8_t vp_index; 536 + uint8_t reserved_3:4; 537 + uint8_t sof_type:4; 538 + uint32_t exchange_address; 539 + struct fcp_hdr_le fcp_hdr_le; 540 + uint8_t reserved_4[16]; 541 + uint32_t exchange_addr_to_abort; 542 + } __packed; 543 + 544 + #define ABTS_PARAM_ABORT_SEQ BIT_0 545 + 546 + struct ba_acc_le { 547 + uint16_t reserved; 548 + uint8_t seq_id_last; 549 + uint8_t seq_id_valid; 550 + #define SEQ_ID_VALID 0x80 551 + #define SEQ_ID_INVALID 0x00 552 + uint16_t rx_id; 553 + uint16_t ox_id; 554 + uint16_t high_seq_cnt; 555 + uint16_t low_seq_cnt; 556 + } __packed; 557 + 558 + struct ba_rjt_le { 559 + uint8_t vendor_uniq; 560 + uint8_t reason_expl; 561 + uint8_t reason_code; 562 + #define BA_RJT_REASON_CODE_INVALID_COMMAND 0x1 563 + #define BA_RJT_REASON_CODE_UNABLE_TO_PERFORM 0x9 564 + uint8_t reserved; 565 + } __packed; 566 + 567 + /* 568 + * ISP queue - ABTS Response IOCB entry structure definition for 24xx. 569 + * The ABTS response to the ABTS received is sent by the 570 + * target driver to the ISP 24xx. 571 + * The IOCB is placed on the request queue. 572 + */ 573 + struct abts_resp_to_24xx { 574 + uint8_t entry_type; /* Entry type. */ 575 + uint8_t entry_count; /* Entry count. */ 576 + uint8_t sys_define; /* System defined. */ 577 + uint8_t entry_status; /* Entry Status. */ 578 + uint32_t handle; 579 + uint16_t reserved_1; 580 + uint16_t nport_handle; 581 + uint16_t control_flags; 582 + #define ABTS_CONTR_FLG_TERM_EXCHG BIT_0 583 + uint8_t vp_index; 584 + uint8_t reserved_3:4; 585 + uint8_t sof_type:4; 586 + uint32_t exchange_address; 587 + struct fcp_hdr_le fcp_hdr_le; 588 + union { 589 + struct ba_acc_le ba_acct; 590 + struct ba_rjt_le ba_rjt; 591 + } __packed payload; 592 + uint32_t reserved_4; 593 + uint32_t exchange_addr_to_abort; 594 + } __packed; 595 + 596 + /* 597 + * ISP queue - ABTS Response IOCB from ISP24xx Firmware entry structure. 598 + * The ABTS response with completion status to the ABTS response 599 + * (sent by the target driver to the ISP 24xx) is sent by the 600 + * ISP24xx firmware to the target driver. 601 + * The IOCB is placed on the response queue. 602 + */ 603 + struct abts_resp_from_24xx_fw { 604 + uint8_t entry_type; /* Entry type. */ 605 + uint8_t entry_count; /* Entry count. */ 606 + uint8_t sys_define; /* System defined. */ 607 + uint8_t entry_status; /* Entry Status. */ 608 + uint32_t handle; 609 + uint16_t compl_status; 610 + #define ABTS_RESP_COMPL_SUCCESS 0 611 + #define ABTS_RESP_COMPL_SUBCODE_ERROR 0x31 612 + uint16_t nport_handle; 613 + uint16_t reserved_1; 614 + uint8_t reserved_2; 615 + uint8_t reserved_3:4; 616 + uint8_t sof_type:4; 617 + uint32_t exchange_address; 618 + struct fcp_hdr_le fcp_hdr_le; 619 + uint8_t reserved_4[8]; 620 + uint32_t error_subcode1; 621 + #define ABTS_RESP_SUBCODE_ERR_ABORTED_EXCH_NOT_TERM 0x1E 622 + uint32_t error_subcode2; 623 + uint32_t exchange_addr_to_abort; 624 + } __packed; 625 + 626 + /********************************************************************\ 627 + * Type Definitions used by initiator & target halves 628 + \********************************************************************/ 629 + 630 + struct qla_tgt_mgmt_cmd; 631 + struct qla_tgt_sess; 632 + 633 + /* 634 + * This structure provides a template of function calls that the 635 + * target driver (from within qla_target.c) can issue to the 636 + * target module (tcm_qla2xxx). 637 + */ 638 + struct qla_tgt_func_tmpl { 639 + 640 + int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, 641 + unsigned char *, uint32_t, int, int, int); 642 + int (*handle_data)(struct qla_tgt_cmd *); 643 + int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, 644 + uint32_t); 645 + void (*free_cmd)(struct qla_tgt_cmd *); 646 + void (*free_mcmd)(struct qla_tgt_mgmt_cmd *); 647 + void (*free_session)(struct qla_tgt_sess *); 648 + 649 + int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *, 650 + void *, uint8_t *, uint16_t); 651 + struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *, 652 + const uint16_t); 653 + struct qla_tgt_sess *(*find_sess_by_s_id)(struct scsi_qla_host *, 654 + const uint8_t *); 655 + void (*clear_nacl_from_fcport_map)(struct qla_tgt_sess *); 656 + void (*put_sess)(struct qla_tgt_sess *); 657 + void (*shutdown_sess)(struct qla_tgt_sess *); 658 + }; 659 + 660 + int qla2x00_wait_for_hba_online(struct scsi_qla_host *); 661 + 662 + #include <target/target_core_base.h> 663 + 664 + #define QLA_TGT_TIMEOUT 10 /* in seconds */ 665 + 666 + #define QLA_TGT_MAX_HW_PENDING_TIME 60 /* in seconds */ 667 + 668 + /* Immediate notify status constants */ 669 + #define IMM_NTFY_LIP_RESET 0x000E 670 + #define IMM_NTFY_LIP_LINK_REINIT 0x000F 671 + #define IMM_NTFY_IOCB_OVERFLOW 0x0016 672 + #define IMM_NTFY_ABORT_TASK 0x0020 673 + #define IMM_NTFY_PORT_LOGOUT 0x0029 674 + #define IMM_NTFY_PORT_CONFIG 0x002A 675 + #define IMM_NTFY_GLBL_TPRLO 0x002D 676 + #define IMM_NTFY_GLBL_LOGO 0x002E 677 + #define IMM_NTFY_RESOURCE 0x0034 678 + #define IMM_NTFY_MSG_RX 0x0036 679 + #define IMM_NTFY_SRR 0x0045 680 + #define IMM_NTFY_ELS 0x0046 681 + 682 + /* Immediate notify task flags */ 683 + #define IMM_NTFY_TASK_MGMT_SHIFT 8 684 + 685 + #define QLA_TGT_CLEAR_ACA 0x40 686 + #define QLA_TGT_TARGET_RESET 0x20 687 + #define QLA_TGT_LUN_RESET 0x10 688 + #define QLA_TGT_CLEAR_TS 0x04 689 + #define QLA_TGT_ABORT_TS 0x02 690 + #define QLA_TGT_ABORT_ALL_SESS 0xFFFF 691 + #define QLA_TGT_ABORT_ALL 0xFFFE 692 + #define QLA_TGT_NEXUS_LOSS_SESS 0xFFFD 693 + #define QLA_TGT_NEXUS_LOSS 0xFFFC 694 + 695 + /* Notify Acknowledge flags */ 696 + #define NOTIFY_ACK_RES_COUNT BIT_8 697 + #define NOTIFY_ACK_CLEAR_LIP_RESET BIT_5 698 + #define NOTIFY_ACK_TM_RESP_CODE_VALID BIT_4 699 + 700 + /* Command's states */ 701 + #define QLA_TGT_STATE_NEW 0 /* New command + target processing */ 702 + #define QLA_TGT_STATE_NEED_DATA 1 /* target needs data to continue */ 703 + #define QLA_TGT_STATE_DATA_IN 2 /* Data arrived + target processing */ 704 + #define QLA_TGT_STATE_PROCESSED 3 /* target done processing */ 705 + #define QLA_TGT_STATE_ABORTED 4 /* Command aborted */ 706 + 707 + /* Special handles */ 708 + #define QLA_TGT_NULL_HANDLE 0 709 + #define QLA_TGT_SKIP_HANDLE (0xFFFFFFFF & ~CTIO_COMPLETION_HANDLE_MARK) 710 + 711 + /* ATIO task_codes field */ 712 + #define ATIO_SIMPLE_QUEUE 0 713 + #define ATIO_HEAD_OF_QUEUE 1 714 + #define ATIO_ORDERED_QUEUE 2 715 + #define ATIO_ACA_QUEUE 4 716 + #define ATIO_UNTAGGED 5 717 + 718 + /* TM failed response codes, see FCP (9.4.11 FCP_RSP_INFO) */ 719 + #define FC_TM_SUCCESS 0 720 + #define FC_TM_BAD_FCP_DATA 1 721 + #define FC_TM_BAD_CMD 2 722 + #define FC_TM_FCP_DATA_MISMATCH 3 723 + #define FC_TM_REJECT 4 724 + #define FC_TM_FAILED 5 725 + 726 + /* 727 + * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was 728 + * terminated, so no more actions is needed and success should be returned 729 + * to target. 730 + */ 731 + #define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED 0x1717 732 + 733 + #if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G) 734 + #define pci_dma_lo32(a) (a & 0xffffffff) 735 + #define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff) 736 + #else 737 + #define pci_dma_lo32(a) (a & 0xffffffff) 738 + #define pci_dma_hi32(a) 0 739 + #endif 740 + 741 + #define QLA_TGT_SENSE_VALID(sense) ((sense != NULL) && \ 742 + (((const uint8_t *)(sense))[0] & 0x70) == 0x70) 743 + 744 + struct qla_port_24xx_data { 745 + uint8_t port_name[WWN_SIZE]; 746 + uint16_t loop_id; 747 + uint16_t reserved; 748 + }; 749 + 750 + struct qla_tgt { 751 + struct scsi_qla_host *vha; 752 + struct qla_hw_data *ha; 753 + 754 + /* 755 + * To sync between IRQ handlers and qlt_target_release(). Needed, 756 + * because req_pkt() can drop/reaquire HW lock inside. Protected by 757 + * HW lock. 758 + */ 759 + int irq_cmd_count; 760 + 761 + int datasegs_per_cmd, datasegs_per_cont, sg_tablesize; 762 + 763 + /* Target's flags, serialized by pha->hardware_lock */ 764 + unsigned int tgt_enable_64bit_addr:1; /* 64-bits PCI addr enabled */ 765 + unsigned int link_reinit_iocb_pending:1; 766 + 767 + /* 768 + * Protected by tgt_mutex AND hardware_lock for writing and tgt_mutex 769 + * OR hardware_lock for reading. 770 + */ 771 + int tgt_stop; /* the target mode driver is being stopped */ 772 + int tgt_stopped; /* the target mode driver has been stopped */ 773 + 774 + /* Count of sessions refering qla_tgt. Protected by hardware_lock. */ 775 + int sess_count; 776 + 777 + /* Protected by hardware_lock. Addition also protected by tgt_mutex. */ 778 + struct list_head sess_list; 779 + 780 + /* Protected by hardware_lock */ 781 + struct list_head del_sess_list; 782 + struct delayed_work sess_del_work; 783 + 784 + spinlock_t sess_work_lock; 785 + struct list_head sess_works_list; 786 + struct work_struct sess_work; 787 + 788 + struct imm_ntfy_from_isp link_reinit_iocb; 789 + wait_queue_head_t waitQ; 790 + int notify_ack_expected; 791 + int abts_resp_expected; 792 + int modify_lun_expected; 793 + 794 + int ctio_srr_id; 795 + int imm_srr_id; 796 + spinlock_t srr_lock; 797 + struct list_head srr_ctio_list; 798 + struct list_head srr_imm_list; 799 + struct work_struct srr_work; 800 + 801 + atomic_t tgt_global_resets_count; 802 + 803 + struct list_head tgt_list_entry; 804 + }; 805 + 806 + /* 807 + * Equivilant to IT Nexus (Initiator-Target) 808 + */ 809 + struct qla_tgt_sess { 810 + uint16_t loop_id; 811 + port_id_t s_id; 812 + 813 + unsigned int conf_compl_supported:1; 814 + unsigned int deleted:1; 815 + unsigned int local:1; 816 + unsigned int tearing_down:1; 817 + 818 + struct se_session *se_sess; 819 + struct scsi_qla_host *vha; 820 + struct qla_tgt *tgt; 821 + 822 + struct list_head sess_list_entry; 823 + unsigned long expires; 824 + struct list_head del_list_entry; 825 + 826 + uint8_t port_name[WWN_SIZE]; 827 + struct work_struct free_work; 828 + }; 829 + 830 + struct qla_tgt_cmd { 831 + struct qla_tgt_sess *sess; 832 + int state; 833 + struct se_cmd se_cmd; 834 + struct work_struct free_work; 835 + struct work_struct work; 836 + /* Sense buffer that will be mapped into outgoing status */ 837 + unsigned char sense_buffer[TRANSPORT_SENSE_BUFFER]; 838 + 839 + /* to save extra sess dereferences */ 840 + unsigned int conf_compl_supported:1; 841 + unsigned int sg_mapped:1; 842 + unsigned int free_sg:1; 843 + unsigned int aborted:1; /* Needed in case of SRR */ 844 + unsigned int write_data_transferred:1; 845 + 846 + struct scatterlist *sg; /* cmd data buffer SG vector */ 847 + int sg_cnt; /* SG segments count */ 848 + int bufflen; /* cmd buffer length */ 849 + int offset; 850 + uint32_t tag; 851 + uint32_t unpacked_lun; 852 + enum dma_data_direction dma_data_direction; 853 + 854 + uint16_t loop_id; /* to save extra sess dereferences */ 855 + struct qla_tgt *tgt; /* to save extra sess dereferences */ 856 + struct scsi_qla_host *vha; 857 + struct list_head cmd_list; 858 + 859 + struct atio_from_isp atio; 860 + }; 861 + 862 + struct qla_tgt_sess_work_param { 863 + struct list_head sess_works_list_entry; 864 + 865 + #define QLA_TGT_SESS_WORK_ABORT 1 866 + #define QLA_TGT_SESS_WORK_TM 2 867 + int type; 868 + 869 + union { 870 + struct abts_recv_from_24xx abts; 871 + struct imm_ntfy_from_isp tm_iocb; 872 + struct atio_from_isp tm_iocb2; 873 + }; 874 + }; 875 + 876 + struct qla_tgt_mgmt_cmd { 877 + uint8_t tmr_func; 878 + uint8_t fc_tm_rsp; 879 + struct qla_tgt_sess *sess; 880 + struct se_cmd se_cmd; 881 + struct work_struct free_work; 882 + unsigned int flags; 883 + #define QLA24XX_MGMT_SEND_NACK 1 884 + union { 885 + struct atio_from_isp atio; 886 + struct imm_ntfy_from_isp imm_ntfy; 887 + struct abts_recv_from_24xx abts; 888 + } __packed orig_iocb; 889 + }; 890 + 891 + struct qla_tgt_prm { 892 + struct qla_tgt_cmd *cmd; 893 + struct qla_tgt *tgt; 894 + void *pkt; 895 + struct scatterlist *sg; /* cmd data buffer SG vector */ 896 + int seg_cnt; 897 + int req_cnt; 898 + uint16_t rq_result; 899 + uint16_t scsi_status; 900 + unsigned char *sense_buffer; 901 + int sense_buffer_len; 902 + int residual; 903 + int add_status_pkt; 904 + }; 905 + 906 + struct qla_tgt_srr_imm { 907 + struct list_head srr_list_entry; 908 + int srr_id; 909 + struct imm_ntfy_from_isp imm_ntfy; 910 + }; 911 + 912 + struct qla_tgt_srr_ctio { 913 + struct list_head srr_list_entry; 914 + int srr_id; 915 + struct qla_tgt_cmd *cmd; 916 + }; 917 + 918 + #define QLA_TGT_XMIT_DATA 1 919 + #define QLA_TGT_XMIT_STATUS 2 920 + #define QLA_TGT_XMIT_ALL (QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA) 921 + 922 + #include <linux/version.h> 923 + 924 + extern struct qla_tgt_data qla_target; 925 + /* 926 + * Internal function prototypes 927 + */ 928 + void qlt_disable_vha(struct scsi_qla_host *); 929 + 930 + /* 931 + * Function prototypes for qla_target.c logic used by qla2xxx LLD code. 932 + */ 933 + extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *); 934 + extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *); 935 + extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64, 936 + int (*callback)(struct scsi_qla_host *), void *); 937 + extern void qlt_lport_deregister(struct scsi_qla_host *); 938 + extern void qlt_unreg_sess(struct qla_tgt_sess *); 939 + extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *); 940 + extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *); 941 + extern void qlt_set_mode(struct scsi_qla_host *ha); 942 + extern void qlt_clear_mode(struct scsi_qla_host *ha); 943 + extern int __init qlt_init(void); 944 + extern void qlt_exit(void); 945 + extern void qlt_update_vp_map(struct scsi_qla_host *, int); 946 + 947 + /* 948 + * This macro is used during early initializations when host->active_mode 949 + * is not set. Right now, ha value is ignored. 950 + */ 951 + #define QLA_TGT_MODE_ENABLED() (ql2x_ini_mode != QLA2XXX_INI_MODE_ENABLED) 952 + 953 + static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha) 954 + { 955 + return ha->host->active_mode & MODE_TARGET; 956 + } 957 + 958 + static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha) 959 + { 960 + return ha->host->active_mode & MODE_INITIATOR; 961 + } 962 + 963 + static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha) 964 + { 965 + if (ha->host->active_mode & MODE_INITIATOR) 966 + ha->host->active_mode &= ~MODE_INITIATOR; 967 + else 968 + ha->host->active_mode |= MODE_INITIATOR; 969 + } 970 + 971 + /* 972 + * Exported symbols from qla_target.c LLD logic used by qla2xxx code.. 973 + */ 974 + extern void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *, 975 + struct atio_from_isp *); 976 + extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); 977 + extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); 978 + extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); 979 + extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); 980 + extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); 981 + extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); 982 + extern void qlt_ctio_completion(struct scsi_qla_host *, uint32_t); 983 + extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *); 984 + extern void qlt_enable_vha(struct scsi_qla_host *); 985 + extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); 986 + extern void qlt_rff_id(struct scsi_qla_host *, struct ct_sns_req *); 987 + extern void qlt_init_atio_q_entries(struct scsi_qla_host *); 988 + extern void qlt_24xx_process_atio_queue(struct scsi_qla_host *); 989 + extern void qlt_24xx_config_rings(struct scsi_qla_host *, 990 + device_reg_t __iomem *); 991 + extern void qlt_24xx_config_nvram_stage1(struct scsi_qla_host *, 992 + struct nvram_24xx *); 993 + extern void qlt_24xx_config_nvram_stage2(struct scsi_qla_host *, 994 + struct init_cb_24xx *); 995 + extern int qlt_24xx_process_response_error(struct scsi_qla_host *, 996 + struct sts_entry_24xx *); 997 + extern void qlt_modify_vp_config(struct scsi_qla_host *, 998 + struct vp_config_entry_24xx *); 999 + extern void qlt_probe_one_stage1(struct scsi_qla_host *, struct qla_hw_data *); 1000 + extern int qlt_mem_alloc(struct qla_hw_data *); 1001 + extern void qlt_mem_free(struct qla_hw_data *); 1002 + extern void qlt_stop_phase1(struct qla_tgt *); 1003 + extern void qlt_stop_phase2(struct qla_tgt *); 1004 + 1005 + #endif /* __QLA_TARGET_H */
+1955
drivers/scsi/qla2xxx/tcm_qla2xxx.c
··· 1 + /******************************************************************************* 2 + * This file contains tcm implementation using v4 configfs fabric infrastructure 3 + * for QLogic target mode HBAs 4 + * 5 + * ?? Copyright 2010-2011 RisingTide Systems LLC. 6 + * 7 + * Licensed to the Linux Foundation under the General Public License (GPL) 8 + * version 2. 9 + * 10 + * Author: Nicholas A. Bellinger <nab@risingtidesystems.com> 11 + * 12 + * tcm_qla2xxx_parse_wwn() and tcm_qla2xxx_format_wwn() contains code from 13 + * the TCM_FC / Open-FCoE.org fabric module. 14 + * 15 + * Copyright (c) 2010 Cisco Systems, Inc 16 + * 17 + * This program is free software; you can redistribute it and/or modify 18 + * it under the terms of the GNU General Public License as published by 19 + * the Free Software Foundation; either version 2 of the License, or 20 + * (at your option) any later version. 21 + * 22 + * This program is distributed in the hope that it will be useful, 23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 + * GNU General Public License for more details. 26 + ****************************************************************************/ 27 + 28 + 29 + #include <linux/module.h> 30 + #include <linux/moduleparam.h> 31 + #include <generated/utsrelease.h> 32 + #include <linux/utsname.h> 33 + #include <linux/init.h> 34 + #include <linux/list.h> 35 + #include <linux/slab.h> 36 + #include <linux/kthread.h> 37 + #include <linux/types.h> 38 + #include <linux/string.h> 39 + #include <linux/configfs.h> 40 + #include <linux/ctype.h> 41 + #include <linux/string.h> 42 + #include <linux/ctype.h> 43 + #include <asm/unaligned.h> 44 + #include <scsi/scsi.h> 45 + #include <scsi/scsi_host.h> 46 + #include <scsi/scsi_device.h> 47 + #include <scsi/scsi_cmnd.h> 48 + #include <target/target_core_base.h> 49 + #include <target/target_core_fabric.h> 50 + #include <target/target_core_fabric_configfs.h> 51 + #include <target/target_core_configfs.h> 52 + #include <target/configfs_macros.h> 53 + 54 + #include "qla_def.h" 55 + #include "qla_target.h" 56 + #include "tcm_qla2xxx.h" 57 + 58 + struct workqueue_struct *tcm_qla2xxx_free_wq; 59 + struct workqueue_struct *tcm_qla2xxx_cmd_wq; 60 + 61 + static int tcm_qla2xxx_check_true(struct se_portal_group *se_tpg) 62 + { 63 + return 1; 64 + } 65 + 66 + static int tcm_qla2xxx_check_false(struct se_portal_group *se_tpg) 67 + { 68 + return 0; 69 + } 70 + 71 + /* 72 + * Parse WWN. 73 + * If strict, we require lower-case hex and colon separators to be sure 74 + * the name is the same as what would be generated by ft_format_wwn() 75 + * so the name and wwn are mapped one-to-one. 76 + */ 77 + static ssize_t tcm_qla2xxx_parse_wwn(const char *name, u64 *wwn, int strict) 78 + { 79 + const char *cp; 80 + char c; 81 + u32 nibble; 82 + u32 byte = 0; 83 + u32 pos = 0; 84 + u32 err; 85 + 86 + *wwn = 0; 87 + for (cp = name; cp < &name[TCM_QLA2XXX_NAMELEN - 1]; cp++) { 88 + c = *cp; 89 + if (c == '\n' && cp[1] == '\0') 90 + continue; 91 + if (strict && pos++ == 2 && byte++ < 7) { 92 + pos = 0; 93 + if (c == ':') 94 + continue; 95 + err = 1; 96 + goto fail; 97 + } 98 + if (c == '\0') { 99 + err = 2; 100 + if (strict && byte != 8) 101 + goto fail; 102 + return cp - name; 103 + } 104 + err = 3; 105 + if (isdigit(c)) 106 + nibble = c - '0'; 107 + else if (isxdigit(c) && (islower(c) || !strict)) 108 + nibble = tolower(c) - 'a' + 10; 109 + else 110 + goto fail; 111 + *wwn = (*wwn << 4) | nibble; 112 + } 113 + err = 4; 114 + fail: 115 + pr_debug("err %u len %zu pos %u byte %u\n", 116 + err, cp - name, pos, byte); 117 + return -1; 118 + } 119 + 120 + static ssize_t tcm_qla2xxx_format_wwn(char *buf, size_t len, u64 wwn) 121 + { 122 + u8 b[8]; 123 + 124 + put_unaligned_be64(wwn, b); 125 + return snprintf(buf, len, 126 + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", 127 + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]); 128 + } 129 + 130 + static char *tcm_qla2xxx_get_fabric_name(void) 131 + { 132 + return "qla2xxx"; 133 + } 134 + 135 + /* 136 + * From drivers/scsi/scsi_transport_fc.c:fc_parse_wwn 137 + */ 138 + static int tcm_qla2xxx_npiv_extract_wwn(const char *ns, u64 *nm) 139 + { 140 + unsigned int i, j, value; 141 + u8 wwn[8]; 142 + 143 + memset(wwn, 0, sizeof(wwn)); 144 + 145 + /* Validate and store the new name */ 146 + for (i = 0, j = 0; i < 16; i++) { 147 + value = hex_to_bin(*ns++); 148 + if (value >= 0) 149 + j = (j << 4) | value; 150 + else 151 + return -EINVAL; 152 + 153 + if (i % 2) { 154 + wwn[i/2] = j & 0xff; 155 + j = 0; 156 + } 157 + } 158 + 159 + *nm = wwn_to_u64(wwn); 160 + return 0; 161 + } 162 + 163 + /* 164 + * This parsing logic follows drivers/scsi/scsi_transport_fc.c: 165 + * store_fc_host_vport_create() 166 + */ 167 + static int tcm_qla2xxx_npiv_parse_wwn( 168 + const char *name, 169 + size_t count, 170 + u64 *wwpn, 171 + u64 *wwnn) 172 + { 173 + unsigned int cnt = count; 174 + int rc; 175 + 176 + *wwpn = 0; 177 + *wwnn = 0; 178 + 179 + /* count may include a LF at end of string */ 180 + if (name[cnt-1] == '\n') 181 + cnt--; 182 + 183 + /* validate we have enough characters for WWPN */ 184 + if ((cnt != (16+1+16)) || (name[16] != ':')) 185 + return -EINVAL; 186 + 187 + rc = tcm_qla2xxx_npiv_extract_wwn(&name[0], wwpn); 188 + if (rc != 0) 189 + return rc; 190 + 191 + rc = tcm_qla2xxx_npiv_extract_wwn(&name[17], wwnn); 192 + if (rc != 0) 193 + return rc; 194 + 195 + return 0; 196 + } 197 + 198 + static ssize_t tcm_qla2xxx_npiv_format_wwn(char *buf, size_t len, 199 + u64 wwpn, u64 wwnn) 200 + { 201 + u8 b[8], b2[8]; 202 + 203 + put_unaligned_be64(wwpn, b); 204 + put_unaligned_be64(wwnn, b2); 205 + return snprintf(buf, len, 206 + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x," 207 + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", 208 + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], 209 + b2[0], b2[1], b2[2], b2[3], b2[4], b2[5], b2[6], b2[7]); 210 + } 211 + 212 + static char *tcm_qla2xxx_npiv_get_fabric_name(void) 213 + { 214 + return "qla2xxx_npiv"; 215 + } 216 + 217 + static u8 tcm_qla2xxx_get_fabric_proto_ident(struct se_portal_group *se_tpg) 218 + { 219 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 220 + struct tcm_qla2xxx_tpg, se_tpg); 221 + struct tcm_qla2xxx_lport *lport = tpg->lport; 222 + u8 proto_id; 223 + 224 + switch (lport->lport_proto_id) { 225 + case SCSI_PROTOCOL_FCP: 226 + default: 227 + proto_id = fc_get_fabric_proto_ident(se_tpg); 228 + break; 229 + } 230 + 231 + return proto_id; 232 + } 233 + 234 + static char *tcm_qla2xxx_get_fabric_wwn(struct se_portal_group *se_tpg) 235 + { 236 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 237 + struct tcm_qla2xxx_tpg, se_tpg); 238 + struct tcm_qla2xxx_lport *lport = tpg->lport; 239 + 240 + return &lport->lport_name[0]; 241 + } 242 + 243 + static char *tcm_qla2xxx_npiv_get_fabric_wwn(struct se_portal_group *se_tpg) 244 + { 245 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 246 + struct tcm_qla2xxx_tpg, se_tpg); 247 + struct tcm_qla2xxx_lport *lport = tpg->lport; 248 + 249 + return &lport->lport_npiv_name[0]; 250 + } 251 + 252 + static u16 tcm_qla2xxx_get_tag(struct se_portal_group *se_tpg) 253 + { 254 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 255 + struct tcm_qla2xxx_tpg, se_tpg); 256 + return tpg->lport_tpgt; 257 + } 258 + 259 + static u32 tcm_qla2xxx_get_default_depth(struct se_portal_group *se_tpg) 260 + { 261 + return 1; 262 + } 263 + 264 + static u32 tcm_qla2xxx_get_pr_transport_id( 265 + struct se_portal_group *se_tpg, 266 + struct se_node_acl *se_nacl, 267 + struct t10_pr_registration *pr_reg, 268 + int *format_code, 269 + unsigned char *buf) 270 + { 271 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 272 + struct tcm_qla2xxx_tpg, se_tpg); 273 + struct tcm_qla2xxx_lport *lport = tpg->lport; 274 + int ret = 0; 275 + 276 + switch (lport->lport_proto_id) { 277 + case SCSI_PROTOCOL_FCP: 278 + default: 279 + ret = fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, 280 + format_code, buf); 281 + break; 282 + } 283 + 284 + return ret; 285 + } 286 + 287 + static u32 tcm_qla2xxx_get_pr_transport_id_len( 288 + struct se_portal_group *se_tpg, 289 + struct se_node_acl *se_nacl, 290 + struct t10_pr_registration *pr_reg, 291 + int *format_code) 292 + { 293 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 294 + struct tcm_qla2xxx_tpg, se_tpg); 295 + struct tcm_qla2xxx_lport *lport = tpg->lport; 296 + int ret = 0; 297 + 298 + switch (lport->lport_proto_id) { 299 + case SCSI_PROTOCOL_FCP: 300 + default: 301 + ret = fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, 302 + format_code); 303 + break; 304 + } 305 + 306 + return ret; 307 + } 308 + 309 + static char *tcm_qla2xxx_parse_pr_out_transport_id( 310 + struct se_portal_group *se_tpg, 311 + const char *buf, 312 + u32 *out_tid_len, 313 + char **port_nexus_ptr) 314 + { 315 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 316 + struct tcm_qla2xxx_tpg, se_tpg); 317 + struct tcm_qla2xxx_lport *lport = tpg->lport; 318 + char *tid = NULL; 319 + 320 + switch (lport->lport_proto_id) { 321 + case SCSI_PROTOCOL_FCP: 322 + default: 323 + tid = fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, 324 + port_nexus_ptr); 325 + break; 326 + } 327 + 328 + return tid; 329 + } 330 + 331 + static int tcm_qla2xxx_check_demo_mode(struct se_portal_group *se_tpg) 332 + { 333 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 334 + struct tcm_qla2xxx_tpg, se_tpg); 335 + 336 + return QLA_TPG_ATTRIB(tpg)->generate_node_acls; 337 + } 338 + 339 + static int tcm_qla2xxx_check_demo_mode_cache(struct se_portal_group *se_tpg) 340 + { 341 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 342 + struct tcm_qla2xxx_tpg, se_tpg); 343 + 344 + return QLA_TPG_ATTRIB(tpg)->cache_dynamic_acls; 345 + } 346 + 347 + static int tcm_qla2xxx_check_demo_write_protect(struct se_portal_group *se_tpg) 348 + { 349 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 350 + struct tcm_qla2xxx_tpg, se_tpg); 351 + 352 + return QLA_TPG_ATTRIB(tpg)->demo_mode_write_protect; 353 + } 354 + 355 + static int tcm_qla2xxx_check_prod_write_protect(struct se_portal_group *se_tpg) 356 + { 357 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 358 + struct tcm_qla2xxx_tpg, se_tpg); 359 + 360 + return QLA_TPG_ATTRIB(tpg)->prod_mode_write_protect; 361 + } 362 + 363 + static struct se_node_acl *tcm_qla2xxx_alloc_fabric_acl( 364 + struct se_portal_group *se_tpg) 365 + { 366 + struct tcm_qla2xxx_nacl *nacl; 367 + 368 + nacl = kzalloc(sizeof(struct tcm_qla2xxx_nacl), GFP_KERNEL); 369 + if (!nacl) { 370 + pr_err("Unable to alocate struct tcm_qla2xxx_nacl\n"); 371 + return NULL; 372 + } 373 + 374 + return &nacl->se_node_acl; 375 + } 376 + 377 + static void tcm_qla2xxx_release_fabric_acl( 378 + struct se_portal_group *se_tpg, 379 + struct se_node_acl *se_nacl) 380 + { 381 + struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, 382 + struct tcm_qla2xxx_nacl, se_node_acl); 383 + kfree(nacl); 384 + } 385 + 386 + static u32 tcm_qla2xxx_tpg_get_inst_index(struct se_portal_group *se_tpg) 387 + { 388 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 389 + struct tcm_qla2xxx_tpg, se_tpg); 390 + 391 + return tpg->lport_tpgt; 392 + } 393 + 394 + static void tcm_qla2xxx_complete_mcmd(struct work_struct *work) 395 + { 396 + struct qla_tgt_mgmt_cmd *mcmd = container_of(work, 397 + struct qla_tgt_mgmt_cmd, free_work); 398 + 399 + transport_generic_free_cmd(&mcmd->se_cmd, 0); 400 + } 401 + 402 + /* 403 + * Called from qla_target_template->free_mcmd(), and will call 404 + * tcm_qla2xxx_release_cmd() via normal struct target_core_fabric_ops 405 + * release callback. qla_hw_data->hardware_lock is expected to be held 406 + */ 407 + static void tcm_qla2xxx_free_mcmd(struct qla_tgt_mgmt_cmd *mcmd) 408 + { 409 + INIT_WORK(&mcmd->free_work, tcm_qla2xxx_complete_mcmd); 410 + queue_work(tcm_qla2xxx_free_wq, &mcmd->free_work); 411 + } 412 + 413 + static void tcm_qla2xxx_complete_free(struct work_struct *work) 414 + { 415 + struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 416 + 417 + transport_generic_free_cmd(&cmd->se_cmd, 0); 418 + } 419 + 420 + /* 421 + * Called from qla_target_template->free_cmd(), and will call 422 + * tcm_qla2xxx_release_cmd via normal struct target_core_fabric_ops 423 + * release callback. qla_hw_data->hardware_lock is expected to be held 424 + */ 425 + static void tcm_qla2xxx_free_cmd(struct qla_tgt_cmd *cmd) 426 + { 427 + INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); 428 + queue_work(tcm_qla2xxx_free_wq, &cmd->work); 429 + } 430 + 431 + /* 432 + * Called from struct target_core_fabric_ops->check_stop_free() context 433 + */ 434 + static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd) 435 + { 436 + return target_put_sess_cmd(se_cmd->se_sess, se_cmd); 437 + } 438 + 439 + /* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying 440 + * fabric descriptor @se_cmd command to release 441 + */ 442 + static void tcm_qla2xxx_release_cmd(struct se_cmd *se_cmd) 443 + { 444 + struct qla_tgt_cmd *cmd; 445 + 446 + if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) { 447 + struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, 448 + struct qla_tgt_mgmt_cmd, se_cmd); 449 + qlt_free_mcmd(mcmd); 450 + return; 451 + } 452 + 453 + cmd = container_of(se_cmd, struct qla_tgt_cmd, se_cmd); 454 + qlt_free_cmd(cmd); 455 + } 456 + 457 + static int tcm_qla2xxx_shutdown_session(struct se_session *se_sess) 458 + { 459 + struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; 460 + struct scsi_qla_host *vha; 461 + unsigned long flags; 462 + 463 + BUG_ON(!sess); 464 + vha = sess->vha; 465 + 466 + spin_lock_irqsave(&vha->hw->hardware_lock, flags); 467 + sess->tearing_down = 1; 468 + target_splice_sess_cmd_list(se_sess); 469 + spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 470 + 471 + return 1; 472 + } 473 + 474 + static void tcm_qla2xxx_close_session(struct se_session *se_sess) 475 + { 476 + struct qla_tgt_sess *sess = se_sess->fabric_sess_ptr; 477 + struct scsi_qla_host *vha; 478 + unsigned long flags; 479 + 480 + BUG_ON(!sess); 481 + vha = sess->vha; 482 + 483 + spin_lock_irqsave(&vha->hw->hardware_lock, flags); 484 + qlt_unreg_sess(sess); 485 + spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 486 + } 487 + 488 + static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess) 489 + { 490 + return 0; 491 + } 492 + 493 + /* 494 + * The LIO target core uses DMA_TO_DEVICE to mean that data is going 495 + * to the target (eg handling a WRITE) and DMA_FROM_DEVICE to mean 496 + * that data is coming from the target (eg handling a READ). However, 497 + * this is just the opposite of what we have to tell the DMA mapping 498 + * layer -- eg when handling a READ, the HBA will have to DMA the data 499 + * out of memory so it can send it to the initiator, which means we 500 + * need to use DMA_TO_DEVICE when we map the data. 501 + */ 502 + static enum dma_data_direction tcm_qla2xxx_mapping_dir(struct se_cmd *se_cmd) 503 + { 504 + if (se_cmd->se_cmd_flags & SCF_BIDI) 505 + return DMA_BIDIRECTIONAL; 506 + 507 + switch (se_cmd->data_direction) { 508 + case DMA_TO_DEVICE: 509 + return DMA_FROM_DEVICE; 510 + case DMA_FROM_DEVICE: 511 + return DMA_TO_DEVICE; 512 + case DMA_NONE: 513 + default: 514 + return DMA_NONE; 515 + } 516 + } 517 + 518 + static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) 519 + { 520 + struct qla_tgt_cmd *cmd = container_of(se_cmd, 521 + struct qla_tgt_cmd, se_cmd); 522 + 523 + cmd->bufflen = se_cmd->data_length; 524 + cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); 525 + 526 + cmd->sg_cnt = se_cmd->t_data_nents; 527 + cmd->sg = se_cmd->t_data_sg; 528 + 529 + /* 530 + * qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup 531 + * the SGL mappings into PCIe memory for incoming FCP WRITE data. 532 + */ 533 + return qlt_rdy_to_xfer(cmd); 534 + } 535 + 536 + static int tcm_qla2xxx_write_pending_status(struct se_cmd *se_cmd) 537 + { 538 + unsigned long flags; 539 + /* 540 + * Check for WRITE_PENDING status to determine if we need to wait for 541 + * CTIO aborts to be posted via hardware in tcm_qla2xxx_handle_data(). 542 + */ 543 + spin_lock_irqsave(&se_cmd->t_state_lock, flags); 544 + if (se_cmd->t_state == TRANSPORT_WRITE_PENDING || 545 + se_cmd->t_state == TRANSPORT_COMPLETE_QF_WP) { 546 + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 547 + wait_for_completion_timeout(&se_cmd->t_transport_stop_comp, 548 + 3000); 549 + return 0; 550 + } 551 + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 552 + 553 + return 0; 554 + } 555 + 556 + static void tcm_qla2xxx_set_default_node_attrs(struct se_node_acl *nacl) 557 + { 558 + return; 559 + } 560 + 561 + static u32 tcm_qla2xxx_get_task_tag(struct se_cmd *se_cmd) 562 + { 563 + struct qla_tgt_cmd *cmd = container_of(se_cmd, 564 + struct qla_tgt_cmd, se_cmd); 565 + 566 + return cmd->tag; 567 + } 568 + 569 + static int tcm_qla2xxx_get_cmd_state(struct se_cmd *se_cmd) 570 + { 571 + return 0; 572 + } 573 + 574 + /* 575 + * Called from process context in qla_target.c:qlt_do_work() code 576 + */ 577 + static int tcm_qla2xxx_handle_cmd(scsi_qla_host_t *vha, struct qla_tgt_cmd *cmd, 578 + unsigned char *cdb, uint32_t data_length, int fcp_task_attr, 579 + int data_dir, int bidi) 580 + { 581 + struct se_cmd *se_cmd = &cmd->se_cmd; 582 + struct se_session *se_sess; 583 + struct qla_tgt_sess *sess; 584 + int flags = TARGET_SCF_ACK_KREF; 585 + 586 + if (bidi) 587 + flags |= TARGET_SCF_BIDI_OP; 588 + 589 + sess = cmd->sess; 590 + if (!sess) { 591 + pr_err("Unable to locate struct qla_tgt_sess from qla_tgt_cmd\n"); 592 + return -EINVAL; 593 + } 594 + 595 + se_sess = sess->se_sess; 596 + if (!se_sess) { 597 + pr_err("Unable to locate active struct se_session\n"); 598 + return -EINVAL; 599 + } 600 + 601 + target_submit_cmd(se_cmd, se_sess, cdb, &cmd->sense_buffer[0], 602 + cmd->unpacked_lun, data_length, fcp_task_attr, 603 + data_dir, flags); 604 + return 0; 605 + } 606 + 607 + static void tcm_qla2xxx_do_rsp(struct work_struct *work) 608 + { 609 + struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); 610 + /* 611 + * Dispatch ->queue_status from workqueue process context 612 + */ 613 + transport_generic_request_failure(&cmd->se_cmd); 614 + } 615 + 616 + /* 617 + * Called from qla_target.c:qlt_do_ctio_completion() 618 + */ 619 + static int tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) 620 + { 621 + struct se_cmd *se_cmd = &cmd->se_cmd; 622 + unsigned long flags; 623 + /* 624 + * Ensure that the complete FCP WRITE payload has been received. 625 + * Otherwise return an exception via CHECK_CONDITION status. 626 + */ 627 + if (!cmd->write_data_transferred) { 628 + /* 629 + * Check if se_cmd has already been aborted via LUN_RESET, and 630 + * waiting upon completion in tcm_qla2xxx_write_pending_status() 631 + */ 632 + spin_lock_irqsave(&se_cmd->t_state_lock, flags); 633 + if (se_cmd->transport_state & CMD_T_ABORTED) { 634 + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 635 + complete(&se_cmd->t_transport_stop_comp); 636 + return 0; 637 + } 638 + spin_unlock_irqrestore(&se_cmd->t_state_lock, flags); 639 + 640 + se_cmd->scsi_sense_reason = TCM_CHECK_CONDITION_ABORT_CMD; 641 + INIT_WORK(&cmd->work, tcm_qla2xxx_do_rsp); 642 + queue_work(tcm_qla2xxx_free_wq, &cmd->work); 643 + return 0; 644 + } 645 + /* 646 + * We now tell TCM to queue this WRITE CDB with TRANSPORT_PROCESS_WRITE 647 + * status to the backstore processing thread. 648 + */ 649 + return transport_generic_handle_data(&cmd->se_cmd); 650 + } 651 + 652 + /* 653 + * Called from qla_target.c:qlt_issue_task_mgmt() 654 + */ 655 + int tcm_qla2xxx_handle_tmr(struct qla_tgt_mgmt_cmd *mcmd, uint32_t lun, 656 + uint8_t tmr_func, uint32_t tag) 657 + { 658 + struct qla_tgt_sess *sess = mcmd->sess; 659 + struct se_cmd *se_cmd = &mcmd->se_cmd; 660 + 661 + return target_submit_tmr(se_cmd, sess->se_sess, NULL, lun, mcmd, 662 + tmr_func, GFP_ATOMIC, tag, TARGET_SCF_ACK_KREF); 663 + } 664 + 665 + static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) 666 + { 667 + struct qla_tgt_cmd *cmd = container_of(se_cmd, 668 + struct qla_tgt_cmd, se_cmd); 669 + 670 + cmd->bufflen = se_cmd->data_length; 671 + cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); 672 + cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); 673 + 674 + cmd->sg_cnt = se_cmd->t_data_nents; 675 + cmd->sg = se_cmd->t_data_sg; 676 + cmd->offset = 0; 677 + 678 + /* 679 + * Now queue completed DATA_IN the qla2xxx LLD and response ring 680 + */ 681 + return qlt_xmit_response(cmd, QLA_TGT_XMIT_DATA|QLA_TGT_XMIT_STATUS, 682 + se_cmd->scsi_status); 683 + } 684 + 685 + static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd) 686 + { 687 + struct qla_tgt_cmd *cmd = container_of(se_cmd, 688 + struct qla_tgt_cmd, se_cmd); 689 + int xmit_type = QLA_TGT_XMIT_STATUS; 690 + 691 + cmd->bufflen = se_cmd->data_length; 692 + cmd->sg = NULL; 693 + cmd->sg_cnt = 0; 694 + cmd->offset = 0; 695 + cmd->dma_data_direction = tcm_qla2xxx_mapping_dir(se_cmd); 696 + cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED); 697 + 698 + if (se_cmd->data_direction == DMA_FROM_DEVICE) { 699 + /* 700 + * For FCP_READ with CHECK_CONDITION status, clear cmd->bufflen 701 + * for qla_tgt_xmit_response LLD code 702 + */ 703 + se_cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; 704 + se_cmd->residual_count = se_cmd->data_length; 705 + 706 + cmd->bufflen = 0; 707 + } 708 + /* 709 + * Now queue status response to qla2xxx LLD code and response ring 710 + */ 711 + return qlt_xmit_response(cmd, xmit_type, se_cmd->scsi_status); 712 + } 713 + 714 + static int tcm_qla2xxx_queue_tm_rsp(struct se_cmd *se_cmd) 715 + { 716 + struct se_tmr_req *se_tmr = se_cmd->se_tmr_req; 717 + struct qla_tgt_mgmt_cmd *mcmd = container_of(se_cmd, 718 + struct qla_tgt_mgmt_cmd, se_cmd); 719 + 720 + pr_debug("queue_tm_rsp: mcmd: %p func: 0x%02x response: 0x%02x\n", 721 + mcmd, se_tmr->function, se_tmr->response); 722 + /* 723 + * Do translation between TCM TM response codes and 724 + * QLA2xxx FC TM response codes. 725 + */ 726 + switch (se_tmr->response) { 727 + case TMR_FUNCTION_COMPLETE: 728 + mcmd->fc_tm_rsp = FC_TM_SUCCESS; 729 + break; 730 + case TMR_TASK_DOES_NOT_EXIST: 731 + mcmd->fc_tm_rsp = FC_TM_BAD_CMD; 732 + break; 733 + case TMR_FUNCTION_REJECTED: 734 + mcmd->fc_tm_rsp = FC_TM_REJECT; 735 + break; 736 + case TMR_LUN_DOES_NOT_EXIST: 737 + default: 738 + mcmd->fc_tm_rsp = FC_TM_FAILED; 739 + break; 740 + } 741 + /* 742 + * Queue the TM response to QLA2xxx LLD to build a 743 + * CTIO response packet. 744 + */ 745 + qlt_xmit_tm_rsp(mcmd); 746 + 747 + return 0; 748 + } 749 + 750 + static u16 tcm_qla2xxx_get_fabric_sense_len(void) 751 + { 752 + return 0; 753 + } 754 + 755 + static u16 tcm_qla2xxx_set_fabric_sense_len(struct se_cmd *se_cmd, 756 + u32 sense_length) 757 + { 758 + return 0; 759 + } 760 + 761 + /* Local pointer to allocated TCM configfs fabric module */ 762 + struct target_fabric_configfs *tcm_qla2xxx_fabric_configfs; 763 + struct target_fabric_configfs *tcm_qla2xxx_npiv_fabric_configfs; 764 + 765 + static int tcm_qla2xxx_setup_nacl_from_rport( 766 + struct se_portal_group *se_tpg, 767 + struct se_node_acl *se_nacl, 768 + struct tcm_qla2xxx_lport *lport, 769 + struct tcm_qla2xxx_nacl *nacl, 770 + u64 rport_wwnn) 771 + { 772 + struct scsi_qla_host *vha = lport->qla_vha; 773 + struct Scsi_Host *sh = vha->host; 774 + struct fc_host_attrs *fc_host = shost_to_fc_host(sh); 775 + struct fc_rport *rport; 776 + unsigned long flags; 777 + void *node; 778 + int rc; 779 + 780 + /* 781 + * Scan the existing rports, and create a session for the 782 + * explict NodeACL is an matching rport->node_name already 783 + * exists. 784 + */ 785 + spin_lock_irqsave(sh->host_lock, flags); 786 + list_for_each_entry(rport, &fc_host->rports, peers) { 787 + if (rport_wwnn != rport->node_name) 788 + continue; 789 + 790 + pr_debug("Located existing rport_wwpn and rport->node_name: 0x%016LX, port_id: 0x%04x\n", 791 + rport->node_name, rport->port_id); 792 + nacl->nport_id = rport->port_id; 793 + 794 + spin_unlock_irqrestore(sh->host_lock, flags); 795 + 796 + spin_lock_irqsave(&vha->hw->hardware_lock, flags); 797 + node = btree_lookup32(&lport->lport_fcport_map, rport->port_id); 798 + if (node) { 799 + rc = btree_update32(&lport->lport_fcport_map, 800 + rport->port_id, se_nacl); 801 + } else { 802 + rc = btree_insert32(&lport->lport_fcport_map, 803 + rport->port_id, se_nacl, 804 + GFP_ATOMIC); 805 + } 806 + spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); 807 + 808 + if (rc) { 809 + pr_err("Unable to insert se_nacl into fcport_map"); 810 + WARN_ON(rc > 0); 811 + return rc; 812 + } 813 + 814 + pr_debug("Inserted into fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%08x\n", 815 + se_nacl, rport_wwnn, nacl->nport_id); 816 + 817 + return 1; 818 + } 819 + spin_unlock_irqrestore(sh->host_lock, flags); 820 + 821 + return 0; 822 + } 823 + 824 + /* 825 + * Expected to be called with struct qla_hw_data->hardware_lock held 826 + */ 827 + static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct qla_tgt_sess *sess) 828 + { 829 + struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; 830 + struct se_portal_group *se_tpg = se_nacl->se_tpg; 831 + struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; 832 + struct tcm_qla2xxx_lport *lport = container_of(se_wwn, 833 + struct tcm_qla2xxx_lport, lport_wwn); 834 + struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, 835 + struct tcm_qla2xxx_nacl, se_node_acl); 836 + void *node; 837 + 838 + pr_debug("fc_rport domain: port_id 0x%06x\n", nacl->nport_id); 839 + 840 + node = btree_remove32(&lport->lport_fcport_map, nacl->nport_id); 841 + WARN_ON(node && (node != se_nacl)); 842 + 843 + pr_debug("Removed from fcport_map: %p for WWNN: 0x%016LX, port_id: 0x%06x\n", 844 + se_nacl, nacl->nport_wwnn, nacl->nport_id); 845 + } 846 + 847 + static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) 848 + { 849 + target_put_session(sess->se_sess); 850 + } 851 + 852 + static void tcm_qla2xxx_shutdown_sess(struct qla_tgt_sess *sess) 853 + { 854 + tcm_qla2xxx_shutdown_session(sess->se_sess); 855 + } 856 + 857 + static struct se_node_acl *tcm_qla2xxx_make_nodeacl( 858 + struct se_portal_group *se_tpg, 859 + struct config_group *group, 860 + const char *name) 861 + { 862 + struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; 863 + struct tcm_qla2xxx_lport *lport = container_of(se_wwn, 864 + struct tcm_qla2xxx_lport, lport_wwn); 865 + struct se_node_acl *se_nacl, *se_nacl_new; 866 + struct tcm_qla2xxx_nacl *nacl; 867 + u64 wwnn; 868 + u32 qla2xxx_nexus_depth; 869 + int rc; 870 + 871 + if (tcm_qla2xxx_parse_wwn(name, &wwnn, 1) < 0) 872 + return ERR_PTR(-EINVAL); 873 + 874 + se_nacl_new = tcm_qla2xxx_alloc_fabric_acl(se_tpg); 875 + if (!se_nacl_new) 876 + return ERR_PTR(-ENOMEM); 877 + /* #warning FIXME: Hardcoded qla2xxx_nexus depth in tcm_qla2xxx_make_nodeacl */ 878 + qla2xxx_nexus_depth = 1; 879 + 880 + /* 881 + * se_nacl_new may be released by core_tpg_add_initiator_node_acl() 882 + * when converting a NodeACL from demo mode -> explict 883 + */ 884 + se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, 885 + name, qla2xxx_nexus_depth); 886 + if (IS_ERR(se_nacl)) { 887 + tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); 888 + return se_nacl; 889 + } 890 + /* 891 + * Locate our struct tcm_qla2xxx_nacl and set the FC Nport WWPN 892 + */ 893 + nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 894 + nacl->nport_wwnn = wwnn; 895 + tcm_qla2xxx_format_wwn(&nacl->nport_name[0], TCM_QLA2XXX_NAMELEN, wwnn); 896 + /* 897 + * Setup a se_nacl handle based on an a matching struct fc_rport setup 898 + * via drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port() 899 + */ 900 + rc = tcm_qla2xxx_setup_nacl_from_rport(se_tpg, se_nacl, lport, 901 + nacl, wwnn); 902 + if (rc < 0) { 903 + tcm_qla2xxx_release_fabric_acl(se_tpg, se_nacl_new); 904 + return ERR_PTR(rc); 905 + } 906 + 907 + return se_nacl; 908 + } 909 + 910 + static void tcm_qla2xxx_drop_nodeacl(struct se_node_acl *se_acl) 911 + { 912 + struct se_portal_group *se_tpg = se_acl->se_tpg; 913 + struct tcm_qla2xxx_nacl *nacl = container_of(se_acl, 914 + struct tcm_qla2xxx_nacl, se_node_acl); 915 + 916 + core_tpg_del_initiator_node_acl(se_tpg, se_acl, 1); 917 + kfree(nacl); 918 + } 919 + 920 + /* Start items for tcm_qla2xxx_tpg_attrib_cit */ 921 + 922 + #define DEF_QLA_TPG_ATTRIB(name) \ 923 + \ 924 + static ssize_t tcm_qla2xxx_tpg_attrib_show_##name( \ 925 + struct se_portal_group *se_tpg, \ 926 + char *page) \ 927 + { \ 928 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, \ 929 + struct tcm_qla2xxx_tpg, se_tpg); \ 930 + \ 931 + return sprintf(page, "%u\n", QLA_TPG_ATTRIB(tpg)->name); \ 932 + } \ 933 + \ 934 + static ssize_t tcm_qla2xxx_tpg_attrib_store_##name( \ 935 + struct se_portal_group *se_tpg, \ 936 + const char *page, \ 937 + size_t count) \ 938 + { \ 939 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, \ 940 + struct tcm_qla2xxx_tpg, se_tpg); \ 941 + unsigned long val; \ 942 + int ret; \ 943 + \ 944 + ret = kstrtoul(page, 0, &val); \ 945 + if (ret < 0) { \ 946 + pr_err("kstrtoul() failed with" \ 947 + " ret: %d\n", ret); \ 948 + return -EINVAL; \ 949 + } \ 950 + ret = tcm_qla2xxx_set_attrib_##name(tpg, val); \ 951 + \ 952 + return (!ret) ? count : -EINVAL; \ 953 + } 954 + 955 + #define DEF_QLA_TPG_ATTR_BOOL(_name) \ 956 + \ 957 + static int tcm_qla2xxx_set_attrib_##_name( \ 958 + struct tcm_qla2xxx_tpg *tpg, \ 959 + unsigned long val) \ 960 + { \ 961 + struct tcm_qla2xxx_tpg_attrib *a = &tpg->tpg_attrib; \ 962 + \ 963 + if ((val != 0) && (val != 1)) { \ 964 + pr_err("Illegal boolean value %lu\n", val); \ 965 + return -EINVAL; \ 966 + } \ 967 + \ 968 + a->_name = val; \ 969 + return 0; \ 970 + } 971 + 972 + #define QLA_TPG_ATTR(_name, _mode) \ 973 + TF_TPG_ATTRIB_ATTR(tcm_qla2xxx, _name, _mode); 974 + 975 + /* 976 + * Define tcm_qla2xxx_tpg_attrib_s_generate_node_acls 977 + */ 978 + DEF_QLA_TPG_ATTR_BOOL(generate_node_acls); 979 + DEF_QLA_TPG_ATTRIB(generate_node_acls); 980 + QLA_TPG_ATTR(generate_node_acls, S_IRUGO | S_IWUSR); 981 + 982 + /* 983 + Define tcm_qla2xxx_attrib_s_cache_dynamic_acls 984 + */ 985 + DEF_QLA_TPG_ATTR_BOOL(cache_dynamic_acls); 986 + DEF_QLA_TPG_ATTRIB(cache_dynamic_acls); 987 + QLA_TPG_ATTR(cache_dynamic_acls, S_IRUGO | S_IWUSR); 988 + 989 + /* 990 + * Define tcm_qla2xxx_tpg_attrib_s_demo_mode_write_protect 991 + */ 992 + DEF_QLA_TPG_ATTR_BOOL(demo_mode_write_protect); 993 + DEF_QLA_TPG_ATTRIB(demo_mode_write_protect); 994 + QLA_TPG_ATTR(demo_mode_write_protect, S_IRUGO | S_IWUSR); 995 + 996 + /* 997 + * Define tcm_qla2xxx_tpg_attrib_s_prod_mode_write_protect 998 + */ 999 + DEF_QLA_TPG_ATTR_BOOL(prod_mode_write_protect); 1000 + DEF_QLA_TPG_ATTRIB(prod_mode_write_protect); 1001 + QLA_TPG_ATTR(prod_mode_write_protect, S_IRUGO | S_IWUSR); 1002 + 1003 + static struct configfs_attribute *tcm_qla2xxx_tpg_attrib_attrs[] = { 1004 + &tcm_qla2xxx_tpg_attrib_generate_node_acls.attr, 1005 + &tcm_qla2xxx_tpg_attrib_cache_dynamic_acls.attr, 1006 + &tcm_qla2xxx_tpg_attrib_demo_mode_write_protect.attr, 1007 + &tcm_qla2xxx_tpg_attrib_prod_mode_write_protect.attr, 1008 + NULL, 1009 + }; 1010 + 1011 + /* End items for tcm_qla2xxx_tpg_attrib_cit */ 1012 + 1013 + static ssize_t tcm_qla2xxx_tpg_show_enable( 1014 + struct se_portal_group *se_tpg, 1015 + char *page) 1016 + { 1017 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 1018 + struct tcm_qla2xxx_tpg, se_tpg); 1019 + 1020 + return snprintf(page, PAGE_SIZE, "%d\n", 1021 + atomic_read(&tpg->lport_tpg_enabled)); 1022 + } 1023 + 1024 + static ssize_t tcm_qla2xxx_tpg_store_enable( 1025 + struct se_portal_group *se_tpg, 1026 + const char *page, 1027 + size_t count) 1028 + { 1029 + struct se_wwn *se_wwn = se_tpg->se_tpg_wwn; 1030 + struct tcm_qla2xxx_lport *lport = container_of(se_wwn, 1031 + struct tcm_qla2xxx_lport, lport_wwn); 1032 + struct scsi_qla_host *vha = lport->qla_vha; 1033 + struct qla_hw_data *ha = vha->hw; 1034 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 1035 + struct tcm_qla2xxx_tpg, se_tpg); 1036 + unsigned long op; 1037 + int rc; 1038 + 1039 + rc = kstrtoul(page, 0, &op); 1040 + if (rc < 0) { 1041 + pr_err("kstrtoul() returned %d\n", rc); 1042 + return -EINVAL; 1043 + } 1044 + if ((op != 1) && (op != 0)) { 1045 + pr_err("Illegal value for tpg_enable: %lu\n", op); 1046 + return -EINVAL; 1047 + } 1048 + 1049 + if (op) { 1050 + atomic_set(&tpg->lport_tpg_enabled, 1); 1051 + qlt_enable_vha(vha); 1052 + } else { 1053 + if (!ha->tgt.qla_tgt) { 1054 + pr_err("truct qla_hw_data *ha->tgt.qla_tgt is NULL\n"); 1055 + return -ENODEV; 1056 + } 1057 + atomic_set(&tpg->lport_tpg_enabled, 0); 1058 + qlt_stop_phase1(ha->tgt.qla_tgt); 1059 + } 1060 + 1061 + return count; 1062 + } 1063 + 1064 + TF_TPG_BASE_ATTR(tcm_qla2xxx, enable, S_IRUGO | S_IWUSR); 1065 + 1066 + static struct configfs_attribute *tcm_qla2xxx_tpg_attrs[] = { 1067 + &tcm_qla2xxx_tpg_enable.attr, 1068 + NULL, 1069 + }; 1070 + 1071 + static struct se_portal_group *tcm_qla2xxx_make_tpg( 1072 + struct se_wwn *wwn, 1073 + struct config_group *group, 1074 + const char *name) 1075 + { 1076 + struct tcm_qla2xxx_lport *lport = container_of(wwn, 1077 + struct tcm_qla2xxx_lport, lport_wwn); 1078 + struct tcm_qla2xxx_tpg *tpg; 1079 + unsigned long tpgt; 1080 + int ret; 1081 + 1082 + if (strstr(name, "tpgt_") != name) 1083 + return ERR_PTR(-EINVAL); 1084 + if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) 1085 + return ERR_PTR(-EINVAL); 1086 + 1087 + if (!lport->qla_npiv_vp && (tpgt != 1)) { 1088 + pr_err("In non NPIV mode, a single TPG=1 is used for HW port mappings\n"); 1089 + return ERR_PTR(-ENOSYS); 1090 + } 1091 + 1092 + tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); 1093 + if (!tpg) { 1094 + pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); 1095 + return ERR_PTR(-ENOMEM); 1096 + } 1097 + tpg->lport = lport; 1098 + tpg->lport_tpgt = tpgt; 1099 + /* 1100 + * By default allow READ-ONLY TPG demo-mode access w/ cached dynamic 1101 + * NodeACLs 1102 + */ 1103 + QLA_TPG_ATTRIB(tpg)->generate_node_acls = 1; 1104 + QLA_TPG_ATTRIB(tpg)->demo_mode_write_protect = 1; 1105 + QLA_TPG_ATTRIB(tpg)->cache_dynamic_acls = 1; 1106 + 1107 + ret = core_tpg_register(&tcm_qla2xxx_fabric_configfs->tf_ops, wwn, 1108 + &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); 1109 + if (ret < 0) { 1110 + kfree(tpg); 1111 + return NULL; 1112 + } 1113 + /* 1114 + * Setup local TPG=1 pointer for non NPIV mode. 1115 + */ 1116 + if (lport->qla_npiv_vp == NULL) 1117 + lport->tpg_1 = tpg; 1118 + 1119 + return &tpg->se_tpg; 1120 + } 1121 + 1122 + static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) 1123 + { 1124 + struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, 1125 + struct tcm_qla2xxx_tpg, se_tpg); 1126 + struct tcm_qla2xxx_lport *lport = tpg->lport; 1127 + struct scsi_qla_host *vha = lport->qla_vha; 1128 + struct qla_hw_data *ha = vha->hw; 1129 + /* 1130 + * Call into qla2x_target.c LLD logic to shutdown the active 1131 + * FC Nexuses and disable target mode operation for this qla_hw_data 1132 + */ 1133 + if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stop) 1134 + qlt_stop_phase1(ha->tgt.qla_tgt); 1135 + 1136 + core_tpg_deregister(se_tpg); 1137 + /* 1138 + * Clear local TPG=1 pointer for non NPIV mode. 1139 + */ 1140 + if (lport->qla_npiv_vp == NULL) 1141 + lport->tpg_1 = NULL; 1142 + 1143 + kfree(tpg); 1144 + } 1145 + 1146 + static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( 1147 + struct se_wwn *wwn, 1148 + struct config_group *group, 1149 + const char *name) 1150 + { 1151 + struct tcm_qla2xxx_lport *lport = container_of(wwn, 1152 + struct tcm_qla2xxx_lport, lport_wwn); 1153 + struct tcm_qla2xxx_tpg *tpg; 1154 + unsigned long tpgt; 1155 + int ret; 1156 + 1157 + if (strstr(name, "tpgt_") != name) 1158 + return ERR_PTR(-EINVAL); 1159 + if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) 1160 + return ERR_PTR(-EINVAL); 1161 + 1162 + tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); 1163 + if (!tpg) { 1164 + pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); 1165 + return ERR_PTR(-ENOMEM); 1166 + } 1167 + tpg->lport = lport; 1168 + tpg->lport_tpgt = tpgt; 1169 + 1170 + ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, 1171 + &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); 1172 + if (ret < 0) { 1173 + kfree(tpg); 1174 + return NULL; 1175 + } 1176 + return &tpg->se_tpg; 1177 + } 1178 + 1179 + /* 1180 + * Expected to be called with struct qla_hw_data->hardware_lock held 1181 + */ 1182 + static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id( 1183 + scsi_qla_host_t *vha, 1184 + const uint8_t *s_id) 1185 + { 1186 + struct qla_hw_data *ha = vha->hw; 1187 + struct tcm_qla2xxx_lport *lport; 1188 + struct se_node_acl *se_nacl; 1189 + struct tcm_qla2xxx_nacl *nacl; 1190 + u32 key; 1191 + 1192 + lport = ha->tgt.target_lport_ptr; 1193 + if (!lport) { 1194 + pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); 1195 + dump_stack(); 1196 + return NULL; 1197 + } 1198 + 1199 + key = (((unsigned long)s_id[0] << 16) | 1200 + ((unsigned long)s_id[1] << 8) | 1201 + (unsigned long)s_id[2]); 1202 + pr_debug("find_sess_by_s_id: 0x%06x\n", key); 1203 + 1204 + se_nacl = btree_lookup32(&lport->lport_fcport_map, key); 1205 + if (!se_nacl) { 1206 + pr_debug("Unable to locate s_id: 0x%06x\n", key); 1207 + return NULL; 1208 + } 1209 + pr_debug("find_sess_by_s_id: located se_nacl: %p, initiatorname: %s\n", 1210 + se_nacl, se_nacl->initiatorname); 1211 + 1212 + nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 1213 + if (!nacl->qla_tgt_sess) { 1214 + pr_err("Unable to locate struct qla_tgt_sess\n"); 1215 + return NULL; 1216 + } 1217 + 1218 + return nacl->qla_tgt_sess; 1219 + } 1220 + 1221 + /* 1222 + * Expected to be called with struct qla_hw_data->hardware_lock held 1223 + */ 1224 + static void tcm_qla2xxx_set_sess_by_s_id( 1225 + struct tcm_qla2xxx_lport *lport, 1226 + struct se_node_acl *new_se_nacl, 1227 + struct tcm_qla2xxx_nacl *nacl, 1228 + struct se_session *se_sess, 1229 + struct qla_tgt_sess *qla_tgt_sess, 1230 + uint8_t *s_id) 1231 + { 1232 + u32 key; 1233 + void *slot; 1234 + int rc; 1235 + 1236 + key = (((unsigned long)s_id[0] << 16) | 1237 + ((unsigned long)s_id[1] << 8) | 1238 + (unsigned long)s_id[2]); 1239 + pr_debug("set_sess_by_s_id: %06x\n", key); 1240 + 1241 + slot = btree_lookup32(&lport->lport_fcport_map, key); 1242 + if (!slot) { 1243 + if (new_se_nacl) { 1244 + pr_debug("Setting up new fc_port entry to new_se_nacl\n"); 1245 + nacl->nport_id = key; 1246 + rc = btree_insert32(&lport->lport_fcport_map, key, 1247 + new_se_nacl, GFP_ATOMIC); 1248 + if (rc) 1249 + printk(KERN_ERR "Unable to insert s_id into fcport_map: %06x\n", 1250 + (int)key); 1251 + } else { 1252 + pr_debug("Wiping nonexisting fc_port entry\n"); 1253 + } 1254 + 1255 + qla_tgt_sess->se_sess = se_sess; 1256 + nacl->qla_tgt_sess = qla_tgt_sess; 1257 + return; 1258 + } 1259 + 1260 + if (nacl->qla_tgt_sess) { 1261 + if (new_se_nacl == NULL) { 1262 + pr_debug("Clearing existing nacl->qla_tgt_sess and fc_port entry\n"); 1263 + btree_remove32(&lport->lport_fcport_map, key); 1264 + nacl->qla_tgt_sess = NULL; 1265 + return; 1266 + } 1267 + pr_debug("Replacing existing nacl->qla_tgt_sess and fc_port entry\n"); 1268 + btree_update32(&lport->lport_fcport_map, key, new_se_nacl); 1269 + qla_tgt_sess->se_sess = se_sess; 1270 + nacl->qla_tgt_sess = qla_tgt_sess; 1271 + return; 1272 + } 1273 + 1274 + if (new_se_nacl == NULL) { 1275 + pr_debug("Clearing existing fc_port entry\n"); 1276 + btree_remove32(&lport->lport_fcport_map, key); 1277 + return; 1278 + } 1279 + 1280 + pr_debug("Replacing existing fc_port entry w/o active nacl->qla_tgt_sess\n"); 1281 + btree_update32(&lport->lport_fcport_map, key, new_se_nacl); 1282 + qla_tgt_sess->se_sess = se_sess; 1283 + nacl->qla_tgt_sess = qla_tgt_sess; 1284 + 1285 + pr_debug("Setup nacl->qla_tgt_sess %p by s_id for se_nacl: %p, initiatorname: %s\n", 1286 + nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); 1287 + } 1288 + 1289 + /* 1290 + * Expected to be called with struct qla_hw_data->hardware_lock held 1291 + */ 1292 + static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id( 1293 + scsi_qla_host_t *vha, 1294 + const uint16_t loop_id) 1295 + { 1296 + struct qla_hw_data *ha = vha->hw; 1297 + struct tcm_qla2xxx_lport *lport; 1298 + struct se_node_acl *se_nacl; 1299 + struct tcm_qla2xxx_nacl *nacl; 1300 + struct tcm_qla2xxx_fc_loopid *fc_loopid; 1301 + 1302 + lport = ha->tgt.target_lport_ptr; 1303 + if (!lport) { 1304 + pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); 1305 + dump_stack(); 1306 + return NULL; 1307 + } 1308 + 1309 + pr_debug("find_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id); 1310 + 1311 + fc_loopid = lport->lport_loopid_map + loop_id; 1312 + se_nacl = fc_loopid->se_nacl; 1313 + if (!se_nacl) { 1314 + pr_debug("Unable to locate se_nacl by loop_id: 0x%04x\n", 1315 + loop_id); 1316 + return NULL; 1317 + } 1318 + 1319 + nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 1320 + 1321 + if (!nacl->qla_tgt_sess) { 1322 + pr_err("Unable to locate struct qla_tgt_sess\n"); 1323 + return NULL; 1324 + } 1325 + 1326 + return nacl->qla_tgt_sess; 1327 + } 1328 + 1329 + /* 1330 + * Expected to be called with struct qla_hw_data->hardware_lock held 1331 + */ 1332 + static void tcm_qla2xxx_set_sess_by_loop_id( 1333 + struct tcm_qla2xxx_lport *lport, 1334 + struct se_node_acl *new_se_nacl, 1335 + struct tcm_qla2xxx_nacl *nacl, 1336 + struct se_session *se_sess, 1337 + struct qla_tgt_sess *qla_tgt_sess, 1338 + uint16_t loop_id) 1339 + { 1340 + struct se_node_acl *saved_nacl; 1341 + struct tcm_qla2xxx_fc_loopid *fc_loopid; 1342 + 1343 + pr_debug("set_sess_by_loop_id: Using loop_id: 0x%04x\n", loop_id); 1344 + 1345 + fc_loopid = &((struct tcm_qla2xxx_fc_loopid *) 1346 + lport->lport_loopid_map)[loop_id]; 1347 + 1348 + saved_nacl = fc_loopid->se_nacl; 1349 + if (!saved_nacl) { 1350 + pr_debug("Setting up new fc_loopid->se_nacl to new_se_nacl\n"); 1351 + fc_loopid->se_nacl = new_se_nacl; 1352 + if (qla_tgt_sess->se_sess != se_sess) 1353 + qla_tgt_sess->se_sess = se_sess; 1354 + if (nacl->qla_tgt_sess != qla_tgt_sess) 1355 + nacl->qla_tgt_sess = qla_tgt_sess; 1356 + return; 1357 + } 1358 + 1359 + if (nacl->qla_tgt_sess) { 1360 + if (new_se_nacl == NULL) { 1361 + pr_debug("Clearing nacl->qla_tgt_sess and fc_loopid->se_nacl\n"); 1362 + fc_loopid->se_nacl = NULL; 1363 + nacl->qla_tgt_sess = NULL; 1364 + return; 1365 + } 1366 + 1367 + pr_debug("Replacing existing nacl->qla_tgt_sess and fc_loopid->se_nacl\n"); 1368 + fc_loopid->se_nacl = new_se_nacl; 1369 + if (qla_tgt_sess->se_sess != se_sess) 1370 + qla_tgt_sess->se_sess = se_sess; 1371 + if (nacl->qla_tgt_sess != qla_tgt_sess) 1372 + nacl->qla_tgt_sess = qla_tgt_sess; 1373 + return; 1374 + } 1375 + 1376 + if (new_se_nacl == NULL) { 1377 + pr_debug("Clearing fc_loopid->se_nacl\n"); 1378 + fc_loopid->se_nacl = NULL; 1379 + return; 1380 + } 1381 + 1382 + pr_debug("Replacing existing fc_loopid->se_nacl w/o active nacl->qla_tgt_sess\n"); 1383 + fc_loopid->se_nacl = new_se_nacl; 1384 + if (qla_tgt_sess->se_sess != se_sess) 1385 + qla_tgt_sess->se_sess = se_sess; 1386 + if (nacl->qla_tgt_sess != qla_tgt_sess) 1387 + nacl->qla_tgt_sess = qla_tgt_sess; 1388 + 1389 + pr_debug("Setup nacl->qla_tgt_sess %p by loop_id for se_nacl: %p, initiatorname: %s\n", 1390 + nacl->qla_tgt_sess, new_se_nacl, new_se_nacl->initiatorname); 1391 + } 1392 + 1393 + static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) 1394 + { 1395 + struct qla_tgt *tgt = sess->tgt; 1396 + struct qla_hw_data *ha = tgt->ha; 1397 + struct se_session *se_sess; 1398 + struct se_node_acl *se_nacl; 1399 + struct tcm_qla2xxx_lport *lport; 1400 + struct tcm_qla2xxx_nacl *nacl; 1401 + unsigned char be_sid[3]; 1402 + unsigned long flags; 1403 + 1404 + BUG_ON(in_interrupt()); 1405 + 1406 + se_sess = sess->se_sess; 1407 + if (!se_sess) { 1408 + pr_err("struct qla_tgt_sess->se_sess is NULL\n"); 1409 + dump_stack(); 1410 + return; 1411 + } 1412 + se_nacl = se_sess->se_node_acl; 1413 + nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 1414 + 1415 + lport = ha->tgt.target_lport_ptr; 1416 + if (!lport) { 1417 + pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); 1418 + dump_stack(); 1419 + return; 1420 + } 1421 + target_wait_for_sess_cmds(se_sess, 0); 1422 + /* 1423 + * And now clear the se_nacl and session pointers from our HW lport 1424 + * mappings for fabric S_ID and LOOP_ID. 1425 + */ 1426 + memset(&be_sid, 0, 3); 1427 + be_sid[0] = sess->s_id.b.domain; 1428 + be_sid[1] = sess->s_id.b.area; 1429 + be_sid[2] = sess->s_id.b.al_pa; 1430 + 1431 + spin_lock_irqsave(&ha->hardware_lock, flags); 1432 + tcm_qla2xxx_set_sess_by_s_id(lport, NULL, nacl, se_sess, 1433 + sess, be_sid); 1434 + tcm_qla2xxx_set_sess_by_loop_id(lport, NULL, nacl, se_sess, 1435 + sess, sess->loop_id); 1436 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 1437 + 1438 + transport_deregister_session_configfs(sess->se_sess); 1439 + transport_deregister_session(sess->se_sess); 1440 + } 1441 + 1442 + /* 1443 + * Called via qlt_create_sess():ha->qla2x_tmpl->check_initiator_node_acl() 1444 + * to locate struct se_node_acl 1445 + */ 1446 + static int tcm_qla2xxx_check_initiator_node_acl( 1447 + scsi_qla_host_t *vha, 1448 + unsigned char *fc_wwpn, 1449 + void *qla_tgt_sess, 1450 + uint8_t *s_id, 1451 + uint16_t loop_id) 1452 + { 1453 + struct qla_hw_data *ha = vha->hw; 1454 + struct tcm_qla2xxx_lport *lport; 1455 + struct tcm_qla2xxx_tpg *tpg; 1456 + struct tcm_qla2xxx_nacl *nacl; 1457 + struct se_portal_group *se_tpg; 1458 + struct se_node_acl *se_nacl; 1459 + struct se_session *se_sess; 1460 + struct qla_tgt_sess *sess = qla_tgt_sess; 1461 + unsigned char port_name[36]; 1462 + unsigned long flags; 1463 + 1464 + lport = ha->tgt.target_lport_ptr; 1465 + if (!lport) { 1466 + pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); 1467 + dump_stack(); 1468 + return -EINVAL; 1469 + } 1470 + /* 1471 + * Locate the TPG=1 reference.. 1472 + */ 1473 + tpg = lport->tpg_1; 1474 + if (!tpg) { 1475 + pr_err("Unable to lcoate struct tcm_qla2xxx_lport->tpg_1\n"); 1476 + return -EINVAL; 1477 + } 1478 + se_tpg = &tpg->se_tpg; 1479 + 1480 + se_sess = transport_init_session(); 1481 + if (IS_ERR(se_sess)) { 1482 + pr_err("Unable to initialize struct se_session\n"); 1483 + return PTR_ERR(se_sess); 1484 + } 1485 + /* 1486 + * Format the FCP Initiator port_name into colon seperated values to 1487 + * match the format by tcm_qla2xxx explict ConfigFS NodeACLs. 1488 + */ 1489 + memset(&port_name, 0, 36); 1490 + snprintf(port_name, 36, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 1491 + fc_wwpn[0], fc_wwpn[1], fc_wwpn[2], fc_wwpn[3], fc_wwpn[4], 1492 + fc_wwpn[5], fc_wwpn[6], fc_wwpn[7]); 1493 + /* 1494 + * Locate our struct se_node_acl either from an explict NodeACL created 1495 + * via ConfigFS, or via running in TPG demo mode. 1496 + */ 1497 + se_sess->se_node_acl = core_tpg_check_initiator_node_acl(se_tpg, 1498 + port_name); 1499 + if (!se_sess->se_node_acl) { 1500 + transport_free_session(se_sess); 1501 + return -EINVAL; 1502 + } 1503 + se_nacl = se_sess->se_node_acl; 1504 + nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); 1505 + /* 1506 + * And now setup the new se_nacl and session pointers into our HW lport 1507 + * mappings for fabric S_ID and LOOP_ID. 1508 + */ 1509 + spin_lock_irqsave(&ha->hardware_lock, flags); 1510 + tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess, 1511 + qla_tgt_sess, s_id); 1512 + tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess, 1513 + qla_tgt_sess, loop_id); 1514 + spin_unlock_irqrestore(&ha->hardware_lock, flags); 1515 + /* 1516 + * Finally register the new FC Nexus with TCM 1517 + */ 1518 + __transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess); 1519 + 1520 + return 0; 1521 + } 1522 + 1523 + /* 1524 + * Calls into tcm_qla2xxx used by qla2xxx LLD I/O path. 1525 + */ 1526 + static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { 1527 + .handle_cmd = tcm_qla2xxx_handle_cmd, 1528 + .handle_data = tcm_qla2xxx_handle_data, 1529 + .handle_tmr = tcm_qla2xxx_handle_tmr, 1530 + .free_cmd = tcm_qla2xxx_free_cmd, 1531 + .free_mcmd = tcm_qla2xxx_free_mcmd, 1532 + .free_session = tcm_qla2xxx_free_session, 1533 + .check_initiator_node_acl = tcm_qla2xxx_check_initiator_node_acl, 1534 + .find_sess_by_s_id = tcm_qla2xxx_find_sess_by_s_id, 1535 + .find_sess_by_loop_id = tcm_qla2xxx_find_sess_by_loop_id, 1536 + .clear_nacl_from_fcport_map = tcm_qla2xxx_clear_nacl_from_fcport_map, 1537 + .put_sess = tcm_qla2xxx_put_sess, 1538 + .shutdown_sess = tcm_qla2xxx_shutdown_sess, 1539 + }; 1540 + 1541 + static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) 1542 + { 1543 + int rc; 1544 + 1545 + rc = btree_init32(&lport->lport_fcport_map); 1546 + if (rc) { 1547 + pr_err("Unable to initialize lport->lport_fcport_map btree\n"); 1548 + return rc; 1549 + } 1550 + 1551 + lport->lport_loopid_map = vmalloc(sizeof(struct tcm_qla2xxx_fc_loopid) * 1552 + 65536); 1553 + if (!lport->lport_loopid_map) { 1554 + pr_err("Unable to allocate lport->lport_loopid_map of %zu bytes\n", 1555 + sizeof(struct tcm_qla2xxx_fc_loopid) * 65536); 1556 + btree_destroy32(&lport->lport_fcport_map); 1557 + return -ENOMEM; 1558 + } 1559 + memset(lport->lport_loopid_map, 0, sizeof(struct tcm_qla2xxx_fc_loopid) 1560 + * 65536); 1561 + pr_debug("qla2xxx: Allocated lport_loopid_map of %zu bytes\n", 1562 + sizeof(struct tcm_qla2xxx_fc_loopid) * 65536); 1563 + return 0; 1564 + } 1565 + 1566 + static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha) 1567 + { 1568 + struct qla_hw_data *ha = vha->hw; 1569 + struct tcm_qla2xxx_lport *lport; 1570 + /* 1571 + * Setup local pointer to vha, NPIV VP pointer (if present) and 1572 + * vha->tcm_lport pointer 1573 + */ 1574 + lport = (struct tcm_qla2xxx_lport *)ha->tgt.target_lport_ptr; 1575 + lport->qla_vha = vha; 1576 + 1577 + return 0; 1578 + } 1579 + 1580 + static struct se_wwn *tcm_qla2xxx_make_lport( 1581 + struct target_fabric_configfs *tf, 1582 + struct config_group *group, 1583 + const char *name) 1584 + { 1585 + struct tcm_qla2xxx_lport *lport; 1586 + u64 wwpn; 1587 + int ret = -ENODEV; 1588 + 1589 + if (tcm_qla2xxx_parse_wwn(name, &wwpn, 1) < 0) 1590 + return ERR_PTR(-EINVAL); 1591 + 1592 + lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); 1593 + if (!lport) { 1594 + pr_err("Unable to allocate struct tcm_qla2xxx_lport\n"); 1595 + return ERR_PTR(-ENOMEM); 1596 + } 1597 + lport->lport_wwpn = wwpn; 1598 + tcm_qla2xxx_format_wwn(&lport->lport_name[0], TCM_QLA2XXX_NAMELEN, 1599 + wwpn); 1600 + 1601 + ret = tcm_qla2xxx_init_lport(lport); 1602 + if (ret != 0) 1603 + goto out; 1604 + 1605 + ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn, 1606 + tcm_qla2xxx_lport_register_cb, lport); 1607 + if (ret != 0) 1608 + goto out_lport; 1609 + 1610 + return &lport->lport_wwn; 1611 + out_lport: 1612 + vfree(lport->lport_loopid_map); 1613 + btree_destroy32(&lport->lport_fcport_map); 1614 + out: 1615 + kfree(lport); 1616 + return ERR_PTR(ret); 1617 + } 1618 + 1619 + static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn) 1620 + { 1621 + struct tcm_qla2xxx_lport *lport = container_of(wwn, 1622 + struct tcm_qla2xxx_lport, lport_wwn); 1623 + struct scsi_qla_host *vha = lport->qla_vha; 1624 + struct qla_hw_data *ha = vha->hw; 1625 + struct se_node_acl *node; 1626 + u32 key = 0; 1627 + 1628 + /* 1629 + * Call into qla2x_target.c LLD logic to complete the 1630 + * shutdown of struct qla_tgt after the call to 1631 + * qlt_stop_phase1() from tcm_qla2xxx_drop_tpg() above.. 1632 + */ 1633 + if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stopped) 1634 + qlt_stop_phase2(ha->tgt.qla_tgt); 1635 + 1636 + qlt_lport_deregister(vha); 1637 + 1638 + vfree(lport->lport_loopid_map); 1639 + btree_for_each_safe32(&lport->lport_fcport_map, key, node) 1640 + btree_remove32(&lport->lport_fcport_map, key); 1641 + btree_destroy32(&lport->lport_fcport_map); 1642 + kfree(lport); 1643 + } 1644 + 1645 + static struct se_wwn *tcm_qla2xxx_npiv_make_lport( 1646 + struct target_fabric_configfs *tf, 1647 + struct config_group *group, 1648 + const char *name) 1649 + { 1650 + struct tcm_qla2xxx_lport *lport; 1651 + u64 npiv_wwpn, npiv_wwnn; 1652 + int ret; 1653 + 1654 + if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1, 1655 + &npiv_wwpn, &npiv_wwnn) < 0) 1656 + return ERR_PTR(-EINVAL); 1657 + 1658 + lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); 1659 + if (!lport) { 1660 + pr_err("Unable to allocate struct tcm_qla2xxx_lport for NPIV\n"); 1661 + return ERR_PTR(-ENOMEM); 1662 + } 1663 + lport->lport_npiv_wwpn = npiv_wwpn; 1664 + lport->lport_npiv_wwnn = npiv_wwnn; 1665 + tcm_qla2xxx_npiv_format_wwn(&lport->lport_npiv_name[0], 1666 + TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); 1667 + 1668 + /* FIXME: tcm_qla2xxx_npiv_make_lport */ 1669 + ret = -ENOSYS; 1670 + if (ret != 0) 1671 + goto out; 1672 + 1673 + return &lport->lport_wwn; 1674 + out: 1675 + kfree(lport); 1676 + return ERR_PTR(ret); 1677 + } 1678 + 1679 + static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn) 1680 + { 1681 + struct tcm_qla2xxx_lport *lport = container_of(wwn, 1682 + struct tcm_qla2xxx_lport, lport_wwn); 1683 + struct scsi_qla_host *vha = lport->qla_vha; 1684 + struct Scsi_Host *sh = vha->host; 1685 + /* 1686 + * Notify libfc that we want to release the lport->npiv_vport 1687 + */ 1688 + fc_vport_terminate(lport->npiv_vport); 1689 + 1690 + scsi_host_put(sh); 1691 + kfree(lport); 1692 + } 1693 + 1694 + 1695 + static ssize_t tcm_qla2xxx_wwn_show_attr_version( 1696 + struct target_fabric_configfs *tf, 1697 + char *page) 1698 + { 1699 + return sprintf(page, 1700 + "TCM QLOGIC QLA2XXX NPIV capable fabric module %s on %s/%s on " 1701 + UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, 1702 + utsname()->machine); 1703 + } 1704 + 1705 + TF_WWN_ATTR_RO(tcm_qla2xxx, version); 1706 + 1707 + static struct configfs_attribute *tcm_qla2xxx_wwn_attrs[] = { 1708 + &tcm_qla2xxx_wwn_version.attr, 1709 + NULL, 1710 + }; 1711 + 1712 + static struct target_core_fabric_ops tcm_qla2xxx_ops = { 1713 + .get_fabric_name = tcm_qla2xxx_get_fabric_name, 1714 + .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, 1715 + .tpg_get_wwn = tcm_qla2xxx_get_fabric_wwn, 1716 + .tpg_get_tag = tcm_qla2xxx_get_tag, 1717 + .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, 1718 + .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, 1719 + .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, 1720 + .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, 1721 + .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode, 1722 + .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache, 1723 + .tpg_check_demo_mode_write_protect = 1724 + tcm_qla2xxx_check_demo_write_protect, 1725 + .tpg_check_prod_mode_write_protect = 1726 + tcm_qla2xxx_check_prod_write_protect, 1727 + .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_true, 1728 + .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, 1729 + .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, 1730 + .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, 1731 + .new_cmd_map = NULL, 1732 + .check_stop_free = tcm_qla2xxx_check_stop_free, 1733 + .release_cmd = tcm_qla2xxx_release_cmd, 1734 + .shutdown_session = tcm_qla2xxx_shutdown_session, 1735 + .close_session = tcm_qla2xxx_close_session, 1736 + .sess_get_index = tcm_qla2xxx_sess_get_index, 1737 + .sess_get_initiator_sid = NULL, 1738 + .write_pending = tcm_qla2xxx_write_pending, 1739 + .write_pending_status = tcm_qla2xxx_write_pending_status, 1740 + .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1741 + .get_task_tag = tcm_qla2xxx_get_task_tag, 1742 + .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1743 + .queue_data_in = tcm_qla2xxx_queue_data_in, 1744 + .queue_status = tcm_qla2xxx_queue_status, 1745 + .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, 1746 + .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, 1747 + .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, 1748 + /* 1749 + * Setup function pointers for generic logic in 1750 + * target_core_fabric_configfs.c 1751 + */ 1752 + .fabric_make_wwn = tcm_qla2xxx_make_lport, 1753 + .fabric_drop_wwn = tcm_qla2xxx_drop_lport, 1754 + .fabric_make_tpg = tcm_qla2xxx_make_tpg, 1755 + .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, 1756 + .fabric_post_link = NULL, 1757 + .fabric_pre_unlink = NULL, 1758 + .fabric_make_np = NULL, 1759 + .fabric_drop_np = NULL, 1760 + .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, 1761 + .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, 1762 + }; 1763 + 1764 + static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { 1765 + .get_fabric_name = tcm_qla2xxx_npiv_get_fabric_name, 1766 + .get_fabric_proto_ident = tcm_qla2xxx_get_fabric_proto_ident, 1767 + .tpg_get_wwn = tcm_qla2xxx_npiv_get_fabric_wwn, 1768 + .tpg_get_tag = tcm_qla2xxx_get_tag, 1769 + .tpg_get_default_depth = tcm_qla2xxx_get_default_depth, 1770 + .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, 1771 + .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, 1772 + .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, 1773 + .tpg_check_demo_mode = tcm_qla2xxx_check_false, 1774 + .tpg_check_demo_mode_cache = tcm_qla2xxx_check_true, 1775 + .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_true, 1776 + .tpg_check_prod_mode_write_protect = tcm_qla2xxx_check_false, 1777 + .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_true, 1778 + .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, 1779 + .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, 1780 + .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, 1781 + .release_cmd = tcm_qla2xxx_release_cmd, 1782 + .shutdown_session = tcm_qla2xxx_shutdown_session, 1783 + .close_session = tcm_qla2xxx_close_session, 1784 + .sess_get_index = tcm_qla2xxx_sess_get_index, 1785 + .sess_get_initiator_sid = NULL, 1786 + .write_pending = tcm_qla2xxx_write_pending, 1787 + .write_pending_status = tcm_qla2xxx_write_pending_status, 1788 + .set_default_node_attributes = tcm_qla2xxx_set_default_node_attrs, 1789 + .get_task_tag = tcm_qla2xxx_get_task_tag, 1790 + .get_cmd_state = tcm_qla2xxx_get_cmd_state, 1791 + .queue_data_in = tcm_qla2xxx_queue_data_in, 1792 + .queue_status = tcm_qla2xxx_queue_status, 1793 + .queue_tm_rsp = tcm_qla2xxx_queue_tm_rsp, 1794 + .get_fabric_sense_len = tcm_qla2xxx_get_fabric_sense_len, 1795 + .set_fabric_sense_len = tcm_qla2xxx_set_fabric_sense_len, 1796 + /* 1797 + * Setup function pointers for generic logic in 1798 + * target_core_fabric_configfs.c 1799 + */ 1800 + .fabric_make_wwn = tcm_qla2xxx_npiv_make_lport, 1801 + .fabric_drop_wwn = tcm_qla2xxx_npiv_drop_lport, 1802 + .fabric_make_tpg = tcm_qla2xxx_npiv_make_tpg, 1803 + .fabric_drop_tpg = tcm_qla2xxx_drop_tpg, 1804 + .fabric_post_link = NULL, 1805 + .fabric_pre_unlink = NULL, 1806 + .fabric_make_np = NULL, 1807 + .fabric_drop_np = NULL, 1808 + .fabric_make_nodeacl = tcm_qla2xxx_make_nodeacl, 1809 + .fabric_drop_nodeacl = tcm_qla2xxx_drop_nodeacl, 1810 + }; 1811 + 1812 + static int tcm_qla2xxx_register_configfs(void) 1813 + { 1814 + struct target_fabric_configfs *fabric, *npiv_fabric; 1815 + int ret; 1816 + 1817 + pr_debug("TCM QLOGIC QLA2XXX fabric module %s on %s/%s on " 1818 + UTS_RELEASE"\n", TCM_QLA2XXX_VERSION, utsname()->sysname, 1819 + utsname()->machine); 1820 + /* 1821 + * Register the top level struct config_item_type with TCM core 1822 + */ 1823 + fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx"); 1824 + if (IS_ERR(fabric)) { 1825 + pr_err("target_fabric_configfs_init() failed\n"); 1826 + return PTR_ERR(fabric); 1827 + } 1828 + /* 1829 + * Setup fabric->tf_ops from our local tcm_qla2xxx_ops 1830 + */ 1831 + fabric->tf_ops = tcm_qla2xxx_ops; 1832 + /* 1833 + * Setup default attribute lists for various fabric->tf_cit_tmpl 1834 + */ 1835 + TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; 1836 + TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_qla2xxx_tpg_attrs; 1837 + TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = 1838 + tcm_qla2xxx_tpg_attrib_attrs; 1839 + TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; 1840 + TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; 1841 + TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; 1842 + TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; 1843 + TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; 1844 + TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; 1845 + /* 1846 + * Register the fabric for use within TCM 1847 + */ 1848 + ret = target_fabric_configfs_register(fabric); 1849 + if (ret < 0) { 1850 + pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); 1851 + return ret; 1852 + } 1853 + /* 1854 + * Setup our local pointer to *fabric 1855 + */ 1856 + tcm_qla2xxx_fabric_configfs = fabric; 1857 + pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_fabric_configfs\n"); 1858 + 1859 + /* 1860 + * Register the top level struct config_item_type for NPIV with TCM core 1861 + */ 1862 + npiv_fabric = target_fabric_configfs_init(THIS_MODULE, "qla2xxx_npiv"); 1863 + if (IS_ERR(npiv_fabric)) { 1864 + pr_err("target_fabric_configfs_init() failed\n"); 1865 + ret = PTR_ERR(npiv_fabric); 1866 + goto out_fabric; 1867 + } 1868 + /* 1869 + * Setup fabric->tf_ops from our local tcm_qla2xxx_npiv_ops 1870 + */ 1871 + npiv_fabric->tf_ops = tcm_qla2xxx_npiv_ops; 1872 + /* 1873 + * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl 1874 + */ 1875 + TF_CIT_TMPL(npiv_fabric)->tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; 1876 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_base_cit.ct_attrs = NULL; 1877 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; 1878 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_param_cit.ct_attrs = NULL; 1879 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; 1880 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; 1881 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; 1882 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; 1883 + TF_CIT_TMPL(npiv_fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; 1884 + /* 1885 + * Register the npiv_fabric for use within TCM 1886 + */ 1887 + ret = target_fabric_configfs_register(npiv_fabric); 1888 + if (ret < 0) { 1889 + pr_err("target_fabric_configfs_register() failed for TCM_QLA2XXX\n"); 1890 + goto out_fabric; 1891 + } 1892 + /* 1893 + * Setup our local pointer to *npiv_fabric 1894 + */ 1895 + tcm_qla2xxx_npiv_fabric_configfs = npiv_fabric; 1896 + pr_debug("TCM_QLA2XXX[0] - Set fabric -> tcm_qla2xxx_npiv_fabric_configfs\n"); 1897 + 1898 + tcm_qla2xxx_free_wq = alloc_workqueue("tcm_qla2xxx_free", 1899 + WQ_MEM_RECLAIM, 0); 1900 + if (!tcm_qla2xxx_free_wq) { 1901 + ret = -ENOMEM; 1902 + goto out_fabric_npiv; 1903 + } 1904 + 1905 + tcm_qla2xxx_cmd_wq = alloc_workqueue("tcm_qla2xxx_cmd", 0, 0); 1906 + if (!tcm_qla2xxx_cmd_wq) { 1907 + ret = -ENOMEM; 1908 + goto out_free_wq; 1909 + } 1910 + 1911 + return 0; 1912 + 1913 + out_free_wq: 1914 + destroy_workqueue(tcm_qla2xxx_free_wq); 1915 + out_fabric_npiv: 1916 + target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); 1917 + out_fabric: 1918 + target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); 1919 + return ret; 1920 + } 1921 + 1922 + static void tcm_qla2xxx_deregister_configfs(void) 1923 + { 1924 + destroy_workqueue(tcm_qla2xxx_cmd_wq); 1925 + destroy_workqueue(tcm_qla2xxx_free_wq); 1926 + 1927 + target_fabric_configfs_deregister(tcm_qla2xxx_fabric_configfs); 1928 + tcm_qla2xxx_fabric_configfs = NULL; 1929 + pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_fabric_configfs\n"); 1930 + 1931 + target_fabric_configfs_deregister(tcm_qla2xxx_npiv_fabric_configfs); 1932 + tcm_qla2xxx_npiv_fabric_configfs = NULL; 1933 + pr_debug("TCM_QLA2XXX[0] - Cleared tcm_qla2xxx_npiv_fabric_configfs\n"); 1934 + } 1935 + 1936 + static int __init tcm_qla2xxx_init(void) 1937 + { 1938 + int ret; 1939 + 1940 + ret = tcm_qla2xxx_register_configfs(); 1941 + if (ret < 0) 1942 + return ret; 1943 + 1944 + return 0; 1945 + } 1946 + 1947 + static void __exit tcm_qla2xxx_exit(void) 1948 + { 1949 + tcm_qla2xxx_deregister_configfs(); 1950 + } 1951 + 1952 + MODULE_DESCRIPTION("TCM QLA2XXX series NPIV enabled fabric driver"); 1953 + MODULE_LICENSE("GPL"); 1954 + module_init(tcm_qla2xxx_init); 1955 + module_exit(tcm_qla2xxx_exit);
+82
drivers/scsi/qla2xxx/tcm_qla2xxx.h
··· 1 + #include <target/target_core_base.h> 2 + #include <linux/btree.h> 3 + 4 + #define TCM_QLA2XXX_VERSION "v0.1" 5 + /* length of ASCII WWPNs including pad */ 6 + #define TCM_QLA2XXX_NAMELEN 32 7 + /* lenth of ASCII NPIV 'WWPN+WWNN' including pad */ 8 + #define TCM_QLA2XXX_NPIV_NAMELEN 66 9 + 10 + #include "qla_target.h" 11 + 12 + struct tcm_qla2xxx_nacl { 13 + /* From libfc struct fc_rport->port_id */ 14 + u32 nport_id; 15 + /* Binary World Wide unique Node Name for remote FC Initiator Nport */ 16 + u64 nport_wwnn; 17 + /* ASCII formatted WWPN for FC Initiator Nport */ 18 + char nport_name[TCM_QLA2XXX_NAMELEN]; 19 + /* Pointer to qla_tgt_sess */ 20 + struct qla_tgt_sess *qla_tgt_sess; 21 + /* Pointer to TCM FC nexus */ 22 + struct se_session *nport_nexus; 23 + /* Returned by tcm_qla2xxx_make_nodeacl() */ 24 + struct se_node_acl se_node_acl; 25 + }; 26 + 27 + struct tcm_qla2xxx_tpg_attrib { 28 + int generate_node_acls; 29 + int cache_dynamic_acls; 30 + int demo_mode_write_protect; 31 + int prod_mode_write_protect; 32 + }; 33 + 34 + struct tcm_qla2xxx_tpg { 35 + /* FC lport target portal group tag for TCM */ 36 + u16 lport_tpgt; 37 + /* Atomic bit to determine TPG active status */ 38 + atomic_t lport_tpg_enabled; 39 + /* Pointer back to tcm_qla2xxx_lport */ 40 + struct tcm_qla2xxx_lport *lport; 41 + /* Used by tcm_qla2xxx_tpg_attrib_cit */ 42 + struct tcm_qla2xxx_tpg_attrib tpg_attrib; 43 + /* Returned by tcm_qla2xxx_make_tpg() */ 44 + struct se_portal_group se_tpg; 45 + }; 46 + 47 + #define QLA_TPG_ATTRIB(tpg) (&(tpg)->tpg_attrib) 48 + 49 + struct tcm_qla2xxx_fc_loopid { 50 + struct se_node_acl *se_nacl; 51 + }; 52 + 53 + struct tcm_qla2xxx_lport { 54 + /* SCSI protocol the lport is providing */ 55 + u8 lport_proto_id; 56 + /* Binary World Wide unique Port Name for FC Target Lport */ 57 + u64 lport_wwpn; 58 + /* Binary World Wide unique Port Name for FC NPIV Target Lport */ 59 + u64 lport_npiv_wwpn; 60 + /* Binary World Wide unique Node Name for FC NPIV Target Lport */ 61 + u64 lport_npiv_wwnn; 62 + /* ASCII formatted WWPN for FC Target Lport */ 63 + char lport_name[TCM_QLA2XXX_NAMELEN]; 64 + /* ASCII formatted WWPN+WWNN for NPIV FC Target Lport */ 65 + char lport_npiv_name[TCM_QLA2XXX_NPIV_NAMELEN]; 66 + /* map for fc_port pointers in 24-bit FC Port ID space */ 67 + struct btree_head32 lport_fcport_map; 68 + /* vmalloc-ed memory for fc_port pointers for 16-bit FC loop ID */ 69 + struct tcm_qla2xxx_fc_loopid *lport_loopid_map; 70 + /* Pointer to struct scsi_qla_host from qla2xxx LLD */ 71 + struct scsi_qla_host *qla_vha; 72 + /* Pointer to struct scsi_qla_host for NPIV VP from qla2xxx LLD */ 73 + struct scsi_qla_host *qla_npiv_vp; 74 + /* Pointer to struct qla_tgt pointer */ 75 + struct qla_tgt lport_qla_tgt; 76 + /* Pointer to struct fc_vport for NPIV vport from libfc */ 77 + struct fc_vport *npiv_vport; 78 + /* Pointer to TPG=1 for non NPIV mode */ 79 + struct tcm_qla2xxx_tpg *tpg_1; 80 + /* Returned by tcm_qla2xxx_make_lport() */ 81 + struct se_wwn lport_wwn; 82 + };
+134
drivers/scsi/qla4xxx/ql4_attr.c
··· 9 9 #include "ql4_glbl.h" 10 10 #include "ql4_dbg.h" 11 11 12 + static ssize_t 13 + qla4_8xxx_sysfs_read_fw_dump(struct file *filep, struct kobject *kobj, 14 + struct bin_attribute *ba, char *buf, loff_t off, 15 + size_t count) 16 + { 17 + struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 18 + struct device, kobj))); 19 + 20 + if (!is_qla8022(ha)) 21 + return -EINVAL; 22 + 23 + if (!test_bit(AF_82XX_DUMP_READING, &ha->flags)) 24 + return 0; 25 + 26 + return memory_read_from_buffer(buf, count, &off, ha->fw_dump, 27 + ha->fw_dump_size); 28 + } 29 + 30 + static ssize_t 31 + qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj, 32 + struct bin_attribute *ba, char *buf, loff_t off, 33 + size_t count) 34 + { 35 + struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, 36 + struct device, kobj))); 37 + uint32_t dev_state; 38 + long reading; 39 + int ret = 0; 40 + 41 + if (!is_qla8022(ha)) 42 + return -EINVAL; 43 + 44 + if (off != 0) 45 + return ret; 46 + 47 + buf[1] = 0; 48 + ret = kstrtol(buf, 10, &reading); 49 + if (ret) { 50 + ql4_printk(KERN_ERR, ha, "%s: Invalid input. Return err %d\n", 51 + __func__, ret); 52 + return ret; 53 + } 54 + 55 + switch (reading) { 56 + case 0: 57 + /* clear dump collection flags */ 58 + if (test_and_clear_bit(AF_82XX_DUMP_READING, &ha->flags)) { 59 + clear_bit(AF_82XX_FW_DUMPED, &ha->flags); 60 + /* Reload minidump template */ 61 + qla4xxx_alloc_fw_dump(ha); 62 + DEBUG2(ql4_printk(KERN_INFO, ha, 63 + "Firmware template reloaded\n")); 64 + } 65 + break; 66 + case 1: 67 + /* Set flag to read dump */ 68 + if (test_bit(AF_82XX_FW_DUMPED, &ha->flags) && 69 + !test_bit(AF_82XX_DUMP_READING, &ha->flags)) { 70 + set_bit(AF_82XX_DUMP_READING, &ha->flags); 71 + DEBUG2(ql4_printk(KERN_INFO, ha, 72 + "Raw firmware dump ready for read on (%ld).\n", 73 + ha->host_no)); 74 + } 75 + break; 76 + case 2: 77 + /* Reset HBA */ 78 + qla4_8xxx_idc_lock(ha); 79 + dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 80 + if (dev_state == QLA82XX_DEV_READY) { 81 + ql4_printk(KERN_INFO, ha, 82 + "%s: Setting Need reset, reset_owner is 0x%x.\n", 83 + __func__, ha->func_num); 84 + qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 85 + QLA82XX_DEV_NEED_RESET); 86 + set_bit(AF_82XX_RST_OWNER, &ha->flags); 87 + } else 88 + ql4_printk(KERN_INFO, ha, 89 + "%s: Reset not performed as device state is 0x%x\n", 90 + __func__, dev_state); 91 + 92 + qla4_8xxx_idc_unlock(ha); 93 + break; 94 + default: 95 + /* do nothing */ 96 + break; 97 + } 98 + 99 + return count; 100 + } 101 + 102 + static struct bin_attribute sysfs_fw_dump_attr = { 103 + .attr = { 104 + .name = "fw_dump", 105 + .mode = S_IRUSR | S_IWUSR, 106 + }, 107 + .size = 0, 108 + .read = qla4_8xxx_sysfs_read_fw_dump, 109 + .write = qla4_8xxx_sysfs_write_fw_dump, 110 + }; 111 + 112 + static struct sysfs_entry { 113 + char *name; 114 + struct bin_attribute *attr; 115 + } bin_file_entries[] = { 116 + { "fw_dump", &sysfs_fw_dump_attr }, 117 + { NULL }, 118 + }; 119 + 120 + void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha) 121 + { 122 + struct Scsi_Host *host = ha->host; 123 + struct sysfs_entry *iter; 124 + int ret; 125 + 126 + for (iter = bin_file_entries; iter->name; iter++) { 127 + ret = sysfs_create_bin_file(&host->shost_gendev.kobj, 128 + iter->attr); 129 + if (ret) 130 + ql4_printk(KERN_ERR, ha, 131 + "Unable to create sysfs %s binary attribute (%d).\n", 132 + iter->name, ret); 133 + } 134 + } 135 + 136 + void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha) 137 + { 138 + struct Scsi_Host *host = ha->host; 139 + struct sysfs_entry *iter; 140 + 141 + for (iter = bin_file_entries; iter->name; iter++) 142 + sysfs_remove_bin_file(&host->shost_gendev.kobj, 143 + iter->attr); 144 + } 145 + 12 146 /* Scsi_Host attributes. */ 13 147 static ssize_t 14 148 qla4xxx_fw_version_show(struct device *dev,
+22
drivers/scsi/qla4xxx/ql4_def.h
··· 398 398 int (*get_sys_info) (struct scsi_qla_host *); 399 399 }; 400 400 401 + struct ql4_mdump_size_table { 402 + uint32_t size; 403 + uint32_t size_cmask_02; 404 + uint32_t size_cmask_04; 405 + uint32_t size_cmask_08; 406 + uint32_t size_cmask_10; 407 + uint32_t size_cmask_FF; 408 + uint32_t version; 409 + }; 410 + 401 411 /*qla4xxx ipaddress configuration details */ 402 412 struct ipaddress_config { 403 413 uint16_t ipv4_options; ··· 495 485 #define AF_EEH_BUSY 20 /* 0x00100000 */ 496 486 #define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ 497 487 #define AF_BUILD_DDB_LIST 22 /* 0x00400000 */ 488 + #define AF_82XX_FW_DUMPED 24 /* 0x01000000 */ 489 + #define AF_82XX_RST_OWNER 25 /* 0x02000000 */ 490 + #define AF_82XX_DUMP_READING 26 /* 0x04000000 */ 491 + 498 492 unsigned long dpc_flags; 499 493 500 494 #define DPC_RESET_HA 1 /* 0x00000002 */ ··· 676 662 677 663 uint32_t nx_dev_init_timeout; 678 664 uint32_t nx_reset_timeout; 665 + void *fw_dump; 666 + uint32_t fw_dump_size; 667 + uint32_t fw_dump_capture_mask; 668 + void *fw_dump_tmplt_hdr; 669 + uint32_t fw_dump_tmplt_size; 679 670 680 671 struct completion mbx_intr_comp; 681 672 ··· 954 935 /* Defines for process_aen() */ 955 936 #define PROCESS_ALL_AENS 0 956 937 #define FLUSH_DDB_CHANGED_AENS 1 938 + 939 + /* Defines for udev events */ 940 + #define QL4_UEVENT_CODE_FW_DUMP 0 957 941 958 942 #endif /*_QLA4XXX_H */
+28
drivers/scsi/qla4xxx/ql4_fw.h
··· 385 385 #define MBOX_CMD_GET_IP_ADDR_STATE 0x0091 386 386 #define MBOX_CMD_SEND_IPV6_ROUTER_SOL 0x0092 387 387 #define MBOX_CMD_GET_DB_ENTRY_CURRENT_IP_ADDR 0x0093 388 + #define MBOX_CMD_MINIDUMP 0x0129 389 + 390 + /* Minidump subcommand */ 391 + #define MINIDUMP_GET_SIZE_SUBCOMMAND 0x00 392 + #define MINIDUMP_GET_TMPLT_SUBCOMMAND 0x01 388 393 389 394 /* Mailbox 1 */ 390 395 #define FW_STATE_READY 0x0000 ··· 1193 1188 uint32_t rx_reject_pdus; /* 0304–0307 */ 1194 1189 1195 1190 uint8_t reserved2[264]; /* 0x0308 - 0x040F */ 1191 + }; 1192 + 1193 + #define QLA82XX_DBG_STATE_ARRAY_LEN 16 1194 + #define QLA82XX_DBG_CAP_SIZE_ARRAY_LEN 8 1195 + #define QLA82XX_DBG_RSVD_ARRAY_LEN 8 1196 + 1197 + struct qla4_8xxx_minidump_template_hdr { 1198 + uint32_t entry_type; 1199 + uint32_t first_entry_offset; 1200 + uint32_t size_of_template; 1201 + uint32_t capture_debug_level; 1202 + uint32_t num_of_entries; 1203 + uint32_t version; 1204 + uint32_t driver_timestamp; 1205 + uint32_t checksum; 1206 + 1207 + uint32_t driver_capture_mask; 1208 + uint32_t driver_info_word2; 1209 + uint32_t driver_info_word3; 1210 + uint32_t driver_info_word4; 1211 + 1212 + uint32_t saved_state_array[QLA82XX_DBG_STATE_ARRAY_LEN]; 1213 + uint32_t capture_size_array[QLA82XX_DBG_CAP_SIZE_ARRAY_LEN]; 1196 1214 }; 1197 1215 1198 1216 #endif /* _QLA4X_FW_H */
+8
drivers/scsi/qla4xxx/ql4_glbl.h
··· 196 196 int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); 197 197 198 198 void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry); 199 + int qla4xxx_get_minidump_template(struct scsi_qla_host *ha, 200 + dma_addr_t phys_addr); 201 + int qla4xxx_req_template_size(struct scsi_qla_host *ha); 202 + void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha); 203 + void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha); 204 + void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha); 199 205 200 206 extern int ql4xextended_error_logging; 201 207 extern int ql4xdontresethba; 202 208 extern int ql4xenablemsix; 209 + extern int ql4xmdcapmask; 210 + extern int ql4xenablemd; 203 211 204 212 extern struct device_attribute *qla4xxx_host_attrs[]; 205 213 #endif /* _QLA4x_GBL_H */
+94 -1
drivers/scsi/qla4xxx/ql4_init.c
··· 277 277 return ipv4_wait|ipv6_wait; 278 278 } 279 279 280 + /** 281 + * qla4xxx_alloc_fw_dump - Allocate memory for minidump data. 282 + * @ha: pointer to host adapter structure. 283 + **/ 284 + void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha) 285 + { 286 + int status; 287 + uint32_t capture_debug_level; 288 + int hdr_entry_bit, k; 289 + void *md_tmp; 290 + dma_addr_t md_tmp_dma; 291 + struct qla4_8xxx_minidump_template_hdr *md_hdr; 292 + 293 + if (ha->fw_dump) { 294 + ql4_printk(KERN_WARNING, ha, 295 + "Firmware dump previously allocated.\n"); 296 + return; 297 + } 298 + 299 + status = qla4xxx_req_template_size(ha); 300 + if (status != QLA_SUCCESS) { 301 + ql4_printk(KERN_INFO, ha, 302 + "scsi%ld: Failed to get template size\n", 303 + ha->host_no); 304 + return; 305 + } 306 + 307 + clear_bit(AF_82XX_FW_DUMPED, &ha->flags); 308 + 309 + /* Allocate memory for saving the template */ 310 + md_tmp = dma_alloc_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, 311 + &md_tmp_dma, GFP_KERNEL); 312 + 313 + /* Request template */ 314 + status = qla4xxx_get_minidump_template(ha, md_tmp_dma); 315 + if (status != QLA_SUCCESS) { 316 + ql4_printk(KERN_INFO, ha, 317 + "scsi%ld: Failed to get minidump template\n", 318 + ha->host_no); 319 + goto alloc_cleanup; 320 + } 321 + 322 + md_hdr = (struct qla4_8xxx_minidump_template_hdr *)md_tmp; 323 + 324 + capture_debug_level = md_hdr->capture_debug_level; 325 + 326 + /* Get capture mask based on module loadtime setting. */ 327 + if (ql4xmdcapmask >= 0x3 && ql4xmdcapmask <= 0x7F) 328 + ha->fw_dump_capture_mask = ql4xmdcapmask; 329 + else 330 + ha->fw_dump_capture_mask = capture_debug_level; 331 + 332 + md_hdr->driver_capture_mask = ha->fw_dump_capture_mask; 333 + 334 + DEBUG2(ql4_printk(KERN_INFO, ha, "Minimum num of entries = %d\n", 335 + md_hdr->num_of_entries)); 336 + DEBUG2(ql4_printk(KERN_INFO, ha, "Dump template size = %d\n", 337 + ha->fw_dump_tmplt_size)); 338 + DEBUG2(ql4_printk(KERN_INFO, ha, "Selected Capture mask =0x%x\n", 339 + ha->fw_dump_capture_mask)); 340 + 341 + /* Calculate fw_dump_size */ 342 + for (hdr_entry_bit = 0x2, k = 1; (hdr_entry_bit & 0xFF); 343 + hdr_entry_bit <<= 1, k++) { 344 + if (hdr_entry_bit & ha->fw_dump_capture_mask) 345 + ha->fw_dump_size += md_hdr->capture_size_array[k]; 346 + } 347 + 348 + /* Total firmware dump size including command header */ 349 + ha->fw_dump_size += ha->fw_dump_tmplt_size; 350 + ha->fw_dump = vmalloc(ha->fw_dump_size); 351 + if (!ha->fw_dump) 352 + goto alloc_cleanup; 353 + 354 + DEBUG2(ql4_printk(KERN_INFO, ha, 355 + "Minidump Tempalate Size = 0x%x KB\n", 356 + ha->fw_dump_tmplt_size)); 357 + DEBUG2(ql4_printk(KERN_INFO, ha, 358 + "Total Minidump size = 0x%x KB\n", ha->fw_dump_size)); 359 + 360 + memcpy(ha->fw_dump, md_tmp, ha->fw_dump_tmplt_size); 361 + ha->fw_dump_tmplt_hdr = ha->fw_dump; 362 + 363 + alloc_cleanup: 364 + dma_free_coherent(&ha->pdev->dev, ha->fw_dump_tmplt_size, 365 + md_tmp, md_tmp_dma); 366 + } 367 + 280 368 static int qla4xxx_fw_ready(struct scsi_qla_host *ha) 281 369 { 282 370 uint32_t timeout_count; ··· 533 445 "control block\n", ha->host_no, __func__)); 534 446 return status; 535 447 } 448 + 536 449 if (!qla4xxx_fw_ready(ha)) 537 450 return status; 451 + 452 + if (is_qla8022(ha) && !test_bit(AF_INIT_DONE, &ha->flags)) 453 + qla4xxx_alloc_fw_dump(ha); 538 454 539 455 return qla4xxx_get_firmware_status(ha); 540 456 } ··· 976 884 switch (state) { 977 885 case DDB_DS_SESSION_ACTIVE: 978 886 case DDB_DS_DISCOVERY: 979 - ddb_entry->unblock_sess(ddb_entry->sess); 980 887 qla4xxx_update_session_conn_param(ha, ddb_entry); 888 + ddb_entry->unblock_sess(ddb_entry->sess); 981 889 status = QLA_SUCCESS; 982 890 break; 983 891 case DDB_DS_SESSION_FAILED: ··· 989 897 } 990 898 break; 991 899 case DDB_DS_SESSION_ACTIVE: 900 + case DDB_DS_DISCOVERY: 992 901 switch (state) { 993 902 case DDB_DS_SESSION_FAILED: 994 903 /*
+92 -19
drivers/scsi/qla4xxx/ql4_mbx.c
··· 51 51 } 52 52 } 53 53 54 - if (is_qla8022(ha)) { 55 - if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 56 - DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " 57 - "prematurely completing mbx cmd as firmware " 58 - "recovery detected\n", ha->host_no, __func__)); 59 - return status; 60 - } 61 - /* Do not send any mbx cmd if h/w is in failed state*/ 62 - qla4_8xxx_idc_lock(ha); 63 - dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 64 - qla4_8xxx_idc_unlock(ha); 65 - if (dev_state == QLA82XX_DEV_FAILED) { 66 - ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: H/W is in " 67 - "failed state, do not send any mailbox commands\n", 68 - ha->host_no, __func__); 69 - return status; 70 - } 71 - } 72 - 73 54 if ((is_aer_supported(ha)) && 74 55 (test_bit(AF_PCI_CHANNEL_IO_PERM_FAILURE, &ha->flags))) { 75 56 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Perm failure on EEH, " ··· 75 94 return status; 76 95 } 77 96 msleep(10); 97 + } 98 + 99 + if (is_qla8022(ha)) { 100 + if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 101 + DEBUG2(ql4_printk(KERN_WARNING, ha, 102 + "scsi%ld: %s: prematurely completing mbx cmd as firmware recovery detected\n", 103 + ha->host_no, __func__)); 104 + goto mbox_exit; 105 + } 106 + /* Do not send any mbx cmd if h/w is in failed state*/ 107 + qla4_8xxx_idc_lock(ha); 108 + dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 109 + qla4_8xxx_idc_unlock(ha); 110 + if (dev_state == QLA82XX_DEV_FAILED) { 111 + ql4_printk(KERN_WARNING, ha, 112 + "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n", 113 + ha->host_no, __func__); 114 + goto mbox_exit; 115 + } 78 116 } 79 117 80 118 spin_lock_irqsave(&ha->hardware_lock, flags); ··· 266 266 clear_bit(AF_MBOX_COMMAND, &ha->flags); 267 267 mutex_unlock(&ha->mbox_sem); 268 268 clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); 269 + 270 + return status; 271 + } 272 + 273 + /** 274 + * qla4xxx_get_minidump_template - Get the firmware template 275 + * @ha: Pointer to host adapter structure. 276 + * @phys_addr: dma address for template 277 + * 278 + * Obtain the minidump template from firmware during initialization 279 + * as it may not be available when minidump is desired. 280 + **/ 281 + int qla4xxx_get_minidump_template(struct scsi_qla_host *ha, 282 + dma_addr_t phys_addr) 283 + { 284 + uint32_t mbox_cmd[MBOX_REG_COUNT]; 285 + uint32_t mbox_sts[MBOX_REG_COUNT]; 286 + int status; 287 + 288 + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 289 + memset(&mbox_sts, 0, sizeof(mbox_sts)); 290 + 291 + mbox_cmd[0] = MBOX_CMD_MINIDUMP; 292 + mbox_cmd[1] = MINIDUMP_GET_TMPLT_SUBCOMMAND; 293 + mbox_cmd[2] = LSDW(phys_addr); 294 + mbox_cmd[3] = MSDW(phys_addr); 295 + mbox_cmd[4] = ha->fw_dump_tmplt_size; 296 + mbox_cmd[5] = 0; 297 + 298 + status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 2, &mbox_cmd[0], 299 + &mbox_sts[0]); 300 + if (status != QLA_SUCCESS) { 301 + DEBUG2(ql4_printk(KERN_INFO, ha, 302 + "scsi%ld: %s: Cmd = %08X, mbx[0] = 0x%04x, mbx[1] = 0x%04x\n", 303 + ha->host_no, __func__, mbox_cmd[0], 304 + mbox_sts[0], mbox_sts[1])); 305 + } 306 + return status; 307 + } 308 + 309 + /** 310 + * qla4xxx_req_template_size - Get minidump template size from firmware. 311 + * @ha: Pointer to host adapter structure. 312 + **/ 313 + int qla4xxx_req_template_size(struct scsi_qla_host *ha) 314 + { 315 + uint32_t mbox_cmd[MBOX_REG_COUNT]; 316 + uint32_t mbox_sts[MBOX_REG_COUNT]; 317 + int status; 318 + 319 + memset(&mbox_cmd, 0, sizeof(mbox_cmd)); 320 + memset(&mbox_sts, 0, sizeof(mbox_sts)); 321 + 322 + mbox_cmd[0] = MBOX_CMD_MINIDUMP; 323 + mbox_cmd[1] = MINIDUMP_GET_SIZE_SUBCOMMAND; 324 + 325 + status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 8, &mbox_cmd[0], 326 + &mbox_sts[0]); 327 + if (status == QLA_SUCCESS) { 328 + ha->fw_dump_tmplt_size = mbox_sts[1]; 329 + DEBUG2(ql4_printk(KERN_INFO, ha, 330 + "%s: sts[0]=0x%04x, template size=0x%04x, size_cm_02=0x%04x, size_cm_04=0x%04x, size_cm_08=0x%04x, size_cm_10=0x%04x, size_cm_FF=0x%04x, version=0x%04x\n", 331 + __func__, mbox_sts[0], mbox_sts[1], 332 + mbox_sts[2], mbox_sts[3], mbox_sts[4], 333 + mbox_sts[5], mbox_sts[6], mbox_sts[7])); 334 + if (ha->fw_dump_tmplt_size == 0) 335 + status = QLA_ERROR; 336 + } else { 337 + ql4_printk(KERN_WARNING, ha, 338 + "%s: Error sts[0]=0x%04x, mbx[1]=0x%04x\n", 339 + __func__, mbox_sts[0], mbox_sts[1]); 340 + status = QLA_ERROR; 341 + } 269 342 270 343 return status; 271 344 }
+722 -16
drivers/scsi/qla4xxx/ql4_nx.c
··· 7 7 #include <linux/delay.h> 8 8 #include <linux/io.h> 9 9 #include <linux/pci.h> 10 + #include <linux/ratelimit.h> 10 11 #include "ql4_def.h" 11 12 #include "ql4_glbl.h" 12 13 ··· 419 418 write_unlock_irqrestore(&ha->hw_lock, flags); 420 419 } 421 420 return data; 421 + } 422 + 423 + /* Minidump related functions */ 424 + static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off, 425 + u32 data, uint8_t flag) 426 + { 427 + uint32_t win_read, off_value, rval = QLA_SUCCESS; 428 + 429 + off_value = off & 0xFFFF0000; 430 + writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase)); 431 + 432 + /* Read back value to make sure write has gone through before trying 433 + * to use it. 434 + */ 435 + win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase)); 436 + if (win_read != off_value) { 437 + DEBUG2(ql4_printk(KERN_INFO, ha, 438 + "%s: Written (0x%x) != Read (0x%x), off=0x%x\n", 439 + __func__, off_value, win_read, off)); 440 + return QLA_ERROR; 441 + } 442 + 443 + off_value = off & 0x0000FFFF; 444 + 445 + if (flag) 446 + writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M + 447 + ha->nx_pcibase)); 448 + else 449 + rval = readl((void __iomem *)(off_value + CRB_INDIRECT_2M + 450 + ha->nx_pcibase)); 451 + 452 + return rval; 422 453 } 423 454 424 455 #define CRB_WIN_LOCK_TIMEOUT 100000000 ··· 1285 1252 } 1286 1253 1287 1254 if (j >= MAX_CTL_CHECK) { 1288 - if (printk_ratelimit()) 1289 - ql4_printk(KERN_ERR, ha, 1290 - "failed to read through agent\n"); 1255 + printk_ratelimited(KERN_ERR 1256 + "%s: failed to read through agent\n", 1257 + __func__); 1291 1258 break; 1292 1259 } 1293 1260 ··· 1423 1390 if (j >= MAX_CTL_CHECK) { 1424 1391 if (printk_ratelimit()) 1425 1392 ql4_printk(KERN_ERR, ha, 1426 - "failed to write through agent\n"); 1393 + "%s: failed to read through agent\n", 1394 + __func__); 1427 1395 ret = -1; 1428 1396 break; 1429 1397 } ··· 1496 1462 1497 1463 drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 1498 1464 drv_active |= (1 << (ha->func_num * 4)); 1465 + ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", 1466 + __func__, ha->host_no, drv_active); 1499 1467 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); 1500 1468 } 1501 1469 ··· 1508 1472 1509 1473 drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 1510 1474 drv_active &= ~(1 << (ha->func_num * 4)); 1475 + ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n", 1476 + __func__, ha->host_no, drv_active); 1511 1477 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active); 1512 1478 } 1513 1479 ··· 1535 1497 1536 1498 drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE); 1537 1499 drv_state |= (1 << (ha->func_num * 4)); 1500 + ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", 1501 + __func__, ha->host_no, drv_state); 1538 1502 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state); 1539 1503 } 1540 1504 ··· 1547 1507 1548 1508 drv_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_STATE); 1549 1509 drv_state &= ~(1 << (ha->func_num * 4)); 1510 + ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n", 1511 + __func__, ha->host_no, drv_state); 1550 1512 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state); 1551 1513 } 1552 1514 ··· 1643 1601 qla4_8xxx_rom_unlock(ha); 1644 1602 } 1645 1603 1604 + static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha, 1605 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1606 + uint32_t **d_ptr) 1607 + { 1608 + uint32_t r_addr, r_stride, loop_cnt, i, r_value; 1609 + struct qla82xx_minidump_entry_crb *crb_hdr; 1610 + uint32_t *data_ptr = *d_ptr; 1611 + 1612 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1613 + crb_hdr = (struct qla82xx_minidump_entry_crb *)entry_hdr; 1614 + r_addr = crb_hdr->addr; 1615 + r_stride = crb_hdr->crb_strd.addr_stride; 1616 + loop_cnt = crb_hdr->op_count; 1617 + 1618 + for (i = 0; i < loop_cnt; i++) { 1619 + r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); 1620 + *data_ptr++ = cpu_to_le32(r_addr); 1621 + *data_ptr++ = cpu_to_le32(r_value); 1622 + r_addr += r_stride; 1623 + } 1624 + *d_ptr = data_ptr; 1625 + } 1626 + 1627 + static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha, 1628 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1629 + uint32_t **d_ptr) 1630 + { 1631 + uint32_t addr, r_addr, c_addr, t_r_addr; 1632 + uint32_t i, k, loop_count, t_value, r_cnt, r_value; 1633 + unsigned long p_wait, w_time, p_mask; 1634 + uint32_t c_value_w, c_value_r; 1635 + struct qla82xx_minidump_entry_cache *cache_hdr; 1636 + int rval = QLA_ERROR; 1637 + uint32_t *data_ptr = *d_ptr; 1638 + 1639 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1640 + cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr; 1641 + 1642 + loop_count = cache_hdr->op_count; 1643 + r_addr = cache_hdr->read_addr; 1644 + c_addr = cache_hdr->control_addr; 1645 + c_value_w = cache_hdr->cache_ctrl.write_value; 1646 + 1647 + t_r_addr = cache_hdr->tag_reg_addr; 1648 + t_value = cache_hdr->addr_ctrl.init_tag_value; 1649 + r_cnt = cache_hdr->read_ctrl.read_addr_cnt; 1650 + p_wait = cache_hdr->cache_ctrl.poll_wait; 1651 + p_mask = cache_hdr->cache_ctrl.poll_mask; 1652 + 1653 + for (i = 0; i < loop_count; i++) { 1654 + qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1); 1655 + 1656 + if (c_value_w) 1657 + qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1); 1658 + 1659 + if (p_mask) { 1660 + w_time = jiffies + p_wait; 1661 + do { 1662 + c_value_r = qla4_8xxx_md_rw_32(ha, c_addr, 1663 + 0, 0); 1664 + if ((c_value_r & p_mask) == 0) { 1665 + break; 1666 + } else if (time_after_eq(jiffies, w_time)) { 1667 + /* capturing dump failed */ 1668 + return rval; 1669 + } 1670 + } while (1); 1671 + } 1672 + 1673 + addr = r_addr; 1674 + for (k = 0; k < r_cnt; k++) { 1675 + r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); 1676 + *data_ptr++ = cpu_to_le32(r_value); 1677 + addr += cache_hdr->read_ctrl.read_addr_stride; 1678 + } 1679 + 1680 + t_value += cache_hdr->addr_ctrl.tag_value_stride; 1681 + } 1682 + *d_ptr = data_ptr; 1683 + return QLA_SUCCESS; 1684 + } 1685 + 1686 + static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha, 1687 + struct qla82xx_minidump_entry_hdr *entry_hdr) 1688 + { 1689 + struct qla82xx_minidump_entry_crb *crb_entry; 1690 + uint32_t read_value, opcode, poll_time, addr, index, rval = QLA_SUCCESS; 1691 + uint32_t crb_addr; 1692 + unsigned long wtime; 1693 + struct qla4_8xxx_minidump_template_hdr *tmplt_hdr; 1694 + int i; 1695 + 1696 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1697 + tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *) 1698 + ha->fw_dump_tmplt_hdr; 1699 + crb_entry = (struct qla82xx_minidump_entry_crb *)entry_hdr; 1700 + 1701 + crb_addr = crb_entry->addr; 1702 + for (i = 0; i < crb_entry->op_count; i++) { 1703 + opcode = crb_entry->crb_ctrl.opcode; 1704 + if (opcode & QLA82XX_DBG_OPCODE_WR) { 1705 + qla4_8xxx_md_rw_32(ha, crb_addr, 1706 + crb_entry->value_1, 1); 1707 + opcode &= ~QLA82XX_DBG_OPCODE_WR; 1708 + } 1709 + if (opcode & QLA82XX_DBG_OPCODE_RW) { 1710 + read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); 1711 + qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); 1712 + opcode &= ~QLA82XX_DBG_OPCODE_RW; 1713 + } 1714 + if (opcode & QLA82XX_DBG_OPCODE_AND) { 1715 + read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); 1716 + read_value &= crb_entry->value_2; 1717 + opcode &= ~QLA82XX_DBG_OPCODE_AND; 1718 + if (opcode & QLA82XX_DBG_OPCODE_OR) { 1719 + read_value |= crb_entry->value_3; 1720 + opcode &= ~QLA82XX_DBG_OPCODE_OR; 1721 + } 1722 + qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); 1723 + } 1724 + if (opcode & QLA82XX_DBG_OPCODE_OR) { 1725 + read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); 1726 + read_value |= crb_entry->value_3; 1727 + qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1); 1728 + opcode &= ~QLA82XX_DBG_OPCODE_OR; 1729 + } 1730 + if (opcode & QLA82XX_DBG_OPCODE_POLL) { 1731 + poll_time = crb_entry->crb_strd.poll_timeout; 1732 + wtime = jiffies + poll_time; 1733 + read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0); 1734 + 1735 + do { 1736 + if ((read_value & crb_entry->value_2) == 1737 + crb_entry->value_1) 1738 + break; 1739 + else if (time_after_eq(jiffies, wtime)) { 1740 + /* capturing dump failed */ 1741 + rval = QLA_ERROR; 1742 + break; 1743 + } else 1744 + read_value = qla4_8xxx_md_rw_32(ha, 1745 + crb_addr, 0, 0); 1746 + } while (1); 1747 + opcode &= ~QLA82XX_DBG_OPCODE_POLL; 1748 + } 1749 + 1750 + if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) { 1751 + if (crb_entry->crb_strd.state_index_a) { 1752 + index = crb_entry->crb_strd.state_index_a; 1753 + addr = tmplt_hdr->saved_state_array[index]; 1754 + } else { 1755 + addr = crb_addr; 1756 + } 1757 + 1758 + read_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); 1759 + index = crb_entry->crb_ctrl.state_index_v; 1760 + tmplt_hdr->saved_state_array[index] = read_value; 1761 + opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE; 1762 + } 1763 + 1764 + if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) { 1765 + if (crb_entry->crb_strd.state_index_a) { 1766 + index = crb_entry->crb_strd.state_index_a; 1767 + addr = tmplt_hdr->saved_state_array[index]; 1768 + } else { 1769 + addr = crb_addr; 1770 + } 1771 + 1772 + if (crb_entry->crb_ctrl.state_index_v) { 1773 + index = crb_entry->crb_ctrl.state_index_v; 1774 + read_value = 1775 + tmplt_hdr->saved_state_array[index]; 1776 + } else { 1777 + read_value = crb_entry->value_1; 1778 + } 1779 + 1780 + qla4_8xxx_md_rw_32(ha, addr, read_value, 1); 1781 + opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE; 1782 + } 1783 + 1784 + if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) { 1785 + index = crb_entry->crb_ctrl.state_index_v; 1786 + read_value = tmplt_hdr->saved_state_array[index]; 1787 + read_value <<= crb_entry->crb_ctrl.shl; 1788 + read_value >>= crb_entry->crb_ctrl.shr; 1789 + if (crb_entry->value_2) 1790 + read_value &= crb_entry->value_2; 1791 + read_value |= crb_entry->value_3; 1792 + read_value += crb_entry->value_1; 1793 + tmplt_hdr->saved_state_array[index] = read_value; 1794 + opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE; 1795 + } 1796 + crb_addr += crb_entry->crb_strd.addr_stride; 1797 + } 1798 + DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s\n", __func__)); 1799 + return rval; 1800 + } 1801 + 1802 + static void qla4_8xxx_minidump_process_rdocm(struct scsi_qla_host *ha, 1803 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1804 + uint32_t **d_ptr) 1805 + { 1806 + uint32_t r_addr, r_stride, loop_cnt, i, r_value; 1807 + struct qla82xx_minidump_entry_rdocm *ocm_hdr; 1808 + uint32_t *data_ptr = *d_ptr; 1809 + 1810 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1811 + ocm_hdr = (struct qla82xx_minidump_entry_rdocm *)entry_hdr; 1812 + r_addr = ocm_hdr->read_addr; 1813 + r_stride = ocm_hdr->read_addr_stride; 1814 + loop_cnt = ocm_hdr->op_count; 1815 + 1816 + DEBUG2(ql4_printk(KERN_INFO, ha, 1817 + "[%s]: r_addr: 0x%x, r_stride: 0x%x, loop_cnt: 0x%x\n", 1818 + __func__, r_addr, r_stride, loop_cnt)); 1819 + 1820 + for (i = 0; i < loop_cnt; i++) { 1821 + r_value = readl((void __iomem *)(r_addr + ha->nx_pcibase)); 1822 + *data_ptr++ = cpu_to_le32(r_value); 1823 + r_addr += r_stride; 1824 + } 1825 + DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%lx\n", 1826 + __func__, (loop_cnt * sizeof(uint32_t)))); 1827 + *d_ptr = data_ptr; 1828 + } 1829 + 1830 + static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha, 1831 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1832 + uint32_t **d_ptr) 1833 + { 1834 + uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value; 1835 + struct qla82xx_minidump_entry_mux *mux_hdr; 1836 + uint32_t *data_ptr = *d_ptr; 1837 + 1838 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1839 + mux_hdr = (struct qla82xx_minidump_entry_mux *)entry_hdr; 1840 + r_addr = mux_hdr->read_addr; 1841 + s_addr = mux_hdr->select_addr; 1842 + s_stride = mux_hdr->select_value_stride; 1843 + s_value = mux_hdr->select_value; 1844 + loop_cnt = mux_hdr->op_count; 1845 + 1846 + for (i = 0; i < loop_cnt; i++) { 1847 + qla4_8xxx_md_rw_32(ha, s_addr, s_value, 1); 1848 + r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); 1849 + *data_ptr++ = cpu_to_le32(s_value); 1850 + *data_ptr++ = cpu_to_le32(r_value); 1851 + s_value += s_stride; 1852 + } 1853 + *d_ptr = data_ptr; 1854 + } 1855 + 1856 + static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha, 1857 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1858 + uint32_t **d_ptr) 1859 + { 1860 + uint32_t addr, r_addr, c_addr, t_r_addr; 1861 + uint32_t i, k, loop_count, t_value, r_cnt, r_value; 1862 + uint32_t c_value_w; 1863 + struct qla82xx_minidump_entry_cache *cache_hdr; 1864 + uint32_t *data_ptr = *d_ptr; 1865 + 1866 + cache_hdr = (struct qla82xx_minidump_entry_cache *)entry_hdr; 1867 + loop_count = cache_hdr->op_count; 1868 + r_addr = cache_hdr->read_addr; 1869 + c_addr = cache_hdr->control_addr; 1870 + c_value_w = cache_hdr->cache_ctrl.write_value; 1871 + 1872 + t_r_addr = cache_hdr->tag_reg_addr; 1873 + t_value = cache_hdr->addr_ctrl.init_tag_value; 1874 + r_cnt = cache_hdr->read_ctrl.read_addr_cnt; 1875 + 1876 + for (i = 0; i < loop_count; i++) { 1877 + qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1); 1878 + qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1); 1879 + addr = r_addr; 1880 + for (k = 0; k < r_cnt; k++) { 1881 + r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0); 1882 + *data_ptr++ = cpu_to_le32(r_value); 1883 + addr += cache_hdr->read_ctrl.read_addr_stride; 1884 + } 1885 + t_value += cache_hdr->addr_ctrl.tag_value_stride; 1886 + } 1887 + *d_ptr = data_ptr; 1888 + } 1889 + 1890 + static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha, 1891 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1892 + uint32_t **d_ptr) 1893 + { 1894 + uint32_t s_addr, r_addr; 1895 + uint32_t r_stride, r_value, r_cnt, qid = 0; 1896 + uint32_t i, k, loop_cnt; 1897 + struct qla82xx_minidump_entry_queue *q_hdr; 1898 + uint32_t *data_ptr = *d_ptr; 1899 + 1900 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1901 + q_hdr = (struct qla82xx_minidump_entry_queue *)entry_hdr; 1902 + s_addr = q_hdr->select_addr; 1903 + r_cnt = q_hdr->rd_strd.read_addr_cnt; 1904 + r_stride = q_hdr->rd_strd.read_addr_stride; 1905 + loop_cnt = q_hdr->op_count; 1906 + 1907 + for (i = 0; i < loop_cnt; i++) { 1908 + qla4_8xxx_md_rw_32(ha, s_addr, qid, 1); 1909 + r_addr = q_hdr->read_addr; 1910 + for (k = 0; k < r_cnt; k++) { 1911 + r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0); 1912 + *data_ptr++ = cpu_to_le32(r_value); 1913 + r_addr += r_stride; 1914 + } 1915 + qid += q_hdr->q_strd.queue_id_stride; 1916 + } 1917 + *d_ptr = data_ptr; 1918 + } 1919 + 1920 + #define MD_DIRECT_ROM_WINDOW 0x42110030 1921 + #define MD_DIRECT_ROM_READ_BASE 0x42150000 1922 + 1923 + static void qla4_8xxx_minidump_process_rdrom(struct scsi_qla_host *ha, 1924 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1925 + uint32_t **d_ptr) 1926 + { 1927 + uint32_t r_addr, r_value; 1928 + uint32_t i, loop_cnt; 1929 + struct qla82xx_minidump_entry_rdrom *rom_hdr; 1930 + uint32_t *data_ptr = *d_ptr; 1931 + 1932 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1933 + rom_hdr = (struct qla82xx_minidump_entry_rdrom *)entry_hdr; 1934 + r_addr = rom_hdr->read_addr; 1935 + loop_cnt = rom_hdr->read_data_size/sizeof(uint32_t); 1936 + 1937 + DEBUG2(ql4_printk(KERN_INFO, ha, 1938 + "[%s]: flash_addr: 0x%x, read_data_size: 0x%x\n", 1939 + __func__, r_addr, loop_cnt)); 1940 + 1941 + for (i = 0; i < loop_cnt; i++) { 1942 + qla4_8xxx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW, 1943 + (r_addr & 0xFFFF0000), 1); 1944 + r_value = qla4_8xxx_md_rw_32(ha, 1945 + MD_DIRECT_ROM_READ_BASE + 1946 + (r_addr & 0x0000FFFF), 0, 0); 1947 + *data_ptr++ = cpu_to_le32(r_value); 1948 + r_addr += sizeof(uint32_t); 1949 + } 1950 + *d_ptr = data_ptr; 1951 + } 1952 + 1953 + #define MD_MIU_TEST_AGT_CTRL 0x41000090 1954 + #define MD_MIU_TEST_AGT_ADDR_LO 0x41000094 1955 + #define MD_MIU_TEST_AGT_ADDR_HI 0x41000098 1956 + 1957 + static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha, 1958 + struct qla82xx_minidump_entry_hdr *entry_hdr, 1959 + uint32_t **d_ptr) 1960 + { 1961 + uint32_t r_addr, r_value, r_data; 1962 + uint32_t i, j, loop_cnt; 1963 + struct qla82xx_minidump_entry_rdmem *m_hdr; 1964 + unsigned long flags; 1965 + uint32_t *data_ptr = *d_ptr; 1966 + 1967 + DEBUG2(ql4_printk(KERN_INFO, ha, "Entering fn: %s\n", __func__)); 1968 + m_hdr = (struct qla82xx_minidump_entry_rdmem *)entry_hdr; 1969 + r_addr = m_hdr->read_addr; 1970 + loop_cnt = m_hdr->read_data_size/16; 1971 + 1972 + DEBUG2(ql4_printk(KERN_INFO, ha, 1973 + "[%s]: Read addr: 0x%x, read_data_size: 0x%x\n", 1974 + __func__, r_addr, m_hdr->read_data_size)); 1975 + 1976 + if (r_addr & 0xf) { 1977 + DEBUG2(ql4_printk(KERN_INFO, ha, 1978 + "[%s]: Read addr 0x%x not 16 bytes alligned\n", 1979 + __func__, r_addr)); 1980 + return QLA_ERROR; 1981 + } 1982 + 1983 + if (m_hdr->read_data_size % 16) { 1984 + DEBUG2(ql4_printk(KERN_INFO, ha, 1985 + "[%s]: Read data[0x%x] not multiple of 16 bytes\n", 1986 + __func__, m_hdr->read_data_size)); 1987 + return QLA_ERROR; 1988 + } 1989 + 1990 + DEBUG2(ql4_printk(KERN_INFO, ha, 1991 + "[%s]: rdmem_addr: 0x%x, read_data_size: 0x%x, loop_cnt: 0x%x\n", 1992 + __func__, r_addr, m_hdr->read_data_size, loop_cnt)); 1993 + 1994 + write_lock_irqsave(&ha->hw_lock, flags); 1995 + for (i = 0; i < loop_cnt; i++) { 1996 + qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1); 1997 + r_value = 0; 1998 + qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1); 1999 + r_value = MIU_TA_CTL_ENABLE; 2000 + qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1); 2001 + r_value = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE; 2002 + qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1); 2003 + 2004 + for (j = 0; j < MAX_CTL_CHECK; j++) { 2005 + r_value = qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, 2006 + 0, 0); 2007 + if ((r_value & MIU_TA_CTL_BUSY) == 0) 2008 + break; 2009 + } 2010 + 2011 + if (j >= MAX_CTL_CHECK) { 2012 + printk_ratelimited(KERN_ERR 2013 + "%s: failed to read through agent\n", 2014 + __func__); 2015 + write_unlock_irqrestore(&ha->hw_lock, flags); 2016 + return QLA_SUCCESS; 2017 + } 2018 + 2019 + for (j = 0; j < 4; j++) { 2020 + r_data = qla4_8xxx_md_rw_32(ha, 2021 + MD_MIU_TEST_AGT_RDDATA[j], 2022 + 0, 0); 2023 + *data_ptr++ = cpu_to_le32(r_data); 2024 + } 2025 + 2026 + r_addr += 16; 2027 + } 2028 + write_unlock_irqrestore(&ha->hw_lock, flags); 2029 + 2030 + DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s datacount: 0x%x\n", 2031 + __func__, (loop_cnt * 16))); 2032 + 2033 + *d_ptr = data_ptr; 2034 + return QLA_SUCCESS; 2035 + } 2036 + 2037 + static void ql4_8xxx_mark_entry_skipped(struct scsi_qla_host *ha, 2038 + struct qla82xx_minidump_entry_hdr *entry_hdr, 2039 + int index) 2040 + { 2041 + entry_hdr->d_ctrl.driver_flags |= QLA82XX_DBG_SKIPPED_FLAG; 2042 + DEBUG2(ql4_printk(KERN_INFO, ha, 2043 + "scsi(%ld): Skipping entry[%d]: ETYPE[0x%x]-ELEVEL[0x%x]\n", 2044 + ha->host_no, index, entry_hdr->entry_type, 2045 + entry_hdr->d_ctrl.entry_capture_mask)); 2046 + } 2047 + 2048 + /** 2049 + * qla82xx_collect_md_data - Retrieve firmware minidump data. 2050 + * @ha: pointer to adapter structure 2051 + **/ 2052 + static int qla4_8xxx_collect_md_data(struct scsi_qla_host *ha) 2053 + { 2054 + int num_entry_hdr = 0; 2055 + struct qla82xx_minidump_entry_hdr *entry_hdr; 2056 + struct qla4_8xxx_minidump_template_hdr *tmplt_hdr; 2057 + uint32_t *data_ptr; 2058 + uint32_t data_collected = 0; 2059 + int i, rval = QLA_ERROR; 2060 + uint64_t now; 2061 + uint32_t timestamp; 2062 + 2063 + if (!ha->fw_dump) { 2064 + ql4_printk(KERN_INFO, ha, "%s(%ld) No buffer to dump\n", 2065 + __func__, ha->host_no); 2066 + return rval; 2067 + } 2068 + 2069 + tmplt_hdr = (struct qla4_8xxx_minidump_template_hdr *) 2070 + ha->fw_dump_tmplt_hdr; 2071 + data_ptr = (uint32_t *)((uint8_t *)ha->fw_dump + 2072 + ha->fw_dump_tmplt_size); 2073 + data_collected += ha->fw_dump_tmplt_size; 2074 + 2075 + num_entry_hdr = tmplt_hdr->num_of_entries; 2076 + ql4_printk(KERN_INFO, ha, "[%s]: starting data ptr: %p\n", 2077 + __func__, data_ptr); 2078 + ql4_printk(KERN_INFO, ha, 2079 + "[%s]: no of entry headers in Template: 0x%x\n", 2080 + __func__, num_entry_hdr); 2081 + ql4_printk(KERN_INFO, ha, "[%s]: Capture Mask obtained: 0x%x\n", 2082 + __func__, ha->fw_dump_capture_mask); 2083 + ql4_printk(KERN_INFO, ha, "[%s]: Total_data_size 0x%x, %d obtained\n", 2084 + __func__, ha->fw_dump_size, ha->fw_dump_size); 2085 + 2086 + /* Update current timestamp before taking dump */ 2087 + now = get_jiffies_64(); 2088 + timestamp = (u32)(jiffies_to_msecs(now) / 1000); 2089 + tmplt_hdr->driver_timestamp = timestamp; 2090 + 2091 + entry_hdr = (struct qla82xx_minidump_entry_hdr *) 2092 + (((uint8_t *)ha->fw_dump_tmplt_hdr) + 2093 + tmplt_hdr->first_entry_offset); 2094 + 2095 + /* Walk through the entry headers - validate/perform required action */ 2096 + for (i = 0; i < num_entry_hdr; i++) { 2097 + if (data_collected >= ha->fw_dump_size) { 2098 + ql4_printk(KERN_INFO, ha, 2099 + "Data collected: [0x%x], Total Dump size: [0x%x]\n", 2100 + data_collected, ha->fw_dump_size); 2101 + return rval; 2102 + } 2103 + 2104 + if (!(entry_hdr->d_ctrl.entry_capture_mask & 2105 + ha->fw_dump_capture_mask)) { 2106 + entry_hdr->d_ctrl.driver_flags |= 2107 + QLA82XX_DBG_SKIPPED_FLAG; 2108 + goto skip_nxt_entry; 2109 + } 2110 + 2111 + DEBUG2(ql4_printk(KERN_INFO, ha, 2112 + "Data collected: [0x%x], Dump size left:[0x%x]\n", 2113 + data_collected, 2114 + (ha->fw_dump_size - data_collected))); 2115 + 2116 + /* Decode the entry type and take required action to capture 2117 + * debug data 2118 + */ 2119 + switch (entry_hdr->entry_type) { 2120 + case QLA82XX_RDEND: 2121 + ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2122 + break; 2123 + case QLA82XX_CNTRL: 2124 + rval = qla4_8xxx_minidump_process_control(ha, 2125 + entry_hdr); 2126 + if (rval != QLA_SUCCESS) { 2127 + ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2128 + goto md_failed; 2129 + } 2130 + break; 2131 + case QLA82XX_RDCRB: 2132 + qla4_8xxx_minidump_process_rdcrb(ha, entry_hdr, 2133 + &data_ptr); 2134 + break; 2135 + case QLA82XX_RDMEM: 2136 + rval = qla4_8xxx_minidump_process_rdmem(ha, entry_hdr, 2137 + &data_ptr); 2138 + if (rval != QLA_SUCCESS) { 2139 + ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2140 + goto md_failed; 2141 + } 2142 + break; 2143 + case QLA82XX_BOARD: 2144 + case QLA82XX_RDROM: 2145 + qla4_8xxx_minidump_process_rdrom(ha, entry_hdr, 2146 + &data_ptr); 2147 + break; 2148 + case QLA82XX_L2DTG: 2149 + case QLA82XX_L2ITG: 2150 + case QLA82XX_L2DAT: 2151 + case QLA82XX_L2INS: 2152 + rval = qla4_8xxx_minidump_process_l2tag(ha, entry_hdr, 2153 + &data_ptr); 2154 + if (rval != QLA_SUCCESS) { 2155 + ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2156 + goto md_failed; 2157 + } 2158 + break; 2159 + case QLA82XX_L1DAT: 2160 + case QLA82XX_L1INS: 2161 + qla4_8xxx_minidump_process_l1cache(ha, entry_hdr, 2162 + &data_ptr); 2163 + break; 2164 + case QLA82XX_RDOCM: 2165 + qla4_8xxx_minidump_process_rdocm(ha, entry_hdr, 2166 + &data_ptr); 2167 + break; 2168 + case QLA82XX_RDMUX: 2169 + qla4_8xxx_minidump_process_rdmux(ha, entry_hdr, 2170 + &data_ptr); 2171 + break; 2172 + case QLA82XX_QUEUE: 2173 + qla4_8xxx_minidump_process_queue(ha, entry_hdr, 2174 + &data_ptr); 2175 + break; 2176 + case QLA82XX_RDNOP: 2177 + default: 2178 + ql4_8xxx_mark_entry_skipped(ha, entry_hdr, i); 2179 + break; 2180 + } 2181 + 2182 + data_collected = (uint8_t *)data_ptr - 2183 + ((uint8_t *)((uint8_t *)ha->fw_dump + 2184 + ha->fw_dump_tmplt_size)); 2185 + skip_nxt_entry: 2186 + /* next entry in the template */ 2187 + entry_hdr = (struct qla82xx_minidump_entry_hdr *) 2188 + (((uint8_t *)entry_hdr) + 2189 + entry_hdr->entry_size); 2190 + } 2191 + 2192 + if ((data_collected + ha->fw_dump_tmplt_size) != ha->fw_dump_size) { 2193 + ql4_printk(KERN_INFO, ha, 2194 + "Dump data mismatch: Data collected: [0x%x], total_data_size:[0x%x]\n", 2195 + data_collected, ha->fw_dump_size); 2196 + goto md_failed; 2197 + } 2198 + 2199 + DEBUG2(ql4_printk(KERN_INFO, ha, "Leaving fn: %s Last entry: 0x%x\n", 2200 + __func__, i)); 2201 + md_failed: 2202 + return rval; 2203 + } 2204 + 2205 + /** 2206 + * qla4_8xxx_uevent_emit - Send uevent when the firmware dump is ready. 2207 + * @ha: pointer to adapter structure 2208 + **/ 2209 + static void qla4_8xxx_uevent_emit(struct scsi_qla_host *ha, u32 code) 2210 + { 2211 + char event_string[40]; 2212 + char *envp[] = { event_string, NULL }; 2213 + 2214 + switch (code) { 2215 + case QL4_UEVENT_CODE_FW_DUMP: 2216 + snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", 2217 + ha->host_no); 2218 + break; 2219 + default: 2220 + /*do nothing*/ 2221 + break; 2222 + } 2223 + 2224 + kobject_uevent_env(&(&ha->pdev->dev)->kobj, KOBJ_CHANGE, envp); 2225 + } 2226 + 1646 2227 /** 1647 2228 * qla4_8xxx_device_bootstrap - Initialize device, set DEV_READY, start fw 1648 2229 * @ha: pointer to adapter structure ··· 2324 1659 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION); 2325 1660 2326 1661 qla4_8xxx_idc_unlock(ha); 1662 + if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) && 1663 + !test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) { 1664 + if (!qla4_8xxx_collect_md_data(ha)) { 1665 + qla4_8xxx_uevent_emit(ha, QL4_UEVENT_CODE_FW_DUMP); 1666 + } else { 1667 + ql4_printk(KERN_INFO, ha, "Unable to collect minidump\n"); 1668 + clear_bit(AF_82XX_FW_DUMPED, &ha->flags); 1669 + } 1670 + } 2327 1671 rval = qla4_8xxx_try_start_fw(ha); 2328 1672 qla4_8xxx_idc_lock(ha); 2329 1673 ··· 2360 1686 qla4_8xxx_need_reset_handler(struct scsi_qla_host *ha) 2361 1687 { 2362 1688 uint32_t dev_state, drv_state, drv_active; 1689 + uint32_t active_mask = 0xFFFFFFFF; 2363 1690 unsigned long reset_timeout; 2364 1691 2365 1692 ql4_printk(KERN_INFO, ha, ··· 2372 1697 qla4_8xxx_idc_lock(ha); 2373 1698 } 2374 1699 2375 - qla4_8xxx_set_rst_ready(ha); 1700 + if (!test_bit(AF_82XX_RST_OWNER, &ha->flags)) { 1701 + DEBUG2(ql4_printk(KERN_INFO, ha, 1702 + "%s(%ld): reset acknowledged\n", 1703 + __func__, ha->host_no)); 1704 + qla4_8xxx_set_rst_ready(ha); 1705 + } else { 1706 + active_mask = (~(1 << (ha->func_num * 4))); 1707 + } 2376 1708 2377 1709 /* wait for 10 seconds for reset ack from all functions */ 2378 1710 reset_timeout = jiffies + (ha->nx_reset_timeout * HZ); ··· 2391 1709 "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n", 2392 1710 __func__, ha->host_no, drv_state, drv_active); 2393 1711 2394 - while (drv_state != drv_active) { 1712 + while (drv_state != (drv_active & active_mask)) { 2395 1713 if (time_after_eq(jiffies, reset_timeout)) { 2396 - printk("%s: RESET TIMEOUT!\n", DRIVER_NAME); 1714 + ql4_printk(KERN_INFO, ha, 1715 + "%s: RESET TIMEOUT! drv_state: 0x%08x, drv_active: 0x%08x\n", 1716 + DRIVER_NAME, drv_state, drv_active); 2397 1717 break; 2398 1718 } 2399 1719 1720 + /* 1721 + * When reset_owner times out, check which functions 1722 + * acked/did not ack 1723 + */ 1724 + if (test_bit(AF_82XX_RST_OWNER, &ha->flags)) { 1725 + ql4_printk(KERN_INFO, ha, 1726 + "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n", 1727 + __func__, ha->host_no, drv_state, 1728 + drv_active); 1729 + } 2400 1730 qla4_8xxx_idc_unlock(ha); 2401 1731 msleep(1000); 2402 1732 qla4_8xxx_idc_lock(ha); ··· 2417 1723 drv_active = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE); 2418 1724 } 2419 1725 1726 + /* Clear RESET OWNER as we are not going to use it any further */ 1727 + clear_bit(AF_82XX_RST_OWNER, &ha->flags); 1728 + 2420 1729 dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 2421 - ql4_printk(KERN_INFO, ha, "3:Device state is 0x%x = %s\n", dev_state, 2422 - dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); 1730 + ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", dev_state, 1731 + dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); 2423 1732 2424 1733 /* Force to DEV_COLD unless someone else is starting a reset */ 2425 1734 if (dev_state != QLA82XX_DEV_INITIALIZING) { 2426 1735 ql4_printk(KERN_INFO, ha, "HW State: COLD/RE-INIT\n"); 2427 1736 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA82XX_DEV_COLD); 1737 + qla4_8xxx_set_rst_ready(ha); 2428 1738 } 2429 1739 } 2430 1740 ··· 2463 1765 } 2464 1766 2465 1767 dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 2466 - ql4_printk(KERN_INFO, ha, "1:Device state is 0x%x = %s\n", dev_state, 2467 - dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); 1768 + DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", 1769 + dev_state, dev_state < MAX_STATES ? 1770 + qdev_state[dev_state] : "Unknown")); 2468 1771 2469 1772 /* wait for 30 seconds for device to go ready */ 2470 1773 dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ); ··· 2474 1775 while (1) { 2475 1776 2476 1777 if (time_after_eq(jiffies, dev_init_timeout)) { 2477 - ql4_printk(KERN_WARNING, ha, "Device init failed!\n"); 1778 + ql4_printk(KERN_WARNING, ha, 1779 + "%s: Device Init Failed 0x%x = %s\n", 1780 + DRIVER_NAME, 1781 + dev_state, dev_state < MAX_STATES ? 1782 + qdev_state[dev_state] : "Unknown"); 2478 1783 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2479 1784 QLA82XX_DEV_FAILED); 2480 1785 } 2481 1786 2482 1787 dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE); 2483 - ql4_printk(KERN_INFO, ha, 2484 - "2:Device state is 0x%x = %s\n", dev_state, 2485 - dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown"); 1788 + ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n", 1789 + dev_state, dev_state < MAX_STATES ? 1790 + qdev_state[dev_state] : "Unknown"); 2486 1791 2487 1792 /* NOTE: Make sure idc unlocked upon exit of switch statement */ 2488 1793 switch (dev_state) { ··· 2887 2184 ql4_printk(KERN_INFO, ha, "HW State: NEED RESET\n"); 2888 2185 qla4_8xxx_wr_32(ha, QLA82XX_CRB_DEV_STATE, 2889 2186 QLA82XX_DEV_NEED_RESET); 2187 + set_bit(AF_82XX_RST_OWNER, &ha->flags); 2890 2188 } else 2891 2189 ql4_printk(KERN_INFO, ha, "HW State: DEVICE INITIALIZING\n"); 2892 2190 ··· 2899 2195 qla4_8xxx_clear_rst_ready(ha); 2900 2196 qla4_8xxx_idc_unlock(ha); 2901 2197 2902 - if (rval == QLA_SUCCESS) 2198 + if (rval == QLA_SUCCESS) { 2199 + ql4_printk(KERN_INFO, ha, "Clearing AF_RECOVERY in qla4_8xxx_isp_reset\n"); 2903 2200 clear_bit(AF_FW_RECOVERY, &ha->flags); 2201 + } 2904 2202 2905 2203 return rval; 2906 2204 }
+192
drivers/scsi/qla4xxx/ql4_nx.h
··· 792 792 #define MIU_TEST_AGT_WRDATA_UPPER_LO (0x0b0) 793 793 #define MIU_TEST_AGT_WRDATA_UPPER_HI (0x0b4) 794 794 795 + /* Minidump related */ 796 + 797 + /* Entry Type Defines */ 798 + #define QLA82XX_RDNOP 0 799 + #define QLA82XX_RDCRB 1 800 + #define QLA82XX_RDMUX 2 801 + #define QLA82XX_QUEUE 3 802 + #define QLA82XX_BOARD 4 803 + #define QLA82XX_RDOCM 6 804 + #define QLA82XX_PREGS 7 805 + #define QLA82XX_L1DTG 8 806 + #define QLA82XX_L1ITG 9 807 + #define QLA82XX_L1DAT 11 808 + #define QLA82XX_L1INS 12 809 + #define QLA82XX_L2DTG 21 810 + #define QLA82XX_L2ITG 22 811 + #define QLA82XX_L2DAT 23 812 + #define QLA82XX_L2INS 24 813 + #define QLA82XX_RDROM 71 814 + #define QLA82XX_RDMEM 72 815 + #define QLA82XX_CNTRL 98 816 + #define QLA82XX_RDEND 255 817 + 818 + /* Opcodes for Control Entries. 819 + * These Flags are bit fields. 820 + */ 821 + #define QLA82XX_DBG_OPCODE_WR 0x01 822 + #define QLA82XX_DBG_OPCODE_RW 0x02 823 + #define QLA82XX_DBG_OPCODE_AND 0x04 824 + #define QLA82XX_DBG_OPCODE_OR 0x08 825 + #define QLA82XX_DBG_OPCODE_POLL 0x10 826 + #define QLA82XX_DBG_OPCODE_RDSTATE 0x20 827 + #define QLA82XX_DBG_OPCODE_WRSTATE 0x40 828 + #define QLA82XX_DBG_OPCODE_MDSTATE 0x80 829 + 830 + /* Driver Flags */ 831 + #define QLA82XX_DBG_SKIPPED_FLAG 0x80 /* driver skipped this entry */ 832 + #define QLA82XX_DBG_SIZE_ERR_FLAG 0x40 /* Entry vs Capture size 833 + * mismatch */ 834 + 835 + /* Driver_code is for driver to write some info about the entry 836 + * currently not used. 837 + */ 838 + struct qla82xx_minidump_entry_hdr { 839 + uint32_t entry_type; 840 + uint32_t entry_size; 841 + uint32_t entry_capture_size; 842 + struct { 843 + uint8_t entry_capture_mask; 844 + uint8_t entry_code; 845 + uint8_t driver_code; 846 + uint8_t driver_flags; 847 + } d_ctrl; 848 + }; 849 + 850 + /* Read CRB entry header */ 851 + struct qla82xx_minidump_entry_crb { 852 + struct qla82xx_minidump_entry_hdr h; 853 + uint32_t addr; 854 + struct { 855 + uint8_t addr_stride; 856 + uint8_t state_index_a; 857 + uint16_t poll_timeout; 858 + } crb_strd; 859 + uint32_t data_size; 860 + uint32_t op_count; 861 + 862 + struct { 863 + uint8_t opcode; 864 + uint8_t state_index_v; 865 + uint8_t shl; 866 + uint8_t shr; 867 + } crb_ctrl; 868 + 869 + uint32_t value_1; 870 + uint32_t value_2; 871 + uint32_t value_3; 872 + }; 873 + 874 + struct qla82xx_minidump_entry_cache { 875 + struct qla82xx_minidump_entry_hdr h; 876 + uint32_t tag_reg_addr; 877 + struct { 878 + uint16_t tag_value_stride; 879 + uint16_t init_tag_value; 880 + } addr_ctrl; 881 + uint32_t data_size; 882 + uint32_t op_count; 883 + uint32_t control_addr; 884 + struct { 885 + uint16_t write_value; 886 + uint8_t poll_mask; 887 + uint8_t poll_wait; 888 + } cache_ctrl; 889 + uint32_t read_addr; 890 + struct { 891 + uint8_t read_addr_stride; 892 + uint8_t read_addr_cnt; 893 + uint16_t rsvd_1; 894 + } read_ctrl; 895 + }; 896 + 897 + /* Read OCM */ 898 + struct qla82xx_minidump_entry_rdocm { 899 + struct qla82xx_minidump_entry_hdr h; 900 + uint32_t rsvd_0; 901 + uint32_t rsvd_1; 902 + uint32_t data_size; 903 + uint32_t op_count; 904 + uint32_t rsvd_2; 905 + uint32_t rsvd_3; 906 + uint32_t read_addr; 907 + uint32_t read_addr_stride; 908 + }; 909 + 910 + /* Read Memory */ 911 + struct qla82xx_minidump_entry_rdmem { 912 + struct qla82xx_minidump_entry_hdr h; 913 + uint32_t rsvd[6]; 914 + uint32_t read_addr; 915 + uint32_t read_data_size; 916 + }; 917 + 918 + /* Read ROM */ 919 + struct qla82xx_minidump_entry_rdrom { 920 + struct qla82xx_minidump_entry_hdr h; 921 + uint32_t rsvd[6]; 922 + uint32_t read_addr; 923 + uint32_t read_data_size; 924 + }; 925 + 926 + /* Mux entry */ 927 + struct qla82xx_minidump_entry_mux { 928 + struct qla82xx_minidump_entry_hdr h; 929 + uint32_t select_addr; 930 + uint32_t rsvd_0; 931 + uint32_t data_size; 932 + uint32_t op_count; 933 + uint32_t select_value; 934 + uint32_t select_value_stride; 935 + uint32_t read_addr; 936 + uint32_t rsvd_1; 937 + }; 938 + 939 + /* Queue entry */ 940 + struct qla82xx_minidump_entry_queue { 941 + struct qla82xx_minidump_entry_hdr h; 942 + uint32_t select_addr; 943 + struct { 944 + uint16_t queue_id_stride; 945 + uint16_t rsvd_0; 946 + } q_strd; 947 + uint32_t data_size; 948 + uint32_t op_count; 949 + uint32_t rsvd_1; 950 + uint32_t rsvd_2; 951 + uint32_t read_addr; 952 + struct { 953 + uint8_t read_addr_stride; 954 + uint8_t read_addr_cnt; 955 + uint16_t rsvd_3; 956 + } rd_strd; 957 + }; 958 + 959 + #define QLA82XX_MINIDUMP_OCM0_SIZE (256 * 1024) 960 + #define QLA82XX_MINIDUMP_L1C_SIZE (256 * 1024) 961 + #define QLA82XX_MINIDUMP_L2C_SIZE 1572864 962 + #define QLA82XX_MINIDUMP_COMMON_STR_SIZE 0 963 + #define QLA82XX_MINIDUMP_FCOE_STR_SIZE 0 964 + #define QLA82XX_MINIDUMP_MEM_SIZE 0 965 + #define QLA82XX_MAX_ENTRY_HDR 4 966 + 967 + struct qla82xx_minidump { 968 + uint32_t md_ocm0_data[QLA82XX_MINIDUMP_OCM0_SIZE]; 969 + uint32_t md_l1c_data[QLA82XX_MINIDUMP_L1C_SIZE]; 970 + uint32_t md_l2c_data[QLA82XX_MINIDUMP_L2C_SIZE]; 971 + uint32_t md_cs_data[QLA82XX_MINIDUMP_COMMON_STR_SIZE]; 972 + uint32_t md_fcoes_data[QLA82XX_MINIDUMP_FCOE_STR_SIZE]; 973 + uint32_t md_mem_data[QLA82XX_MINIDUMP_MEM_SIZE]; 974 + }; 975 + 976 + #define MBC_DIAGNOSTIC_MINIDUMP_TEMPLATE 0x129 977 + #define RQST_TMPLT_SIZE 0x0 978 + #define RQST_TMPLT 0x1 979 + #define MD_DIRECT_ROM_WINDOW 0x42110030 980 + #define MD_DIRECT_ROM_READ_BASE 0x42150000 981 + #define MD_MIU_TEST_AGT_CTRL 0x41000090 982 + #define MD_MIU_TEST_AGT_ADDR_LO 0x41000094 983 + #define MD_MIU_TEST_AGT_ADDR_HI 0x41000098 984 + 985 + static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 986 + 0x410000AC, 0x410000B8, 0x410000BC }; 795 987 #endif
+77 -1
drivers/scsi/qla4xxx/ql4_os.c
··· 68 68 " Maximum queue depth to report for target devices.\n" 69 69 "\t\t Default: 32."); 70 70 71 + static int ql4xqfulltracking = 1; 72 + module_param(ql4xqfulltracking, int, S_IRUGO | S_IWUSR); 73 + MODULE_PARM_DESC(ql4xqfulltracking, 74 + " Enable or disable dynamic tracking and adjustment of\n" 75 + "\t\t scsi device queue depth.\n" 76 + "\t\t 0 - Disable.\n" 77 + "\t\t 1 - Enable. (Default)"); 78 + 71 79 static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO; 72 80 module_param(ql4xsess_recovery_tmo, int, S_IRUGO); 73 81 MODULE_PARM_DESC(ql4xsess_recovery_tmo, 74 82 " Target Session Recovery Timeout.\n" 75 83 "\t\t Default: 120 sec."); 84 + 85 + int ql4xmdcapmask = 0x1F; 86 + module_param(ql4xmdcapmask, int, S_IRUGO); 87 + MODULE_PARM_DESC(ql4xmdcapmask, 88 + " Set the Minidump driver capture mask level.\n" 89 + "\t\t Default is 0x1F.\n" 90 + "\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F"); 91 + 92 + int ql4xenablemd = 1; 93 + module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR); 94 + MODULE_PARM_DESC(ql4xenablemd, 95 + " Set to enable minidump.\n" 96 + "\t\t 0 - disable minidump\n" 97 + "\t\t 1 - enable minidump (Default)"); 76 98 77 99 static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); 78 100 /* ··· 162 140 static void qla4xxx_slave_destroy(struct scsi_device *sdev); 163 141 static umode_t ql4_attr_is_visible(int param_type, int param); 164 142 static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); 143 + static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, 144 + int reason); 165 145 166 146 static struct qla4_8xxx_legacy_intr_set legacy_intr[] = 167 147 QLA82XX_LEGACY_INTR_CONFIG; ··· 183 159 .slave_configure = qla4xxx_slave_configure, 184 160 .slave_alloc = qla4xxx_slave_alloc, 185 161 .slave_destroy = qla4xxx_slave_destroy, 162 + .change_queue_depth = qla4xxx_change_queue_depth, 186 163 187 164 .this_id = -1, 188 165 .cmd_per_lun = 3, ··· 1580 1555 struct iscsi_session *sess; 1581 1556 struct ddb_entry *ddb_entry; 1582 1557 struct scsi_qla_host *ha; 1583 - unsigned long flags; 1558 + unsigned long flags, wtime; 1559 + struct dev_db_entry *fw_ddb_entry = NULL; 1560 + dma_addr_t fw_ddb_entry_dma; 1561 + uint32_t ddb_state; 1562 + int ret; 1584 1563 1585 1564 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); 1586 1565 sess = cls_sess->dd_data; 1587 1566 ddb_entry = sess->dd_data; 1588 1567 ha = ddb_entry->ha; 1589 1568 1569 + fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1570 + &fw_ddb_entry_dma, GFP_KERNEL); 1571 + if (!fw_ddb_entry) { 1572 + ql4_printk(KERN_ERR, ha, 1573 + "%s: Unable to allocate dma buffer\n", __func__); 1574 + goto destroy_session; 1575 + } 1576 + 1577 + wtime = jiffies + (HZ * LOGOUT_TOV); 1578 + do { 1579 + ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, 1580 + fw_ddb_entry, fw_ddb_entry_dma, 1581 + NULL, NULL, &ddb_state, NULL, 1582 + NULL, NULL); 1583 + if (ret == QLA_ERROR) 1584 + goto destroy_session; 1585 + 1586 + if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) || 1587 + (ddb_state == DDB_DS_SESSION_FAILED)) 1588 + goto destroy_session; 1589 + 1590 + schedule_timeout_uninterruptible(HZ); 1591 + } while ((time_after(wtime, jiffies))); 1592 + 1593 + destroy_session: 1590 1594 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); 1591 1595 1592 1596 spin_lock_irqsave(&ha->hardware_lock, flags); 1593 1597 qla4xxx_free_ddb(ha, ddb_entry); 1594 1598 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1599 + 1595 1600 iscsi_session_teardown(cls_sess); 1601 + 1602 + if (fw_ddb_entry) 1603 + dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1604 + fw_ddb_entry, fw_ddb_entry_dma); 1596 1605 } 1597 1606 1598 1607 static struct iscsi_cls_conn * ··· 2279 2220 dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, 2280 2221 ha->queues_dma); 2281 2222 2223 + if (ha->fw_dump) 2224 + vfree(ha->fw_dump); 2225 + 2282 2226 ha->queues_len = 0; 2283 2227 ha->queues = NULL; 2284 2228 ha->queues_dma = 0; ··· 2291 2229 ha->response_dma = 0; 2292 2230 ha->shadow_regs = NULL; 2293 2231 ha->shadow_regs_dma = 0; 2232 + ha->fw_dump = NULL; 2233 + ha->fw_dump_size = 0; 2294 2234 2295 2235 /* Free srb pool. */ 2296 2236 if (ha->srb_mempool) ··· 5087 5023 5088 5024 set_bit(AF_INIT_DONE, &ha->flags); 5089 5025 5026 + qla4_8xxx_alloc_sysfs_attr(ha); 5027 + 5090 5028 printk(KERN_INFO 5091 5029 " QLogic iSCSI HBA Driver version: %s\n" 5092 5030 " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", ··· 5215 5149 iscsi_boot_destroy_kset(ha->boot_kset); 5216 5150 5217 5151 qla4xxx_destroy_fw_ddb_session(ha); 5152 + qla4_8xxx_free_sysfs_attr(ha); 5218 5153 5219 5154 scsi_remove_host(ha->host); 5220 5155 ··· 5282 5215 static void qla4xxx_slave_destroy(struct scsi_device *sdev) 5283 5216 { 5284 5217 scsi_deactivate_tcq(sdev, 1); 5218 + } 5219 + 5220 + static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, 5221 + int reason) 5222 + { 5223 + if (!ql4xqfulltracking) 5224 + return -EOPNOTSUPP; 5225 + 5226 + return iscsi_change_queue_depth(sdev, qdepth, reason); 5285 5227 } 5286 5228 5287 5229 /**
+1 -1
drivers/scsi/qla4xxx/ql4_version.h
··· 5 5 * See LICENSE.qla4xxx for copyright and licensing details. 6 6 */ 7 7 8 - #define QLA4XXX_DRIVER_VERSION "5.02.00-k16" 8 + #define QLA4XXX_DRIVER_VERSION "5.02.00-k17"
+7 -4
drivers/scsi/scsi_lib.c
··· 1378 1378 { 1379 1379 struct scsi_device *sdev = q->queuedata; 1380 1380 struct Scsi_Host *shost; 1381 - struct scsi_target *starget; 1382 1381 1383 1382 if (!sdev) 1384 1383 return 0; 1385 1384 1386 1385 shost = sdev->host; 1387 - starget = scsi_target(sdev); 1388 1386 1389 - if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) || 1390 - scsi_target_is_busy(starget) || scsi_device_is_busy(sdev)) 1387 + /* 1388 + * Ignore host/starget busy state. 1389 + * Since block layer does not have a concept of fairness across 1390 + * multiple queues, congestion of host/starget needs to be handled 1391 + * in SCSI layer. 1392 + */ 1393 + if (scsi_host_in_recovery(shost) || scsi_device_is_busy(sdev)) 1391 1394 return 1; 1392 1395 1393 1396 return 0;
+4 -1
drivers/scsi/scsi_pm.c
··· 24 24 err = scsi_device_quiesce(to_scsi_device(dev)); 25 25 if (err == 0) { 26 26 drv = dev->driver; 27 - if (drv && drv->suspend) 27 + if (drv && drv->suspend) { 28 28 err = drv->suspend(dev, msg); 29 + if (err) 30 + scsi_device_resume(to_scsi_device(dev)); 31 + } 29 32 } 30 33 dev_dbg(dev, "scsi suspend: %d\n", err); 31 34 return err;
+5 -2
drivers/scsi/scsi_scan.c
··· 147 147 148 148 do { 149 149 if (list_empty(&scanning_hosts)) 150 - return 0; 150 + goto out; 151 151 /* If we can't get memory immediately, that's OK. Just 152 152 * sleep a little. Even if we never get memory, the async 153 153 * scans will finish eventually. ··· 179 179 } 180 180 done: 181 181 spin_unlock(&async_scan_lock); 182 - 183 182 kfree(data); 183 + 184 + out: 185 + async_synchronize_full_domain(&scsi_sd_probe_domain); 186 + 184 187 return 0; 185 188 } 186 189
+1 -1
drivers/scsi/scsi_wait_scan.c
··· 12 12 13 13 #include <linux/module.h> 14 14 #include <linux/device.h> 15 - #include <scsi/scsi_scan.h> 15 + #include "scsi_priv.h" 16 16 17 17 static int __init wait_scan_init(void) 18 18 {
+3 -2
drivers/scsi/ufs/ufshcd.c
··· 1836 1836 err = pci_request_regions(pdev, UFSHCD); 1837 1837 if (err < 0) { 1838 1838 dev_err(&pdev->dev, "request regions failed\n"); 1839 - goto out_disable; 1839 + goto out_host_put; 1840 1840 } 1841 1841 1842 1842 hba->mmio_base = pci_ioremap_bar(pdev, 0); ··· 1925 1925 iounmap(hba->mmio_base); 1926 1926 out_release_regions: 1927 1927 pci_release_regions(pdev); 1928 - out_disable: 1928 + out_host_put: 1929 1929 scsi_host_put(host); 1930 + out_disable: 1930 1931 pci_clear_master(pdev); 1931 1932 pci_disable_device(pdev); 1932 1933 out_error:
+124
include/scsi/fcoe_sysfs.h
··· 1 + /* 2 + * Copyright (c) 2011-2012 Intel Corporation. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program; if not, write to the Free Software Foundation, Inc., 15 + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 + * 17 + * Maintained at www.Open-FCoE.org 18 + */ 19 + 20 + #ifndef FCOE_SYSFS 21 + #define FCOE_SYSFS 22 + 23 + #include <linux/if_ether.h> 24 + #include <linux/device.h> 25 + #include <scsi/fc/fc_fcoe.h> 26 + 27 + struct fcoe_ctlr_device; 28 + struct fcoe_fcf_device; 29 + 30 + struct fcoe_sysfs_function_template { 31 + void (*get_fcoe_ctlr_link_fail)(struct fcoe_ctlr_device *); 32 + void (*get_fcoe_ctlr_vlink_fail)(struct fcoe_ctlr_device *); 33 + void (*get_fcoe_ctlr_miss_fka)(struct fcoe_ctlr_device *); 34 + void (*get_fcoe_ctlr_symb_err)(struct fcoe_ctlr_device *); 35 + void (*get_fcoe_ctlr_err_block)(struct fcoe_ctlr_device *); 36 + void (*get_fcoe_ctlr_fcs_error)(struct fcoe_ctlr_device *); 37 + void (*get_fcoe_ctlr_mode)(struct fcoe_ctlr_device *); 38 + void (*get_fcoe_fcf_selected)(struct fcoe_fcf_device *); 39 + void (*get_fcoe_fcf_vlan_id)(struct fcoe_fcf_device *); 40 + }; 41 + 42 + #define dev_to_ctlr(d) \ 43 + container_of((d), struct fcoe_ctlr_device, dev) 44 + 45 + enum fip_conn_type { 46 + FIP_CONN_TYPE_UNKNOWN, 47 + FIP_CONN_TYPE_FABRIC, 48 + FIP_CONN_TYPE_VN2VN, 49 + }; 50 + 51 + struct fcoe_ctlr_device { 52 + u32 id; 53 + 54 + struct device dev; 55 + struct fcoe_sysfs_function_template *f; 56 + 57 + struct list_head fcfs; 58 + char work_q_name[20]; 59 + struct workqueue_struct *work_q; 60 + char devloss_work_q_name[20]; 61 + struct workqueue_struct *devloss_work_q; 62 + struct mutex lock; 63 + 64 + int fcf_dev_loss_tmo; 65 + enum fip_conn_type mode; 66 + 67 + /* expected in host order for displaying */ 68 + struct fcoe_fc_els_lesb lesb; 69 + }; 70 + 71 + static inline void *fcoe_ctlr_device_priv(const struct fcoe_ctlr_device *ctlr) 72 + { 73 + return (void *)(ctlr + 1); 74 + } 75 + 76 + /* fcf states */ 77 + enum fcf_state { 78 + FCOE_FCF_STATE_UNKNOWN, 79 + FCOE_FCF_STATE_DISCONNECTED, 80 + FCOE_FCF_STATE_CONNECTED, 81 + FCOE_FCF_STATE_DELETED, 82 + }; 83 + 84 + struct fcoe_fcf_device { 85 + u32 id; 86 + struct device dev; 87 + struct list_head peers; 88 + struct work_struct delete_work; 89 + struct delayed_work dev_loss_work; 90 + u32 dev_loss_tmo; 91 + void *priv; 92 + enum fcf_state state; 93 + 94 + u64 fabric_name; 95 + u64 switch_name; 96 + u32 fc_map; 97 + u16 vfid; 98 + u8 mac[ETH_ALEN]; 99 + u8 priority; 100 + u32 fka_period; 101 + u8 selected; 102 + u16 vlan_id; 103 + }; 104 + 105 + #define dev_to_fcf(d) \ 106 + container_of((d), struct fcoe_fcf_device, dev) 107 + /* parentage should never be missing */ 108 + #define fcoe_fcf_dev_to_ctlr_dev(x) \ 109 + dev_to_ctlr((x)->dev.parent) 110 + #define fcoe_fcf_device_priv(x) \ 111 + ((x)->priv) 112 + 113 + struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, 114 + struct fcoe_sysfs_function_template *f, 115 + int priv_size); 116 + void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *); 117 + struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *, 118 + struct fcoe_fcf_device *); 119 + void fcoe_fcf_device_delete(struct fcoe_fcf_device *); 120 + 121 + int __init fcoe_sysfs_setup(void); 122 + void __exit fcoe_sysfs_teardown(void); 123 + 124 + #endif /* FCOE_SYSFS */
+27
include/scsi/libfcoe.h
··· 29 29 #include <linux/random.h> 30 30 #include <scsi/fc/fc_fcoe.h> 31 31 #include <scsi/libfc.h> 32 + #include <scsi/fcoe_sysfs.h> 32 33 33 34 #define FCOE_MAX_CMD_LEN 16 /* Supported CDB length */ 34 35 ··· 160 159 }; 161 160 162 161 /** 162 + * fcoe_ctlr_priv() - Return the private data from a fcoe_ctlr 163 + * @cltr: The fcoe_ctlr whose private data will be returned 164 + */ 165 + static inline void *fcoe_ctlr_priv(const struct fcoe_ctlr *ctlr) 166 + { 167 + return (void *)(ctlr + 1); 168 + } 169 + 170 + #define fcoe_ctlr_to_ctlr_dev(x) \ 171 + (struct fcoe_ctlr_device *)(((struct fcoe_ctlr_device *)(x)) - 1) 172 + 173 + /** 163 174 * struct fcoe_fcf - Fibre-Channel Forwarder 164 175 * @list: list linkage 176 + * @event_work: Work for FC Transport actions queue 177 + * @event: The event to be processed 178 + * @fip: The controller that the FCF was discovered on 179 + * @fcf_dev: The associated fcoe_fcf_device instance 165 180 * @time: system time (jiffies) when an advertisement was last received 166 181 * @switch_name: WWN of switch from advertisement 167 182 * @fabric_name: WWN of fabric from advertisement ··· 199 182 */ 200 183 struct fcoe_fcf { 201 184 struct list_head list; 185 + struct work_struct event_work; 186 + struct fcoe_ctlr *fip; 187 + struct fcoe_fcf_device *fcf_dev; 202 188 unsigned long time; 203 189 204 190 u64 switch_name; ··· 217 197 u32 fka_period; 218 198 u8 fd_flags:1; 219 199 }; 200 + 201 + #define fcoe_fcf_to_fcf_dev(x) \ 202 + ((x)->fcf_dev) 220 203 221 204 /** 222 205 * struct fcoe_rport - VN2VN remote port ··· 355 332 void fcoe_queue_timer(ulong lport); 356 333 int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen, 357 334 struct fcoe_percpu_s *fps); 335 + 336 + /* FCoE Sysfs helpers */ 337 + void fcoe_fcf_get_selected(struct fcoe_fcf_device *); 338 + void fcoe_ctlr_get_fip_mode(struct fcoe_ctlr_device *); 358 339 359 340 /** 360 341 * struct netdev_list