1 /* 2 * zfcp device driver 3 * 4 * Registration and callback for the s390 common I/O layer. 5 * 6 * Copyright IBM Corporation 2002, 2009 7 */ 8 9 #define KMSG_COMPONENT "zfcp" 10 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 11 12 #include "zfcp_ext.h" 13 14 #define ZFCP_MODEL_PRIV 0x4 15 16 static DEFINE_SPINLOCK(zfcp_ccw_adapter_ref_lock); 17 18 struct zfcp_adapter *zfcp_ccw_adapter_by_cdev(struct ccw_device *cdev) 19 { 20 struct zfcp_adapter *adapter; 21 unsigned long flags; 22 23 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags); 24 adapter = dev_get_drvdata(&cdev->dev); 25 if (adapter) 26 kref_get(&adapter->ref); 27 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); 28 return adapter; 29 } 30 31 void zfcp_ccw_adapter_put(struct zfcp_adapter *adapter) 32 { 33 unsigned long flags; 34 35 spin_lock_irqsave(&zfcp_ccw_adapter_ref_lock, flags); 36 kref_put(&adapter->ref, zfcp_adapter_release); 37 spin_unlock_irqrestore(&zfcp_ccw_adapter_ref_lock, flags); 38 } 39 40 static int zfcp_ccw_activate(struct ccw_device *cdev) 41 42 { 43 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 44 45 if (!adapter) 46 return 0; 47 48 zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL, 49 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 50 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 51 "ccresu2", NULL); 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->sysfs_device, 126 &zfcp_sysfs_unit_attrs); 127 128 list_for_each_entry_safe(port, p, &port_remove_lh, list) 129 zfcp_device_unregister(&port->sysfs_device, 130 &zfcp_sysfs_port_attrs); 131 132 zfcp_adapter_unregister(adapter); 133 } 134 135 /** 136 * zfcp_ccw_set_online - set_online function of zfcp driver 137 * @cdev: pointer to belonging ccw device 138 * 139 * This function gets called by the common i/o layer and sets an 140 * adapter into state online. The first call will allocate all 141 * adapter resources that will be retained until the device is removed 142 * via zfcp_ccw_remove. 143 * 144 * Setting an fcp device online means that it will be registered with 145 * the SCSI stack, that the QDIO queues will be set up and that the 146 * adapter will be opened. 147 */ 148 static int zfcp_ccw_set_online(struct ccw_device *cdev) 149 { 150 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 151 152 if (!adapter) { 153 adapter = zfcp_adapter_enqueue(cdev); 154 155 if (IS_ERR(adapter)) { 156 dev_err(&cdev->dev, 157 "Setting up data structures for the " 158 "FCP adapter failed\n"); 159 return PTR_ERR(adapter); 160 } 161 kref_get(&adapter->ref); 162 } 163 164 /* initialize request counter */ 165 BUG_ON(!zfcp_reqlist_isempty(adapter)); 166 adapter->req_no = 0; 167 168 zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL, 169 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 170 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 171 "ccsonl2", NULL); 172 zfcp_erp_wait(adapter); 173 174 flush_work(&adapter->scan_work); 175 176 zfcp_ccw_adapter_put(adapter); 177 return 0; 178 } 179 180 /** 181 * zfcp_ccw_set_offline - set_offline function of zfcp driver 182 * @cdev: pointer to belonging ccw device 183 * 184 * This function gets called by the common i/o layer and sets an adapter 185 * into state offline. 186 */ 187 static int zfcp_ccw_set_offline(struct ccw_device *cdev) 188 { 189 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 190 191 if (!adapter) 192 return 0; 193 194 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); 195 zfcp_erp_wait(adapter); 196 197 zfcp_ccw_adapter_put(adapter); 198 return 0; 199 } 200 201 /** 202 * zfcp_ccw_notify - ccw notify function 203 * @cdev: pointer to belonging ccw device 204 * @event: indicates if adapter was detached or attached 205 * 206 * This function gets called by the common i/o layer if an adapter has gone 207 * or reappeared. 208 */ 209 static int zfcp_ccw_notify(struct ccw_device *cdev, int event) 210 { 211 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 212 213 if (!adapter) 214 return 1; 215 216 switch (event) { 217 case CIO_GONE: 218 dev_warn(&cdev->dev, "The FCP device has been detached\n"); 219 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL); 220 break; 221 case CIO_NO_PATH: 222 dev_warn(&cdev->dev, 223 "The CHPID for the FCP device is offline\n"); 224 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL); 225 break; 226 case CIO_OPER: 227 dev_info(&cdev->dev, "The FCP device is operational again\n"); 228 zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL, 229 ZFCP_STATUS_COMMON_RUNNING, 230 ZFCP_SET); 231 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 232 "ccnoti4", NULL); 233 break; 234 case CIO_BOXED: 235 dev_warn(&cdev->dev, "The FCP device did not respond within " 236 "the specified time\n"); 237 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); 238 break; 239 } 240 241 zfcp_ccw_adapter_put(adapter); 242 return 1; 243 } 244 245 /** 246 * zfcp_ccw_shutdown - handle shutdown from cio 247 * @cdev: device for adapter to shutdown. 248 */ 249 static void zfcp_ccw_shutdown(struct ccw_device *cdev) 250 { 251 struct zfcp_adapter *adapter = zfcp_ccw_adapter_by_cdev(cdev); 252 253 if (!adapter) 254 return; 255 256 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); 257 zfcp_erp_wait(adapter); 258 zfcp_erp_thread_kill(adapter); 259 260 zfcp_ccw_adapter_put(adapter); 261 } 262 263 struct ccw_driver zfcp_ccw_driver = { 264 .owner = THIS_MODULE, 265 .name = "zfcp", 266 .ids = zfcp_ccw_device_id, 267 .probe = zfcp_ccw_probe, 268 .remove = zfcp_ccw_remove, 269 .set_online = zfcp_ccw_set_online, 270 .set_offline = zfcp_ccw_set_offline, 271 .notify = zfcp_ccw_notify, 272 .shutdown = zfcp_ccw_shutdown, 273 .freeze = zfcp_ccw_set_offline, 274 .thaw = zfcp_ccw_activate, 275 .restore = zfcp_ccw_activate, 276 }; 277