1 /* 2 * zfcp device driver 3 * 4 * Registration and callback for the s390 common I/O layer. 5 * 6 * Copyright IBM Corporation 2002, 2008 7 */ 8 9 #include "zfcp_ext.h" 10 11 /** 12 * zfcp_ccw_probe - probe function of zfcp driver 13 * @ccw_device: pointer to belonging ccw device 14 * 15 * This function gets called by the common i/o layer and sets up the initial 16 * data structures for each fcp adapter, which was detected by the system. 17 * Also the sysfs files for this adapter will be created by this function. 18 * In addition the nameserver port will be added to the ports of the adapter 19 * and its sysfs representation will be created too. 20 */ 21 static int zfcp_ccw_probe(struct ccw_device *ccw_device) 22 { 23 int retval = 0; 24 25 down(&zfcp_data.config_sema); 26 if (zfcp_adapter_enqueue(ccw_device)) { 27 dev_err(&ccw_device->dev, 28 "Setting up data structures for the " 29 "FCP adapter failed\n"); 30 retval = -EINVAL; 31 } 32 up(&zfcp_data.config_sema); 33 return retval; 34 } 35 36 /** 37 * zfcp_ccw_remove - remove function of zfcp driver 38 * @ccw_device: pointer to belonging ccw device 39 * 40 * This function gets called by the common i/o layer and removes an adapter 41 * from the system. Task of this function is to get rid of all units and 42 * ports that belong to this adapter. And in addition all resources of this 43 * adapter will be freed too. 44 */ 45 static void zfcp_ccw_remove(struct ccw_device *ccw_device) 46 { 47 struct zfcp_adapter *adapter; 48 struct zfcp_port *port, *p; 49 struct zfcp_unit *unit, *u; 50 LIST_HEAD(unit_remove_lh); 51 LIST_HEAD(port_remove_lh); 52 53 ccw_device_set_offline(ccw_device); 54 down(&zfcp_data.config_sema); 55 adapter = dev_get_drvdata(&ccw_device->dev); 56 57 write_lock_irq(&zfcp_data.config_lock); 58 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { 59 list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { 60 list_move(&unit->list, &unit_remove_lh); 61 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, 62 &unit->status); 63 } 64 list_move(&port->list, &port_remove_lh); 65 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 66 } 67 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); 68 write_unlock_irq(&zfcp_data.config_lock); 69 70 list_for_each_entry_safe(port, p, &port_remove_lh, list) { 71 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { 72 if (atomic_read(&unit->status) & 73 ZFCP_STATUS_UNIT_REGISTERED) 74 scsi_remove_device(unit->device); 75 zfcp_unit_dequeue(unit); 76 } 77 zfcp_port_dequeue(port); 78 } 79 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); 80 zfcp_adapter_dequeue(adapter); 81 82 up(&zfcp_data.config_sema); 83 } 84 85 /** 86 * zfcp_ccw_set_online - set_online function of zfcp driver 87 * @ccw_device: pointer to belonging ccw device 88 * 89 * This function gets called by the common i/o layer and sets an adapter 90 * into state online. Setting an fcp device online means that it will be 91 * registered with the SCSI stack, that the QDIO queues will be set up 92 * and that the adapter will be opened (asynchronously). 93 */ 94 static int zfcp_ccw_set_online(struct ccw_device *ccw_device) 95 { 96 struct zfcp_adapter *adapter; 97 int retval; 98 99 down(&zfcp_data.config_sema); 100 adapter = dev_get_drvdata(&ccw_device->dev); 101 102 retval = zfcp_erp_thread_setup(adapter); 103 if (retval) 104 goto out; 105 106 retval = zfcp_adapter_scsi_register(adapter); 107 if (retval) 108 goto out_scsi_register; 109 110 /* initialize request counter */ 111 BUG_ON(!zfcp_reqlist_isempty(adapter)); 112 adapter->req_no = 0; 113 114 zfcp_erp_modify_adapter_status(adapter, 10, NULL, 115 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 116 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85, 117 NULL); 118 zfcp_erp_wait(adapter); 119 goto out; 120 121 out_scsi_register: 122 zfcp_erp_thread_kill(adapter); 123 out: 124 up(&zfcp_data.config_sema); 125 return retval; 126 } 127 128 /** 129 * zfcp_ccw_set_offline - set_offline function of zfcp driver 130 * @ccw_device: pointer to belonging ccw device 131 * 132 * This function gets called by the common i/o layer and sets an adapter 133 * into state offline. 134 */ 135 static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) 136 { 137 struct zfcp_adapter *adapter; 138 139 down(&zfcp_data.config_sema); 140 adapter = dev_get_drvdata(&ccw_device->dev); 141 zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL); 142 zfcp_erp_wait(adapter); 143 zfcp_erp_thread_kill(adapter); 144 up(&zfcp_data.config_sema); 145 return 0; 146 } 147 148 /** 149 * zfcp_ccw_notify - ccw notify function 150 * @ccw_device: pointer to belonging ccw device 151 * @event: indicates if adapter was detached or attached 152 * 153 * This function gets called by the common i/o layer if an adapter has gone 154 * or reappeared. 155 */ 156 static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) 157 { 158 struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev); 159 160 switch (event) { 161 case CIO_GONE: 162 dev_warn(&adapter->ccw_device->dev, 163 "The FCP device has been detached\n"); 164 zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL); 165 break; 166 case CIO_NO_PATH: 167 dev_warn(&adapter->ccw_device->dev, 168 "The CHPID for the FCP device is offline\n"); 169 zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL); 170 break; 171 case CIO_OPER: 172 dev_info(&adapter->ccw_device->dev, 173 "The FCP device is operational again\n"); 174 zfcp_erp_modify_adapter_status(adapter, 11, NULL, 175 ZFCP_STATUS_COMMON_RUNNING, 176 ZFCP_SET); 177 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 178 89, NULL); 179 break; 180 } 181 return 1; 182 } 183 184 /** 185 * zfcp_ccw_shutdown - handle shutdown from cio 186 * @cdev: device for adapter to shutdown. 187 */ 188 static void zfcp_ccw_shutdown(struct ccw_device *cdev) 189 { 190 struct zfcp_adapter *adapter; 191 192 down(&zfcp_data.config_sema); 193 adapter = dev_get_drvdata(&cdev->dev); 194 zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL); 195 zfcp_erp_wait(adapter); 196 up(&zfcp_data.config_sema); 197 } 198 199 static struct ccw_device_id zfcp_ccw_device_id[] = { 200 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, 201 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x4) }, /* priv. */ 202 {}, 203 }; 204 205 MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); 206 207 static struct ccw_driver zfcp_ccw_driver = { 208 .owner = THIS_MODULE, 209 .name = "zfcp", 210 .ids = zfcp_ccw_device_id, 211 .probe = zfcp_ccw_probe, 212 .remove = zfcp_ccw_remove, 213 .set_online = zfcp_ccw_set_online, 214 .set_offline = zfcp_ccw_set_offline, 215 .notify = zfcp_ccw_notify, 216 .shutdown = zfcp_ccw_shutdown, 217 }; 218 219 /** 220 * zfcp_ccw_register - ccw register function 221 * 222 * Registers the driver at the common i/o layer. This function will be called 223 * at module load time/system start. 224 */ 225 int __init zfcp_ccw_register(void) 226 { 227 return ccw_driver_register(&zfcp_ccw_driver); 228 } 229 230 /** 231 * zfcp_get_adapter_by_busid - find zfcp_adapter struct 232 * @busid: bus id string of zfcp adapter to find 233 */ 234 struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid) 235 { 236 struct ccw_device *ccw_device; 237 struct zfcp_adapter *adapter = NULL; 238 239 ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); 240 if (ccw_device) { 241 adapter = dev_get_drvdata(&ccw_device->dev); 242 put_device(&ccw_device->dev); 243 } 244 return adapter; 245 } 246