static void __init zfcp_init_device_setup(char *devstr) { char *token; char *str; char busid[ZFCP_BUS_ID_SIZE]; u64 wwpn, lun; /* duplicate devstr and keep the original for sysfs presentation*/ str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); if (!str) return; strcpy(str, devstr); token = strsep(&str, ","); if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) goto err_out; strncpy(busid, token, ZFCP_BUS_ID_SIZE); token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &wwpn)) goto err_out; token = strsep(&str, ","); if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) goto err_out; kfree(str); zfcp_init_device_configure(busid, wwpn, lun); return; err_out: kfree(str); pr_err("%s is not a valid SCSI device\n", devstr); }
static int __init zfcp_module_init(void) { int retval = -ENOMEM; zfcp_data.fsf_req_qtcb_cache = zfcp_cache_create( sizeof(struct zfcp_fsf_req_qtcb), "zfcp_fsf"); if (!zfcp_data.fsf_req_qtcb_cache) goto out; zfcp_data.sr_buffer_cache = zfcp_cache_create( sizeof(struct fsf_status_read_buffer), "zfcp_sr"); if (!zfcp_data.sr_buffer_cache) goto out_sr_cache; zfcp_data.gid_pn_cache = zfcp_cache_create( sizeof(struct zfcp_gid_pn_data), "zfcp_gid"); if (!zfcp_data.gid_pn_cache) goto out_gid_cache; INIT_LIST_HEAD(&zfcp_data.adapter_list_head); INIT_LIST_HEAD(&zfcp_data.adapter_remove_lh); sema_init(&zfcp_data.config_sema, 1); rwlock_init(&zfcp_data.config_lock); zfcp_data.scsi_transport_template = fc_attach_transport(&zfcp_transport_functions); if (!zfcp_data.scsi_transport_template) goto out_transport; retval = misc_register(&zfcp_cfdc_misc); if (retval) { pr_err("zfcp: registration of misc device zfcp_cfdc failed\n"); goto out_misc; } retval = zfcp_ccw_register(); if (retval) { pr_err("zfcp: Registration with common I/O layer failed.\n"); goto out_ccw_register; } if (zfcp_device_setup(device)) zfcp_init_device_configure(); goto out; out_ccw_register: misc_deregister(&zfcp_cfdc_misc); out_misc: fc_release_transport(zfcp_data.scsi_transport_template); out_transport: kmem_cache_destroy(zfcp_data.gid_pn_cache); out_gid_cache: kmem_cache_destroy(zfcp_data.sr_buffer_cache); out_sr_cache: kmem_cache_destroy(zfcp_data.fsf_req_qtcb_cache); out: return retval; }