0001
0002
0003
0004 #include <linux/module.h>
0005 #include <linux/mempool.h>
0006 #include <linux/string.h>
0007 #include <linux/slab.h>
0008 #include <linux/errno.h>
0009 #include <linux/init.h>
0010 #include <linux/pci.h>
0011 #include <linux/skbuff.h>
0012 #include <linux/interrupt.h>
0013 #include <linux/spinlock.h>
0014 #include <linux/workqueue.h>
0015 #include <scsi/scsi_host.h>
0016 #include <scsi/scsi_tcq.h>
0017
0018 #include "snic.h"
0019 #include "snic_fwint.h"
0020
0021 #define PCI_DEVICE_ID_CISCO_SNIC 0x0046
0022
0023
0024 static struct pci_device_id snic_id_table[] = {
0025 {PCI_DEVICE(0x1137, PCI_DEVICE_ID_CISCO_SNIC) },
0026 { 0, }
0027 };
0028
0029 unsigned int snic_log_level = 0x0;
0030 module_param(snic_log_level, int, S_IRUGO|S_IWUSR);
0031 MODULE_PARM_DESC(snic_log_level, "bitmask for snic logging levels");
0032
0033 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0034 unsigned int snic_trace_max_pages = 16;
0035 module_param(snic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
0036 MODULE_PARM_DESC(snic_trace_max_pages,
0037 "Total allocated memory pages for snic trace buffer");
0038
0039 #endif
0040 unsigned int snic_max_qdepth = SNIC_DFLT_QUEUE_DEPTH;
0041 module_param(snic_max_qdepth, uint, S_IRUGO | S_IWUSR);
0042 MODULE_PARM_DESC(snic_max_qdepth, "Queue depth to report for each LUN");
0043
0044
0045
0046
0047
0048 static int
0049 snic_slave_alloc(struct scsi_device *sdev)
0050 {
0051 struct snic_tgt *tgt = starget_to_tgt(scsi_target(sdev));
0052
0053 if (!tgt || snic_tgt_chkready(tgt))
0054 return -ENXIO;
0055
0056 return 0;
0057 }
0058
0059
0060
0061
0062
0063 static int
0064 snic_slave_configure(struct scsi_device *sdev)
0065 {
0066 struct snic *snic = shost_priv(sdev->host);
0067 u32 qdepth = 0, max_ios = 0;
0068 int tmo = SNIC_DFLT_CMD_TIMEOUT * HZ;
0069
0070
0071 max_ios = snic_max_qdepth;
0072 qdepth = min_t(u32, max_ios, SNIC_MAX_QUEUE_DEPTH);
0073 scsi_change_queue_depth(sdev, qdepth);
0074
0075 if (snic->fwinfo.io_tmo > 1)
0076 tmo = snic->fwinfo.io_tmo * HZ;
0077
0078
0079 blk_queue_rq_timeout(sdev->request_queue, tmo);
0080
0081 return 0;
0082 }
0083
0084 static int
0085 snic_change_queue_depth(struct scsi_device *sdev, int qdepth)
0086 {
0087 struct snic *snic = shost_priv(sdev->host);
0088 int qsz = 0;
0089
0090 qsz = min_t(u32, qdepth, SNIC_MAX_QUEUE_DEPTH);
0091 if (qsz < sdev->queue_depth)
0092 atomic64_inc(&snic->s_stats.misc.qsz_rampdown);
0093 else if (qsz > sdev->queue_depth)
0094 atomic64_inc(&snic->s_stats.misc.qsz_rampup);
0095
0096 atomic64_set(&snic->s_stats.misc.last_qsz, sdev->queue_depth);
0097
0098 scsi_change_queue_depth(sdev, qsz);
0099
0100 return sdev->queue_depth;
0101 }
0102
0103 static struct scsi_host_template snic_host_template = {
0104 .module = THIS_MODULE,
0105 .name = SNIC_DRV_NAME,
0106 .queuecommand = snic_queuecommand,
0107 .eh_abort_handler = snic_abort_cmd,
0108 .eh_device_reset_handler = snic_device_reset,
0109 .eh_host_reset_handler = snic_host_reset,
0110 .slave_alloc = snic_slave_alloc,
0111 .slave_configure = snic_slave_configure,
0112 .change_queue_depth = snic_change_queue_depth,
0113 .this_id = -1,
0114 .cmd_per_lun = SNIC_DFLT_QUEUE_DEPTH,
0115 .can_queue = SNIC_MAX_IO_REQ,
0116 .sg_tablesize = SNIC_MAX_SG_DESC_CNT,
0117 .max_sectors = 0x800,
0118 .shost_groups = snic_host_groups,
0119 .track_queue_depth = 1,
0120 .cmd_size = sizeof(struct snic_internal_io_state),
0121 .proc_name = "snic_scsi",
0122 };
0123
0124
0125
0126
0127 void
0128 snic_handle_link_event(struct snic *snic)
0129 {
0130 unsigned long flags;
0131
0132 spin_lock_irqsave(&snic->snic_lock, flags);
0133 if (snic->stop_link_events) {
0134 spin_unlock_irqrestore(&snic->snic_lock, flags);
0135
0136 return;
0137 }
0138 spin_unlock_irqrestore(&snic->snic_lock, flags);
0139
0140 queue_work(snic_glob->event_q, &snic->link_work);
0141 }
0142
0143
0144
0145
0146
0147
0148
0149 static int
0150 snic_notify_set(struct snic *snic)
0151 {
0152 int ret = 0;
0153 enum vnic_dev_intr_mode intr_mode;
0154
0155 intr_mode = svnic_dev_get_intr_mode(snic->vdev);
0156
0157 if (intr_mode == VNIC_DEV_INTR_MODE_MSIX) {
0158 ret = svnic_dev_notify_set(snic->vdev, SNIC_MSIX_ERR_NOTIFY);
0159 } else {
0160 SNIC_HOST_ERR(snic->shost,
0161 "Interrupt mode should be setup before devcmd notify set %d\n",
0162 intr_mode);
0163 ret = -1;
0164 }
0165
0166 return ret;
0167 }
0168
0169
0170
0171
0172 static int
0173 snic_dev_wait(struct vnic_dev *vdev,
0174 int (*start)(struct vnic_dev *, int),
0175 int (*finished)(struct vnic_dev *, int *),
0176 int arg)
0177 {
0178 unsigned long time;
0179 int ret, done;
0180 int retry_cnt = 0;
0181
0182 ret = start(vdev, arg);
0183 if (ret)
0184 return ret;
0185
0186
0187
0188
0189
0190
0191
0192
0193 time = jiffies + (HZ * 2);
0194 do {
0195 ret = finished(vdev, &done);
0196 if (ret)
0197 return ret;
0198
0199 if (done)
0200 return 0;
0201 schedule_timeout_uninterruptible(HZ/10);
0202 ++retry_cnt;
0203 } while (time_after(time, jiffies) || (retry_cnt < 3));
0204
0205 return -ETIMEDOUT;
0206 }
0207
0208
0209
0210
0211
0212
0213 static int
0214 snic_cleanup(struct snic *snic)
0215 {
0216 unsigned int i;
0217 int ret;
0218
0219 svnic_dev_disable(snic->vdev);
0220 for (i = 0; i < snic->intr_count; i++)
0221 svnic_intr_mask(&snic->intr[i]);
0222
0223 for (i = 0; i < snic->wq_count; i++) {
0224 ret = svnic_wq_disable(&snic->wq[i]);
0225 if (ret)
0226 return ret;
0227 }
0228
0229
0230 snic_fwcq_cmpl_handler(snic, -1);
0231
0232 snic_wq_cmpl_handler(snic, -1);
0233
0234
0235 for (i = 0; i < snic->wq_count; i++)
0236 svnic_wq_clean(&snic->wq[i], snic_free_wq_buf);
0237
0238 for (i = 0; i < snic->cq_count; i++)
0239 svnic_cq_clean(&snic->cq[i]);
0240
0241 for (i = 0; i < snic->intr_count; i++)
0242 svnic_intr_clean(&snic->intr[i]);
0243
0244
0245 snic_free_all_untagged_reqs(snic);
0246
0247
0248 snic_shutdown_scsi_cleanup(snic);
0249
0250 for (i = 0; i < SNIC_REQ_MAX_CACHES; i++)
0251 mempool_destroy(snic->req_pool[i]);
0252
0253 return 0;
0254 }
0255
0256
0257 static void
0258 snic_iounmap(struct snic *snic)
0259 {
0260 if (snic->bar0.vaddr)
0261 iounmap(snic->bar0.vaddr);
0262 }
0263
0264
0265
0266
0267 static int
0268 snic_vdev_open_done(struct vnic_dev *vdev, int *done)
0269 {
0270 struct snic *snic = svnic_dev_priv(vdev);
0271 int ret;
0272 int nretries = 5;
0273
0274 do {
0275 ret = svnic_dev_open_done(vdev, done);
0276 if (ret == 0)
0277 break;
0278
0279 SNIC_HOST_INFO(snic->shost, "VNIC_DEV_OPEN Timedout.\n");
0280 } while (nretries--);
0281
0282 return ret;
0283 }
0284
0285
0286
0287
0288 static int
0289 snic_add_host(struct Scsi_Host *shost, struct pci_dev *pdev)
0290 {
0291 int ret = 0;
0292
0293 ret = scsi_add_host(shost, &pdev->dev);
0294 if (ret) {
0295 SNIC_HOST_ERR(shost,
0296 "snic: scsi_add_host failed. %d\n",
0297 ret);
0298
0299 return ret;
0300 }
0301
0302 SNIC_BUG_ON(shost->work_q != NULL);
0303 snprintf(shost->work_q_name, sizeof(shost->work_q_name), "scsi_wq_%d",
0304 shost->host_no);
0305 shost->work_q = create_singlethread_workqueue(shost->work_q_name);
0306 if (!shost->work_q) {
0307 SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");
0308
0309 ret = -ENOMEM;
0310 }
0311
0312 return ret;
0313 }
0314
0315 static void
0316 snic_del_host(struct Scsi_Host *shost)
0317 {
0318 if (!shost->work_q)
0319 return;
0320
0321 destroy_workqueue(shost->work_q);
0322 shost->work_q = NULL;
0323 scsi_remove_host(shost);
0324 }
0325
0326 int
0327 snic_get_state(struct snic *snic)
0328 {
0329 return atomic_read(&snic->state);
0330 }
0331
0332 void
0333 snic_set_state(struct snic *snic, enum snic_state state)
0334 {
0335 SNIC_HOST_INFO(snic->shost, "snic state change from %s to %s\n",
0336 snic_state_to_str(snic_get_state(snic)),
0337 snic_state_to_str(state));
0338
0339 atomic_set(&snic->state, state);
0340 }
0341
0342
0343
0344
0345 static int
0346 snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0347 {
0348 struct Scsi_Host *shost;
0349 struct snic *snic;
0350 mempool_t *pool;
0351 unsigned long flags;
0352 u32 max_ios = 0;
0353 int ret, i;
0354
0355
0356 SNIC_INFO("snic device %4x:%4x:%4x:%4x: ",
0357 pdev->vendor, pdev->device, pdev->subsystem_vendor,
0358 pdev->subsystem_device);
0359
0360 SNIC_INFO("snic device bus %x: slot %x: fn %x\n",
0361 pdev->bus->number, PCI_SLOT(pdev->devfn),
0362 PCI_FUNC(pdev->devfn));
0363
0364
0365
0366
0367 shost = scsi_host_alloc(&snic_host_template, sizeof(struct snic));
0368 if (!shost) {
0369 SNIC_ERR("Unable to alloc scsi_host\n");
0370 ret = -ENOMEM;
0371
0372 goto prob_end;
0373 }
0374 snic = shost_priv(shost);
0375 snic->shost = shost;
0376
0377 snprintf(snic->name, sizeof(snic->name) - 1, "%s%d", SNIC_DRV_NAME,
0378 shost->host_no);
0379
0380 SNIC_HOST_INFO(shost,
0381 "snic%d = %p shost = %p device bus %x: slot %x: fn %x\n",
0382 shost->host_no, snic, shost, pdev->bus->number,
0383 PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
0384 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0385
0386 snic_stats_debugfs_init(snic);
0387 #endif
0388
0389
0390 pci_set_drvdata(pdev, snic);
0391 snic->pdev = pdev;
0392
0393 ret = pci_enable_device(pdev);
0394 if (ret) {
0395 SNIC_HOST_ERR(shost,
0396 "Cannot enable PCI Resources, aborting : %d\n",
0397 ret);
0398
0399 goto err_free_snic;
0400 }
0401
0402 ret = pci_request_regions(pdev, SNIC_DRV_NAME);
0403 if (ret) {
0404 SNIC_HOST_ERR(shost,
0405 "Cannot obtain PCI Resources, aborting : %d\n",
0406 ret);
0407
0408 goto err_pci_disable;
0409 }
0410
0411 pci_set_master(pdev);
0412
0413
0414
0415
0416
0417
0418 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(43));
0419 if (ret) {
0420 ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
0421 if (ret) {
0422 SNIC_HOST_ERR(shost,
0423 "No Usable DMA Configuration, aborting %d\n",
0424 ret);
0425 goto err_rel_regions;
0426 }
0427 }
0428
0429
0430 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
0431 SNIC_HOST_ERR(shost, "BAR0 not memory mappable aborting.\n");
0432
0433 ret = -ENODEV;
0434 goto err_rel_regions;
0435 }
0436
0437 snic->bar0.vaddr = pci_iomap(pdev, 0, 0);
0438 if (!snic->bar0.vaddr) {
0439 SNIC_HOST_ERR(shost,
0440 "Cannot memory map BAR0 res hdr aborting.\n");
0441
0442 ret = -ENODEV;
0443 goto err_rel_regions;
0444 }
0445
0446 snic->bar0.bus_addr = pci_resource_start(pdev, 0);
0447 snic->bar0.len = pci_resource_len(pdev, 0);
0448 SNIC_BUG_ON(snic->bar0.bus_addr == 0);
0449
0450
0451 snic->vdev = svnic_dev_alloc_discover(NULL, snic, pdev, &snic->bar0, 1);
0452 if (!snic->vdev) {
0453 SNIC_HOST_ERR(shost, "vNIC Resource Discovery Failed.\n");
0454
0455 ret = -ENODEV;
0456 goto err_iounmap;
0457 }
0458
0459 ret = svnic_dev_cmd_init(snic->vdev, 0);
0460 if (ret) {
0461 SNIC_HOST_INFO(shost, "Devcmd2 Init Failed. err = %d\n", ret);
0462
0463 goto err_vnic_unreg;
0464 }
0465
0466 ret = snic_dev_wait(snic->vdev, svnic_dev_open, snic_vdev_open_done, 0);
0467 if (ret) {
0468 SNIC_HOST_ERR(shost,
0469 "vNIC dev open failed, aborting. %d\n",
0470 ret);
0471
0472 goto err_vnic_unreg;
0473 }
0474
0475 ret = svnic_dev_init(snic->vdev, 0);
0476 if (ret) {
0477 SNIC_HOST_ERR(shost,
0478 "vNIC dev init failed. aborting. %d\n",
0479 ret);
0480
0481 goto err_dev_close;
0482 }
0483
0484
0485 ret = snic_get_vnic_config(snic);
0486 if (ret) {
0487 SNIC_HOST_ERR(shost,
0488 "Get vNIC configuration failed, aborting. %d\n",
0489 ret);
0490
0491 goto err_dev_close;
0492 }
0493
0494
0495 max_ios = snic->config.io_throttle_count;
0496 if (max_ios != SNIC_UCSM_DFLT_THROTTLE_CNT_BLD)
0497 shost->can_queue = min_t(u32, SNIC_MAX_IO_REQ,
0498 max_t(u32, SNIC_MIN_IO_REQ, max_ios));
0499
0500 snic->max_tag_id = shost->can_queue;
0501
0502 shost->max_lun = snic->config.luns_per_tgt;
0503 shost->max_id = SNIC_MAX_TARGET;
0504
0505 shost->max_cmd_len = MAX_COMMAND_SIZE;
0506
0507 snic_get_res_counts(snic);
0508
0509
0510
0511
0512 ret = snic_set_intr_mode(snic);
0513 if (ret) {
0514 SNIC_HOST_ERR(shost,
0515 "Failed to set intr mode aborting. %d\n",
0516 ret);
0517
0518 goto err_dev_close;
0519 }
0520
0521 ret = snic_alloc_vnic_res(snic);
0522 if (ret) {
0523 SNIC_HOST_ERR(shost,
0524 "Failed to alloc vNIC resources aborting. %d\n",
0525 ret);
0526
0527 goto err_clear_intr;
0528 }
0529
0530
0531 INIT_LIST_HEAD(&snic->list);
0532
0533
0534
0535
0536
0537 INIT_LIST_HEAD(&snic->spl_cmd_list);
0538 spin_lock_init(&snic->spl_cmd_lock);
0539
0540
0541 spin_lock_init(&snic->snic_lock);
0542
0543 for (i = 0; i < SNIC_WQ_MAX; i++)
0544 spin_lock_init(&snic->wq_lock[i]);
0545
0546 for (i = 0; i < SNIC_IO_LOCKS; i++)
0547 spin_lock_init(&snic->io_req_lock[i]);
0548
0549 pool = mempool_create_slab_pool(2,
0550 snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);
0551 if (!pool) {
0552 SNIC_HOST_ERR(shost, "dflt sgl pool creation failed\n");
0553
0554 ret = -ENOMEM;
0555 goto err_free_res;
0556 }
0557
0558 snic->req_pool[SNIC_REQ_CACHE_DFLT_SGL] = pool;
0559
0560 pool = mempool_create_slab_pool(2,
0561 snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);
0562 if (!pool) {
0563 SNIC_HOST_ERR(shost, "max sgl pool creation failed\n");
0564
0565 ret = -ENOMEM;
0566 goto err_free_dflt_sgl_pool;
0567 }
0568
0569 snic->req_pool[SNIC_REQ_CACHE_MAX_SGL] = pool;
0570
0571 pool = mempool_create_slab_pool(2,
0572 snic_glob->req_cache[SNIC_REQ_TM_CACHE]);
0573 if (!pool) {
0574 SNIC_HOST_ERR(shost, "snic tmreq info pool creation failed.\n");
0575
0576 ret = -ENOMEM;
0577 goto err_free_max_sgl_pool;
0578 }
0579
0580 snic->req_pool[SNIC_REQ_TM_CACHE] = pool;
0581
0582
0583 atomic_set(&snic->state, SNIC_INIT);
0584
0585 atomic_set(&snic->ios_inflight, 0);
0586
0587
0588 ret = snic_notify_set(snic);
0589 if (ret) {
0590 SNIC_HOST_ERR(shost,
0591 "Failed to alloc notify buffer aborting. %d\n",
0592 ret);
0593
0594 goto err_free_tmreq_pool;
0595 }
0596
0597 spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
0598 list_add_tail(&snic->list, &snic_glob->snic_list);
0599 spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);
0600
0601 snic_disc_init(&snic->disc);
0602 INIT_WORK(&snic->tgt_work, snic_handle_tgt_disc);
0603 INIT_WORK(&snic->disc_work, snic_handle_disc);
0604 INIT_WORK(&snic->link_work, snic_handle_link);
0605
0606
0607 for (i = 0; i < snic->wq_count; i++)
0608 svnic_wq_enable(&snic->wq[i]);
0609
0610 ret = svnic_dev_enable_wait(snic->vdev);
0611 if (ret) {
0612 SNIC_HOST_ERR(shost,
0613 "vNIC dev enable failed w/ error %d\n",
0614 ret);
0615
0616 goto err_vdev_enable;
0617 }
0618
0619 ret = snic_request_intr(snic);
0620 if (ret) {
0621 SNIC_HOST_ERR(shost, "Unable to request irq. %d\n", ret);
0622
0623 goto err_req_intr;
0624 }
0625
0626 for (i = 0; i < snic->intr_count; i++)
0627 svnic_intr_unmask(&snic->intr[i]);
0628
0629
0630 ret = snic_get_conf(snic);
0631 if (ret) {
0632 SNIC_HOST_ERR(shost,
0633 "Failed to get snic io config from FW w err %d\n",
0634 ret);
0635
0636 goto err_get_conf;
0637 }
0638
0639
0640
0641
0642
0643 ret = snic_add_host(shost, pdev);
0644 if (ret) {
0645 SNIC_HOST_ERR(shost,
0646 "Adding scsi host Failed ... exiting. %d\n",
0647 ret);
0648
0649 goto err_get_conf;
0650 }
0651
0652 snic_set_state(snic, SNIC_ONLINE);
0653
0654 ret = snic_disc_start(snic);
0655 if (ret) {
0656 SNIC_HOST_ERR(shost, "snic_probe:Discovery Failed w err = %d\n",
0657 ret);
0658
0659 goto err_get_conf;
0660 }
0661
0662 SNIC_HOST_INFO(shost, "SNIC Device Probe Successful.\n");
0663
0664 return 0;
0665
0666 err_get_conf:
0667 snic_free_all_untagged_reqs(snic);
0668
0669 for (i = 0; i < snic->intr_count; i++)
0670 svnic_intr_mask(&snic->intr[i]);
0671
0672 snic_free_intr(snic);
0673
0674 err_req_intr:
0675 svnic_dev_disable(snic->vdev);
0676
0677 err_vdev_enable:
0678 svnic_dev_notify_unset(snic->vdev);
0679
0680 for (i = 0; i < snic->wq_count; i++) {
0681 int rc = 0;
0682
0683 rc = svnic_wq_disable(&snic->wq[i]);
0684 if (rc) {
0685 SNIC_HOST_ERR(shost,
0686 "WQ Disable Failed w/ err = %d\n", rc);
0687
0688 break;
0689 }
0690 }
0691 snic_del_host(snic->shost);
0692
0693 err_free_tmreq_pool:
0694 mempool_destroy(snic->req_pool[SNIC_REQ_TM_CACHE]);
0695
0696 err_free_max_sgl_pool:
0697 mempool_destroy(snic->req_pool[SNIC_REQ_CACHE_MAX_SGL]);
0698
0699 err_free_dflt_sgl_pool:
0700 mempool_destroy(snic->req_pool[SNIC_REQ_CACHE_DFLT_SGL]);
0701
0702 err_free_res:
0703 snic_free_vnic_res(snic);
0704
0705 err_clear_intr:
0706 snic_clear_intr_mode(snic);
0707
0708 err_dev_close:
0709 svnic_dev_close(snic->vdev);
0710
0711 err_vnic_unreg:
0712 svnic_dev_unregister(snic->vdev);
0713
0714 err_iounmap:
0715 snic_iounmap(snic);
0716
0717 err_rel_regions:
0718 pci_release_regions(pdev);
0719
0720 err_pci_disable:
0721 pci_disable_device(pdev);
0722
0723 err_free_snic:
0724 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0725 snic_stats_debugfs_remove(snic);
0726 #endif
0727 scsi_host_put(shost);
0728 pci_set_drvdata(pdev, NULL);
0729
0730 prob_end:
0731 SNIC_INFO("sNIC device : bus %d: slot %d: fn %d Registration Failed.\n",
0732 pdev->bus->number, PCI_SLOT(pdev->devfn),
0733 PCI_FUNC(pdev->devfn));
0734
0735 return ret;
0736 }
0737
0738
0739
0740
0741
0742
0743 static void
0744 snic_remove(struct pci_dev *pdev)
0745 {
0746 struct snic *snic = pci_get_drvdata(pdev);
0747 unsigned long flags;
0748
0749 if (!snic) {
0750 SNIC_INFO("sNIC dev: bus %d slot %d fn %d snic inst is null.\n",
0751 pdev->bus->number, PCI_SLOT(pdev->devfn),
0752 PCI_FUNC(pdev->devfn));
0753
0754 return;
0755 }
0756
0757
0758
0759
0760
0761
0762
0763 snic_set_state(snic, SNIC_OFFLINE);
0764 spin_lock_irqsave(&snic->snic_lock, flags);
0765 snic->stop_link_events = 1;
0766 spin_unlock_irqrestore(&snic->snic_lock, flags);
0767
0768 flush_workqueue(snic_glob->event_q);
0769 snic_disc_term(snic);
0770
0771 spin_lock_irqsave(&snic->snic_lock, flags);
0772 snic->in_remove = 1;
0773 spin_unlock_irqrestore(&snic->snic_lock, flags);
0774
0775
0776
0777
0778
0779
0780 snic_cleanup(snic);
0781
0782 spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
0783 list_del(&snic->list);
0784 spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);
0785
0786 snic_tgt_del_all(snic);
0787 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0788 snic_stats_debugfs_remove(snic);
0789 #endif
0790 snic_del_host(snic->shost);
0791
0792 svnic_dev_notify_unset(snic->vdev);
0793 snic_free_intr(snic);
0794 snic_free_vnic_res(snic);
0795 snic_clear_intr_mode(snic);
0796 svnic_dev_close(snic->vdev);
0797 svnic_dev_unregister(snic->vdev);
0798 snic_iounmap(snic);
0799 pci_release_regions(pdev);
0800 pci_disable_device(pdev);
0801 pci_set_drvdata(pdev, NULL);
0802
0803
0804 scsi_host_put(snic->shost);
0805 }
0806
0807
0808 struct snic_global *snic_glob;
0809
0810
0811
0812
0813
0814
0815 static int
0816 snic_global_data_init(void)
0817 {
0818 int ret = 0;
0819 struct kmem_cache *cachep;
0820 ssize_t len = 0;
0821
0822 snic_glob = kzalloc(sizeof(*snic_glob), GFP_KERNEL);
0823
0824 if (!snic_glob) {
0825 SNIC_ERR("Failed to allocate Global Context.\n");
0826
0827 ret = -ENOMEM;
0828 goto gdi_end;
0829 }
0830
0831 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0832
0833
0834 snic_debugfs_init();
0835
0836
0837
0838 ret = snic_trc_init();
0839 if (ret < 0) {
0840 SNIC_ERR("Trace buffer init failed, SNIC tracing disabled\n");
0841 snic_trc_free();
0842
0843 }
0844
0845 #endif
0846 INIT_LIST_HEAD(&snic_glob->snic_list);
0847 spin_lock_init(&snic_glob->snic_list_lock);
0848
0849
0850 len = sizeof(struct snic_req_info);
0851 len += sizeof(struct snic_host_req) + sizeof(struct snic_dflt_sgl);
0852 cachep = kmem_cache_create("snic_req_dfltsgl", len, SNIC_SG_DESC_ALIGN,
0853 SLAB_HWCACHE_ALIGN, NULL);
0854 if (!cachep) {
0855 SNIC_ERR("Failed to create snic default sgl slab\n");
0856 ret = -ENOMEM;
0857
0858 goto err_dflt_req_slab;
0859 }
0860 snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL] = cachep;
0861
0862
0863 len = sizeof(struct snic_req_info);
0864 len += sizeof(struct snic_host_req) + sizeof(struct snic_max_sgl);
0865 cachep = kmem_cache_create("snic_req_maxsgl", len, SNIC_SG_DESC_ALIGN,
0866 SLAB_HWCACHE_ALIGN, NULL);
0867 if (!cachep) {
0868 SNIC_ERR("Failed to create snic max sgl slab\n");
0869 ret = -ENOMEM;
0870
0871 goto err_max_req_slab;
0872 }
0873 snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL] = cachep;
0874
0875 len = sizeof(struct snic_host_req);
0876 cachep = kmem_cache_create("snic_req_maxsgl", len, SNIC_SG_DESC_ALIGN,
0877 SLAB_HWCACHE_ALIGN, NULL);
0878 if (!cachep) {
0879 SNIC_ERR("Failed to create snic tm req slab\n");
0880 ret = -ENOMEM;
0881
0882 goto err_tmreq_slab;
0883 }
0884 snic_glob->req_cache[SNIC_REQ_TM_CACHE] = cachep;
0885
0886
0887 snic_glob->event_q = create_singlethread_workqueue("snic_event_wq");
0888 if (!snic_glob->event_q) {
0889 SNIC_ERR("snic event queue create failed\n");
0890 ret = -ENOMEM;
0891
0892 goto err_eventq;
0893 }
0894
0895 return ret;
0896
0897 err_eventq:
0898 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_TM_CACHE]);
0899
0900 err_tmreq_slab:
0901 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);
0902
0903 err_max_req_slab:
0904 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);
0905
0906 err_dflt_req_slab:
0907 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0908 snic_trc_free();
0909 snic_debugfs_term();
0910 #endif
0911 kfree(snic_glob);
0912 snic_glob = NULL;
0913
0914 gdi_end:
0915 return ret;
0916 }
0917
0918
0919
0920
0921 static void
0922 snic_global_data_cleanup(void)
0923 {
0924 SNIC_BUG_ON(snic_glob == NULL);
0925
0926 destroy_workqueue(snic_glob->event_q);
0927 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_TM_CACHE]);
0928 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);
0929 kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);
0930
0931 #ifdef CONFIG_SCSI_SNIC_DEBUG_FS
0932
0933 snic_trc_free();
0934
0935
0936 snic_debugfs_term();
0937 #endif
0938 kfree(snic_glob);
0939 snic_glob = NULL;
0940 }
0941
0942 static struct pci_driver snic_driver = {
0943 .name = SNIC_DRV_NAME,
0944 .id_table = snic_id_table,
0945 .probe = snic_probe,
0946 .remove = snic_remove,
0947 };
0948
0949 static int __init
0950 snic_init_module(void)
0951 {
0952 int ret = 0;
0953
0954 #ifndef __x86_64__
0955 SNIC_INFO("SNIC Driver is supported only for x86_64 platforms!\n");
0956 add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
0957 #endif
0958
0959 SNIC_INFO("%s, ver %s\n", SNIC_DRV_DESCRIPTION, SNIC_DRV_VERSION);
0960
0961 ret = snic_global_data_init();
0962 if (ret) {
0963 SNIC_ERR("Failed to Initialize Global Data.\n");
0964
0965 return ret;
0966 }
0967
0968 ret = pci_register_driver(&snic_driver);
0969 if (ret < 0) {
0970 SNIC_ERR("PCI driver register error\n");
0971
0972 goto err_pci_reg;
0973 }
0974
0975 return ret;
0976
0977 err_pci_reg:
0978 snic_global_data_cleanup();
0979
0980 return ret;
0981 }
0982
0983 static void __exit
0984 snic_cleanup_module(void)
0985 {
0986 pci_unregister_driver(&snic_driver);
0987 snic_global_data_cleanup();
0988 }
0989
0990 module_init(snic_init_module);
0991 module_exit(snic_cleanup_module);
0992
0993 MODULE_LICENSE("GPL v2");
0994 MODULE_DESCRIPTION(SNIC_DRV_DESCRIPTION);
0995 MODULE_VERSION(SNIC_DRV_VERSION);
0996 MODULE_DEVICE_TABLE(pci, snic_id_table);
0997 MODULE_AUTHOR("Narsimhulu Musini <nmusini@cisco.com>, "
0998 "Sesidhar Baddela <sebaddel@cisco.com>");