1/* cxgb3i_init.c: Chelsio S3xx iSCSI driver. 2 * 3 * Copyright (c) 2008 Chelsio Communications, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation. 8 * 9 * Written by: Karen Xie (kxie@chelsio.com) 10 */ 11 12#include "cxgb3i.h" 13 14#define DRV_MODULE_NAME "cxgb3i" 15#define DRV_MODULE_VERSION "1.0.2" 16#define DRV_MODULE_RELDATE "Mar. 2009" 17 18static char version[] = 19 "Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME 20 " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; 21 22MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>"); 23MODULE_DESCRIPTION("Chelsio S3xx iSCSI Driver"); 24MODULE_LICENSE("GPL"); 25MODULE_VERSION(DRV_MODULE_VERSION); 26 27static void open_s3_dev(struct t3cdev *); 28static void close_s3_dev(struct t3cdev *); 29static void s3_event_handler(struct t3cdev *tdev, u32 event, u32 port); 30 31static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS]; 32static struct cxgb3_client t3c_client = { 33 .name = "iscsi_cxgb3", 34 .handlers = cxgb3i_cpl_handlers, 35 .add = open_s3_dev, 36 .remove = close_s3_dev, 37 .event_handler = s3_event_handler, 38}; 39 40/** 41 * open_s3_dev - register with cxgb3 LLD 42 * @t3dev: cxgb3 adapter instance 43 */ 44static void open_s3_dev(struct t3cdev *t3dev) 45{ 46 static int vers_printed; 47 48 if (!vers_printed) { 49 printk(KERN_INFO "%s", version); 50 vers_printed = 1; 51 } 52 53 cxgb3i_ddp_init(t3dev); 54 cxgb3i_sdev_add(t3dev, &t3c_client); 55 cxgb3i_adapter_open(t3dev); 56} 57 58/** 59 * close_s3_dev - de-register with cxgb3 LLD 60 * @t3dev: cxgb3 adapter instance 61 */ 62static void close_s3_dev(struct t3cdev *t3dev) 63{ 64 cxgb3i_adapter_close(t3dev); 65 cxgb3i_sdev_remove(t3dev); 66 cxgb3i_ddp_cleanup(t3dev); 67} 68 69static void s3_event_handler(struct t3cdev *tdev, u32 event, u32 port) 70{ 71 struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev); 72 73 cxgb3i_log_info("snic 0x%p, tdev 0x%p, event 0x%x, port 0x%x.\n", 74 snic, tdev, event, port); 75 if (!snic) 76 return; 77 78 switch (event) { 79 case OFFLOAD_STATUS_DOWN: 80 snic->flags |= CXGB3I_ADAPTER_FLAG_RESET; 81 break; 82 case OFFLOAD_STATUS_UP: 83 snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET; 84 break; 85 } 86} 87 88/** 89 * cxgb3i_init_module - module init entry point 90 * 91 * initialize any driver wide global data structures and register itself 92 * with the cxgb3 module 93 */ 94static int __init cxgb3i_init_module(void) 95{ 96 int err; 97 98 err = cxgb3i_sdev_init(cxgb3i_cpl_handlers); 99 if (err < 0) 100 return err; 101 102 err = cxgb3i_iscsi_init(); 103 if (err < 0) 104 return err; 105 106 err = cxgb3i_pdu_init(); 107 if (err < 0) { 108 cxgb3i_iscsi_cleanup(); 109 return err; 110 } 111 112 cxgb3_register_client(&t3c_client); 113 114 return 0; 115} 116 117/** 118 * cxgb3i_exit_module - module cleanup/exit entry point 119 * 120 * go through the driver hba list and for each hba, release any resource held. 121 * and unregisters iscsi transport and the cxgb3 module 122 */ 123static void __exit cxgb3i_exit_module(void) 124{ 125 cxgb3_unregister_client(&t3c_client); 126 cxgb3i_pdu_cleanup(); 127 cxgb3i_iscsi_cleanup(); 128 cxgb3i_sdev_cleanup(); 129} 130 131module_init(cxgb3i_init_module); 132module_exit(cxgb3i_exit_module); 133