aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_aux.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_aux.c')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c110
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
37static char *device;
38
39MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com"); 37MODULE_AUTHOR("IBM Deutschland Entwicklung GmbH - linux390@de.ibm.com");
40MODULE_DESCRIPTION("FCP HBA driver"); 38MODULE_DESCRIPTION("FCP HBA driver");
41MODULE_LICENSE("GPL"); 39MODULE_LICENSE("GPL");
42 40
43module_param(device, charp, 0400); 41static char *init_device;
42module_param_named(device, init_device, charp, 0400);
44MODULE_PARM_DESC(device, "specify initial device"); 43MODULE_PARM_DESC(device, "specify initial device");
45 44
46static int zfcp_reqlist_alloc(struct zfcp_adapter *adapter) 45static 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
76static int __init zfcp_device_setup(char *devstr) 75static 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
115static 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
123static 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
163static int __init zfcp_module_init(void) 159static 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
211out_ccw_register: 205out_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
539sysfs_failed: 530sysfs_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);