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