diff options
-rw-r--r-- | drivers/scsi/dpt_i2o.c | 132 | ||||
-rw-r--r-- | drivers/scsi/dpti.h | 9 |
2 files changed, 68 insertions, 73 deletions
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 8258506ba7d7..70f48a1a6d58 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -173,20 +173,20 @@ static struct pci_device_id dptids[] = { | |||
173 | }; | 173 | }; |
174 | MODULE_DEVICE_TABLE(pci,dptids); | 174 | MODULE_DEVICE_TABLE(pci,dptids); |
175 | 175 | ||
176 | static void adpt_exit(void); | 176 | static int adpt_detect(struct scsi_host_template* sht) |
177 | |||
178 | static int adpt_detect(void) | ||
179 | { | 177 | { |
180 | struct pci_dev *pDev = NULL; | 178 | struct pci_dev *pDev = NULL; |
181 | adpt_hba* pHba; | 179 | adpt_hba* pHba; |
182 | 180 | ||
181 | adpt_init(); | ||
182 | |||
183 | PINFO("Detecting Adaptec I2O RAID controllers...\n"); | 183 | PINFO("Detecting Adaptec I2O RAID controllers...\n"); |
184 | 184 | ||
185 | /* search for all Adatpec I2O RAID cards */ | 185 | /* search for all Adatpec I2O RAID cards */ |
186 | while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) { | 186 | while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) { |
187 | if(pDev->device == PCI_DPT_DEVICE_ID || | 187 | if(pDev->device == PCI_DPT_DEVICE_ID || |
188 | pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){ | 188 | pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){ |
189 | if(adpt_install_hba(pDev) ){ | 189 | if(adpt_install_hba(sht, pDev) ){ |
190 | PERROR("Could not Init an I2O RAID device\n"); | 190 | PERROR("Could not Init an I2O RAID device\n"); |
191 | PERROR("Will not try to detect others.\n"); | 191 | PERROR("Will not try to detect others.\n"); |
192 | return hba_count-1; | 192 | return hba_count-1; |
@@ -248,33 +248,34 @@ rebuild_sys_tab: | |||
248 | } | 248 | } |
249 | 249 | ||
250 | for (pHba = hba_chain; pHba; pHba = pHba->next) { | 250 | for (pHba = hba_chain; pHba; pHba = pHba->next) { |
251 | if (adpt_scsi_register(pHba) < 0) { | 251 | if( adpt_scsi_register(pHba,sht) < 0){ |
252 | adpt_i2o_delete_hba(pHba); | 252 | adpt_i2o_delete_hba(pHba); |
253 | continue; | 253 | continue; |
254 | } | 254 | } |
255 | pHba->initialized = TRUE; | 255 | pHba->initialized = TRUE; |
256 | pHba->state &= ~DPTI_STATE_RESET; | 256 | pHba->state &= ~DPTI_STATE_RESET; |
257 | scsi_scan_host(pHba->host); | ||
258 | } | 257 | } |
259 | 258 | ||
260 | // Register our control device node | 259 | // Register our control device node |
261 | // nodes will need to be created in /dev to access this | 260 | // nodes will need to be created in /dev to access this |
262 | // the nodes can not be created from within the driver | 261 | // the nodes can not be created from within the driver |
263 | if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) { | 262 | if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) { |
264 | adpt_exit(); | 263 | adpt_i2o_sys_shutdown(); |
265 | return 0; | 264 | return 0; |
266 | } | 265 | } |
267 | return hba_count; | 266 | return hba_count; |
268 | } | 267 | } |
269 | 268 | ||
270 | 269 | ||
271 | static int adpt_release(adpt_hba *pHba) | 270 | /* |
271 | * scsi_unregister will be called AFTER we return. | ||
272 | */ | ||
273 | static int adpt_release(struct Scsi_Host *host) | ||
272 | { | 274 | { |
273 | struct Scsi_Host *shost = pHba->host; | 275 | adpt_hba* pHba = (adpt_hba*) host->hostdata[0]; |
274 | scsi_remove_host(shost); | ||
275 | // adpt_i2o_quiesce_hba(pHba); | 276 | // adpt_i2o_quiesce_hba(pHba); |
276 | adpt_i2o_delete_hba(pHba); | 277 | adpt_i2o_delete_hba(pHba); |
277 | scsi_host_put(shost); | 278 | scsi_unregister(host); |
278 | return 0; | 279 | return 0; |
279 | } | 280 | } |
280 | 281 | ||
@@ -881,7 +882,7 @@ static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p) | |||
881 | #endif | 882 | #endif |
882 | 883 | ||
883 | 884 | ||
884 | static int adpt_install_hba(struct pci_dev* pDev) | 885 | static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) |
885 | { | 886 | { |
886 | 887 | ||
887 | adpt_hba* pHba = NULL; | 888 | adpt_hba* pHba = NULL; |
@@ -1028,6 +1029,8 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) | |||
1028 | 1029 | ||
1029 | 1030 | ||
1030 | mutex_lock(&adpt_configuration_lock); | 1031 | mutex_lock(&adpt_configuration_lock); |
1032 | // scsi_unregister calls our adpt_release which | ||
1033 | // does a quiese | ||
1031 | if(pHba->host){ | 1034 | if(pHba->host){ |
1032 | free_irq(pHba->host->irq, pHba); | 1035 | free_irq(pHba->host->irq, pHba); |
1033 | } | 1036 | } |
@@ -1079,6 +1082,17 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) | |||
1079 | } | 1082 | } |
1080 | 1083 | ||
1081 | 1084 | ||
1085 | static int adpt_init(void) | ||
1086 | { | ||
1087 | printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); | ||
1088 | #ifdef REBOOT_NOTIFIER | ||
1089 | register_reboot_notifier(&adpt_reboot_notifier); | ||
1090 | #endif | ||
1091 | |||
1092 | return 0; | ||
1093 | } | ||
1094 | |||
1095 | |||
1082 | static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) | 1096 | static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun) |
1083 | { | 1097 | { |
1084 | struct adpt_device* d; | 1098 | struct adpt_device* d; |
@@ -2164,6 +2178,37 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d | |||
2164 | } | 2178 | } |
2165 | 2179 | ||
2166 | 2180 | ||
2181 | static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht) | ||
2182 | { | ||
2183 | struct Scsi_Host *host = NULL; | ||
2184 | |||
2185 | host = scsi_register(sht, sizeof(adpt_hba*)); | ||
2186 | if (host == NULL) { | ||
2187 | printk ("%s: scsi_register returned NULL\n",pHba->name); | ||
2188 | return -1; | ||
2189 | } | ||
2190 | host->hostdata[0] = (unsigned long)pHba; | ||
2191 | pHba->host = host; | ||
2192 | |||
2193 | host->irq = pHba->pDev->irq; | ||
2194 | /* no IO ports, so don't have to set host->io_port and | ||
2195 | * host->n_io_port | ||
2196 | */ | ||
2197 | host->io_port = 0; | ||
2198 | host->n_io_port = 0; | ||
2199 | /* see comments in scsi_host.h */ | ||
2200 | host->max_id = 16; | ||
2201 | host->max_lun = 256; | ||
2202 | host->max_channel = pHba->top_scsi_channel + 1; | ||
2203 | host->cmd_per_lun = 1; | ||
2204 | host->unique_id = (uint) pHba; | ||
2205 | host->sg_tablesize = pHba->sg_tablesize; | ||
2206 | host->can_queue = pHba->post_fifo_size; | ||
2207 | |||
2208 | return 0; | ||
2209 | } | ||
2210 | |||
2211 | |||
2167 | static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) | 2212 | static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd) |
2168 | { | 2213 | { |
2169 | adpt_hba* pHba; | 2214 | adpt_hba* pHba; |
@@ -3279,10 +3324,12 @@ static static void adpt_delay(int millisec) | |||
3279 | 3324 | ||
3280 | #endif | 3325 | #endif |
3281 | 3326 | ||
3282 | static struct scsi_host_template adpt_template = { | 3327 | static struct scsi_host_template driver_template = { |
3283 | .name = "dpt_i2o", | 3328 | .name = "dpt_i2o", |
3284 | .proc_name = "dpt_i2o", | 3329 | .proc_name = "dpt_i2o", |
3285 | .proc_info = adpt_proc_info, | 3330 | .proc_info = adpt_proc_info, |
3331 | .detect = adpt_detect, | ||
3332 | .release = adpt_release, | ||
3286 | .info = adpt_info, | 3333 | .info = adpt_info, |
3287 | .queuecommand = adpt_queue, | 3334 | .queuecommand = adpt_queue, |
3288 | .eh_abort_handler = adpt_abort, | 3335 | .eh_abort_handler = adpt_abort, |
@@ -3297,62 +3344,5 @@ static struct scsi_host_template adpt_template = { | |||
3297 | .use_clustering = ENABLE_CLUSTERING, | 3344 | .use_clustering = ENABLE_CLUSTERING, |
3298 | .use_sg_chaining = ENABLE_SG_CHAINING, | 3345 | .use_sg_chaining = ENABLE_SG_CHAINING, |
3299 | }; | 3346 | }; |
3300 | 3347 | #include "scsi_module.c" | |
3301 | static s32 adpt_scsi_register(adpt_hba* pHba) | ||
3302 | { | ||
3303 | struct Scsi_Host *host; | ||
3304 | |||
3305 | host = scsi_host_alloc(&adpt_template, sizeof(adpt_hba*)); | ||
3306 | if (host == NULL) { | ||
3307 | printk ("%s: scsi_host_alloc returned NULL\n",pHba->name); | ||
3308 | return -1; | ||
3309 | } | ||
3310 | host->hostdata[0] = (unsigned long)pHba; | ||
3311 | pHba->host = host; | ||
3312 | |||
3313 | host->irq = pHba->pDev->irq; | ||
3314 | /* no IO ports, so don't have to set host->io_port and | ||
3315 | * host->n_io_port | ||
3316 | */ | ||
3317 | host->io_port = 0; | ||
3318 | host->n_io_port = 0; | ||
3319 | /* see comments in scsi_host.h */ | ||
3320 | host->max_id = 16; | ||
3321 | host->max_lun = 256; | ||
3322 | host->max_channel = pHba->top_scsi_channel + 1; | ||
3323 | host->cmd_per_lun = 1; | ||
3324 | host->unique_id = (uint) pHba; | ||
3325 | host->sg_tablesize = pHba->sg_tablesize; | ||
3326 | host->can_queue = pHba->post_fifo_size; | ||
3327 | |||
3328 | if (scsi_add_host(host, &pHba->pDev->dev)) { | ||
3329 | scsi_host_put(host); | ||
3330 | return -1; | ||
3331 | } | ||
3332 | |||
3333 | return 0; | ||
3334 | } | ||
3335 | |||
3336 | static int __init adpt_init(void) | ||
3337 | { | ||
3338 | int count; | ||
3339 | |||
3340 | printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n"); | ||
3341 | #ifdef REBOOT_NOTIFIER | ||
3342 | register_reboot_notifier(&adpt_reboot_notifier); | ||
3343 | #endif | ||
3344 | |||
3345 | count = adpt_detect(); | ||
3346 | |||
3347 | return count > 0 ? 0 : -ENODEV; | ||
3348 | } | ||
3349 | |||
3350 | static void adpt_exit(void) | ||
3351 | { | ||
3352 | while (hba_chain) | ||
3353 | adpt_release(hba_chain); | ||
3354 | } | ||
3355 | |||
3356 | module_init(adpt_init); | ||
3357 | module_exit(adpt_exit); | ||
3358 | MODULE_LICENSE("GPL"); | 3348 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index 0892f6c70319..fd79068c5869 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h | |||
@@ -28,9 +28,11 @@ | |||
28 | * SCSI interface function Prototypes | 28 | * SCSI interface function Prototypes |
29 | */ | 29 | */ |
30 | 30 | ||
31 | static int adpt_detect(struct scsi_host_template * sht); | ||
31 | static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *)); | 32 | static int adpt_queue(struct scsi_cmnd * cmd, void (*cmdcomplete) (struct scsi_cmnd *)); |
32 | static int adpt_abort(struct scsi_cmnd * cmd); | 33 | static int adpt_abort(struct scsi_cmnd * cmd); |
33 | static int adpt_reset(struct scsi_cmnd* cmd); | 34 | static int adpt_reset(struct scsi_cmnd* cmd); |
35 | static int adpt_release(struct Scsi_Host *host); | ||
34 | static int adpt_slave_configure(struct scsi_device *); | 36 | static int adpt_slave_configure(struct scsi_device *); |
35 | 37 | ||
36 | static const char *adpt_info(struct Scsi_Host *pSHost); | 38 | static const char *adpt_info(struct Scsi_Host *pSHost); |
@@ -47,6 +49,8 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); | |||
47 | 49 | ||
48 | #define DPT_DRIVER_NAME "Adaptec I2O RAID" | 50 | #define DPT_DRIVER_NAME "Adaptec I2O RAID" |
49 | 51 | ||
52 | #ifndef HOSTS_C | ||
53 | |||
50 | #include "dpt/sys_info.h" | 54 | #include "dpt/sys_info.h" |
51 | #include <linux/wait.h> | 55 | #include <linux/wait.h> |
52 | #include "dpt/dpti_i2o.h" | 56 | #include "dpt/dpti_i2o.h" |
@@ -285,7 +289,7 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba); | |||
285 | static s32 adpt_i2o_hrt_get(adpt_hba* pHba); | 289 | static s32 adpt_i2o_hrt_get(adpt_hba* pHba); |
286 | static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); | 290 | static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* dptdevice); |
287 | static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); | 291 | static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd); |
288 | static s32 adpt_scsi_register(adpt_hba* pHba); | 292 | static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht); |
289 | static s32 adpt_hba_reset(adpt_hba* pHba); | 293 | static s32 adpt_hba_reset(adpt_hba* pHba); |
290 | static s32 adpt_i2o_reset_hba(adpt_hba* pHba); | 294 | static s32 adpt_i2o_reset_hba(adpt_hba* pHba); |
291 | static s32 adpt_rescan(adpt_hba* pHba); | 295 | static s32 adpt_rescan(adpt_hba* pHba); |
@@ -295,7 +299,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba); | |||
295 | static void adpt_inquiry(adpt_hba* pHba); | 299 | static void adpt_inquiry(adpt_hba* pHba); |
296 | static void adpt_fail_posted_scbs(adpt_hba* pHba); | 300 | static void adpt_fail_posted_scbs(adpt_hba* pHba); |
297 | static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun); | 301 | static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun); |
298 | static int adpt_install_hba(struct pci_dev* pDev) ; | 302 | static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) ; |
299 | static int adpt_i2o_online_hba(adpt_hba* pHba); | 303 | static int adpt_i2o_online_hba(adpt_hba* pHba); |
300 | static void adpt_i2o_post_wait_complete(u32, int); | 304 | static void adpt_i2o_post_wait_complete(u32, int); |
301 | static int adpt_i2o_systab_send(adpt_hba* pHba); | 305 | static int adpt_i2o_systab_send(adpt_hba* pHba); |
@@ -339,4 +343,5 @@ static void adpt_i386_info(sysInfo_S* si); | |||
339 | #define FW_DEBUG_BLED_OFFSET 8 | 343 | #define FW_DEBUG_BLED_OFFSET 8 |
340 | 344 | ||
341 | #define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01 | 345 | #define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01 |
346 | #endif /* !HOSTS_C */ | ||
342 | #endif /* _DPT_H */ | 347 | #endif /* _DPT_H */ |