Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.31 291 lines 8.2 kB view raw
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 16static int zfcp_ccw_suspend(struct ccw_device *cdev) 17 18{ 19 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev); 20 21 down(&zfcp_data.config_sema); 22 23 zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL); 24 zfcp_erp_wait(adapter); 25 26 up(&zfcp_data.config_sema); 27 28 return 0; 29} 30 31static int zfcp_ccw_activate(struct ccw_device *cdev) 32 33{ 34 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev); 35 36 zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL, 37 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 38 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 39 "ccresu2", NULL); 40 zfcp_erp_wait(adapter); 41 flush_work(&adapter->scan_work); 42 43 return 0; 44} 45 46static struct ccw_device_id zfcp_ccw_device_id[] = { 47 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, 48 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) }, 49 {}, 50}; 51MODULE_DEVICE_TABLE(ccw, zfcp_ccw_device_id); 52 53/** 54 * zfcp_ccw_priv_sch - check if subchannel is privileged 55 * @adapter: Adapter/Subchannel to check 56 */ 57int zfcp_ccw_priv_sch(struct zfcp_adapter *adapter) 58{ 59 return adapter->ccw_device->id.dev_model == ZFCP_MODEL_PRIV; 60} 61 62/** 63 * zfcp_ccw_probe - probe function of zfcp driver 64 * @ccw_device: pointer to belonging ccw device 65 * 66 * This function gets called by the common i/o layer and sets up the initial 67 * data structures for each fcp adapter, which was detected by the system. 68 * Also the sysfs files for this adapter will be created by this function. 69 * In addition the nameserver port will be added to the ports of the adapter 70 * and its sysfs representation will be created too. 71 */ 72static int zfcp_ccw_probe(struct ccw_device *ccw_device) 73{ 74 int retval = 0; 75 76 down(&zfcp_data.config_sema); 77 if (zfcp_adapter_enqueue(ccw_device)) { 78 dev_err(&ccw_device->dev, 79 "Setting up data structures for the " 80 "FCP adapter failed\n"); 81 retval = -EINVAL; 82 } 83 up(&zfcp_data.config_sema); 84 return retval; 85} 86 87/** 88 * zfcp_ccw_remove - remove function of zfcp driver 89 * @ccw_device: pointer to belonging ccw device 90 * 91 * This function gets called by the common i/o layer and removes an adapter 92 * from the system. Task of this function is to get rid of all units and 93 * ports that belong to this adapter. And in addition all resources of this 94 * adapter will be freed too. 95 */ 96static void zfcp_ccw_remove(struct ccw_device *ccw_device) 97{ 98 struct zfcp_adapter *adapter; 99 struct zfcp_port *port, *p; 100 struct zfcp_unit *unit, *u; 101 LIST_HEAD(unit_remove_lh); 102 LIST_HEAD(port_remove_lh); 103 104 ccw_device_set_offline(ccw_device); 105 down(&zfcp_data.config_sema); 106 adapter = dev_get_drvdata(&ccw_device->dev); 107 108 write_lock_irq(&zfcp_data.config_lock); 109 list_for_each_entry_safe(port, p, &adapter->port_list_head, list) { 110 list_for_each_entry_safe(unit, u, &port->unit_list_head, list) { 111 list_move(&unit->list, &unit_remove_lh); 112 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, 113 &unit->status); 114 } 115 list_move(&port->list, &port_remove_lh); 116 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); 117 } 118 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); 119 write_unlock_irq(&zfcp_data.config_lock); 120 121 list_for_each_entry_safe(port, p, &port_remove_lh, list) { 122 list_for_each_entry_safe(unit, u, &unit_remove_lh, list) { 123 if (unit->device) 124 scsi_remove_device(unit->device); 125 zfcp_unit_dequeue(unit); 126 } 127 zfcp_port_dequeue(port); 128 } 129 wait_event(adapter->remove_wq, atomic_read(&adapter->refcount) == 0); 130 zfcp_adapter_dequeue(adapter); 131 132 up(&zfcp_data.config_sema); 133} 134 135/** 136 * zfcp_ccw_set_online - set_online function of zfcp driver 137 * @ccw_device: pointer to belonging ccw device 138 * 139 * This function gets called by the common i/o layer and sets an adapter 140 * into state online. Setting an fcp device online means that it will be 141 * registered with the SCSI stack, that the QDIO queues will be set up 142 * and that the adapter will be opened (asynchronously). 143 */ 144static int zfcp_ccw_set_online(struct ccw_device *ccw_device) 145{ 146 struct zfcp_adapter *adapter; 147 int retval; 148 149 down(&zfcp_data.config_sema); 150 adapter = dev_get_drvdata(&ccw_device->dev); 151 152 retval = zfcp_erp_thread_setup(adapter); 153 if (retval) 154 goto out; 155 156 /* initialize request counter */ 157 BUG_ON(!zfcp_reqlist_isempty(adapter)); 158 adapter->req_no = 0; 159 160 zfcp_erp_modify_adapter_status(adapter, "ccsonl1", NULL, 161 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET); 162 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 163 "ccsonl2", NULL); 164 zfcp_erp_wait(adapter); 165 up(&zfcp_data.config_sema); 166 flush_work(&adapter->scan_work); 167 return 0; 168 169 out: 170 up(&zfcp_data.config_sema); 171 return retval; 172} 173 174/** 175 * zfcp_ccw_set_offline - set_offline function of zfcp driver 176 * @ccw_device: pointer to belonging ccw device 177 * 178 * This function gets called by the common i/o layer and sets an adapter 179 * into state offline. 180 */ 181static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) 182{ 183 struct zfcp_adapter *adapter; 184 185 down(&zfcp_data.config_sema); 186 adapter = dev_get_drvdata(&ccw_device->dev); 187 zfcp_erp_adapter_shutdown(adapter, 0, "ccsoff1", NULL); 188 zfcp_erp_wait(adapter); 189 zfcp_erp_thread_kill(adapter); 190 up(&zfcp_data.config_sema); 191 return 0; 192} 193 194/** 195 * zfcp_ccw_notify - ccw notify function 196 * @ccw_device: pointer to belonging ccw device 197 * @event: indicates if adapter was detached or attached 198 * 199 * This function gets called by the common i/o layer if an adapter has gone 200 * or reappeared. 201 */ 202static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) 203{ 204 struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev); 205 206 switch (event) { 207 case CIO_GONE: 208 dev_warn(&adapter->ccw_device->dev, 209 "The FCP device has been detached\n"); 210 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti1", NULL); 211 break; 212 case CIO_NO_PATH: 213 dev_warn(&adapter->ccw_device->dev, 214 "The CHPID for the FCP device is offline\n"); 215 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti2", NULL); 216 break; 217 case CIO_OPER: 218 dev_info(&adapter->ccw_device->dev, 219 "The FCP device is operational again\n"); 220 zfcp_erp_modify_adapter_status(adapter, "ccnoti3", NULL, 221 ZFCP_STATUS_COMMON_RUNNING, 222 ZFCP_SET); 223 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 224 "ccnoti4", NULL); 225 break; 226 case CIO_BOXED: 227 dev_warn(&adapter->ccw_device->dev, "The FCP device " 228 "did not respond within the specified time\n"); 229 zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL); 230 break; 231 } 232 return 1; 233} 234 235/** 236 * zfcp_ccw_shutdown - handle shutdown from cio 237 * @cdev: device for adapter to shutdown. 238 */ 239static void zfcp_ccw_shutdown(struct ccw_device *cdev) 240{ 241 struct zfcp_adapter *adapter; 242 243 down(&zfcp_data.config_sema); 244 adapter = dev_get_drvdata(&cdev->dev); 245 zfcp_erp_adapter_shutdown(adapter, 0, "ccshut1", NULL); 246 zfcp_erp_wait(adapter); 247 up(&zfcp_data.config_sema); 248} 249 250static struct ccw_driver zfcp_ccw_driver = { 251 .owner = THIS_MODULE, 252 .name = "zfcp", 253 .ids = zfcp_ccw_device_id, 254 .probe = zfcp_ccw_probe, 255 .remove = zfcp_ccw_remove, 256 .set_online = zfcp_ccw_set_online, 257 .set_offline = zfcp_ccw_set_offline, 258 .notify = zfcp_ccw_notify, 259 .shutdown = zfcp_ccw_shutdown, 260 .freeze = zfcp_ccw_suspend, 261 .thaw = zfcp_ccw_activate, 262 .restore = zfcp_ccw_activate, 263}; 264 265/** 266 * zfcp_ccw_register - ccw register function 267 * 268 * Registers the driver at the common i/o layer. This function will be called 269 * at module load time/system start. 270 */ 271int __init zfcp_ccw_register(void) 272{ 273 return ccw_driver_register(&zfcp_ccw_driver); 274} 275 276/** 277 * zfcp_get_adapter_by_busid - find zfcp_adapter struct 278 * @busid: bus id string of zfcp adapter to find 279 */ 280struct zfcp_adapter *zfcp_get_adapter_by_busid(char *busid) 281{ 282 struct ccw_device *ccw_device; 283 struct zfcp_adapter *adapter = NULL; 284 285 ccw_device = get_ccwdev_by_busid(&zfcp_ccw_driver, busid); 286 if (ccw_device) { 287 adapter = dev_get_drvdata(&ccw_device->dev); 288 put_device(&ccw_device->dev); 289 } 290 return adapter; 291}