diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 110 |
1 files changed, 47 insertions, 63 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index e529b55b3ce9..8af7dfbe022c 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -34,13 +34,12 @@ | |||
34 | 34 | ||
35 | #define ZFCP_BUS_ID_SIZE 20 | 35 | #define ZFCP_BUS_ID_SIZE 20 |
36 | 36 | ||
37 | static char *device; | ||
38 | |||
39 | MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); | 37 | MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); |
40 | MODULE_DESCRIPTION("FCP HBA driver"); | 38 | MODULE_DESCRIPTION("FCP HBA driver"); |
41 | MODULE_LICENSE("GPL"); | 39 | MODULE_LICENSE("GPL"); |
42 | 40 | ||
43 | module_param(device, charp, 0400); | 41 | static char *init_device; |
42 | module_param_named(device, init_device, charp, 0400); | ||
44 | MODULE_PARM_DESC(device, "specify initial device"); | 43 | MODULE_PARM_DESC(device, "specify initial device"); |
45 | 44 | ||
46 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) | 45 | static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) |
@@ -73,46 +72,7 @@ int zfcp_reqlist_isempty(struct zfcp_adapter *adapter) | |||
73 | return 1; | 72 | return 1; |
74 | } | 73 | } |
75 | 74 | ||
76 | static int __init zfcp_device_setup(char *devstr) | 75 | static void __init zfcp_init_device_configure(char *busid, u64 wwpn, u64 lun) |
77 | { | ||
78 | char *token; | ||
79 | char *str; | ||
80 | |||
81 | if (!devstr) | ||
82 | return 0; | ||
83 | |||
84 | /* duplicate devstr and keep the original for sysfs presentation*/ | ||
85 | str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); | ||
86 | if (!str) | ||
87 | return 0; | ||
88 | |||
89 | strcpy(str, devstr); | ||
90 | |||
91 | token = strsep(&str, ","); | ||
92 | if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) | ||
93 | goto err_out; | ||
94 | strncpy(zfcp_data.init_busid, token, ZFCP_BUS_ID_SIZE); | ||
95 | |||
96 | token = strsep(&str, ","); | ||
97 | if (!token || strict_strtoull(token, 0, | ||
98 | (unsigned long long *) &zfcp_data.init_wwpn)) | ||
99 | goto err_out; | ||
100 | |||
101 | token = strsep(&str, ","); | ||
102 | if (!token || strict_strtoull(token, 0, | ||
103 | (unsigned long long *) &zfcp_data.init_fcp_lun)) | ||
104 | goto err_out; | ||
105 | |||
106 | kfree(str); | ||
107 | return 1; | ||
108 | |||
109 | err_out: | ||
110 | kfree(str); | ||
111 | pr_err("%s is not a valid SCSI device\n", devstr); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static void __init zfcp_init_device_configure(void) | ||
116 | { | 76 | { |
117 | struct zfcp_adapter *adapter; | 77 | struct zfcp_adapter *adapter; |
118 | struct zfcp_port *port; | 78 | struct zfcp_port *port; |
@@ -120,17 +80,17 @@ static void __init zfcp_init_device_configure(void) | |||
120 | 80 | ||
121 | down(&zfcp_data.config_sema); | 81 | down(&zfcp_data.config_sema); |
122 | read_lock_irq(&zfcp_data.config_lock); | 82 | read_lock_irq(&zfcp_data.config_lock); |
123 | adapter = zfcp_get_adapter_by_busid(zfcp_data.init_busid); | 83 | adapter = zfcp_get_adapter_by_busid(busid); |
124 | if (adapter) | 84 | if (adapter) |
125 | zfcp_adapter_get(adapter); | 85 | zfcp_adapter_get(adapter); |
126 | read_unlock_irq(&zfcp_data.config_lock); | 86 | read_unlock_irq(&zfcp_data.config_lock); |
127 | 87 | ||
128 | if (!adapter) | 88 | if (!adapter) |
129 | goto out_adapter; | 89 | goto out_adapter; |
130 | port = zfcp_port_enqueue(adapter, zfcp_data.init_wwpn, 0, 0); | 90 | port = zfcp_port_enqueue(adapter, wwpn, 0, 0); |
131 | if (IS_ERR(port)) | 91 | if (IS_ERR(port)) |
132 | goto out_port; | 92 | goto out_port; |
133 | unit = zfcp_unit_enqueue(port, zfcp_data.init_fcp_lun); | 93 | unit = zfcp_unit_enqueue(port, lun); |
134 | if (IS_ERR(unit)) | 94 | if (IS_ERR(unit)) |
135 | goto out_unit; | 95 | goto out_unit; |
136 | up(&zfcp_data.config_sema); | 96 | up(&zfcp_data.config_sema); |
@@ -160,6 +120,42 @@ static struct kmem_cache *zfcp_cache_create(int size, char *name) | |||
160 | return kmem_cache_create(name , size, align, 0, NULL); | 120 | return kmem_cache_create(name , size, align, 0, NULL); |
161 | } | 121 | } |
162 | 122 | ||
123 | static void __init zfcp_init_device_setup(char *devstr) | ||
124 | { | ||
125 | char *token; | ||
126 | char *str; | ||
127 | char busid[ZFCP_BUS_ID_SIZE]; | ||
128 | u64 wwpn, lun; | ||
129 | |||
130 | /* duplicate devstr and keep the original for sysfs presentation*/ | ||
131 | str = kmalloc(strlen(devstr) + 1, GFP_KERNEL); | ||
132 | if (!str) | ||
133 | return; | ||
134 | |||
135 | strcpy(str, devstr); | ||
136 | |||
137 | token = strsep(&str, ","); | ||
138 | if (!token || strlen(token) >= ZFCP_BUS_ID_SIZE) | ||
139 | goto err_out; | ||
140 | strncpy(busid, token, ZFCP_BUS_ID_SIZE); | ||
141 | |||
142 | token = strsep(&str, ","); | ||
143 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &wwpn)) | ||
144 | goto err_out; | ||
145 | |||
146 | token = strsep(&str, ","); | ||
147 | if (!token || strict_strtoull(token, 0, (unsigned long long *) &lun)) | ||
148 | goto err_out; | ||
149 | |||
150 | kfree(str); | ||
151 | zfcp_init_device_configure(busid, wwpn, lun); | ||
152 | return; | ||
153 | |||
154 | err_out: | ||
155 | kfree(str); | ||
156 | pr_err("%s is not a valid SCSI device\n", devstr); | ||
157 | } | ||
158 | |||
163 | static int __init zfcp_module_init(void) | 159 | static int __init zfcp_module_init(void) |
164 | { | 160 | { |
165 | int retval = -ENOMEM; | 161 | int retval = -ENOMEM; |
@@ -181,7 +177,6 @@ static int __init zfcp_module_init(void) | |||
181 | 177 | ||
182 | zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq"); | 178 | zfcp_data.work_queue = create_singlethread_workqueue("zfcp_wq"); |
183 | 179 | ||
184 | INIT_LIST_HEAD(&zfcp_data.adapter_list_head); | ||
185 | sema_init(&zfcp_data.config_sema, 1); | 180 | sema_init(&zfcp_data.config_sema, 1); |
186 | rwlock_init(&zfcp_data.config_lock); | 181 | rwlock_init(&zfcp_data.config_lock); |
187 | 182 | ||
@@ -203,10 +198,9 @@ static int __init zfcp_module_init(void) | |||
203 | goto out_ccw_register; | 198 | goto out_ccw_register; |
204 | } | 199 | } |
205 | 200 | ||
206 | if (zfcp_device_setup(device)) | 201 | if (init_device) |
207 | zfcp_init_device_configure(); | 202 | zfcp_init_device_setup(init_device); |
208 | 203 | return 0; | |
209 | goto out; | ||
210 | 204 | ||
211 | out_ccw_register: | 205 | out_ccw_register: |
212 | misc_deregister(&zfcp_cfdc_misc); | 206 | misc_deregister(&zfcp_cfdc_misc); |
@@ -527,14 +521,11 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device) | |||
527 | &zfcp_sysfs_adapter_attrs)) | 521 | &zfcp_sysfs_adapter_attrs)) |
528 | goto sysfs_failed; | 522 | goto sysfs_failed; |
529 | 523 | ||
530 | write_lock_irq(&zfcp_data.config_lock); | ||
531 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); | 524 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &adapter->status); |
532 | list_add_tail(&adapter->list, &zfcp_data.adapter_list_head); | ||
533 | write_unlock_irq(&zfcp_data.config_lock); | ||
534 | |||
535 | zfcp_fc_nameserver_init(adapter); | 525 | zfcp_fc_nameserver_init(adapter); |
536 | 526 | ||
537 | return 0; | 527 | if (!zfcp_adapter_scsi_register(adapter)) |
528 | return 0; | ||
538 | 529 | ||
539 | sysfs_failed: | 530 | sysfs_failed: |
540 | zfcp_adapter_debug_unregister(adapter); | 531 | zfcp_adapter_debug_unregister(adapter); |
@@ -573,14 +564,7 @@ void zfcp_adapter_dequeue(struct zfcp_adapter *adapter) | |||
573 | return; | 564 | return; |
574 | 565 | ||
575 | zfcp_adapter_debug_unregister(adapter); | 566 | zfcp_adapter_debug_unregister(adapter); |
576 | |||
577 | /* remove specified adapter data structure from list */ | ||
578 | write_lock_irq(&zfcp_data.config_lock); | ||
579 | list_del(&adapter->list); | ||
580 | write_unlock_irq(&zfcp_data.config_lock); | ||
581 | |||
582 | zfcp_qdio_free(adapter); | 567 | zfcp_qdio_free(adapter); |
583 | |||
584 | zfcp_free_low_mem_buffers(adapter); | 568 | zfcp_free_low_mem_buffers(adapter); |
585 | kfree(adapter->req_list); | 569 | kfree(adapter->req_list); |
586 | kfree(adapter->fc_stats); | 570 | kfree(adapter->fc_stats); |