1 /* 2 * zfcp device driver 3 * 4 * Registration and callback for the s390 common I/O layer. 5 * 6 * Copyright IBM Corporation 2002, 2010 7 */ 8 9 #define KMSG_COMPONENT "zfcp" 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 12 #include "zfcp_ext.h" 13 #include "zfcp_reqlist.h" 14 15 #define ZFCP_MODEL_PRIV 0x4 16 17 static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock); 18 19 struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev) 20 { 21 struct zfcp_adapter *adapter; 22 unsigned long flags; 23 24 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags); 25 adapter = dev_get_drvdata(&cdev->dev); 26 if (adapter) 27 kref_get(&adapter->ref); 28 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); 29 return adapter; 30 } 31 32 void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter) 33 { 34 unsigned long flags; 35 36 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags); 37 kref_put(&adapter->ref, zfcp_adapter_release); 38 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); 39 } 40 41 static int zfcp_ccw_activate(struct ccw_device *cdev) 42 43 { 44 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 45 46 if (!adapter) 47 return 0; 48 49 zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); 50 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 51 "ccresu2"); 52 zfcp_erp_wait(adapter); 53 flush_work(&adapter->scan_work); 54 55 zfcp_ccw_adapter_put(adapter); 56 57 return 0; 58 } 59 60 static struct ccw_device_id zfcp_ccw_device_id[] = { 61 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, 62 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) }, 63 {}, 64 }; 65 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); 66 67 /** 68 * zfcp_ccw_priv_sch - check if subchannel is privileged 69 * @adapter: Adapter/Subchannel to check 70 */ 71 int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter) 72 { 73 return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV; 74 } 75 76 /** 77 * zfcp_ccw_probe - probe function of zfcp driver 78 * @cdev: pointer to belonging ccw device 79 * 80 * This function gets called by the common i/o layer for each FCP 81 * device found on the current system. This is only a stub to make cio 82 * work: To only allocate adapter resources for devices actually used, 83 * the allocation is deferred to the first call to ccw_set_online. 84 */ 85 static int zfcp_ccw_probe(struct ccw_device *cdev) 86 { 87 return 0; 88 } 89 90 /** 91 * zfcp_ccw_remove - remove function of zfcp driver 92 * @cdev: pointer to belonging ccw device 93 * 94 * This function gets called by the common i/o layer and removes an adapter 95 * from the system. Task of this function is to get rid of all units and 96 * ports that belong to this adapter. And in addition all resources of this 97 * adapter will be freed too. 98 */ 99 static void zfcp_ccw_remove(struct ccw_device *cdev) 100 { 101 struct zfcp_adapter *adapter; 102 struct zfcp_port *port, *p; 103 struct zfcp_unit *unit, *u; 104 LIST_HEAD(unit_remove_lh); 105 LIST_HEAD(port_remove_lh); 106 107 ccw_device_set_offline(cdev); 108 109 adapter = zfcp_ccw_adapter_by_cdev(cdev); 110 if (!adapter) 111 return; 112 113 write_lock_irq(&adapter->port_list_lock); 114 list_for_each_entry_safe(port, p, &adapter->port_list, list) { 115 write_lock(&port->unit_list_lock); 116 list_for_each_entry_safe(unit, u, &port->unit_list, list) 117 list_move(&unit->list, &unit_remove_lh); 118 write_unlock(&port->unit_list_lock); 119 list_move(&port->list, &port_remove_lh); 120 } 121 write_unlock_irq(&adapter->port_list_lock); 122 zfcp_ccw_adapter_put(adapter); /* put from zfcp_ccw_adapter_by_cdev */ 123 124 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) 125 zfcp_device_unregister(&unit->dev, &zfcp_sysfs_unit_attrs); 126 127 list_for_each_entry_safe(port, p, &port_remove_lh, list) 128 zfcp_device_unregister(&port->dev, &zfcp_sysfs_port_attrs); 129 130 zfcp_adapter_unregister(adapter); 131 } 132 133 /** 134 * zfcp_ccw_set_online - set_online function of zfcp driver 135 * @cdev: pointer to belonging ccw device 136 * 137 * This function gets called by the common i/o layer and sets an 138 * adapter into state online. The first call will allocate all 139 * adapter resources that will be retained until the device is removed 140 * via zfcp_ccw_remove. 141 * 142 * Setting an fcp device online means that it will be registered with 143 * the SCSI stack, that the QDIO queues will be set up and that the 144 * adapter will be opened. 145 */ 146 static int zfcp_ccw_set_online(struct ccw_device *cdev) 147 { 148 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 149 150 if (!adapter) { 151 adapter = zfcp_adapter_enqueue(cdev); 152 153 if (IS_ERR(adapter)) { 154 dev_err(&cdev->dev, 155 "Setting up data structures for the " 156 "FCP adapter failed\n"); 157 return PTR_ERR(adapter); 158 } 159 kref_get(&adapter->ref); 160 } 161 162 /* initialize request counter */ 163 BUG_ON(!zfcp_reqlist_isempty(adapter->req_list)); 164 adapter->req_no = 0; 165 166 zfcp_ccw_activate(cdev); 167 zfcp_ccw_adapter_put(adapter); 168 return 0; 169 } 170 171 /** 172 * zfcp_ccw_set_offline - set_offline function of zfcp driver 173 * @cdev: pointer to belonging ccw device 174 * 175 * This function gets called by the common i/o layer and sets an adapter 176 * into state offline. 177 */ 178 static int zfcp_ccw_set_offline(struct ccw_device *cdev) 179 { 180 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 181 182 if (!adapter) 183 return 0; 184 185 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1"); 186 zfcp_erp_wait(adapter); 187 188 zfcp_ccw_adapter_put(adapter); 189 return 0; 190 } 191 192 /** 193 * zfcp_ccw_notify - ccw notify function 194 * @cdev: pointer to belonging ccw device 195 * @event: indicates if adapter was detached or attached 196 * 197 * This function gets called by the common i/o layer if an adapter has gone 198 * or reappeared. 199 */ 200 static int zfcp_ccw_notify(struct ccw_device *cdev, int event) 201 { 202 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 203 204 if (!adapter) 205 return 1; 206 207 switch (event) { 208 case CIO_GONE: 209 dev_warn(&cdev->dev, "The FCP device has been detached\n"); 210 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1"); 211 break; 212 case CIO_NO_PATH: 213 dev_warn(&cdev->dev, 214 "The CHPID for the FCP device is offline\n"); 215 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2"); 216 break; 217 case CIO_OPER: 218 dev_info(&cdev->dev, "The FCP device is operational again\n"); 219 zfcp_erp_set_adapter_status(adapter, 220 ZFCP_STATUS_COMMON_RUNNING); 221 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 222 "ccnoti4"); 223 break; 224 case CIO_BOXED: 225 dev_warn(&cdev->dev, "The FCP device did not respond within " 226 "the specified time\n"); 227 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5"); 228 break; 229 } 230 231 zfcp_ccw_adapter_put(adapter); 232 return 1; 233 } 234 235 /** 236 * zfcp_ccw_shutdown - handle shutdown from cio 237 * @cdev: device for adapter to shutdown. 238 */ 239 static void zfcp_ccw_shutdown(struct ccw_device *cdev) 240 { 241 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 242 243 if (!adapter) 244 return; 245 246 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1"); 247 zfcp_erp_wait(adapter); 248 zfcp_erp_thread_kill(adapter); 249 250 zfcp_ccw_adapter_put(adapter); 251 } 252 253 struct ccw_driver zfcp_ccw_driver = { 254 .owner = THIS_MODULE, 255 .name = "zfcp", 256 .ids = zfcp_ccw_device_id, 257 .probe = zfcp_ccw_probe, 258 .remove = zfcp_ccw_remove, 259 .set_online = zfcp_ccw_set_online, 260 .set_offline = zfcp_ccw_set_offline, 261 .notify = zfcp_ccw_notify, 262 .shutdown = zfcp_ccw_shutdown, 263 .freeze = zfcp_ccw_set_offline, 264 .thaw = zfcp_ccw_activate, 265 .restore = zfcp_ccw_activate, 266 }; 267