diff options
Diffstat (limited to 'drivers/scsi/bnx2fc/bnx2fc_fcoe.c')
| -rw-r--r-- | drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 266 |
1 files changed, 102 insertions, 164 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 7dfe709a7138..0f68739d380a 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -16,6 +16,8 @@ #include "bnx2fc.h" +#include <linux/ethtool.h> + static struct list_head adapter_list; static struct list_head if_list; static u32 adapter_count; @@ -50,7 +52,7 @@ struct workqueue_struct *bnx2fc_wq; * Here the io threads are per cpu but the l2 thread is just one */ struct fcoe_percpu_s bnx2fc_global; -DEFINE_SPINLOCK(bnx2fc_global_lock); +static DEFINE_SPINLOCK(bnx2fc_global_lock); static struct cnic_ulp_ops bnx2fc_cnic_cb; static struct libfc_function_template bnx2fc_libfc_fcn_templ; @@ -80,7 +82,7 @@ static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba); static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba); static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct device *parent, int npiv); -static void bnx2fc_destroy_work(struct work_struct *work); +static void bnx2fc_port_destroy(struct fcoe_port *port); static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device *phys_dev); static struct bnx2fc_interface *bnx2fc_interface_lookup(struct net_device @@ -108,22 +110,22 @@ MODULE_PARM_DESC(debug_logging, "\t\t0x10 - fcoe L2 fame related logs.\n" "\t\t0xff - LOG all messages."); -uint bnx2fc_devloss_tmo; +static uint bnx2fc_devloss_tmo; module_param_named(devloss_tmo, bnx2fc_devloss_tmo, uint, S_IRUGO); MODULE_PARM_DESC(devloss_tmo, " Change devloss_tmo for the remote ports " "attached via bnx2fc."); -uint bnx2fc_max_luns = BNX2FC_MAX_LUN; +static uint bnx2fc_max_luns = BNX2FC_MAX_LUN; module_param_named(max_luns, bnx2fc_max_luns, uint, S_IRUGO); MODULE_PARM_DESC(max_luns, " Change the default max_lun per SCSI host. Default " "0xffff."); -uint bnx2fc_queue_depth; +static uint bnx2fc_queue_depth; module_param_named(queue_depth, bnx2fc_queue_depth, uint, S_IRUGO); MODULE_PARM_DESC(queue_depth, " Change the default queue depth of SCSI devices " "attached via bnx2fc."); -uint bnx2fc_log_fka; +static uint bnx2fc_log_fka; module_param_named(log_fka, bnx2fc_log_fka, uint, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(log_fka, " Print message to kernel log when fcoe is " "initiating a FIP keep alive when debug logging is enabled."); @@ -150,15 +152,11 @@ static void bnx2fc_clean_rx_queue(struct fc_lport *lp) struct fcoe_rcv_info *fr; struct sk_buff_head *list; struct sk_buff *skb, *next; - struct sk_buff *head; bg = &bnx2fc_global; spin_lock_bh(&bg->fcoe_rx_list.lock); list = &bg->fcoe_rx_list; - head = list->next; - for (skb = head; skb != (struct sk_buff *)list; - skb = next) { - next = skb->next; + skb_queue_walk_safe(list, skb, next) { fr = fcoe_dev_from_skb(skb); if (fr->fr_dev == lp) { __skb_unlink(skb, list); @@ -275,7 +273,6 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) struct fcoe_port *port; struct fcoe_hdr *hp; struct bnx2fc_rport *tgt; - struct fc_stats *stats; u8 sof, eof; u32 crc; unsigned int hlen, tlen, elen; @@ -350,7 +347,7 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) return -ENOMEM; } frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1]; - cp = kmap_atomic(skb_frag_page(frag)) + frag->page_offset; + cp = kmap_atomic(skb_frag_page(frag)) + skb_frag_off(frag); } else { cp = skb_put(skb, tlen); } @@ -401,10 +398,8 @@ static int bnx2fc_xmit(struct fc_lport *lport, struct fc_frame *fp) } /*update tx stats */ - stats = per_cpu_ptr(lport->stats, get_cpu()); - stats->TxFrames++; - stats->TxWords += wlen; - put_cpu(); + this_cpu_inc(lport->stats->TxFrames); + this_cpu_add(lport->stats->TxWords, wlen); /* send down to lld */ fr_dev(fp) = lport; @@ -432,11 +427,8 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, struct fc_lport *lport; struct bnx2fc_interface *interface; struct fcoe_ctlr *ctlr; - struct fc_frame_header *fh; struct fcoe_rcv_info *fr; struct fcoe_percpu_s *bg; - struct sk_buff *tmp_skb; - unsigned short oxid; interface = container_of(ptype, struct bnx2fc_interface, fcoe_packet_type); @@ -448,11 +440,9 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, goto err; } - tmp_skb = skb_share_check(skb, GFP_ATOMIC); - if (!tmp_skb) - goto err; - - skb = tmp_skb; + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) + return -1; if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) { printk(KERN_ERR PFX "bnx2fc_rcv: Wrong FC type frame\n"); @@ -468,9 +458,6 @@ static int bnx2fc_rcv(struct sk_buff *skb, struct net_device *dev, goto err; skb_set_transport_header(skb, sizeof(struct fcoe_hdr)); - fh = (struct fc_frame_header *) skb_transport_header(skb); - - oxid = ntohs(fh->fh_ox_id); fr = fcoe_dev_from_skb(skb); fr->fr_dev = lport; @@ -515,10 +502,10 @@ static int bnx2fc_l2_rcv_thread(void *arg) static void bnx2fc_recv_frame(struct sk_buff *skb) { - u32 fr_len; + u64 crc_err; + u32 fr_len, fr_crc; struct fc_lport *lport; struct fcoe_rcv_info *fr; - struct fc_stats *stats; struct fc_frame_header *fh; struct fcoe_crc_eof crc_eof; struct fc_frame *fp; @@ -549,6 +536,9 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) skb_pull(skb, sizeof(struct fcoe_hdr)); fr_len = skb->len - sizeof(struct fcoe_crc_eof); + this_cpu_inc(lport->stats->RxFrames); + this_cpu_add(lport->stats->RxWords, fr_len / FCOE_WORD_TO_BYTE); + fp = (struct fc_frame *)skb; fc_frame_init(fp); fr_dev(fp) = lport; @@ -631,16 +621,13 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) return; } - stats = per_cpu_ptr(lport->stats, smp_processor_id()); - stats->RxFrames++; - stats->RxWords += fr_len / FCOE_WORD_TO_BYTE; + fr_crc = le32_to_cpu(fr_crc(fp)); - if (le32_to_cpu(fr_crc(fp)) != - ~crc32(~0, skb->data, fr_len)) { - if (stats->InvalidCRCCount < 5) + if (unlikely(fr_crc != ~crc32(~0, skb->data, fr_len))) { + crc_err = this_cpu_inc_return(lport->stats->InvalidCRCCount); + if (crc_err < 5) printk(KERN_WARNING PFX "dropping frame with " "CRC error\n"); - stats->InvalidCRCCount++; kfree_skb(skb); return; } @@ -669,7 +656,10 @@ static int bnx2fc_percpu_io_thread(void *arg) list_for_each_entry_safe(work, tmp, &work_list, list) { list_del_init(&work->list); - bnx2fc_process_cq_compl(work->tgt, work->wqe); + bnx2fc_process_cq_compl(work->tgt, work->wqe, + work->rq_data, + work->num_rq, + work->task); kfree(work); } @@ -823,7 +813,7 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev) skb_queue_head_init(&port->fcoe_pending_queue); port->fcoe_pending_queue_active = 0; - setup_timer(&port->timer, fcoe_queue_timer, (unsigned long) lport); + timer_setup(&port->timer, fcoe_queue_timer, 0); fcoe_link_speed_update(lport); @@ -845,9 +835,9 @@ static int bnx2fc_net_config(struct fc_lport *lport, struct net_device *netdev) return 0; } -static void bnx2fc_destroy_timer(unsigned long data) +static void bnx2fc_destroy_timer(struct timer_list *t) { - struct bnx2fc_hba *hba = (struct bnx2fc_hba *)data; + struct bnx2fc_hba *hba = timer_container_of(hba, t, destroy_timer); printk(KERN_ERR PFX "ERROR:bnx2fc_destroy_timer - " "Destroy compl not received!!\n"); @@ -911,9 +901,6 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, __bnx2fc_destroy(interface); } mutex_unlock(&bnx2fc_dev_lock); - - /* Ensure ALL destroy work has been completed before return */ - flush_workqueue(bnx2fc_wq); return; default: @@ -951,7 +938,7 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, */ if (interface->enabled) fcoe_ctlr_link_up(ctlr); - }; + } } else if (fcoe_ctlr_link_down(ctlr)) { switch (cdev->enabled) { case FCOE_CTLR_DISABLED: @@ -966,12 +953,10 @@ static void bnx2fc_indicate_netevent(void *context, unsigned long event, mutex_unlock(&lport->lp_mutex); fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; - per_cpu_ptr(lport->stats, - get_cpu())->LinkFailureCount++; - put_cpu(); + this_cpu_inc(lport->stats->LinkFailureCount); fcoe_clean_pending_queue(lport); wait_for_upload = 1; - }; + } } } mutex_unlock(&bnx2fc_dev_lock); @@ -1077,9 +1062,8 @@ static int bnx2fc_fip_recv(struct sk_buff *skb, struct net_device *dev, /** * bnx2fc_update_src_mac - Update Ethernet MAC filters. * - * @fip: FCoE controller. - * @old: Unicast MAC address to delete if the MAC is non-zero. - * @new: Unicast MAC address to add. + * @lport: The local port + * @addr: Location of data to copy * * Remove any previously-set unicast MAC filter. * Add secondary FCoE MAC address filter for our OUI. @@ -1220,8 +1204,8 @@ static int bnx2fc_vport_destroy(struct fc_vport *vport) mutex_unlock(&n_port->lp_mutex); bnx2fc_free_vport(interface->hba, port->lport); bnx2fc_port_shutdown(port->lport); + bnx2fc_port_destroy(port); bnx2fc_interface_put(interface); - queue_work(bnx2fc_wq, &port->destroy_work); return 0; } @@ -1397,7 +1381,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) hba->next_conn_id = 0; hba->tgt_ofld_list = - kzalloc(sizeof(struct bnx2fc_rport *) * BNX2FC_NUM_MAX_SESS, + kcalloc(BNX2FC_NUM_MAX_SESS, sizeof(struct bnx2fc_rport *), GFP_KERNEL); if (!hba->tgt_ofld_list) { printk(KERN_ERR PFX "Unable to allocate tgt offload list\n"); @@ -1445,7 +1429,7 @@ bind_err: static struct bnx2fc_interface * bnx2fc_interface_create(struct bnx2fc_hba *hba, struct net_device *netdev, - enum fip_state fip_mode) + enum fip_mode fip_mode) { struct fcoe_ctlr_device *ctlr_dev; struct bnx2fc_interface *interface; @@ -1530,7 +1514,6 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, port->lport = lport; port->priv = interface; port->get_netdev = bnx2fc_netdev; - INIT_WORK(&port->destroy_work, bnx2fc_destroy_work); /* Configure fcoe_port */ rc = bnx2fc_lport_config(lport); @@ -1552,7 +1535,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, rc = bnx2fc_shost_config(lport, parent); if (rc) { - printk(KERN_ERR PFX "Couldnt configure shost for %s\n", + printk(KERN_ERR PFX "Couldn't configure shost for %s\n", interface->netdev->name); goto lp_config_err; } @@ -1560,7 +1543,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, /* Initialize the libfc library */ rc = bnx2fc_libfc_config(lport); if (rc) { - printk(KERN_ERR PFX "Couldnt configure libfc\n"); + printk(KERN_ERR PFX "Couldn't configure libfc\n"); goto shost_err; } fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN; @@ -1616,7 +1599,7 @@ static void bnx2fc_interface_cleanup(struct bnx2fc_interface *interface) struct bnx2fc_hba *hba = interface->hba; /* Stop the transmit retry timer */ - del_timer_sync(&port->timer); + timer_delete_sync(&port->timer); /* Free existing transmit skbs */ fcoe_clean_pending_queue(lport); @@ -1658,15 +1641,14 @@ static void __bnx2fc_destroy(struct bnx2fc_interface *interface) bnx2fc_interface_cleanup(interface); bnx2fc_stop(interface); list_del(&interface->list); + bnx2fc_port_destroy(port); bnx2fc_interface_put(interface); - queue_work(bnx2fc_wq, &port->destroy_work); } /** * bnx2fc_destroy - Destroy a bnx2fc FCoE interface * - * @buffer: The name of the Ethernet interface to be destroyed - * @kp: The associated kernel parameter + * @netdev: The net device that the FCoE interface is on * * Called from sysfs. * @@ -1700,15 +1682,12 @@ netdev_err: return rc; } -static void bnx2fc_destroy_work(struct work_struct *work) +static void bnx2fc_port_destroy(struct fcoe_port *port) { - struct fcoe_port *port; struct fc_lport *lport; - port = container_of(work, struct fcoe_port, destroy_work); lport = port->lport; - - BNX2FC_HBA_DBG(lport, "Entered bnx2fc_destroy_work\n"); + BNX2FC_HBA_DBG(lport, "Entered %s, destroying lport %p\n", __func__, lport); bnx2fc_if_destroy(lport); } @@ -1755,32 +1734,32 @@ static int bnx2fc_bind_pcidev(struct bnx2fc_hba *hba) switch (pdev->device) { case PCI_DEVICE_ID_NX2_57710: - strncpy(hba->chip_num, "BCM57710", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57710", sizeof(hba->chip_num)); break; case PCI_DEVICE_ID_NX2_57711: - strncpy(hba->chip_num, "BCM57711", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57711", sizeof(hba->chip_num)); break; case PCI_DEVICE_ID_NX2_57712: case PCI_DEVICE_ID_NX2_57712_MF: case PCI_DEVICE_ID_NX2_57712_VF: - strncpy(hba->chip_num, "BCM57712", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57712", sizeof(hba->chip_num)); break; case PCI_DEVICE_ID_NX2_57800: case PCI_DEVICE_ID_NX2_57800_MF: case PCI_DEVICE_ID_NX2_57800_VF: - strncpy(hba->chip_num, "BCM57800", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57800", sizeof(hba->chip_num)); break; case PCI_DEVICE_ID_NX2_57810: case PCI_DEVICE_ID_NX2_57810_MF: case PCI_DEVICE_ID_NX2_57810_VF: - strncpy(hba->chip_num, "BCM57810", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57810", sizeof(hba->chip_num)); break; case PCI_DEVICE_ID_NX2_57840: case PCI_DEVICE_ID_NX2_57840_MF: case PCI_DEVICE_ID_NX2_57840_VF: case PCI_DEVICE_ID_NX2_57840_2_20: case PCI_DEVICE_ID_NX2_57840_4_10: - strncpy(hba->chip_num, "BCM57840", BCM_CHIP_LEN); + strscpy(hba->chip_num, "BCM57840", sizeof(hba->chip_num)); break; default: pr_err(PFX "Unknown device id 0x%x\n", pdev->device); @@ -1802,7 +1781,7 @@ static void bnx2fc_unbind_pcidev(struct bnx2fc_hba *hba) /** * bnx2fc_ulp_get_stats - cnic callback to populate FCoE stats * - * @handle: transport handle pointing to adapter struture + * @handle: transport handle pointing to adapter structure */ static int bnx2fc_ulp_get_stats(void *handle) { @@ -1818,7 +1797,7 @@ static int bnx2fc_ulp_get_stats(void *handle) if (!stats_addr) return -EINVAL; - strncpy(stats_addr->version, BNX2FC_VERSION, + strscpy(stats_addr->version, BNX2FC_VERSION, sizeof(stats_addr->version)); stats_addr->txq_size = BNX2FC_SQ_WQES_MAX; stats_addr->rxq_size = BNX2FC_CQ_WQES_MAX; @@ -1946,11 +1925,10 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) { if (test_and_clear_bit(BNX2FC_FLAG_FW_INIT_DONE, &hba->flags)) { if (bnx2fc_send_fw_fcoe_destroy_msg(hba) == 0) { - init_timer(&hba->destroy_timer); + timer_setup(&hba->destroy_timer, bnx2fc_destroy_timer, + 0); hba->destroy_timer.expires = BNX2FC_FW_TIMEOUT + jiffies; - hba->destroy_timer.function = bnx2fc_destroy_timer; - hba->destroy_timer.data = (unsigned long)hba; add_timer(&hba->destroy_timer); wait_event_interruptible(hba->destroy_wait, test_bit(BNX2FC_FLAG_DESTROY_CMPL, @@ -1960,7 +1938,7 @@ static void bnx2fc_fw_destroy(struct bnx2fc_hba *hba) if (signal_pending(current)) flush_signals(current); - del_timer_sync(&hba->destroy_timer); + timer_delete_sync(&hba->destroy_timer); } bnx2fc_unbind_adapter_devices(hba); } @@ -2095,7 +2073,7 @@ static int __bnx2fc_disable(struct fcoe_ctlr *ctlr) { struct bnx2fc_interface *interface = fcoe_ctlr_priv(ctlr); - if (interface->enabled == true) { + if (interface->enabled) { if (!ctlr->lp) { pr_err(PFX "__bnx2fc_disable: lport not found\n"); return -ENODEV; @@ -2108,7 +2086,7 @@ static int __bnx2fc_disable(struct fcoe_ctlr *ctlr) return 0; } -/** +/* * Deperecated: Use bnx2fc_enabled() */ static int bnx2fc_disable(struct net_device *netdev) @@ -2193,7 +2171,7 @@ static int __bnx2fc_enable(struct fcoe_ctlr *ctlr) struct cnic_fc_npiv_tbl *npiv_tbl; struct fc_lport *lport; - if (interface->enabled == false) { + if (!interface->enabled) { if (!ctlr->lp) { pr_err(PFX "__bnx2fc_enable: lport not found\n"); return -ENODEV; @@ -2236,7 +2214,7 @@ done: return 0; } -/** +/* * Deprecated: Use bnx2fc_enabled() */ static int bnx2fc_enable(struct net_device *netdev) @@ -2284,7 +2262,7 @@ static int bnx2fc_ctlr_enabled(struct fcoe_ctlr_device *cdev) case FCOE_CTLR_UNUSED: default: return -ENOTSUPP; - }; + } } enum bnx2fc_create_link_state { @@ -2372,7 +2350,7 @@ static int _bnx2fc_create(struct net_device *netdev, if (!interface) { printk(KERN_ERR PFX "bnx2fc_interface_create failed\n"); rc = -ENOMEM; - goto ifput_err; + goto netdev_err; } if (is_vlan_dev(netdev)) { @@ -2385,8 +2363,8 @@ static int _bnx2fc_create(struct net_device *netdev, interface->vlan_id = vlan_id; interface->tm_timeout = BNX2FC_TM_TIMEOUT; - interface->timer_work_queue = - create_singlethread_workqueue("bnx2fc_timer_wq"); + interface->timer_work_queue = alloc_ordered_workqueue( + "%s", WQ_MEM_RECLAIM, "bnx2fc_timer_wq"); if (!interface->timer_work_queue) { printk(KERN_ERR PFX "ulp_init could not create timer_wq\n"); rc = -EINVAL; @@ -2530,7 +2508,7 @@ static struct bnx2fc_hba *bnx2fc_hba_lookup(struct net_device /** * bnx2fc_ulp_exit - shuts down adapter instance and frees all resources * - * @dev cnic device handle + * @dev: cnic device handle */ static void bnx2fc_ulp_exit(struct cnic_dev *dev) { @@ -2563,9 +2541,6 @@ static void bnx2fc_ulp_exit(struct cnic_dev *dev) __bnx2fc_destroy(interface); mutex_unlock(&bnx2fc_dev_lock); - /* Ensure ALL destroy work has been completed before return */ - flush_workqueue(bnx2fc_wq); - bnx2fc_ulp_stop(hba); /* unregister cnic device */ if (test_and_clear_bit(BNX2FC_CNIC_REGISTERED, &hba->reg_with_cnic)) @@ -2624,30 +2599,28 @@ static struct fcoe_transport bnx2fc_transport = { }; /** - * bnx2fc_percpu_thread_create - Create a receive thread for an - * online CPU + * bnx2fc_cpu_online - Create a receive thread for an online CPU * * @cpu: cpu index for the online cpu */ -static void bnx2fc_percpu_thread_create(unsigned int cpu) +static int bnx2fc_cpu_online(unsigned int cpu) { struct bnx2fc_percpu_s *p; struct task_struct *thread; p = &per_cpu(bnx2fc_percpu, cpu); - thread = kthread_create_on_node(bnx2fc_percpu_io_thread, - (void *)p, cpu_to_node(cpu), - "bnx2fc_thread/%d", cpu); - /* bind thread to the cpu */ - if (likely(!IS_ERR(thread))) { - kthread_bind(thread, cpu); - p->iothread = thread; - wake_up_process(thread); - } + thread = kthread_create_on_cpu(bnx2fc_percpu_io_thread, + (void *)p, cpu, "bnx2fc_thread/%d"); + if (IS_ERR(thread)) + return PTR_ERR(thread); + + p->iothread = thread; + wake_up_process(thread); + return 0; } -static void bnx2fc_percpu_thread_destroy(unsigned int cpu) +static int bnx2fc_cpu_offline(unsigned int cpu) { struct bnx2fc_percpu_s *p; struct task_struct *thread; @@ -2661,11 +2634,11 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu) thread = p->iothread; p->iothread = NULL; - /* Free all work in the list */ list_for_each_entry_safe(work, tmp, &p->work_list, list) { list_del_init(&work->list); - bnx2fc_process_cq_compl(work->tgt, work->wqe); + bnx2fc_process_cq_compl(work->tgt, work->wqe, work->rq_data, + work->num_rq, work->task); kfree(work); } @@ -2673,24 +2646,11 @@ static void bnx2fc_percpu_thread_destroy(unsigned int cpu) if (thread) kthread_stop(thread); -} - - -static int bnx2fc_cpu_online(unsigned int cpu) -{ - printk(PFX "CPU %x online: Create Rx thread\n", cpu); - bnx2fc_percpu_thread_create(cpu); - return 0; -} - -static int bnx2fc_cpu_dead(unsigned int cpu) -{ - printk(PFX "CPU %x offline: Remove Rx thread\n", cpu); - bnx2fc_percpu_thread_destroy(cpu); return 0; } -static int bnx2fc_slave_configure(struct scsi_device *sdev) +static int bnx2fc_sdev_configure(struct scsi_device *sdev, + struct queue_limits *lim) { if (!bnx2fc_queue_depth) return 0; @@ -2735,7 +2695,7 @@ static int __init bnx2fc_mod_init(void) if (rc) goto detach_ft; - bnx2fc_wq = alloc_workqueue("bnx2fc", 0, 0); + bnx2fc_wq = alloc_workqueue("bnx2fc", WQ_PERCPU, 0); if (!bnx2fc_wq) { rc = -ENOMEM; goto release_bt; @@ -2743,14 +2703,13 @@ static int __init bnx2fc_mod_init(void) bg = &bnx2fc_global; skb_queue_head_init(&bg->fcoe_rx_list); - l2_thread = kthread_create(bnx2fc_l2_rcv_thread, - (void *)bg, - "bnx2fc_l2_thread"); + l2_thread = kthread_run(bnx2fc_l2_rcv_thread, + (void *)bg, + "bnx2fc_l2_thread"); if (IS_ERR(l2_thread)) { rc = PTR_ERR(l2_thread); goto free_wq; } - wake_up_process(l2_thread); spin_lock_bh(&bg->fcoe_rx_list.lock); bg->kthread = l2_thread; spin_unlock_bh(&bg->fcoe_rx_list.lock); @@ -2761,30 +2720,16 @@ static int __init bnx2fc_mod_init(void) spin_lock_init(&p->fp_work_lock); } - get_online_cpus(); - - for_each_online_cpu(cpu) - bnx2fc_percpu_thread_create(cpu); - - rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, - "scsi/bnx2fc:online", - bnx2fc_cpu_online, NULL); + rc = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "scsi/bnx2fc:online", + bnx2fc_cpu_online, bnx2fc_cpu_offline); if (rc < 0) - goto stop_threads; + goto stop_thread; bnx2fc_online_state = rc; - cpuhp_setup_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD, "scsi/bnx2fc:dead", - NULL, bnx2fc_cpu_dead); - put_online_cpus(); - cnic_register_driver(CNIC_ULP_FCOE, &bnx2fc_cnic_cb); - return 0; -stop_threads: - for_each_online_cpu(cpu) - bnx2fc_percpu_thread_destroy(cpu); - put_online_cpus(); +stop_thread: kthread_stop(l2_thread); free_wq: destroy_workqueue(bnx2fc_wq); @@ -2803,7 +2748,6 @@ static void __exit bnx2fc_mod_exit(void) struct fcoe_percpu_s *bg; struct task_struct *l2_thread; struct sk_buff *skb; - unsigned int cpu = 0; /* * NOTE: Since cnic calls register_driver routine rtnl_lock, @@ -2844,16 +2788,7 @@ static void __exit bnx2fc_mod_exit(void) if (l2_thread) kthread_stop(l2_thread); - get_online_cpus(); - /* Destroy per cpu threads */ - for_each_online_cpu(cpu) { - bnx2fc_percpu_thread_destroy(cpu); - } - - cpuhp_remove_state_nocalls(bnx2fc_online_state); - cpuhp_remove_state_nocalls(CPUHP_SCSI_BNX2FC_DEAD); - - put_online_cpus(); + cpuhp_remove_state(bnx2fc_online_state); destroy_workqueue(bnx2fc_wq); /* @@ -2995,12 +2930,14 @@ bnx2fc_tm_timeout_store(struct device *dev, static DEVICE_ATTR(tm_timeout, S_IRUGO|S_IWUSR, bnx2fc_tm_timeout_show, bnx2fc_tm_timeout_store); -static struct device_attribute *bnx2fc_host_attrs[] = { - &dev_attr_tm_timeout, +static struct attribute *bnx2fc_host_attrs[] = { + &dev_attr_tm_timeout.attr, NULL, }; -/** +ATTRIBUTE_GROUPS(bnx2fc_host); + +/* * scsi_host_template structure used while registering with SCSI-ml */ static struct scsi_host_template bnx2fc_shost_template = { @@ -3012,16 +2949,17 @@ static struct scsi_host_template bnx2fc_shost_template = { .eh_device_reset_handler = bnx2fc_eh_device_reset, /* lun reset */ .eh_target_reset_handler = bnx2fc_eh_target_reset, /* tgt reset */ .eh_host_reset_handler = fc_eh_host_reset, - .slave_alloc = fc_slave_alloc, + .sdev_init = fc_sdev_init, .change_queue_depth = scsi_change_queue_depth, .this_id = -1, .cmd_per_lun = 3, - .use_clustering = ENABLE_CLUSTERING, .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD, - .max_sectors = 1024, + .dma_boundary = 0x7fff, + .max_sectors = 0x3fbf, .track_queue_depth = 1, - .slave_configure = bnx2fc_slave_configure, - .shost_attrs = bnx2fc_host_attrs, + .sdev_configure = bnx2fc_sdev_configure, + .shost_groups = bnx2fc_host_groups, + .cmd_size = sizeof(struct bnx2fc_priv), }; static struct libfc_function_template bnx2fc_libfc_fcn_templ = { @@ -3033,7 +2971,7 @@ static struct libfc_function_template bnx2fc_libfc_fcn_templ = { .rport_event_callback = bnx2fc_rport_event_handler, }; -/** +/* * bnx2fc_cnic_cb - global template of bnx2fc - cnic driver interface * structure carrying callback function pointers */ |
