diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2007-05-03 12:13:08 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-22 11:39:08 -0400 |
commit | 67b2009ae26ece6a54d0b689827903f53d6d21e6 (patch) | |
tree | 4ad832dd8dcf3ada2530ef12f0f32769bc595e7e /drivers/scsi/ibmmca.c | |
parent | a53eb5e060c0ec7245c8f93b9dcd94afa6041e06 (diff) |
[SCSI] ibmmca: convert to new probing API and fix oopses
This is basically a straight conversion. I have one of these things, so
I know it works ... my problem is that it has a wierd SCA like
connector, so I can't connect anything to it (no cables).
However, previously it panic'd in the interrupt, now it completes a bus
scan.
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/ibmmca.c')
-rw-r--r-- | drivers/scsi/ibmmca.c | 1245 |
1 files changed, 562 insertions, 683 deletions
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 0e57fb6964d5..bec242df3613 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c | |||
@@ -31,14 +31,21 @@ | |||
31 | #include <linux/mca.h> | 31 | #include <linux/mca.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/mca-legacy.h> | ||
35 | 34 | ||
36 | #include <asm/system.h> | 35 | #include <asm/system.h> |
37 | #include <asm/io.h> | 36 | #include <asm/io.h> |
38 | 37 | ||
39 | #include "scsi.h" | 38 | #include "scsi.h" |
40 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
41 | #include "ibmmca.h" | 40 | |
41 | /* Common forward declarations for all Linux-versions: */ | ||
42 | static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); | ||
43 | static int ibmmca_abort (Scsi_Cmnd *); | ||
44 | static int ibmmca_host_reset (Scsi_Cmnd *); | ||
45 | static int ibmmca_biosparam (struct scsi_device *, struct block_device *, sector_t, int *); | ||
46 | static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout); | ||
47 | |||
48 | |||
42 | 49 | ||
43 | /* current version of this driver-source: */ | 50 | /* current version of this driver-source: */ |
44 | #define IBMMCA_SCSI_DRIVER_VERSION "4.0b-ac" | 51 | #define IBMMCA_SCSI_DRIVER_VERSION "4.0b-ac" |
@@ -65,11 +72,11 @@ | |||
65 | #define IM_DEBUG_CMD_DEVICE TYPE_TAPE | 72 | #define IM_DEBUG_CMD_DEVICE TYPE_TAPE |
66 | 73 | ||
67 | /* relative addresses of hardware registers on a subsystem */ | 74 | /* relative addresses of hardware registers on a subsystem */ |
68 | #define IM_CMD_REG(hi) (hosts[(hi)]->io_port) /*Command Interface, (4 bytes long) */ | 75 | #define IM_CMD_REG(h) ((h)->io_port) /*Command Interface, (4 bytes long) */ |
69 | #define IM_ATTN_REG(hi) (hosts[(hi)]->io_port+4) /*Attention (1 byte) */ | 76 | #define IM_ATTN_REG(h) ((h)->io_port+4) /*Attention (1 byte) */ |
70 | #define IM_CTR_REG(hi) (hosts[(hi)]->io_port+5) /*Basic Control (1 byte) */ | 77 | #define IM_CTR_REG(h) ((h)->io_port+5) /*Basic Control (1 byte) */ |
71 | #define IM_INTR_REG(hi) (hosts[(hi)]->io_port+6) /*Interrupt Status (1 byte, r/o) */ | 78 | #define IM_INTR_REG(h) ((h)->io_port+6) /*Interrupt Status (1 byte, r/o) */ |
72 | #define IM_STAT_REG(hi) (hosts[(hi)]->io_port+7) /*Basic Status (1 byte, read only) */ | 79 | #define IM_STAT_REG(h) ((h)->io_port+7) /*Basic Status (1 byte, read only) */ |
73 | 80 | ||
74 | /* basic I/O-port of first adapter */ | 81 | /* basic I/O-port of first adapter */ |
75 | #define IM_IO_PORT 0x3540 | 82 | #define IM_IO_PORT 0x3540 |
@@ -266,30 +273,36 @@ static int global_adapter_speed = 0; /* full speed by default */ | |||
266 | if ((display_mode & LED_ACTIVITY)||(!display_mode)) \ | 273 | if ((display_mode & LED_ACTIVITY)||(!display_mode)) \ |
267 | outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); } | 274 | outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); } |
268 | 275 | ||
269 | /*list of supported subsystems */ | ||
270 | struct subsys_list_struct { | ||
271 | unsigned short mca_id; | ||
272 | char *description; | ||
273 | }; | ||
274 | |||
275 | /* types of different supported hardware that goes to hostdata special */ | 276 | /* types of different supported hardware that goes to hostdata special */ |
276 | #define IBM_SCSI2_FW 0 | 277 | #define IBM_SCSI2_FW 0 |
277 | #define IBM_7568_WCACHE 1 | 278 | #define IBM_7568_WCACHE 1 |
278 | #define IBM_EXP_UNIT 2 | 279 | #define IBM_EXP_UNIT 2 |
279 | #define IBM_SCSI_WCACHE 3 | 280 | #define IBM_SCSI_WCACHE 3 |
280 | #define IBM_SCSI 4 | 281 | #define IBM_SCSI 4 |
282 | #define IBM_INTEGSCSI 5 | ||
281 | 283 | ||
282 | /* other special flags for hostdata structure */ | 284 | /* other special flags for hostdata structure */ |
283 | #define FORCED_DETECTION 100 | 285 | #define FORCED_DETECTION 100 |
284 | #define INTEGRATED_SCSI 101 | 286 | #define INTEGRATED_SCSI 101 |
285 | 287 | ||
286 | /* List of possible IBM-SCSI-adapters */ | 288 | /* List of possible IBM-SCSI-adapters */ |
287 | static struct subsys_list_struct subsys_list[] = { | 289 | static short ibmmca_id_table[] = { |
288 | {0x8efc, "IBM SCSI-2 F/W Adapter"}, /* special = 0 */ | 290 | 0x8efc, |
289 | {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"}, /* special = 1 */ | 291 | 0x8efd, |
290 | {0x8ef8, "IBM Expansion Unit SCSI Controller"}, /* special = 2 */ | 292 | 0x8ef8, |
291 | {0x8eff, "IBM SCSI Adapter w/Cache"}, /* special = 3 */ | 293 | 0x8eff, |
292 | {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */ | 294 | 0x8efe, |
295 | /* No entry for integrated SCSI, that's part of the register */ | ||
296 | 0 | ||
297 | }; | ||
298 | |||
299 | static const char *ibmmca_description[] = { | ||
300 | "IBM SCSI-2 F/W Adapter", /* special = 0 */ | ||
301 | "IBM 7568 Industrial Computer SCSI Adapter w/Cache", /* special = 1 */ | ||
302 | "IBM Expansion Unit SCSI Controller", /* special = 2 */ | ||
303 | "IBM SCSI Adapter w/Cache", /* special = 3 */ | ||
304 | "IBM SCSI Adapter", /* special = 4 */ | ||
305 | "IBM Integrated SCSI Controller", /* special = 5 */ | ||
293 | }; | 306 | }; |
294 | 307 | ||
295 | /* Max number of logical devices (can be up from 0 to 14). 15 is the address | 308 | /* Max number of logical devices (can be up from 0 to 14). 15 is the address |
@@ -375,30 +388,30 @@ struct ibmmca_hostdata { | |||
375 | }; | 388 | }; |
376 | 389 | ||
377 | /* macros to access host data structure */ | 390 | /* macros to access host data structure */ |
378 | #define subsystem_pun(hi) (hosts[(hi)]->this_id) | 391 | #define subsystem_pun(h) ((h)->this_id) |
379 | #define subsystem_maxid(hi) (hosts[(hi)]->max_id) | 392 | #define subsystem_maxid(h) ((h)->max_id) |
380 | #define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld) | 393 | #define ld(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_ld) |
381 | #define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn) | 394 | #define get_ldn(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_get_ldn) |
382 | #define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi) | 395 | #define get_scsi(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_get_scsi) |
383 | #define local_checking_phase_flag(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_local_checking_phase_flag) | 396 | #define local_checking_phase_flag(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_local_checking_phase_flag) |
384 | #define got_interrupt(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_got_interrupt) | 397 | #define got_interrupt(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_got_interrupt) |
385 | #define stat_result(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_stat_result) | 398 | #define stat_result(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_stat_result) |
386 | #define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status) | 399 | #define reset_status(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_reset_status) |
387 | #define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command) | 400 | #define last_scsi_command(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_command) |
388 | #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type) | 401 | #define last_scsi_type(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_type) |
389 | #define last_scsi_blockcount(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_blockcount) | 402 | #define last_scsi_blockcount(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_blockcount) |
390 | #define last_scsi_logical_block(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_logical_block) | 403 | #define last_scsi_logical_block(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_logical_block) |
391 | #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type) | 404 | #define last_scsi_type(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_last_scsi_type) |
392 | #define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn) | 405 | #define next_ldn(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_next_ldn) |
393 | #define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS) | 406 | #define IBM_DS(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_IBM_DS) |
394 | #define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special) | 407 | #define special(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_special) |
395 | #define subsystem_connector_size(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_connector_size) | 408 | #define subsystem_connector_size(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_connector_size) |
396 | #define adapter_speed(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_adapter_speed) | 409 | #define adapter_speed(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_adapter_speed) |
397 | #define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[2]) | 410 | #define pos2(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[2]) |
398 | #define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[3]) | 411 | #define pos3(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[3]) |
399 | #define pos4(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[4]) | 412 | #define pos4(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[4]) |
400 | #define pos5(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[5]) | 413 | #define pos5(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[5]) |
401 | #define pos6(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[6]) | 414 | #define pos6(h) (((struct ibmmca_hostdata *) (h)->hostdata)->_pos[6]) |
402 | 415 | ||
403 | /* Define a arbitrary number as subsystem-marker-type. This number is, as | 416 | /* Define a arbitrary number as subsystem-marker-type. This number is, as |
404 | described in the ANSI-SCSI-standard, not occupied by other device-types. */ | 417 | described in the ANSI-SCSI-standard, not occupied by other device-types. */ |
@@ -459,11 +472,6 @@ MODULE_LICENSE("GPL"); | |||
459 | /*counter of concurrent disk read/writes, to turn on/off disk led */ | 472 | /*counter of concurrent disk read/writes, to turn on/off disk led */ |
460 | static int disk_rw_in_progress = 0; | 473 | static int disk_rw_in_progress = 0; |
461 | 474 | ||
462 | /* host information */ | ||
463 | static int found = 0; | ||
464 | static struct Scsi_Host *hosts[IM_MAX_HOSTS + 1] = { | ||
465 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | ||
466 | }; | ||
467 | static unsigned int pos[8]; /* whole pos register-line for diagnosis */ | 475 | static unsigned int pos[8]; /* whole pos register-line for diagnosis */ |
468 | /* Taking into account the additions, made by ZP Gu. | 476 | /* Taking into account the additions, made by ZP Gu. |
469 | * This selects now the preset value from the configfile and | 477 | * This selects now the preset value from the configfile and |
@@ -474,70 +482,68 @@ static char ibm_ansi_order = 1; | |||
474 | static char ibm_ansi_order = 0; | 482 | static char ibm_ansi_order = 0; |
475 | #endif | 483 | #endif |
476 | 484 | ||
477 | static void issue_cmd(int, unsigned long, unsigned char); | 485 | static void issue_cmd(struct Scsi_Host *, unsigned long, unsigned char); |
478 | static void internal_done(Scsi_Cmnd * cmd); | 486 | static void internal_done(Scsi_Cmnd * cmd); |
479 | static void check_devices(int, int); | 487 | static void check_devices(struct Scsi_Host *, int); |
480 | static int immediate_assign(int, unsigned int, unsigned int, unsigned int, unsigned int); | 488 | static int immediate_assign(struct Scsi_Host *, unsigned int, unsigned int, unsigned int, unsigned int); |
481 | static int immediate_feature(int, unsigned int, unsigned int); | 489 | static int immediate_feature(struct Scsi_Host *, unsigned int, unsigned int); |
482 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET | 490 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET |
483 | static int immediate_reset(int, unsigned int); | 491 | static int immediate_reset(struct Scsi_Host *, unsigned int); |
484 | #endif | 492 | #endif |
485 | static int device_inquiry(int, int); | 493 | static int device_inquiry(struct Scsi_Host *, int); |
486 | static int read_capacity(int, int); | 494 | static int read_capacity(struct Scsi_Host *, int); |
487 | static int get_pos_info(int); | 495 | static int get_pos_info(struct Scsi_Host *); |
488 | static char *ti_p(int); | 496 | static char *ti_p(int); |
489 | static char *ti_l(int); | 497 | static char *ti_l(int); |
490 | static char *ibmrate(unsigned int, int); | 498 | static char *ibmrate(unsigned int, int); |
491 | static int probe_display(int); | 499 | static int probe_display(int); |
492 | static int probe_bus_mode(int); | 500 | static int probe_bus_mode(struct Scsi_Host *); |
493 | static int device_exists(int, int, int *, int *); | 501 | static int device_exists(struct Scsi_Host *, int, int *, int *); |
494 | static struct Scsi_Host *ibmmca_register(struct scsi_host_template *, int, int, int, char *); | ||
495 | static int option_setup(char *); | 502 | static int option_setup(char *); |
496 | /* local functions needed for proc_info */ | 503 | /* local functions needed for proc_info */ |
497 | static int ldn_access_load(int, int); | 504 | static int ldn_access_load(struct Scsi_Host *, int); |
498 | static int ldn_access_total_read_write(int); | 505 | static int ldn_access_total_read_write(struct Scsi_Host *); |
499 | 506 | ||
500 | static irqreturn_t interrupt_handler(int irq, void *dev_id) | 507 | static irqreturn_t interrupt_handler(int irq, void *dev_id) |
501 | { | 508 | { |
502 | int host_index, ihost_index; | ||
503 | unsigned int intr_reg; | 509 | unsigned int intr_reg; |
504 | unsigned int cmd_result; | 510 | unsigned int cmd_result; |
505 | unsigned int ldn; | 511 | unsigned int ldn; |
512 | unsigned long flags; | ||
506 | Scsi_Cmnd *cmd; | 513 | Scsi_Cmnd *cmd; |
507 | int lastSCSI; | 514 | int lastSCSI; |
508 | struct Scsi_Host *dev = dev_id; | 515 | struct device *dev = dev_id; |
516 | struct Scsi_Host *shpnt = dev_get_drvdata(dev); | ||
509 | 517 | ||
510 | spin_lock(dev->host_lock); | 518 | spin_lock_irqsave(shpnt->host_lock, flags); |
511 | /* search for one adapter-response on shared interrupt */ | 519 | |
512 | for (host_index = 0; hosts[host_index] && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST); host_index++); | 520 | if(!(inb(IM_STAT_REG(shpnt)) & IM_INTR_REQUEST)) { |
513 | /* return if some other device on this IRQ caused the interrupt */ | 521 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
514 | if (!hosts[host_index]) { | ||
515 | spin_unlock(dev->host_lock); | ||
516 | return IRQ_NONE; | 522 | return IRQ_NONE; |
517 | } | 523 | } |
518 | 524 | ||
519 | /* the reset-function already did all the job, even ints got | 525 | /* the reset-function already did all the job, even ints got |
520 | renabled on the subsystem, so just return */ | 526 | renabled on the subsystem, so just return */ |
521 | if ((reset_status(host_index) == IM_RESET_NOT_IN_PROGRESS_NO_INT) || (reset_status(host_index) == IM_RESET_FINISHED_OK_NO_INT)) { | 527 | if ((reset_status(shpnt) == IM_RESET_NOT_IN_PROGRESS_NO_INT) || (reset_status(shpnt) == IM_RESET_FINISHED_OK_NO_INT)) { |
522 | reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS; | 528 | reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS; |
523 | spin_unlock(dev->host_lock); | 529 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
524 | return IRQ_HANDLED; | 530 | return IRQ_HANDLED; |
525 | } | 531 | } |
526 | 532 | ||
527 | /*must wait for attention reg not busy, then send EOI to subsystem */ | 533 | /*must wait for attention reg not busy, then send EOI to subsystem */ |
528 | while (1) { | 534 | while (1) { |
529 | if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY)) | 535 | if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY)) |
530 | break; | 536 | break; |
531 | cpu_relax(); | 537 | cpu_relax(); |
532 | } | 538 | } |
533 | ihost_index = host_index; | 539 | |
534 | /*get command result and logical device */ | 540 | /*get command result and logical device */ |
535 | intr_reg = (unsigned char) (inb(IM_INTR_REG(ihost_index))); | 541 | intr_reg = (unsigned char) (inb(IM_INTR_REG(shpnt))); |
536 | cmd_result = intr_reg & 0xf0; | 542 | cmd_result = intr_reg & 0xf0; |
537 | ldn = intr_reg & 0x0f; | 543 | ldn = intr_reg & 0x0f; |
538 | /* get the last_scsi_command here */ | 544 | /* get the last_scsi_command here */ |
539 | lastSCSI = last_scsi_command(ihost_index)[ldn]; | 545 | lastSCSI = last_scsi_command(shpnt)[ldn]; |
540 | outb(IM_EOI | ldn, IM_ATTN_REG(ihost_index)); | 546 | outb(IM_EOI | ldn, IM_ATTN_REG(shpnt)); |
541 | 547 | ||
542 | /*these should never happen (hw fails, or a local programming bug) */ | 548 | /*these should never happen (hw fails, or a local programming bug) */ |
543 | if (!global_command_error_excuse) { | 549 | if (!global_command_error_excuse) { |
@@ -547,38 +553,38 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
547 | case IM_SOFTWARE_SEQUENCING_ERROR: | 553 | case IM_SOFTWARE_SEQUENCING_ERROR: |
548 | case IM_CMD_ERROR: | 554 | case IM_CMD_ERROR: |
549 | printk(KERN_ERR "IBM MCA SCSI: Fatal Subsystem ERROR!\n"); | 555 | printk(KERN_ERR "IBM MCA SCSI: Fatal Subsystem ERROR!\n"); |
550 | printk(KERN_ERR " Last cmd=0x%x, ena=%x, len=", lastSCSI, ld(ihost_index)[ldn].scb.enable); | 556 | printk(KERN_ERR " Last cmd=0x%x, ena=%x, len=", lastSCSI, ld(shpnt)[ldn].scb.enable); |
551 | if (ld(ihost_index)[ldn].cmd) | 557 | if (ld(shpnt)[ldn].cmd) |
552 | printk("%ld/%ld,", (long) (ld(ihost_index)[ldn].cmd->request_bufflen), (long) (ld(ihost_index)[ldn].scb.sys_buf_length)); | 558 | printk("%ld/%ld,", (long) (ld(shpnt)[ldn].cmd->request_bufflen), (long) (ld(shpnt)[ldn].scb.sys_buf_length)); |
553 | else | 559 | else |
554 | printk("none,"); | 560 | printk("none,"); |
555 | if (ld(ihost_index)[ldn].cmd) | 561 | if (ld(shpnt)[ldn].cmd) |
556 | printk("Blocksize=%d", ld(ihost_index)[ldn].scb.u2.blk.length); | 562 | printk("Blocksize=%d", ld(shpnt)[ldn].scb.u2.blk.length); |
557 | else | 563 | else |
558 | printk("Blocksize=none"); | 564 | printk("Blocksize=none"); |
559 | printk(", host=0x%x, ldn=0x%x\n", ihost_index, ldn); | 565 | printk(", host=%p, ldn=0x%x\n", shpnt, ldn); |
560 | if (ld(ihost_index)[ldn].cmd) { | 566 | if (ld(shpnt)[ldn].cmd) { |
561 | printk(KERN_ERR "Blockcount=%d/%d\n", last_scsi_blockcount(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u2.blk.count); | 567 | printk(KERN_ERR "Blockcount=%d/%d\n", last_scsi_blockcount(shpnt)[ldn], ld(shpnt)[ldn].scb.u2.blk.count); |
562 | printk(KERN_ERR "Logical block=%lx/%lx\n", last_scsi_logical_block(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u1.log_blk_adr); | 568 | printk(KERN_ERR "Logical block=%lx/%lx\n", last_scsi_logical_block(shpnt)[ldn], ld(shpnt)[ldn].scb.u1.log_blk_adr); |
563 | } | 569 | } |
564 | printk(KERN_ERR "Reason given: %s\n", (cmd_result == IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" : (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" : (cmd_result == IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN"); | 570 | printk(KERN_ERR "Reason given: %s\n", (cmd_result == IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" : (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" : (cmd_result == IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN"); |
565 | /* if errors appear, enter this section to give detailed info */ | 571 | /* if errors appear, enter this section to give detailed info */ |
566 | printk(KERN_ERR "IBM MCA SCSI: Subsystem Error-Status follows:\n"); | 572 | printk(KERN_ERR "IBM MCA SCSI: Subsystem Error-Status follows:\n"); |
567 | printk(KERN_ERR " Command Type................: %x\n", last_scsi_type(ihost_index)[ldn]); | 573 | printk(KERN_ERR " Command Type................: %x\n", last_scsi_type(shpnt)[ldn]); |
568 | printk(KERN_ERR " Attention Register..........: %x\n", inb(IM_ATTN_REG(ihost_index))); | 574 | printk(KERN_ERR " Attention Register..........: %x\n", inb(IM_ATTN_REG(shpnt))); |
569 | printk(KERN_ERR " Basic Control Register......: %x\n", inb(IM_CTR_REG(ihost_index))); | 575 | printk(KERN_ERR " Basic Control Register......: %x\n", inb(IM_CTR_REG(shpnt))); |
570 | printk(KERN_ERR " Interrupt Status Register...: %x\n", intr_reg); | 576 | printk(KERN_ERR " Interrupt Status Register...: %x\n", intr_reg); |
571 | printk(KERN_ERR " Basic Status Register.......: %x\n", inb(IM_STAT_REG(ihost_index))); | 577 | printk(KERN_ERR " Basic Status Register.......: %x\n", inb(IM_STAT_REG(shpnt))); |
572 | if ((last_scsi_type(ihost_index)[ldn] == IM_SCB) || (last_scsi_type(ihost_index)[ldn] == IM_LONG_SCB)) { | 578 | if ((last_scsi_type(shpnt)[ldn] == IM_SCB) || (last_scsi_type(shpnt)[ldn] == IM_LONG_SCB)) { |
573 | printk(KERN_ERR " SCB-Command.................: %x\n", ld(ihost_index)[ldn].scb.command); | 579 | printk(KERN_ERR " SCB-Command.................: %x\n", ld(shpnt)[ldn].scb.command); |
574 | printk(KERN_ERR " SCB-Enable..................: %x\n", ld(ihost_index)[ldn].scb.enable); | 580 | printk(KERN_ERR " SCB-Enable..................: %x\n", ld(shpnt)[ldn].scb.enable); |
575 | printk(KERN_ERR " SCB-logical block address...: %lx\n", ld(ihost_index)[ldn].scb.u1.log_blk_adr); | 581 | printk(KERN_ERR " SCB-logical block address...: %lx\n", ld(shpnt)[ldn].scb.u1.log_blk_adr); |
576 | printk(KERN_ERR " SCB-system buffer address...: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_adr); | 582 | printk(KERN_ERR " SCB-system buffer address...: %lx\n", ld(shpnt)[ldn].scb.sys_buf_adr); |
577 | printk(KERN_ERR " SCB-system buffer length....: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_length); | 583 | printk(KERN_ERR " SCB-system buffer length....: %lx\n", ld(shpnt)[ldn].scb.sys_buf_length); |
578 | printk(KERN_ERR " SCB-tsb address.............: %lx\n", ld(ihost_index)[ldn].scb.tsb_adr); | 584 | printk(KERN_ERR " SCB-tsb address.............: %lx\n", ld(shpnt)[ldn].scb.tsb_adr); |
579 | printk(KERN_ERR " SCB-Chain address...........: %lx\n", ld(ihost_index)[ldn].scb.scb_chain_adr); | 585 | printk(KERN_ERR " SCB-Chain address...........: %lx\n", ld(shpnt)[ldn].scb.scb_chain_adr); |
580 | printk(KERN_ERR " SCB-block count.............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.count); | 586 | printk(KERN_ERR " SCB-block count.............: %x\n", ld(shpnt)[ldn].scb.u2.blk.count); |
581 | printk(KERN_ERR " SCB-block length............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.length); | 587 | printk(KERN_ERR " SCB-block length............: %x\n", ld(shpnt)[ldn].scb.u2.blk.length); |
582 | } | 588 | } |
583 | printk(KERN_ERR " Send this report to the maintainer.\n"); | 589 | printk(KERN_ERR " Send this report to the maintainer.\n"); |
584 | panic("IBM MCA SCSI: Fatal error message from the subsystem (0x%X,0x%X)!\n", lastSCSI, cmd_result); | 590 | panic("IBM MCA SCSI: Fatal error message from the subsystem (0x%X,0x%X)!\n", lastSCSI, cmd_result); |
@@ -600,72 +606,73 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
600 | } | 606 | } |
601 | } | 607 | } |
602 | /* if no panic appeared, increase the interrupt-counter */ | 608 | /* if no panic appeared, increase the interrupt-counter */ |
603 | IBM_DS(ihost_index).total_interrupts++; | 609 | IBM_DS(shpnt).total_interrupts++; |
604 | /*only for local checking phase */ | 610 | /*only for local checking phase */ |
605 | if (local_checking_phase_flag(ihost_index)) { | 611 | if (local_checking_phase_flag(shpnt)) { |
606 | stat_result(ihost_index) = cmd_result; | 612 | stat_result(shpnt) = cmd_result; |
607 | got_interrupt(ihost_index) = 1; | 613 | got_interrupt(shpnt) = 1; |
608 | reset_status(ihost_index) = IM_RESET_FINISHED_OK; | 614 | reset_status(shpnt) = IM_RESET_FINISHED_OK; |
609 | last_scsi_command(ihost_index)[ldn] = NO_SCSI; | 615 | last_scsi_command(shpnt)[ldn] = NO_SCSI; |
610 | spin_unlock(dev->host_lock); | 616 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
611 | return IRQ_HANDLED; | 617 | return IRQ_HANDLED; |
612 | } | 618 | } |
613 | /* handling of commands coming from upper level of scsi driver */ | 619 | /* handling of commands coming from upper level of scsi driver */ |
614 | if (last_scsi_type(ihost_index)[ldn] == IM_IMM_CMD) { | 620 | if (last_scsi_type(shpnt)[ldn] == IM_IMM_CMD) { |
615 | /* verify ldn, and may handle rare reset immediate command */ | 621 | /* verify ldn, and may handle rare reset immediate command */ |
616 | if ((reset_status(ihost_index) == IM_RESET_IN_PROGRESS) && (last_scsi_command(ihost_index)[ldn] == IM_RESET_IMM_CMD)) { | 622 | if ((reset_status(shpnt) == IM_RESET_IN_PROGRESS) && (last_scsi_command(shpnt)[ldn] == IM_RESET_IMM_CMD)) { |
617 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) { | 623 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) { |
618 | disk_rw_in_progress = 0; | 624 | disk_rw_in_progress = 0; |
619 | PS2_DISK_LED_OFF(); | 625 | PS2_DISK_LED_OFF(); |
620 | reset_status(ihost_index) = IM_RESET_FINISHED_FAIL; | 626 | reset_status(shpnt) = IM_RESET_FINISHED_FAIL; |
621 | } else { | 627 | } else { |
622 | /*reset disk led counter, turn off disk led */ | 628 | /*reset disk led counter, turn off disk led */ |
623 | disk_rw_in_progress = 0; | 629 | disk_rw_in_progress = 0; |
624 | PS2_DISK_LED_OFF(); | 630 | PS2_DISK_LED_OFF(); |
625 | reset_status(ihost_index) = IM_RESET_FINISHED_OK; | 631 | reset_status(shpnt) = IM_RESET_FINISHED_OK; |
626 | } | 632 | } |
627 | stat_result(ihost_index) = cmd_result; | 633 | stat_result(shpnt) = cmd_result; |
628 | last_scsi_command(ihost_index)[ldn] = NO_SCSI; | 634 | last_scsi_command(shpnt)[ldn] = NO_SCSI; |
629 | last_scsi_type(ihost_index)[ldn] = 0; | 635 | last_scsi_type(shpnt)[ldn] = 0; |
630 | spin_unlock(dev->host_lock); | 636 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
631 | return IRQ_HANDLED; | 637 | return IRQ_HANDLED; |
632 | } else if (last_scsi_command(ihost_index)[ldn] == IM_ABORT_IMM_CMD) { | 638 | } else if (last_scsi_command(shpnt)[ldn] == IM_ABORT_IMM_CMD) { |
633 | /* react on SCSI abort command */ | 639 | /* react on SCSI abort command */ |
634 | #ifdef IM_DEBUG_PROBE | 640 | #ifdef IM_DEBUG_PROBE |
635 | printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n"); | 641 | printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n"); |
636 | #endif | 642 | #endif |
637 | disk_rw_in_progress = 0; | 643 | disk_rw_in_progress = 0; |
638 | PS2_DISK_LED_OFF(); | 644 | PS2_DISK_LED_OFF(); |
639 | cmd = ld(ihost_index)[ldn].cmd; | 645 | cmd = ld(shpnt)[ldn].cmd; |
640 | ld(ihost_index)[ldn].cmd = NULL; | 646 | ld(shpnt)[ldn].cmd = NULL; |
641 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) | 647 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) |
642 | cmd->result = DID_NO_CONNECT << 16; | 648 | cmd->result = DID_NO_CONNECT << 16; |
643 | else | 649 | else |
644 | cmd->result = DID_ABORT << 16; | 650 | cmd->result = DID_ABORT << 16; |
645 | stat_result(ihost_index) = cmd_result; | 651 | stat_result(shpnt) = cmd_result; |
646 | last_scsi_command(ihost_index)[ldn] = NO_SCSI; | 652 | last_scsi_command(shpnt)[ldn] = NO_SCSI; |
647 | last_scsi_type(ihost_index)[ldn] = 0; | 653 | last_scsi_type(shpnt)[ldn] = 0; |
648 | if (cmd->scsi_done) | 654 | if (cmd->scsi_done) |
649 | (cmd->scsi_done) (cmd); /* should be the internal_done */ | 655 | (cmd->scsi_done) (cmd); /* should be the internal_done */ |
650 | spin_unlock(dev->host_lock); | 656 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
651 | return IRQ_HANDLED; | 657 | return IRQ_HANDLED; |
652 | } else { | 658 | } else { |
653 | disk_rw_in_progress = 0; | 659 | disk_rw_in_progress = 0; |
654 | PS2_DISK_LED_OFF(); | 660 | PS2_DISK_LED_OFF(); |
655 | reset_status(ihost_index) = IM_RESET_FINISHED_OK; | 661 | reset_status(shpnt) = IM_RESET_FINISHED_OK; |
656 | stat_result(ihost_index) = cmd_result; | 662 | stat_result(shpnt) = cmd_result; |
657 | last_scsi_command(ihost_index)[ldn] = NO_SCSI; | 663 | last_scsi_command(shpnt)[ldn] = NO_SCSI; |
658 | spin_unlock(dev->host_lock); | 664 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
659 | return IRQ_HANDLED; | 665 | return IRQ_HANDLED; |
660 | } | 666 | } |
661 | } | 667 | } |
662 | last_scsi_command(ihost_index)[ldn] = NO_SCSI; | 668 | last_scsi_command(shpnt)[ldn] = NO_SCSI; |
663 | last_scsi_type(ihost_index)[ldn] = 0; | 669 | last_scsi_type(shpnt)[ldn] = 0; |
664 | cmd = ld(ihost_index)[ldn].cmd; | 670 | cmd = ld(shpnt)[ldn].cmd; |
665 | ld(ihost_index)[ldn].cmd = NULL; | 671 | ld(shpnt)[ldn].cmd = NULL; |
666 | #ifdef IM_DEBUG_TIMEOUT | 672 | #ifdef IM_DEBUG_TIMEOUT |
667 | if (cmd) { | 673 | if (cmd) { |
668 | if ((cmd->target == TIMEOUT_PUN) && (cmd->device->lun == TIMEOUT_LUN)) { | 674 | if ((cmd->target == TIMEOUT_PUN) && (cmd->device->lun == TIMEOUT_LUN)) { |
675 | spin_unlock_irqsave(shpnt->host_lock, flags); | ||
669 | printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->device->lun); | 676 | printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->device->lun); |
670 | return IRQ_HANDLED; | 677 | return IRQ_HANDLED; |
671 | } | 678 | } |
@@ -674,15 +681,15 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
674 | /*if no command structure, just return, else clear cmd */ | 681 | /*if no command structure, just return, else clear cmd */ |
675 | if (!cmd) | 682 | if (!cmd) |
676 | { | 683 | { |
677 | spin_unlock(dev->host_lock); | 684 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
678 | return IRQ_HANDLED; | 685 | return IRQ_HANDLED; |
679 | } | 686 | } |
680 | 687 | ||
681 | #ifdef IM_DEBUG_INT | 688 | #ifdef IM_DEBUG_INT |
682 | printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", cmd->cmnd[0], intr_reg, ld(ihost_index)[ldn].tsb.dev_status, ld(ihost_index)[ldn].tsb.cmd_status, ld(ihost_index)[ldn].tsb.dev_error, ld(ihost_index)[ldn].tsb.cmd_error); | 689 | printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", cmd->cmnd[0], intr_reg, ld(shpnt)[ldn].tsb.dev_status, ld(shpnt)[ldn].tsb.cmd_status, ld(shpnt)[ldn].tsb.dev_error, ld(shpnt)[ldn].tsb.cmd_error); |
683 | #endif | 690 | #endif |
684 | /*if this is end of media read/write, may turn off PS/2 disk led */ | 691 | /*if this is end of media read/write, may turn off PS/2 disk led */ |
685 | if ((ld(ihost_index)[ldn].device_type != TYPE_NO_LUN) && (ld(ihost_index)[ldn].device_type != TYPE_NO_DEVICE)) { | 692 | if ((ld(shpnt)[ldn].device_type != TYPE_NO_LUN) && (ld(shpnt)[ldn].device_type != TYPE_NO_DEVICE)) { |
686 | /* only access this, if there was a valid device addressed */ | 693 | /* only access this, if there was a valid device addressed */ |
687 | if (--disk_rw_in_progress == 0) | 694 | if (--disk_rw_in_progress == 0) |
688 | PS2_DISK_LED_OFF(); | 695 | PS2_DISK_LED_OFF(); |
@@ -693,8 +700,8 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
693 | * adapters do not support CMD_TERMINATED, TASK_SET_FULL and | 700 | * adapters do not support CMD_TERMINATED, TASK_SET_FULL and |
694 | * ACA_ACTIVE as returning statusbyte information. (ML) */ | 701 | * ACA_ACTIVE as returning statusbyte information. (ML) */ |
695 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) { | 702 | if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) { |
696 | cmd->result = (unsigned char) (ld(ihost_index)[ldn].tsb.dev_status & 0x1e); | 703 | cmd->result = (unsigned char) (ld(shpnt)[ldn].tsb.dev_status & 0x1e); |
697 | IBM_DS(ihost_index).total_errors++; | 704 | IBM_DS(shpnt).total_errors++; |
698 | } else | 705 | } else |
699 | cmd->result = 0; | 706 | cmd->result = 0; |
700 | /* write device status into cmd->result, and call done function */ | 707 | /* write device status into cmd->result, and call done function */ |
@@ -705,24 +712,25 @@ static irqreturn_t interrupt_handler(int irq, void *dev_id) | |||
705 | cmd->result |= DID_OK << 16; | 712 | cmd->result |= DID_OK << 16; |
706 | if (cmd->scsi_done) | 713 | if (cmd->scsi_done) |
707 | (cmd->scsi_done) (cmd); | 714 | (cmd->scsi_done) (cmd); |
708 | spin_unlock(dev->host_lock); | 715 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
709 | return IRQ_HANDLED; | 716 | return IRQ_HANDLED; |
710 | } | 717 | } |
711 | 718 | ||
712 | static void issue_cmd(int host_index, unsigned long cmd_reg, unsigned char attn_reg) | 719 | static void issue_cmd(struct Scsi_Host *shpnt, unsigned long cmd_reg, |
720 | unsigned char attn_reg) | ||
713 | { | 721 | { |
714 | unsigned long flags; | 722 | unsigned long flags; |
715 | /* must wait for attention reg not busy */ | 723 | /* must wait for attention reg not busy */ |
716 | while (1) { | 724 | while (1) { |
717 | spin_lock_irqsave(hosts[host_index]->host_lock, flags); | 725 | spin_lock_irqsave(shpnt->host_lock, flags); |
718 | if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY)) | 726 | if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY)) |
719 | break; | 727 | break; |
720 | spin_unlock_irqrestore(hosts[host_index]->host_lock, flags); | 728 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
721 | } | 729 | } |
722 | /* write registers and enable system interrupts */ | 730 | /* write registers and enable system interrupts */ |
723 | outl(cmd_reg, IM_CMD_REG(host_index)); | 731 | outl(cmd_reg, IM_CMD_REG(shpnt)); |
724 | outb(attn_reg, IM_ATTN_REG(host_index)); | 732 | outb(attn_reg, IM_ATTN_REG(shpnt)); |
725 | spin_unlock_irqrestore(hosts[host_index]->host_lock, flags); | 733 | spin_unlock_irqrestore(shpnt->host_lock, flags); |
726 | } | 734 | } |
727 | 735 | ||
728 | static void internal_done(Scsi_Cmnd * cmd) | 736 | static void internal_done(Scsi_Cmnd * cmd) |
@@ -732,34 +740,34 @@ static void internal_done(Scsi_Cmnd * cmd) | |||
732 | } | 740 | } |
733 | 741 | ||
734 | /* SCSI-SCB-command for device_inquiry */ | 742 | /* SCSI-SCB-command for device_inquiry */ |
735 | static int device_inquiry(int host_index, int ldn) | 743 | static int device_inquiry(struct Scsi_Host *shpnt, int ldn) |
736 | { | 744 | { |
737 | int retr; | 745 | int retr; |
738 | struct im_scb *scb; | 746 | struct im_scb *scb; |
739 | struct im_tsb *tsb; | 747 | struct im_tsb *tsb; |
740 | unsigned char *buf; | 748 | unsigned char *buf; |
741 | 749 | ||
742 | scb = &(ld(host_index)[ldn].scb); | 750 | scb = &(ld(shpnt)[ldn].scb); |
743 | tsb = &(ld(host_index)[ldn].tsb); | 751 | tsb = &(ld(shpnt)[ldn].tsb); |
744 | buf = (unsigned char *) (&(ld(host_index)[ldn].buf)); | 752 | buf = (unsigned char *) (&(ld(shpnt)[ldn].buf)); |
745 | ld(host_index)[ldn].tsb.dev_status = 0; /* prepare statusblock */ | 753 | ld(shpnt)[ldn].tsb.dev_status = 0; /* prepare statusblock */ |
746 | for (retr = 0; retr < 3; retr++) { | 754 | for (retr = 0; retr < 3; retr++) { |
747 | /* fill scb with inquiry command */ | 755 | /* fill scb with inquiry command */ |
748 | scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT; | 756 | scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT; |
749 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; | 757 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; |
750 | last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD; | 758 | last_scsi_command(shpnt)[ldn] = IM_DEVICE_INQUIRY_CMD; |
751 | last_scsi_type(host_index)[ldn] = IM_SCB; | 759 | last_scsi_type(shpnt)[ldn] = IM_SCB; |
752 | scb->sys_buf_adr = isa_virt_to_bus(buf); | 760 | scb->sys_buf_adr = isa_virt_to_bus(buf); |
753 | scb->sys_buf_length = 255; /* maximum bufferlength gives max info */ | 761 | scb->sys_buf_length = 255; /* maximum bufferlength gives max info */ |
754 | scb->tsb_adr = isa_virt_to_bus(tsb); | 762 | scb->tsb_adr = isa_virt_to_bus(tsb); |
755 | /* issue scb to passed ldn, and busy wait for interrupt */ | 763 | /* issue scb to passed ldn, and busy wait for interrupt */ |
756 | got_interrupt(host_index) = 0; | 764 | got_interrupt(shpnt) = 0; |
757 | issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn); | 765 | issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn); |
758 | while (!got_interrupt(host_index)) | 766 | while (!got_interrupt(shpnt)) |
759 | barrier(); | 767 | barrier(); |
760 | 768 | ||
761 | /*if command successful, break */ | 769 | /*if command successful, break */ |
762 | if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) | 770 | if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) |
763 | return 1; | 771 | return 1; |
764 | } | 772 | } |
765 | /*if all three retries failed, return "no device at this ldn" */ | 773 | /*if all three retries failed, return "no device at this ldn" */ |
@@ -769,34 +777,34 @@ static int device_inquiry(int host_index, int ldn) | |||
769 | return 1; | 777 | return 1; |
770 | } | 778 | } |
771 | 779 | ||
772 | static int read_capacity(int host_index, int ldn) | 780 | static int read_capacity(struct Scsi_Host *shpnt, int ldn) |
773 | { | 781 | { |
774 | int retr; | 782 | int retr; |
775 | struct im_scb *scb; | 783 | struct im_scb *scb; |
776 | struct im_tsb *tsb; | 784 | struct im_tsb *tsb; |
777 | unsigned char *buf; | 785 | unsigned char *buf; |
778 | 786 | ||
779 | scb = &(ld(host_index)[ldn].scb); | 787 | scb = &(ld(shpnt)[ldn].scb); |
780 | tsb = &(ld(host_index)[ldn].tsb); | 788 | tsb = &(ld(shpnt)[ldn].tsb); |
781 | buf = (unsigned char *) (&(ld(host_index)[ldn].buf)); | 789 | buf = (unsigned char *) (&(ld(shpnt)[ldn].buf)); |
782 | ld(host_index)[ldn].tsb.dev_status = 0; | 790 | ld(shpnt)[ldn].tsb.dev_status = 0; |
783 | for (retr = 0; retr < 3; retr++) { | 791 | for (retr = 0; retr < 3; retr++) { |
784 | /*fill scb with read capacity command */ | 792 | /*fill scb with read capacity command */ |
785 | scb->command = IM_READ_CAPACITY_CMD; | 793 | scb->command = IM_READ_CAPACITY_CMD; |
786 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; | 794 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; |
787 | last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD; | 795 | last_scsi_command(shpnt)[ldn] = IM_READ_CAPACITY_CMD; |
788 | last_scsi_type(host_index)[ldn] = IM_SCB; | 796 | last_scsi_type(shpnt)[ldn] = IM_SCB; |
789 | scb->sys_buf_adr = isa_virt_to_bus(buf); | 797 | scb->sys_buf_adr = isa_virt_to_bus(buf); |
790 | scb->sys_buf_length = 8; | 798 | scb->sys_buf_length = 8; |
791 | scb->tsb_adr = isa_virt_to_bus(tsb); | 799 | scb->tsb_adr = isa_virt_to_bus(tsb); |
792 | /*issue scb to passed ldn, and busy wait for interrupt */ | 800 | /*issue scb to passed ldn, and busy wait for interrupt */ |
793 | got_interrupt(host_index) = 0; | 801 | got_interrupt(shpnt) = 0; |
794 | issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn); | 802 | issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn); |
795 | while (!got_interrupt(host_index)) | 803 | while (!got_interrupt(shpnt)) |
796 | barrier(); | 804 | barrier(); |
797 | 805 | ||
798 | /*if got capacity, get block length and return one device found */ | 806 | /*if got capacity, get block length and return one device found */ |
799 | if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) | 807 | if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) |
800 | return 1; | 808 | return 1; |
801 | } | 809 | } |
802 | /*if all three retries failed, return "no device at this ldn" */ | 810 | /*if all three retries failed, return "no device at this ldn" */ |
@@ -806,39 +814,39 @@ static int read_capacity(int host_index, int ldn) | |||
806 | return 1; | 814 | return 1; |
807 | } | 815 | } |
808 | 816 | ||
809 | static int get_pos_info(int host_index) | 817 | static int get_pos_info(struct Scsi_Host *shpnt) |
810 | { | 818 | { |
811 | int retr; | 819 | int retr; |
812 | struct im_scb *scb; | 820 | struct im_scb *scb; |
813 | struct im_tsb *tsb; | 821 | struct im_tsb *tsb; |
814 | unsigned char *buf; | 822 | unsigned char *buf; |
815 | 823 | ||
816 | scb = &(ld(host_index)[MAX_LOG_DEV].scb); | 824 | scb = &(ld(shpnt)[MAX_LOG_DEV].scb); |
817 | tsb = &(ld(host_index)[MAX_LOG_DEV].tsb); | 825 | tsb = &(ld(shpnt)[MAX_LOG_DEV].tsb); |
818 | buf = (unsigned char *) (&(ld(host_index)[MAX_LOG_DEV].buf)); | 826 | buf = (unsigned char *) (&(ld(shpnt)[MAX_LOG_DEV].buf)); |
819 | ld(host_index)[MAX_LOG_DEV].tsb.dev_status = 0; | 827 | ld(shpnt)[MAX_LOG_DEV].tsb.dev_status = 0; |
820 | for (retr = 0; retr < 3; retr++) { | 828 | for (retr = 0; retr < 3; retr++) { |
821 | /*fill scb with get_pos_info command */ | 829 | /*fill scb with get_pos_info command */ |
822 | scb->command = IM_GET_POS_INFO_CMD; | 830 | scb->command = IM_GET_POS_INFO_CMD; |
823 | scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; | 831 | scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER; |
824 | last_scsi_command(host_index)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD; | 832 | last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD; |
825 | last_scsi_type(host_index)[MAX_LOG_DEV] = IM_SCB; | 833 | last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_SCB; |
826 | scb->sys_buf_adr = isa_virt_to_bus(buf); | 834 | scb->sys_buf_adr = isa_virt_to_bus(buf); |
827 | if (special(host_index) == IBM_SCSI2_FW) | 835 | if (special(shpnt) == IBM_SCSI2_FW) |
828 | scb->sys_buf_length = 256; /* get all info from F/W adapter */ | 836 | scb->sys_buf_length = 256; /* get all info from F/W adapter */ |
829 | else | 837 | else |
830 | scb->sys_buf_length = 18; /* get exactly 18 bytes for other SCSI */ | 838 | scb->sys_buf_length = 18; /* get exactly 18 bytes for other SCSI */ |
831 | scb->tsb_adr = isa_virt_to_bus(tsb); | 839 | scb->tsb_adr = isa_virt_to_bus(tsb); |
832 | /*issue scb to ldn=15, and busy wait for interrupt */ | 840 | /*issue scb to ldn=15, and busy wait for interrupt */ |
833 | got_interrupt(host_index) = 0; | 841 | got_interrupt(shpnt) = 0; |
834 | issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | MAX_LOG_DEV); | 842 | issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | MAX_LOG_DEV); |
835 | 843 | ||
836 | /* FIXME: timeout */ | 844 | /* FIXME: timeout */ |
837 | while (!got_interrupt(host_index)) | 845 | while (!got_interrupt(shpnt)) |
838 | barrier(); | 846 | barrier(); |
839 | 847 | ||
840 | /*if got POS-stuff, get block length and return one device found */ | 848 | /*if got POS-stuff, get block length and return one device found */ |
841 | if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) | 849 | if ((stat_result(shpnt) == IM_SCB_CMD_COMPLETED) || (stat_result(shpnt) == IM_SCB_CMD_COMPLETED_WITH_RETRIES)) |
842 | return 1; | 850 | return 1; |
843 | } | 851 | } |
844 | /* if all three retries failed, return "no device at this ldn" */ | 852 | /* if all three retries failed, return "no device at this ldn" */ |
@@ -851,14 +859,16 @@ static int get_pos_info(int host_index) | |||
851 | /* SCSI-immediate-command for assign. This functions maps/unmaps specific | 859 | /* SCSI-immediate-command for assign. This functions maps/unmaps specific |
852 | ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the | 860 | ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the |
853 | subsystem and for dynamical remapping od ldns. */ | 861 | subsystem and for dynamical remapping od ldns. */ |
854 | static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, unsigned int ldn, unsigned int operation) | 862 | static int immediate_assign(struct Scsi_Host *shpnt, unsigned int pun, |
863 | unsigned int lun, unsigned int ldn, | ||
864 | unsigned int operation) | ||
855 | { | 865 | { |
856 | int retr; | 866 | int retr; |
857 | unsigned long imm_cmd; | 867 | unsigned long imm_cmd; |
858 | 868 | ||
859 | for (retr = 0; retr < 3; retr++) { | 869 | for (retr = 0; retr < 3; retr++) { |
860 | /* select mutation level of the SCSI-adapter */ | 870 | /* select mutation level of the SCSI-adapter */ |
861 | switch (special(host_index)) { | 871 | switch (special(shpnt)) { |
862 | case IBM_SCSI2_FW: | 872 | case IBM_SCSI2_FW: |
863 | imm_cmd = (unsigned long) (IM_ASSIGN_IMM_CMD); | 873 | imm_cmd = (unsigned long) (IM_ASSIGN_IMM_CMD); |
864 | imm_cmd |= (unsigned long) ((lun & 7) << 24); | 874 | imm_cmd |= (unsigned long) ((lun & 7) << 24); |
@@ -867,7 +877,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, | |||
867 | imm_cmd |= (unsigned long) ((ldn & 15) << 16); | 877 | imm_cmd |= (unsigned long) ((ldn & 15) << 16); |
868 | break; | 878 | break; |
869 | default: | 879 | default: |
870 | imm_cmd = inl(IM_CMD_REG(host_index)); | 880 | imm_cmd = inl(IM_CMD_REG(shpnt)); |
871 | imm_cmd &= (unsigned long) (0xF8000000); /* keep reserved bits */ | 881 | imm_cmd &= (unsigned long) (0xF8000000); /* keep reserved bits */ |
872 | imm_cmd |= (unsigned long) (IM_ASSIGN_IMM_CMD); | 882 | imm_cmd |= (unsigned long) (IM_ASSIGN_IMM_CMD); |
873 | imm_cmd |= (unsigned long) ((lun & 7) << 24); | 883 | imm_cmd |= (unsigned long) ((lun & 7) << 24); |
@@ -876,15 +886,15 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, | |||
876 | imm_cmd |= (unsigned long) ((ldn & 15) << 16); | 886 | imm_cmd |= (unsigned long) ((ldn & 15) << 16); |
877 | break; | 887 | break; |
878 | } | 888 | } |
879 | last_scsi_command(host_index)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD; | 889 | last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD; |
880 | last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD; | 890 | last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_IMM_CMD; |
881 | got_interrupt(host_index) = 0; | 891 | got_interrupt(shpnt) = 0; |
882 | issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV); | 892 | issue_cmd(shpnt, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV); |
883 | while (!got_interrupt(host_index)) | 893 | while (!got_interrupt(shpnt)) |
884 | barrier(); | 894 | barrier(); |
885 | 895 | ||
886 | /*if command successful, break */ | 896 | /*if command successful, break */ |
887 | if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) | 897 | if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED) |
888 | return 1; | 898 | return 1; |
889 | } | 899 | } |
890 | if (retr >= 3) | 900 | if (retr >= 3) |
@@ -893,7 +903,7 @@ static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, | |||
893 | return 1; | 903 | return 1; |
894 | } | 904 | } |
895 | 905 | ||
896 | static int immediate_feature(int host_index, unsigned int speed, unsigned int timeout) | 906 | static int immediate_feature(struct Scsi_Host *shpnt, unsigned int speed, unsigned int timeout) |
897 | { | 907 | { |
898 | int retr; | 908 | int retr; |
899 | unsigned long imm_cmd; | 909 | unsigned long imm_cmd; |
@@ -903,16 +913,16 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti | |||
903 | imm_cmd = IM_FEATURE_CTR_IMM_CMD; | 913 | imm_cmd = IM_FEATURE_CTR_IMM_CMD; |
904 | imm_cmd |= (unsigned long) ((speed & 0x7) << 29); | 914 | imm_cmd |= (unsigned long) ((speed & 0x7) << 29); |
905 | imm_cmd |= (unsigned long) ((timeout & 0x1fff) << 16); | 915 | imm_cmd |= (unsigned long) ((timeout & 0x1fff) << 16); |
906 | last_scsi_command(host_index)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD; | 916 | last_scsi_command(shpnt)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD; |
907 | last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD; | 917 | last_scsi_type(shpnt)[MAX_LOG_DEV] = IM_IMM_CMD; |
908 | got_interrupt(host_index) = 0; | 918 | got_interrupt(shpnt) = 0; |
909 | /* we need to run into command errors in order to probe for the | 919 | /* we need to run into command errors in order to probe for the |
910 | * right speed! */ | 920 | * right speed! */ |
911 | global_command_error_excuse = 1; | 921 | global_command_error_excuse = 1; |
912 | issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV); | 922 | issue_cmd(shpnt, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV); |
913 | 923 | ||
914 | /* FIXME: timeout */ | 924 | /* FIXME: timeout */ |
915 | while (!got_interrupt(host_index)) | 925 | while (!got_interrupt(shpnt)) |
916 | barrier(); | 926 | barrier(); |
917 | if (global_command_error_excuse == CMD_FAIL) { | 927 | if (global_command_error_excuse == CMD_FAIL) { |
918 | global_command_error_excuse = 0; | 928 | global_command_error_excuse = 0; |
@@ -920,7 +930,7 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti | |||
920 | } else | 930 | } else |
921 | global_command_error_excuse = 0; | 931 | global_command_error_excuse = 0; |
922 | /*if command successful, break */ | 932 | /*if command successful, break */ |
923 | if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) | 933 | if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED) |
924 | return 1; | 934 | return 1; |
925 | } | 935 | } |
926 | if (retr >= 3) | 936 | if (retr >= 3) |
@@ -930,35 +940,35 @@ static int immediate_feature(int host_index, unsigned int speed, unsigned int ti | |||
930 | } | 940 | } |
931 | 941 | ||
932 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET | 942 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET |
933 | static int immediate_reset(int host_index, unsigned int ldn) | 943 | static int immediate_reset(struct Scsi_Host *shpnt, unsigned int ldn) |
934 | { | 944 | { |
935 | int retries; | 945 | int retries; |
936 | int ticks; | 946 | int ticks; |
937 | unsigned long imm_command; | 947 | unsigned long imm_command; |
938 | 948 | ||
939 | for (retries = 0; retries < 3; retries++) { | 949 | for (retries = 0; retries < 3; retries++) { |
940 | imm_command = inl(IM_CMD_REG(host_index)); | 950 | imm_command = inl(IM_CMD_REG(shpnt)); |
941 | imm_command &= (unsigned long) (0xFFFF0000); /* keep reserved bits */ | 951 | imm_command &= (unsigned long) (0xFFFF0000); /* keep reserved bits */ |
942 | imm_command |= (unsigned long) (IM_RESET_IMM_CMD); | 952 | imm_command |= (unsigned long) (IM_RESET_IMM_CMD); |
943 | last_scsi_command(host_index)[ldn] = IM_RESET_IMM_CMD; | 953 | last_scsi_command(shpnt)[ldn] = IM_RESET_IMM_CMD; |
944 | last_scsi_type(host_index)[ldn] = IM_IMM_CMD; | 954 | last_scsi_type(shpnt)[ldn] = IM_IMM_CMD; |
945 | got_interrupt(host_index) = 0; | 955 | got_interrupt(shpnt) = 0; |
946 | reset_status(host_index) = IM_RESET_IN_PROGRESS; | 956 | reset_status(shpnt) = IM_RESET_IN_PROGRESS; |
947 | issue_cmd(host_index, (unsigned long) (imm_command), IM_IMM_CMD | ldn); | 957 | issue_cmd(shpnt, (unsigned long) (imm_command), IM_IMM_CMD | ldn); |
948 | ticks = IM_RESET_DELAY * HZ; | 958 | ticks = IM_RESET_DELAY * HZ; |
949 | while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks) { | 959 | while (reset_status(shpnt) == IM_RESET_IN_PROGRESS && --ticks) { |
950 | udelay((1 + 999 / HZ) * 1000); | 960 | udelay((1 + 999 / HZ) * 1000); |
951 | barrier(); | 961 | barrier(); |
952 | } | 962 | } |
953 | /* if reset did not complete, just complain */ | 963 | /* if reset did not complete, just complain */ |
954 | if (!ticks) { | 964 | if (!ticks) { |
955 | printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY); | 965 | printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY); |
956 | reset_status(host_index) = IM_RESET_FINISHED_OK; | 966 | reset_status(shpnt) = IM_RESET_FINISHED_OK; |
957 | /* did not work, finish */ | 967 | /* did not work, finish */ |
958 | return 1; | 968 | return 1; |
959 | } | 969 | } |
960 | /*if command successful, break */ | 970 | /*if command successful, break */ |
961 | if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED) | 971 | if (stat_result(shpnt) == IM_IMMEDIATE_CMD_COMPLETED) |
962 | return 1; | 972 | return 1; |
963 | } | 973 | } |
964 | if (retries >= 3) | 974 | if (retries >= 3) |
@@ -1060,35 +1070,35 @@ static int probe_display(int what) | |||
1060 | return 0; | 1070 | return 0; |
1061 | } | 1071 | } |
1062 | 1072 | ||
1063 | static int probe_bus_mode(int host_index) | 1073 | static int probe_bus_mode(struct Scsi_Host *shpnt) |
1064 | { | 1074 | { |
1065 | struct im_pos_info *info; | 1075 | struct im_pos_info *info; |
1066 | int num_bus = 0; | 1076 | int num_bus = 0; |
1067 | int ldn; | 1077 | int ldn; |
1068 | 1078 | ||
1069 | info = (struct im_pos_info *) (&(ld(host_index)[MAX_LOG_DEV].buf)); | 1079 | info = (struct im_pos_info *) (&(ld(shpnt)[MAX_LOG_DEV].buf)); |
1070 | if (get_pos_info(host_index)) { | 1080 | if (get_pos_info(shpnt)) { |
1071 | if (info->connector_size & 0xf000) | 1081 | if (info->connector_size & 0xf000) |
1072 | subsystem_connector_size(host_index) = 16; | 1082 | subsystem_connector_size(shpnt) = 16; |
1073 | else | 1083 | else |
1074 | subsystem_connector_size(host_index) = 32; | 1084 | subsystem_connector_size(shpnt) = 32; |
1075 | num_bus |= (info->pos_4b & 8) >> 3; | 1085 | num_bus |= (info->pos_4b & 8) >> 3; |
1076 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { | 1086 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { |
1077 | if ((special(host_index) == IBM_SCSI_WCACHE) || (special(host_index) == IBM_7568_WCACHE)) { | 1087 | if ((special(shpnt) == IBM_SCSI_WCACHE) || (special(shpnt) == IBM_7568_WCACHE)) { |
1078 | if (!((info->cache_stat >> ldn) & 1)) | 1088 | if (!((info->cache_stat >> ldn) & 1)) |
1079 | ld(host_index)[ldn].cache_flag = 0; | 1089 | ld(shpnt)[ldn].cache_flag = 0; |
1080 | } | 1090 | } |
1081 | if (!((info->retry_stat >> ldn) & 1)) | 1091 | if (!((info->retry_stat >> ldn) & 1)) |
1082 | ld(host_index)[ldn].retry_flag = 0; | 1092 | ld(shpnt)[ldn].retry_flag = 0; |
1083 | } | 1093 | } |
1084 | #ifdef IM_DEBUG_PROBE | 1094 | #ifdef IM_DEBUG_PROBE |
1085 | printk("IBM MCA SCSI: SCSI-Cache bits: "); | 1095 | printk("IBM MCA SCSI: SCSI-Cache bits: "); |
1086 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { | 1096 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { |
1087 | printk("%d", ld(host_index)[ldn].cache_flag); | 1097 | printk("%d", ld(shpnt)[ldn].cache_flag); |
1088 | } | 1098 | } |
1089 | printk("\nIBM MCA SCSI: SCSI-Retry bits: "); | 1099 | printk("\nIBM MCA SCSI: SCSI-Retry bits: "); |
1090 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { | 1100 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { |
1091 | printk("%d", ld(host_index)[ldn].retry_flag); | 1101 | printk("%d", ld(shpnt)[ldn].retry_flag); |
1092 | } | 1102 | } |
1093 | printk("\n"); | 1103 | printk("\n"); |
1094 | #endif | 1104 | #endif |
@@ -1097,7 +1107,7 @@ static int probe_bus_mode(int host_index) | |||
1097 | } | 1107 | } |
1098 | 1108 | ||
1099 | /* probing scsi devices */ | 1109 | /* probing scsi devices */ |
1100 | static void check_devices(int host_index, int adaptertype) | 1110 | static void check_devices(struct Scsi_Host *shpnt, int adaptertype) |
1101 | { | 1111 | { |
1102 | int id, lun, ldn, ticks; | 1112 | int id, lun, ldn, ticks; |
1103 | int count_devices; /* local counter for connected device */ | 1113 | int count_devices; /* local counter for connected device */ |
@@ -1108,24 +1118,24 @@ static void check_devices(int host_index, int adaptertype) | |||
1108 | /* assign default values to certain variables */ | 1118 | /* assign default values to certain variables */ |
1109 | ticks = 0; | 1119 | ticks = 0; |
1110 | count_devices = 0; | 1120 | count_devices = 0; |
1111 | IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */ | 1121 | IBM_DS(shpnt).dyn_flag = 0; /* normally no need for dynamical ldn management */ |
1112 | IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */ | 1122 | IBM_DS(shpnt).total_errors = 0; /* set errorcounter to 0 */ |
1113 | next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired' */ | 1123 | next_ldn(shpnt) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired' */ |
1114 | 1124 | ||
1115 | /* initialize the very important driver-informational arrays/structs */ | 1125 | /* initialize the very important driver-informational arrays/structs */ |
1116 | memset(ld(host_index), 0, sizeof(ld(host_index))); | 1126 | memset(ld(shpnt), 0, sizeof(ld(shpnt))); |
1117 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { | 1127 | for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) { |
1118 | last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */ | 1128 | last_scsi_command(shpnt)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */ |
1119 | last_scsi_type(host_index)[ldn] = 0; | 1129 | last_scsi_type(shpnt)[ldn] = 0; |
1120 | ld(host_index)[ldn].cache_flag = 1; | 1130 | ld(shpnt)[ldn].cache_flag = 1; |
1121 | ld(host_index)[ldn].retry_flag = 1; | 1131 | ld(shpnt)[ldn].retry_flag = 1; |
1122 | } | 1132 | } |
1123 | memset(get_ldn(host_index), TYPE_NO_DEVICE, sizeof(get_ldn(host_index))); /* this is essential ! */ | 1133 | memset(get_ldn(shpnt), TYPE_NO_DEVICE, sizeof(get_ldn(shpnt))); /* this is essential ! */ |
1124 | memset(get_scsi(host_index), TYPE_NO_DEVICE, sizeof(get_scsi(host_index))); /* this is essential ! */ | 1134 | memset(get_scsi(shpnt), TYPE_NO_DEVICE, sizeof(get_scsi(shpnt))); /* this is essential ! */ |
1125 | for (lun = 0; lun < 8; lun++) { | 1135 | for (lun = 0; lun < 8; lun++) { |
1126 | /* mark the adapter at its pun on all luns */ | 1136 | /* mark the adapter at its pun on all luns */ |
1127 | get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER; | 1137 | get_scsi(shpnt)[subsystem_pun(shpnt)][lun] = TYPE_IBM_SCSI_ADAPTER; |
1128 | get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV; /* make sure, the subsystem | 1138 | get_ldn(shpnt)[subsystem_pun(shpnt)][lun] = MAX_LOG_DEV; /* make sure, the subsystem |
1129 | ldn is active for all | 1139 | ldn is active for all |
1130 | luns. */ | 1140 | luns. */ |
1131 | } | 1141 | } |
@@ -1134,9 +1144,9 @@ static void check_devices(int host_index, int adaptertype) | |||
1134 | /* monitor connected on model XX95. */ | 1144 | /* monitor connected on model XX95. */ |
1135 | 1145 | ||
1136 | /* STEP 1: */ | 1146 | /* STEP 1: */ |
1137 | adapter_speed(host_index) = global_adapter_speed; | 1147 | adapter_speed(shpnt) = global_adapter_speed; |
1138 | speedrun = adapter_speed(host_index); | 1148 | speedrun = adapter_speed(shpnt); |
1139 | while (immediate_feature(host_index, speedrun, adapter_timeout) == 2) { | 1149 | while (immediate_feature(shpnt, speedrun, adapter_timeout) == 2) { |
1140 | probe_display(1); | 1150 | probe_display(1); |
1141 | if (speedrun == 7) | 1151 | if (speedrun == 7) |
1142 | panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n"); | 1152 | panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n"); |
@@ -1144,30 +1154,30 @@ static void check_devices(int host_index, int adaptertype) | |||
1144 | if (speedrun > 7) | 1154 | if (speedrun > 7) |
1145 | speedrun = 7; | 1155 | speedrun = 7; |
1146 | } | 1156 | } |
1147 | adapter_speed(host_index) = speedrun; | 1157 | adapter_speed(shpnt) = speedrun; |
1148 | /* Get detailed information about the current adapter, necessary for | 1158 | /* Get detailed information about the current adapter, necessary for |
1149 | * device operations: */ | 1159 | * device operations: */ |
1150 | num_bus = probe_bus_mode(host_index); | 1160 | num_bus = probe_bus_mode(shpnt); |
1151 | 1161 | ||
1152 | /* num_bus contains only valid data for the F/W adapter! */ | 1162 | /* num_bus contains only valid data for the F/W adapter! */ |
1153 | if (adaptertype == IBM_SCSI2_FW) { /* F/W SCSI adapter: */ | 1163 | if (adaptertype == IBM_SCSI2_FW) { /* F/W SCSI adapter: */ |
1154 | /* F/W adapter PUN-space extension evaluation: */ | 1164 | /* F/W adapter PUN-space extension evaluation: */ |
1155 | if (num_bus) { | 1165 | if (num_bus) { |
1156 | printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n"); | 1166 | printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n"); |
1157 | subsystem_maxid(host_index) = 16; | 1167 | subsystem_maxid(shpnt) = 16; |
1158 | } else { | 1168 | } else { |
1159 | printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n"); | 1169 | printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n"); |
1160 | subsystem_maxid(host_index) = 8; | 1170 | subsystem_maxid(shpnt) = 8; |
1161 | } | 1171 | } |
1162 | printk(KERN_INFO "IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n", ibmrate(speedrun, adaptertype)); | 1172 | printk(KERN_INFO "IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n", ibmrate(speedrun, adaptertype)); |
1163 | } else /* all other IBM SCSI adapters: */ | 1173 | } else /* all other IBM SCSI adapters: */ |
1164 | printk(KERN_INFO "IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n", ibmrate(speedrun, adaptertype)); | 1174 | printk(KERN_INFO "IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n", ibmrate(speedrun, adaptertype)); |
1165 | 1175 | ||
1166 | /* assign correct PUN device space */ | 1176 | /* assign correct PUN device space */ |
1167 | max_pun = subsystem_maxid(host_index); | 1177 | max_pun = subsystem_maxid(shpnt); |
1168 | 1178 | ||
1169 | #ifdef IM_DEBUG_PROBE | 1179 | #ifdef IM_DEBUG_PROBE |
1170 | printk("IBM MCA SCSI: Current SCSI-host index: %d\n", host_index); | 1180 | printk("IBM MCA SCSI: Current SCSI-host index: %d\n", shpnt); |
1171 | printk("IBM MCA SCSI: Removing default logical SCSI-device mapping."); | 1181 | printk("IBM MCA SCSI: Removing default logical SCSI-device mapping."); |
1172 | #else | 1182 | #else |
1173 | printk(KERN_INFO "IBM MCA SCSI: Dev. Order: %s, Mapping (takes <2min): ", (ibm_ansi_order) ? "ANSI" : "New"); | 1183 | printk(KERN_INFO "IBM MCA SCSI: Dev. Order: %s, Mapping (takes <2min): ", (ibm_ansi_order) ? "ANSI" : "New"); |
@@ -1177,7 +1187,7 @@ static void check_devices(int host_index, int adaptertype) | |||
1177 | #ifdef IM_DEBUG_PROBE | 1187 | #ifdef IM_DEBUG_PROBE |
1178 | printk("."); | 1188 | printk("."); |
1179 | #endif | 1189 | #endif |
1180 | immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN); /* remove ldn (wherever) */ | 1190 | immediate_assign(shpnt, 0, 0, ldn, REMOVE_LDN); /* remove ldn (wherever) */ |
1181 | } | 1191 | } |
1182 | lun = 0; /* default lun is 0 */ | 1192 | lun = 0; /* default lun is 0 */ |
1183 | #ifndef IM_DEBUG_PROBE | 1193 | #ifndef IM_DEBUG_PROBE |
@@ -1196,18 +1206,18 @@ static void check_devices(int host_index, int adaptertype) | |||
1196 | #ifdef IM_DEBUG_PROBE | 1206 | #ifdef IM_DEBUG_PROBE |
1197 | printk("."); | 1207 | printk("."); |
1198 | #endif | 1208 | #endif |
1199 | if (id != subsystem_pun(host_index)) { | 1209 | if (id != subsystem_pun(shpnt)) { |
1200 | /* if pun is not the adapter: */ | 1210 | /* if pun is not the adapter: */ |
1201 | /* set ldn=0 to pun,lun */ | 1211 | /* set ldn=0 to pun,lun */ |
1202 | immediate_assign(host_index, id, lun, PROBE_LDN, SET_LDN); | 1212 | immediate_assign(shpnt, id, lun, PROBE_LDN, SET_LDN); |
1203 | if (device_inquiry(host_index, PROBE_LDN)) { /* probe device */ | 1213 | if (device_inquiry(shpnt, PROBE_LDN)) { /* probe device */ |
1204 | get_scsi(host_index)[id][lun] = (unsigned char) (ld(host_index)[PROBE_LDN].buf[0]); | 1214 | get_scsi(shpnt)[id][lun] = (unsigned char) (ld(shpnt)[PROBE_LDN].buf[0]); |
1205 | /* entry, even for NO_LUN */ | 1215 | /* entry, even for NO_LUN */ |
1206 | if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN) | 1216 | if (ld(shpnt)[PROBE_LDN].buf[0] != TYPE_NO_LUN) |
1207 | count_devices++; /* a existing device is found */ | 1217 | count_devices++; /* a existing device is found */ |
1208 | } | 1218 | } |
1209 | /* remove ldn */ | 1219 | /* remove ldn */ |
1210 | immediate_assign(host_index, id, lun, PROBE_LDN, REMOVE_LDN); | 1220 | immediate_assign(shpnt, id, lun, PROBE_LDN, REMOVE_LDN); |
1211 | } | 1221 | } |
1212 | } | 1222 | } |
1213 | #ifndef IM_DEBUG_PROBE | 1223 | #ifndef IM_DEBUG_PROBE |
@@ -1227,16 +1237,16 @@ static void check_devices(int host_index, int adaptertype) | |||
1227 | #ifdef IM_DEBUG_PROBE | 1237 | #ifdef IM_DEBUG_PROBE |
1228 | printk("."); | 1238 | printk("."); |
1229 | #endif | 1239 | #endif |
1230 | if (id != subsystem_pun(host_index)) { | 1240 | if (id != subsystem_pun(shpnt)) { |
1231 | if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN && get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE) { | 1241 | if (get_scsi(shpnt)[id][lun] != TYPE_NO_LUN && get_scsi(shpnt)[id][lun] != TYPE_NO_DEVICE) { |
1232 | /* Only map if accepted type. Always enter for | 1242 | /* Only map if accepted type. Always enter for |
1233 | lun == 0 to get no gaps into ldn-mapping for ldn<7. */ | 1243 | lun == 0 to get no gaps into ldn-mapping for ldn<7. */ |
1234 | immediate_assign(host_index, id, lun, ldn, SET_LDN); | 1244 | immediate_assign(shpnt, id, lun, ldn, SET_LDN); |
1235 | get_ldn(host_index)[id][lun] = ldn; /* map ldn */ | 1245 | get_ldn(shpnt)[id][lun] = ldn; /* map ldn */ |
1236 | if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) { | 1246 | if (device_exists(shpnt, ldn, &ld(shpnt)[ldn].block_length, &ld(shpnt)[ldn].device_type)) { |
1237 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET | 1247 | #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET |
1238 | printk("resetting device at ldn=%x ... ", ldn); | 1248 | printk("resetting device at ldn=%x ... ", ldn); |
1239 | immediate_reset(host_index, ldn); | 1249 | immediate_reset(shpnt, ldn); |
1240 | #endif | 1250 | #endif |
1241 | ldn++; | 1251 | ldn++; |
1242 | } else { | 1252 | } else { |
@@ -1244,15 +1254,15 @@ static void check_devices(int host_index, int adaptertype) | |||
1244 | * handle it or because it has problems */ | 1254 | * handle it or because it has problems */ |
1245 | if (lun > 0) { | 1255 | if (lun > 0) { |
1246 | /* remove mapping */ | 1256 | /* remove mapping */ |
1247 | get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE; | 1257 | get_ldn(shpnt)[id][lun] = TYPE_NO_DEVICE; |
1248 | immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN); | 1258 | immediate_assign(shpnt, 0, 0, ldn, REMOVE_LDN); |
1249 | } else | 1259 | } else |
1250 | ldn++; | 1260 | ldn++; |
1251 | } | 1261 | } |
1252 | } else if (lun == 0) { | 1262 | } else if (lun == 0) { |
1253 | /* map lun == 0, even if no device exists */ | 1263 | /* map lun == 0, even if no device exists */ |
1254 | immediate_assign(host_index, id, lun, ldn, SET_LDN); | 1264 | immediate_assign(shpnt, id, lun, ldn, SET_LDN); |
1255 | get_ldn(host_index)[id][lun] = ldn; /* map ldn */ | 1265 | get_ldn(shpnt)[id][lun] = ldn; /* map ldn */ |
1256 | ldn++; | 1266 | ldn++; |
1257 | } | 1267 | } |
1258 | } | 1268 | } |
@@ -1262,14 +1272,14 @@ static void check_devices(int host_index, int adaptertype) | |||
1262 | /* map remaining ldns to non-existing devices */ | 1272 | /* map remaining ldns to non-existing devices */ |
1263 | for (lun = 1; lun < 8 && ldn < MAX_LOG_DEV; lun++) | 1273 | for (lun = 1; lun < 8 && ldn < MAX_LOG_DEV; lun++) |
1264 | for (id = 0; id < max_pun && ldn < MAX_LOG_DEV; id++) { | 1274 | for (id = 0; id < max_pun && ldn < MAX_LOG_DEV; id++) { |
1265 | if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN || get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE) { | 1275 | if (get_scsi(shpnt)[id][lun] == TYPE_NO_LUN || get_scsi(shpnt)[id][lun] == TYPE_NO_DEVICE) { |
1266 | probe_display(1); | 1276 | probe_display(1); |
1267 | /* Map remaining ldns only to NON-existing pun,lun | 1277 | /* Map remaining ldns only to NON-existing pun,lun |
1268 | combinations to make sure an inquiry will fail. | 1278 | combinations to make sure an inquiry will fail. |
1269 | For MULTI_LUN, it is needed to avoid adapter autonome | 1279 | For MULTI_LUN, it is needed to avoid adapter autonome |
1270 | SCSI-remapping. */ | 1280 | SCSI-remapping. */ |
1271 | immediate_assign(host_index, id, lun, ldn, SET_LDN); | 1281 | immediate_assign(shpnt, id, lun, ldn, SET_LDN); |
1272 | get_ldn(host_index)[id][lun] = ldn; | 1282 | get_ldn(shpnt)[id][lun] = ldn; |
1273 | ldn++; | 1283 | ldn++; |
1274 | } | 1284 | } |
1275 | } | 1285 | } |
@@ -1292,51 +1302,51 @@ static void check_devices(int host_index, int adaptertype) | |||
1292 | for (id = 0; id < max_pun; id++) { | 1302 | for (id = 0; id < max_pun; id++) { |
1293 | printk("%2d ", id); | 1303 | printk("%2d ", id); |
1294 | for (lun = 0; lun < 8; lun++) | 1304 | for (lun = 0; lun < 8; lun++) |
1295 | printk("%2s ", ti_p(get_scsi(host_index)[id][lun])); | 1305 | printk("%2s ", ti_p(get_scsi(shpnt)[id][lun])); |
1296 | printk(" %2d ", id); | 1306 | printk(" %2d ", id); |
1297 | for (lun = 0; lun < 8; lun++) | 1307 | for (lun = 0; lun < 8; lun++) |
1298 | printk("%2s ", ti_l(get_ldn(host_index)[id][lun])); | 1308 | printk("%2s ", ti_l(get_ldn(shpnt)[id][lun])); |
1299 | printk("\n"); | 1309 | printk("\n"); |
1300 | } | 1310 | } |
1301 | #endif | 1311 | #endif |
1302 | 1312 | ||
1303 | /* assign total number of found SCSI-devices to the statistics struct */ | 1313 | /* assign total number of found SCSI-devices to the statistics struct */ |
1304 | IBM_DS(host_index).total_scsi_devices = count_devices; | 1314 | IBM_DS(shpnt).total_scsi_devices = count_devices; |
1305 | 1315 | ||
1306 | /* decide for output in /proc-filesystem, if the configuration of | 1316 | /* decide for output in /proc-filesystem, if the configuration of |
1307 | SCSI-devices makes dynamical reassignment of devices necessary */ | 1317 | SCSI-devices makes dynamical reassignment of devices necessary */ |
1308 | if (count_devices >= MAX_LOG_DEV) | 1318 | if (count_devices >= MAX_LOG_DEV) |
1309 | IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */ | 1319 | IBM_DS(shpnt).dyn_flag = 1; /* dynamical assignment is necessary */ |
1310 | else | 1320 | else |
1311 | IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */ | 1321 | IBM_DS(shpnt).dyn_flag = 0; /* dynamical assignment is not necessary */ |
1312 | 1322 | ||
1313 | /* If no SCSI-devices are assigned, return 1 in order to cause message. */ | 1323 | /* If no SCSI-devices are assigned, return 1 in order to cause message. */ |
1314 | if (ldn == 0) | 1324 | if (ldn == 0) |
1315 | printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n"); | 1325 | printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n"); |
1316 | 1326 | ||
1317 | /* reset the counters for statistics on the current adapter */ | 1327 | /* reset the counters for statistics on the current adapter */ |
1318 | IBM_DS(host_index).scbs = 0; | 1328 | IBM_DS(shpnt).scbs = 0; |
1319 | IBM_DS(host_index).long_scbs = 0; | 1329 | IBM_DS(shpnt).long_scbs = 0; |
1320 | IBM_DS(host_index).total_accesses = 0; | 1330 | IBM_DS(shpnt).total_accesses = 0; |
1321 | IBM_DS(host_index).total_interrupts = 0; | 1331 | IBM_DS(shpnt).total_interrupts = 0; |
1322 | IBM_DS(host_index).dynamical_assignments = 0; | 1332 | IBM_DS(shpnt).dynamical_assignments = 0; |
1323 | memset(IBM_DS(host_index).ldn_access, 0x0, sizeof(IBM_DS(host_index).ldn_access)); | 1333 | memset(IBM_DS(shpnt).ldn_access, 0x0, sizeof(IBM_DS(shpnt).ldn_access)); |
1324 | memset(IBM_DS(host_index).ldn_read_access, 0x0, sizeof(IBM_DS(host_index).ldn_read_access)); | 1334 | memset(IBM_DS(shpnt).ldn_read_access, 0x0, sizeof(IBM_DS(shpnt).ldn_read_access)); |
1325 | memset(IBM_DS(host_index).ldn_write_access, 0x0, sizeof(IBM_DS(host_index).ldn_write_access)); | 1335 | memset(IBM_DS(shpnt).ldn_write_access, 0x0, sizeof(IBM_DS(shpnt).ldn_write_access)); |
1326 | memset(IBM_DS(host_index).ldn_inquiry_access, 0x0, sizeof(IBM_DS(host_index).ldn_inquiry_access)); | 1336 | memset(IBM_DS(shpnt).ldn_inquiry_access, 0x0, sizeof(IBM_DS(shpnt).ldn_inquiry_access)); |
1327 | memset(IBM_DS(host_index).ldn_modeselect_access, 0x0, sizeof(IBM_DS(host_index).ldn_modeselect_access)); | 1337 | memset(IBM_DS(shpnt).ldn_modeselect_access, 0x0, sizeof(IBM_DS(shpnt).ldn_modeselect_access)); |
1328 | memset(IBM_DS(host_index).ldn_assignments, 0x0, sizeof(IBM_DS(host_index).ldn_assignments)); | 1338 | memset(IBM_DS(shpnt).ldn_assignments, 0x0, sizeof(IBM_DS(shpnt).ldn_assignments)); |
1329 | probe_display(0); | 1339 | probe_display(0); |
1330 | return; | 1340 | return; |
1331 | } | 1341 | } |
1332 | 1342 | ||
1333 | static int device_exists(int host_index, int ldn, int *block_length, int *device_type) | 1343 | static int device_exists(struct Scsi_Host *shpnt, int ldn, int *block_length, int *device_type) |
1334 | { | 1344 | { |
1335 | unsigned char *buf; | 1345 | unsigned char *buf; |
1336 | /* if no valid device found, return immediately with 0 */ | 1346 | /* if no valid device found, return immediately with 0 */ |
1337 | if (!(device_inquiry(host_index, ldn))) | 1347 | if (!(device_inquiry(shpnt, ldn))) |
1338 | return 0; | 1348 | return 0; |
1339 | buf = (unsigned char *) (&(ld(host_index)[ldn].buf)); | 1349 | buf = (unsigned char *) (&(ld(shpnt)[ldn].buf)); |
1340 | if (*buf == TYPE_ROM) { | 1350 | if (*buf == TYPE_ROM) { |
1341 | *device_type = TYPE_ROM; | 1351 | *device_type = TYPE_ROM; |
1342 | *block_length = 2048; /* (standard blocksize for yellow-/red-book) */ | 1352 | *block_length = 2048; /* (standard blocksize for yellow-/red-book) */ |
@@ -1349,7 +1359,7 @@ static int device_exists(int host_index, int ldn, int *block_length, int *device | |||
1349 | } | 1359 | } |
1350 | if (*buf == TYPE_DISK) { | 1360 | if (*buf == TYPE_DISK) { |
1351 | *device_type = TYPE_DISK; | 1361 | *device_type = TYPE_DISK; |
1352 | if (read_capacity(host_index, ldn)) { | 1362 | if (read_capacity(shpnt, ldn)) { |
1353 | *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24); | 1363 | *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24); |
1354 | return 1; | 1364 | return 1; |
1355 | } else | 1365 | } else |
@@ -1357,7 +1367,7 @@ static int device_exists(int host_index, int ldn, int *block_length, int *device | |||
1357 | } | 1367 | } |
1358 | if (*buf == TYPE_MOD) { | 1368 | if (*buf == TYPE_MOD) { |
1359 | *device_type = TYPE_MOD; | 1369 | *device_type = TYPE_MOD; |
1360 | if (read_capacity(host_index, ldn)) { | 1370 | if (read_capacity(shpnt, ldn)) { |
1361 | *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24); | 1371 | *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24); |
1362 | return 1; | 1372 | return 1; |
1363 | } else | 1373 | } else |
@@ -1430,6 +1440,9 @@ static void internal_ibmmca_scsi_setup(char *str, int *ints) | |||
1430 | return; | 1440 | return; |
1431 | } | 1441 | } |
1432 | 1442 | ||
1443 | #if 0 | ||
1444 | FIXME NEED TO MOVE TO SYSFS | ||
1445 | |||
1433 | static int ibmmca_getinfo(char *buf, int slot, void *dev_id) | 1446 | static int ibmmca_getinfo(char *buf, int slot, void *dev_id) |
1434 | { | 1447 | { |
1435 | struct Scsi_Host *shpnt; | 1448 | struct Scsi_Host *shpnt; |
@@ -1480,58 +1493,34 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id) | |||
1480 | 1493 | ||
1481 | return len; | 1494 | return len; |
1482 | } | 1495 | } |
1496 | #endif | ||
1483 | 1497 | ||
1484 | int ibmmca_detect(struct scsi_host_template * scsi_template) | 1498 | static struct scsi_host_template ibmmca_driver_template = { |
1499 | .proc_name = "ibmmca", | ||
1500 | .proc_info = ibmmca_proc_info, | ||
1501 | .name = "IBM SCSI-Subsystem", | ||
1502 | .queuecommand = ibmmca_queuecommand, | ||
1503 | .eh_abort_handler = ibmmca_abort, | ||
1504 | .eh_host_reset_handler = ibmmca_host_reset, | ||
1505 | .bios_param = ibmmca_biosparam, | ||
1506 | .can_queue = 16, | ||
1507 | .this_id = 7, | ||
1508 | .sg_tablesize = 16, | ||
1509 | .cmd_per_lun = 1, | ||
1510 | .use_clustering = ENABLE_CLUSTERING, | ||
1511 | }; | ||
1512 | |||
1513 | static int ibmmca_probe(struct device *dev) | ||
1485 | { | 1514 | { |
1486 | struct Scsi_Host *shpnt; | 1515 | struct Scsi_Host *shpnt; |
1487 | int port, id, i, j, k, slot; | 1516 | int port, id, i, j, k, irq, enabled, ret = -EINVAL; |
1488 | int devices_on_irq_11 = 0; | 1517 | struct mca_device *mca_dev = to_mca_device(dev); |
1489 | int devices_on_irq_14 = 0; | 1518 | const char *description = ibmmca_description[mca_dev->index]; |
1490 | int IRQ14_registered = 0; | ||
1491 | int IRQ11_registered = 0; | ||
1492 | |||
1493 | found = 0; /* make absolutely sure, that found is set to 0 */ | ||
1494 | 1519 | ||
1495 | /* First of all, print the version number of the driver. This is | 1520 | /* First of all, print the version number of the driver. This is |
1496 | * important to allow better user bugreports in case of already | 1521 | * important to allow better user bugreports in case of already |
1497 | * having problems with the MCA_bus probing. */ | 1522 | * having problems with the MCA_bus probing. */ |
1498 | printk(KERN_INFO "IBM MCA SCSI: Version %s\n", IBMMCA_SCSI_DRIVER_VERSION); | 1523 | printk(KERN_INFO "IBM MCA SCSI: Version %s\n", IBMMCA_SCSI_DRIVER_VERSION); |
1499 | /* if this is not MCA machine, return "nothing found" */ | ||
1500 | if (!MCA_bus) { | ||
1501 | printk(KERN_INFO "IBM MCA SCSI: No Microchannel-bus present --> Aborting.\n" " This machine does not have any IBM MCA-bus\n" " or the MCA-Kernel-support is not enabled!\n"); | ||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | #ifdef MODULE | ||
1506 | /* If the driver is run as module, read from conf.modules or cmd-line */ | ||
1507 | if (boot_options) | ||
1508 | option_setup(boot_options); | ||
1509 | #endif | ||
1510 | |||
1511 | /* get interrupt request level */ | ||
1512 | if (request_irq(IM_IRQ, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) { | ||
1513 | printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ); | ||
1514 | return 0; | ||
1515 | } else | ||
1516 | IRQ14_registered++; | ||
1517 | |||
1518 | /* if ibmmcascsi setup option was passed to kernel, return "found" */ | ||
1519 | for (i = 0; i < IM_MAX_HOSTS; i++) | ||
1520 | if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8) { | ||
1521 | printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n", io_port[i], scsi_id[i]); | ||
1522 | if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i], FORCED_DETECTION, "forced detected SCSI Adapter"))) { | ||
1523 | for (k = 2; k < 7; k++) | ||
1524 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = 0; | ||
1525 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = FORCED_DETECTION; | ||
1526 | mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter"); | ||
1527 | mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt); | ||
1528 | mca_mark_as_used(MCA_INTEGSCSI); | ||
1529 | devices_on_irq_14++; | ||
1530 | } | ||
1531 | } | ||
1532 | if (found) | ||
1533 | return found; | ||
1534 | |||
1535 | /* The POS2-register of all PS/2 model SCSI-subsystems has the following | 1524 | /* The POS2-register of all PS/2 model SCSI-subsystems has the following |
1536 | * interpretation of bits: | 1525 | * interpretation of bits: |
1537 | * Bit 7 - 4 : Chip Revision ID (Release) | 1526 | * Bit 7 - 4 : Chip Revision ID (Release) |
@@ -1558,7 +1547,14 @@ int ibmmca_detect(struct scsi_host_template * scsi_template) | |||
1558 | 1547 | ||
1559 | /* first look for the IBM SCSI integrated subsystem on the motherboard */ | 1548 | /* first look for the IBM SCSI integrated subsystem on the motherboard */ |
1560 | for (j = 0; j < 8; j++) /* read the pos-information */ | 1549 | for (j = 0; j < 8; j++) /* read the pos-information */ |
1561 | pos[j] = mca_read_stored_pos(MCA_INTEGSCSI, j); | 1550 | pos[j] = mca_device_read_pos(mca_dev, j); |
1551 | id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */ | ||
1552 | enabled = (pos[2] &0x01); | ||
1553 | if (!enabled) { | ||
1554 | printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n"); | ||
1555 | printk(KERN_WARNING " SCSI-operations may not work.\n"); | ||
1556 | } | ||
1557 | |||
1562 | /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present, but | 1558 | /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present, but |
1563 | * if we ignore the settings of all surrounding pos registers, it is not | 1559 | * if we ignore the settings of all surrounding pos registers, it is not |
1564 | * completely sufficient to only check pos2 and pos3. */ | 1560 | * completely sufficient to only check pos2 and pos3. */ |
@@ -1566,232 +1562,137 @@ int ibmmca_detect(struct scsi_host_template * scsi_template) | |||
1566 | * make sure, we see a real integrated onboard SCSI-interface and no | 1562 | * make sure, we see a real integrated onboard SCSI-interface and no |
1567 | * internal system information, which gets mapped to some pos registers | 1563 | * internal system information, which gets mapped to some pos registers |
1568 | * on models 95xx. */ | 1564 | * on models 95xx. */ |
1569 | if ((!pos[0] && !pos[1] && pos[2] > 0 && pos[3] > 0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) || (pos[0] == 0xff && pos[1] == 0xff && pos[2] < 0xff && pos[3] < 0xff && pos[4] == 0xff && pos[5] == 0xff && pos[6] == 0xff && pos[7] == 0xff)) { | 1565 | if (mca_dev->slot == MCA_INTEGSCSI && |
1570 | if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */ | 1566 | ((!pos[0] && !pos[1] && pos[2] > 0 && |
1571 | port = IM_IO_PORT; | 1567 | pos[3] > 0 && !pos[4] && !pos[5] && |
1572 | else { /* if disabled, no IRQs will be generated, as the chip won't | 1568 | !pos[6] && !pos[7]) || |
1573 | * listen to the incoming commands and will do really nothing, | 1569 | (pos[0] == 0xff && pos[1] == 0xff && |
1574 | * except for listening to the pos-register settings. If this | 1570 | pos[2] < 0xff && pos[3] < 0xff && |
1575 | * happens, I need to hugely think about it, as one has to | 1571 | pos[4] == 0xff && pos[5] == 0xff && |
1576 | * write something to the MCA-Bus pos register in order to | 1572 | pos[6] == 0xff && pos[7] == 0xff))) { |
1577 | * enable the chip. Normally, IBM-SCSI won't pass the POST, | 1573 | irq = IM_IRQ; |
1578 | * when the chip is disabled (see IBM tech. ref.). */ | 1574 | port = IM_IO_PORT; |
1579 | port = IM_IO_PORT; /* anyway, set the portnumber and warn */ | 1575 | } else { |
1580 | printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n" " SCSI-operations may not work.\n"); | 1576 | irq = IM_IRQ; |
1577 | port = IM_IO_PORT + ((pos[2] &0x0e) << 2); | ||
1578 | if ((mca_dev->index == IBM_SCSI2_FW) && (pos[6] != 0)) { | ||
1579 | printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n"); | ||
1580 | printk(KERN_ERR " Impossible to determine adapter PUN!\n"); | ||
1581 | printk(KERN_ERR " Guessing adapter PUN = 7.\n"); | ||
1582 | id = 7; | ||
1583 | } else { | ||
1584 | id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */ | ||
1585 | if (mca_dev->index == IBM_SCSI2_FW) { | ||
1586 | id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit | ||
1587 | * for F/W adapters */ | ||
1588 | } | ||
1581 | } | 1589 | } |
1582 | id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */ | 1590 | if ((mca_dev->index == IBM_SCSI2_FW) && |
1583 | /* give detailed information on the subsystem. This helps me | 1591 | (pos[4] & 0x01) && (pos[6] == 0)) { |
1584 | * additionally during debugging and analyzing bug-reports. */ | 1592 | /* IRQ11 is used by SCSI-2 F/W Adapter/A */ |
1585 | printk(KERN_INFO "IBM MCA SCSI: IBM Integrated SCSI Controller ffound, io=0x%x, scsi id=%d,\n", port, id); | 1593 | printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n"); |
1586 | printk(KERN_INFO " chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible", (pos[2] & 1) ? "enabled." : "disabled."); | 1594 | irq = IM_IRQ_FW; |
1587 | |||
1588 | /* register the found integrated SCSI-subsystem */ | ||
1589 | if ((shpnt = ibmmca_register(scsi_template, port, id, INTEGRATED_SCSI, "IBM Integrated SCSI Controller"))) | ||
1590 | { | ||
1591 | for (k = 2; k < 7; k++) | ||
1592 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k]; | ||
1593 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = INTEGRATED_SCSI; | ||
1594 | mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller"); | ||
1595 | mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt); | ||
1596 | mca_mark_as_used(MCA_INTEGSCSI); | ||
1597 | devices_on_irq_14++; | ||
1598 | } | 1595 | } |
1599 | } | 1596 | } |
1600 | 1597 | ||
1601 | /* now look for other adapters in MCA slots, */ | ||
1602 | /* determine the number of known IBM-SCSI-subsystem types */ | ||
1603 | /* see the pos[2] dependence to get the adapter port-offset. */ | ||
1604 | for (i = 0; i < ARRAY_SIZE(subsys_list); i++) { | ||
1605 | /* scan each slot for a fitting adapter id */ | ||
1606 | slot = 0; /* start at slot 0 */ | ||
1607 | while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot)) | ||
1608 | != MCA_NOTFOUND) { /* scan through all slots */ | ||
1609 | for (j = 0; j < 8; j++) /* read the pos-information */ | ||
1610 | pos[j] = mca_read_stored_pos(slot, j); | ||
1611 | if ((pos[2] & 1) == 1) | ||
1612 | /* is the subsystem chip enabled ? */ | ||
1613 | /* (explanations see above) */ | ||
1614 | port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); | ||
1615 | else { | ||
1616 | /* anyway, set the portnumber and warn */ | ||
1617 | port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); | ||
1618 | printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n"); | ||
1619 | printk(KERN_WARNING " SCSI-operations may not work.\n"); | ||
1620 | } | ||
1621 | if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) { | ||
1622 | printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n"); | ||
1623 | printk(KERN_ERR " Impossible to determine adapter PUN!\n"); | ||
1624 | printk(KERN_ERR " Guessing adapter PUN = 7.\n"); | ||
1625 | id = 7; | ||
1626 | } else { | ||
1627 | id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */ | ||
1628 | if (i == IBM_SCSI2_FW) { | ||
1629 | id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit | ||
1630 | * for F/W adapters */ | ||
1631 | } | ||
1632 | } | ||
1633 | if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) { | ||
1634 | /* IRQ11 is used by SCSI-2 F/W Adapter/A */ | ||
1635 | printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n"); | ||
1636 | /* get interrupt request level */ | ||
1637 | if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) { | ||
1638 | printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW); | ||
1639 | } else | ||
1640 | IRQ11_registered++; | ||
1641 | } | ||
1642 | printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id); | ||
1643 | if ((pos[2] & 0xf0) == 0xf0) | ||
1644 | printk(KERN_DEBUG" ROM Addr.=off,"); | ||
1645 | else | ||
1646 | printk(KERN_DEBUG " ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000); | ||
1647 | printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled."); | ||
1648 | |||
1649 | /* register the hostadapter */ | ||
1650 | if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) { | ||
1651 | for (k = 2; k < 8; k++) | ||
1652 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k]; | ||
1653 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i; | ||
1654 | mca_set_adapter_name(slot, subsys_list[i].description); | ||
1655 | mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt); | ||
1656 | mca_mark_as_used(slot); | ||
1657 | if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) | ||
1658 | devices_on_irq_11++; | ||
1659 | else | ||
1660 | devices_on_irq_14++; | ||
1661 | } | ||
1662 | slot++; /* advance to next slot */ | ||
1663 | } /* advance to next adapter id in the list of IBM-SCSI-subsystems */ | ||
1664 | } | ||
1665 | 1598 | ||
1666 | /* now check for SCSI-adapters, mapped to the integrated SCSI | ||
1667 | * area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here, | ||
1668 | * as this is a known effect on some models 95xx. */ | ||
1669 | for (i = 0; i < ARRAY_SIZE(subsys_list); i++) { | ||
1670 | /* scan each slot for a fitting adapter id */ | ||
1671 | slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI); | ||
1672 | if (slot != MCA_NOTFOUND) { /* scan through all slots */ | ||
1673 | for (j = 0; j < 8; j++) /* read the pos-information */ | ||
1674 | pos[j] = mca_read_stored_pos(slot, j); | ||
1675 | if ((pos[2] & 1) == 1) { /* is the subsystem chip enabled ? */ | ||
1676 | /* (explanations see above) */ | ||
1677 | port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); | ||
1678 | } else { /* anyway, set the portnumber and warn */ | ||
1679 | port = IM_IO_PORT + ((pos[2] & 0x0e) << 2); | ||
1680 | printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n"); | ||
1681 | printk(KERN_WARNING " SCSI-operations may not work.\n"); | ||
1682 | } | ||
1683 | if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) { | ||
1684 | printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n"); | ||
1685 | printk(KERN_ERR " Impossible to determine adapter PUN!\n"); | ||
1686 | printk(KERN_ERR " Guessing adapter PUN = 7.\n"); | ||
1687 | id = 7; | ||
1688 | } else { | ||
1689 | id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */ | ||
1690 | if (i == IBM_SCSI2_FW) | ||
1691 | id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit | ||
1692 | * for F/W adapters */ | ||
1693 | } | ||
1694 | if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) { | ||
1695 | /* IRQ11 is used by SCSI-2 F/W Adapter/A */ | ||
1696 | printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n"); | ||
1697 | /* get interrupt request level */ | ||
1698 | if (request_irq(IM_IRQ_FW, interrupt_handler, IRQF_SHARED, "ibmmcascsi", hosts)) | ||
1699 | printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW); | ||
1700 | else | ||
1701 | IRQ11_registered++; | ||
1702 | } | ||
1703 | printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id); | ||
1704 | if ((pos[2] & 0xf0) == 0xf0) | ||
1705 | printk(KERN_DEBUG " ROM Addr.=off,"); | ||
1706 | else | ||
1707 | printk(KERN_DEBUG " ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000); | ||
1708 | printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled."); | ||
1709 | |||
1710 | /* register the hostadapter */ | ||
1711 | if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) { | ||
1712 | for (k = 2; k < 7; k++) | ||
1713 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k]; | ||
1714 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i; | ||
1715 | mca_set_adapter_name(slot, subsys_list[i].description); | ||
1716 | mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt); | ||
1717 | mca_mark_as_used(slot); | ||
1718 | if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) | ||
1719 | devices_on_irq_11++; | ||
1720 | else | ||
1721 | devices_on_irq_14++; | ||
1722 | } | ||
1723 | slot++; /* advance to next slot */ | ||
1724 | } /* advance to next adapter id in the list of IBM-SCSI-subsystems */ | ||
1725 | } | ||
1726 | if (IRQ11_registered && !devices_on_irq_11) | ||
1727 | free_irq(IM_IRQ_FW, hosts); /* no devices on IRQ 11 */ | ||
1728 | if (IRQ14_registered && !devices_on_irq_14) | ||
1729 | free_irq(IM_IRQ, hosts); /* no devices on IRQ 14 */ | ||
1730 | if (!devices_on_irq_11 && !devices_on_irq_14) | ||
1731 | printk(KERN_WARNING "IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n"); | ||
1732 | return found; /* return the number of found SCSI hosts. Should be 1 or 0. */ | ||
1733 | } | ||
1734 | 1599 | ||
1735 | static struct Scsi_Host *ibmmca_register(struct scsi_host_template * scsi_template, int port, int id, int adaptertype, char *hostname) | 1600 | /* give detailed information on the subsystem. This helps me |
1736 | { | 1601 | * additionally during debugging and analyzing bug-reports. */ |
1737 | struct Scsi_Host *shpnt; | 1602 | printk(KERN_INFO "IBM MCA SCSI: %s found, io=0x%x, scsi id=%d,\n", |
1738 | int i, j; | 1603 | description, port, id); |
1739 | unsigned int ctrl; | 1604 | if (mca_dev->slot == MCA_INTEGSCSI) |
1605 | printk(KERN_INFO " chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible", (pos[2] & 1) ? "enabled." : "disabled."); | ||
1606 | else { | ||
1607 | if ((pos[2] & 0xf0) == 0xf0) | ||
1608 | printk(KERN_DEBUG " ROM Addr.=off,"); | ||
1609 | else | ||
1610 | printk(KERN_DEBUG " ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000); | ||
1611 | |||
1612 | printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled."); | ||
1613 | } | ||
1740 | 1614 | ||
1741 | /* check I/O region */ | 1615 | /* check I/O region */ |
1742 | if (!request_region(port, IM_N_IO_PORT, hostname)) { | 1616 | if (!request_region(port, IM_N_IO_PORT, description)) { |
1743 | printk(KERN_ERR "IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n", port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT); | 1617 | printk(KERN_ERR "IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n", port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT); |
1744 | return NULL; | 1618 | goto out_fail; |
1745 | } | 1619 | } |
1746 | 1620 | ||
1747 | /* register host */ | 1621 | /* register host */ |
1748 | shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata)); | 1622 | shpnt = scsi_host_alloc(&ibmmca_driver_template, |
1623 | sizeof(struct ibmmca_hostdata)); | ||
1749 | if (!shpnt) { | 1624 | if (!shpnt) { |
1750 | printk(KERN_ERR "IBM MCA SCSI: Unable to register host.\n"); | 1625 | printk(KERN_ERR "IBM MCA SCSI: Unable to register host.\n"); |
1751 | release_region(port, IM_N_IO_PORT); | 1626 | goto out_release; |
1752 | return NULL; | 1627 | } |
1628 | |||
1629 | dev_set_drvdata(dev, shpnt); | ||
1630 | if(request_irq(irq, interrupt_handler, IRQF_SHARED, description, dev)) { | ||
1631 | printk(KERN_ERR "IBM MCA SCSI: failed to request interrupt %d\n", irq); | ||
1632 | goto out_free_host; | ||
1753 | } | 1633 | } |
1754 | 1634 | ||
1755 | /* request I/O region */ | 1635 | /* request I/O region */ |
1756 | hosts[found] = shpnt; /* add new found hostadapter to the list */ | 1636 | special(shpnt) = mca_dev->index; /* important assignment or else crash! */ |
1757 | special(found) = adaptertype; /* important assignment or else crash! */ | 1637 | subsystem_connector_size(shpnt) = 0; /* preset slot-size */ |
1758 | subsystem_connector_size(found) = 0; /* preset slot-size */ | 1638 | shpnt->irq = irq; /* assign necessary stuff for the adapter */ |
1759 | shpnt->irq = IM_IRQ; /* assign necessary stuff for the adapter */ | ||
1760 | shpnt->io_port = port; | 1639 | shpnt->io_port = port; |
1761 | shpnt->n_io_port = IM_N_IO_PORT; | 1640 | shpnt->n_io_port = IM_N_IO_PORT; |
1762 | shpnt->this_id = id; | 1641 | shpnt->this_id = id; |
1763 | shpnt->max_id = 8; /* 8 PUNs are default */ | 1642 | shpnt->max_id = 8; /* 8 PUNs are default */ |
1764 | /* now, the SCSI-subsystem is connected to Linux */ | 1643 | /* now, the SCSI-subsystem is connected to Linux */ |
1765 | 1644 | ||
1766 | ctrl = (unsigned int) (inb(IM_CTR_REG(found))); /* get control-register status */ | ||
1767 | #ifdef IM_DEBUG_PROBE | 1645 | #ifdef IM_DEBUG_PROBE |
1646 | ctrl = (unsigned int) (inb(IM_CTR_REG(found))); /* get control-register status */ | ||
1768 | printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n", ctrl, inb(IM_STAT_REG(found))); | 1647 | printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n", ctrl, inb(IM_STAT_REG(found))); |
1769 | printk("IBM MCA SCSI: This adapters' POS-registers: "); | 1648 | printk("IBM MCA SCSI: This adapters' POS-registers: "); |
1770 | for (i = 0; i < 8; i++) | 1649 | for (i = 0; i < 8; i++) |
1771 | printk("%x ", pos[i]); | 1650 | printk("%x ", pos[i]); |
1772 | printk("\n"); | 1651 | printk("\n"); |
1773 | #endif | 1652 | #endif |
1774 | reset_status(found) = IM_RESET_NOT_IN_PROGRESS; | 1653 | reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS; |
1775 | 1654 | ||
1776 | for (i = 0; i < 16; i++) /* reset the tables */ | 1655 | for (i = 0; i < 16; i++) /* reset the tables */ |
1777 | for (j = 0; j < 8; j++) | 1656 | for (j = 0; j < 8; j++) |
1778 | get_ldn(found)[i][j] = MAX_LOG_DEV; | 1657 | get_ldn(shpnt)[i][j] = MAX_LOG_DEV; |
1779 | 1658 | ||
1780 | /* check which logical devices exist */ | 1659 | /* check which logical devices exist */ |
1781 | /* after this line, local interrupting is possible: */ | 1660 | /* after this line, local interrupting is possible: */ |
1782 | local_checking_phase_flag(found) = 1; | 1661 | local_checking_phase_flag(shpnt) = 1; |
1783 | check_devices(found, adaptertype); /* call by value, using the global variable hosts */ | 1662 | check_devices(shpnt, mca_dev->index); /* call by value, using the global variable hosts */ |
1784 | local_checking_phase_flag(found) = 0; | 1663 | local_checking_phase_flag(shpnt) = 0; |
1785 | found++; /* now increase index to be prepared for next found subsystem */ | 1664 | |
1786 | /* an ibm mca subsystem has been detected */ | 1665 | /* an ibm mca subsystem has been detected */ |
1787 | return shpnt; | 1666 | |
1667 | for (k = 2; k < 7; k++) | ||
1668 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k]; | ||
1669 | ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = INTEGRATED_SCSI; | ||
1670 | mca_device_set_name(mca_dev, description); | ||
1671 | /* FIXME: NEED TO REPLUMB TO SYSFS | ||
1672 | mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt); | ||
1673 | */ | ||
1674 | mca_device_set_claim(mca_dev, 1); | ||
1675 | if (scsi_add_host(shpnt, dev)) { | ||
1676 | dev_printk(KERN_ERR, dev, "IBM MCA SCSI: scsi_add_host failed\n"); | ||
1677 | goto out_free_host; | ||
1678 | } | ||
1679 | scsi_scan_host(shpnt); | ||
1680 | |||
1681 | return 0; | ||
1682 | out_free_host: | ||
1683 | scsi_host_put(shpnt); | ||
1684 | out_release: | ||
1685 | release_region(port, IM_N_IO_PORT); | ||
1686 | out_fail: | ||
1687 | return ret; | ||
1788 | } | 1688 | } |
1789 | 1689 | ||
1790 | static int ibmmca_release(struct Scsi_Host *shpnt) | 1690 | static int __devexit ibmmca_remove(struct device *dev) |
1791 | { | 1691 | { |
1692 | struct Scsi_Host *shpnt = dev_get_drvdata(dev); | ||
1693 | scsi_remove_host(shpnt); | ||
1792 | release_region(shpnt->io_port, shpnt->n_io_port); | 1694 | release_region(shpnt->io_port, shpnt->n_io_port); |
1793 | if (!(--found)) | 1695 | free_irq(shpnt->irq, dev); |
1794 | free_irq(shpnt->irq, hosts); | ||
1795 | return 0; | 1696 | return 0; |
1796 | } | 1697 | } |
1797 | 1698 | ||
@@ -1805,33 +1706,24 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1805 | int current_ldn; | 1706 | int current_ldn; |
1806 | int id, lun; | 1707 | int id, lun; |
1807 | int target; | 1708 | int target; |
1808 | int host_index; | ||
1809 | int max_pun; | 1709 | int max_pun; |
1810 | int i; | 1710 | int i; |
1811 | struct scatterlist *sl; | 1711 | struct scatterlist *sl; |
1812 | 1712 | ||
1813 | shpnt = cmd->device->host; | 1713 | shpnt = cmd->device->host; |
1814 | /* search for the right hostadapter */ | ||
1815 | for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++); | ||
1816 | 1714 | ||
1817 | if (!hosts[host_index]) { /* invalid hostadapter descriptor address */ | 1715 | max_pun = subsystem_maxid(shpnt); |
1818 | cmd->result = DID_NO_CONNECT << 16; | ||
1819 | if (done) | ||
1820 | done(cmd); | ||
1821 | return 0; | ||
1822 | } | ||
1823 | max_pun = subsystem_maxid(host_index); | ||
1824 | if (ibm_ansi_order) { | 1716 | if (ibm_ansi_order) { |
1825 | target = max_pun - 1 - cmd->device->id; | 1717 | target = max_pun - 1 - cmd->device->id; |
1826 | if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index))) | 1718 | if ((target <= subsystem_pun(shpnt)) && (cmd->device->id <= subsystem_pun(shpnt))) |
1827 | target--; | 1719 | target--; |
1828 | else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index))) | 1720 | else if ((target >= subsystem_pun(shpnt)) && (cmd->device->id >= subsystem_pun(shpnt))) |
1829 | target++; | 1721 | target++; |
1830 | } else | 1722 | } else |
1831 | target = cmd->device->id; | 1723 | target = cmd->device->id; |
1832 | 1724 | ||
1833 | /* if (target,lun) is NO LUN or not existing at all, return error */ | 1725 | /* if (target,lun) is NO LUN or not existing at all, return error */ |
1834 | if ((get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_DEVICE)) { | 1726 | if ((get_scsi(shpnt)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(shpnt)[target][cmd->device->lun] == TYPE_NO_DEVICE)) { |
1835 | cmd->result = DID_NO_CONNECT << 16; | 1727 | cmd->result = DID_NO_CONNECT << 16; |
1836 | if (done) | 1728 | if (done) |
1837 | done(cmd); | 1729 | done(cmd); |
@@ -1839,16 +1731,16 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1839 | } | 1731 | } |
1840 | 1732 | ||
1841 | /*if (target,lun) unassigned, do further checks... */ | 1733 | /*if (target,lun) unassigned, do further checks... */ |
1842 | ldn = get_ldn(host_index)[target][cmd->device->lun]; | 1734 | ldn = get_ldn(shpnt)[target][cmd->device->lun]; |
1843 | if (ldn >= MAX_LOG_DEV) { /* on invalid ldn do special stuff */ | 1735 | if (ldn >= MAX_LOG_DEV) { /* on invalid ldn do special stuff */ |
1844 | if (ldn > MAX_LOG_DEV) { /* dynamical remapping if ldn unassigned */ | 1736 | if (ldn > MAX_LOG_DEV) { /* dynamical remapping if ldn unassigned */ |
1845 | current_ldn = next_ldn(host_index); /* stop-value for one circle */ | 1737 | current_ldn = next_ldn(shpnt); /* stop-value for one circle */ |
1846 | while (ld(host_index)[next_ldn(host_index)].cmd) { /* search for a occupied, but not in */ | 1738 | while (ld(shpnt)[next_ldn(shpnt)].cmd) { /* search for a occupied, but not in */ |
1847 | /* command-processing ldn. */ | 1739 | /* command-processing ldn. */ |
1848 | next_ldn(host_index)++; | 1740 | next_ldn(shpnt)++; |
1849 | if (next_ldn(host_index) >= MAX_LOG_DEV) | 1741 | if (next_ldn(shpnt) >= MAX_LOG_DEV) |
1850 | next_ldn(host_index) = 7; | 1742 | next_ldn(shpnt) = 7; |
1851 | if (current_ldn == next_ldn(host_index)) { /* One circle done ? */ | 1743 | if (current_ldn == next_ldn(shpnt)) { /* One circle done ? */ |
1852 | /* no non-processing ldn found */ | 1744 | /* no non-processing ldn found */ |
1853 | scmd_printk(KERN_WARNING, cmd, | 1745 | scmd_printk(KERN_WARNING, cmd, |
1854 | "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" | 1746 | "IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" |
@@ -1864,56 +1756,56 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1864 | /* unmap non-processing ldn */ | 1756 | /* unmap non-processing ldn */ |
1865 | for (id = 0; id < max_pun; id++) | 1757 | for (id = 0; id < max_pun; id++) |
1866 | for (lun = 0; lun < 8; lun++) { | 1758 | for (lun = 0; lun < 8; lun++) { |
1867 | if (get_ldn(host_index)[id][lun] == next_ldn(host_index)) { | 1759 | if (get_ldn(shpnt)[id][lun] == next_ldn(shpnt)) { |
1868 | get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE; | 1760 | get_ldn(shpnt)[id][lun] = TYPE_NO_DEVICE; |
1869 | get_scsi(host_index)[id][lun] = TYPE_NO_DEVICE; | 1761 | get_scsi(shpnt)[id][lun] = TYPE_NO_DEVICE; |
1870 | /* unmap entry */ | 1762 | /* unmap entry */ |
1871 | } | 1763 | } |
1872 | } | 1764 | } |
1873 | /* set reduced interrupt_handler-mode for checking */ | 1765 | /* set reduced interrupt_handler-mode for checking */ |
1874 | local_checking_phase_flag(host_index) = 1; | 1766 | local_checking_phase_flag(shpnt) = 1; |
1875 | /* map found ldn to pun,lun */ | 1767 | /* map found ldn to pun,lun */ |
1876 | get_ldn(host_index)[target][cmd->device->lun] = next_ldn(host_index); | 1768 | get_ldn(shpnt)[target][cmd->device->lun] = next_ldn(shpnt); |
1877 | /* change ldn to the right value, that is now next_ldn */ | 1769 | /* change ldn to the right value, that is now next_ldn */ |
1878 | ldn = next_ldn(host_index); | 1770 | ldn = next_ldn(shpnt); |
1879 | /* unassign all ldns (pun,lun,ldn does not matter for remove) */ | 1771 | /* unassign all ldns (pun,lun,ldn does not matter for remove) */ |
1880 | immediate_assign(host_index, 0, 0, 0, REMOVE_LDN); | 1772 | immediate_assign(shpnt, 0, 0, 0, REMOVE_LDN); |
1881 | /* set only LDN for remapped device */ | 1773 | /* set only LDN for remapped device */ |
1882 | immediate_assign(host_index, target, cmd->device->lun, ldn, SET_LDN); | 1774 | immediate_assign(shpnt, target, cmd->device->lun, ldn, SET_LDN); |
1883 | /* get device information for ld[ldn] */ | 1775 | /* get device information for ld[ldn] */ |
1884 | if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) { | 1776 | if (device_exists(shpnt, ldn, &ld(shpnt)[ldn].block_length, &ld(shpnt)[ldn].device_type)) { |
1885 | ld(host_index)[ldn].cmd = NULL; /* To prevent panic set 0, because | 1777 | ld(shpnt)[ldn].cmd = NULL; /* To prevent panic set 0, because |
1886 | devices that were not assigned, | 1778 | devices that were not assigned, |
1887 | should have nothing in progress. */ | 1779 | should have nothing in progress. */ |
1888 | get_scsi(host_index)[target][cmd->device->lun] = ld(host_index)[ldn].device_type; | 1780 | get_scsi(shpnt)[target][cmd->device->lun] = ld(shpnt)[ldn].device_type; |
1889 | /* increase assignment counters for statistics in /proc */ | 1781 | /* increase assignment counters for statistics in /proc */ |
1890 | IBM_DS(host_index).dynamical_assignments++; | 1782 | IBM_DS(shpnt).dynamical_assignments++; |
1891 | IBM_DS(host_index).ldn_assignments[ldn]++; | 1783 | IBM_DS(shpnt).ldn_assignments[ldn]++; |
1892 | } else | 1784 | } else |
1893 | /* panic here, because a device, found at boottime has | 1785 | /* panic here, because a device, found at boottime has |
1894 | vanished */ | 1786 | vanished */ |
1895 | panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->device->lun); | 1787 | panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->device->lun); |
1896 | /* unassign again all ldns (pun,lun,ldn does not matter for remove) */ | 1788 | /* unassign again all ldns (pun,lun,ldn does not matter for remove) */ |
1897 | immediate_assign(host_index, 0, 0, 0, REMOVE_LDN); | 1789 | immediate_assign(shpnt, 0, 0, 0, REMOVE_LDN); |
1898 | /* remap all ldns, as written in the pun/lun table */ | 1790 | /* remap all ldns, as written in the pun/lun table */ |
1899 | lun = 0; | 1791 | lun = 0; |
1900 | #ifdef CONFIG_SCSI_MULTI_LUN | 1792 | #ifdef CONFIG_SCSI_MULTI_LUN |
1901 | for (lun = 0; lun < 8; lun++) | 1793 | for (lun = 0; lun < 8; lun++) |
1902 | #endif | 1794 | #endif |
1903 | for (id = 0; id < max_pun; id++) { | 1795 | for (id = 0; id < max_pun; id++) { |
1904 | if (get_ldn(host_index)[id][lun] <= MAX_LOG_DEV) | 1796 | if (get_ldn(shpnt)[id][lun] <= MAX_LOG_DEV) |
1905 | immediate_assign(host_index, id, lun, get_ldn(host_index)[id][lun], SET_LDN); | 1797 | immediate_assign(shpnt, id, lun, get_ldn(shpnt)[id][lun], SET_LDN); |
1906 | } | 1798 | } |
1907 | /* set back to normal interrupt_handling */ | 1799 | /* set back to normal interrupt_handling */ |
1908 | local_checking_phase_flag(host_index) = 0; | 1800 | local_checking_phase_flag(shpnt) = 0; |
1909 | #ifdef IM_DEBUG_PROBE | 1801 | #ifdef IM_DEBUG_PROBE |
1910 | /* Information on syslog terminal */ | 1802 | /* Information on syslog terminal */ |
1911 | printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->device->lun); | 1803 | printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->device->lun); |
1912 | #endif | 1804 | #endif |
1913 | /* increase next_ldn for next dynamical assignment */ | 1805 | /* increase next_ldn for next dynamical assignment */ |
1914 | next_ldn(host_index)++; | 1806 | next_ldn(shpnt)++; |
1915 | if (next_ldn(host_index) >= MAX_LOG_DEV) | 1807 | if (next_ldn(shpnt) >= MAX_LOG_DEV) |
1916 | next_ldn(host_index) = 7; | 1808 | next_ldn(shpnt) = 7; |
1917 | } else { /* wall against Linux accesses to the subsystem adapter */ | 1809 | } else { /* wall against Linux accesses to the subsystem adapter */ |
1918 | cmd->result = DID_BAD_TARGET << 16; | 1810 | cmd->result = DID_BAD_TARGET << 16; |
1919 | if (done) | 1811 | if (done) |
@@ -1923,18 +1815,18 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1923 | } | 1815 | } |
1924 | 1816 | ||
1925 | /*verify there is no command already in progress for this log dev */ | 1817 | /*verify there is no command already in progress for this log dev */ |
1926 | if (ld(host_index)[ldn].cmd) | 1818 | if (ld(shpnt)[ldn].cmd) |
1927 | panic("IBM MCA SCSI: cmd already in progress for this ldn.\n"); | 1819 | panic("IBM MCA SCSI: cmd already in progress for this ldn.\n"); |
1928 | 1820 | ||
1929 | /*save done in cmd, and save cmd for the interrupt handler */ | 1821 | /*save done in cmd, and save cmd for the interrupt handler */ |
1930 | cmd->scsi_done = done; | 1822 | cmd->scsi_done = done; |
1931 | ld(host_index)[ldn].cmd = cmd; | 1823 | ld(shpnt)[ldn].cmd = cmd; |
1932 | 1824 | ||
1933 | /*fill scb information independent of the scsi command */ | 1825 | /*fill scb information independent of the scsi command */ |
1934 | scb = &(ld(host_index)[ldn].scb); | 1826 | scb = &(ld(shpnt)[ldn].scb); |
1935 | ld(host_index)[ldn].tsb.dev_status = 0; | 1827 | ld(shpnt)[ldn].tsb.dev_status = 0; |
1936 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE; | 1828 | scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE; |
1937 | scb->tsb_adr = isa_virt_to_bus(&(ld(host_index)[ldn].tsb)); | 1829 | scb->tsb_adr = isa_virt_to_bus(&(ld(shpnt)[ldn].tsb)); |
1938 | scsi_cmd = cmd->cmnd[0]; | 1830 | scsi_cmd = cmd->cmnd[0]; |
1939 | 1831 | ||
1940 | if (cmd->use_sg) { | 1832 | if (cmd->use_sg) { |
@@ -1943,11 +1835,11 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1943 | if (i > 16) | 1835 | if (i > 16) |
1944 | panic("IBM MCA SCSI: scatter-gather list too long.\n"); | 1836 | panic("IBM MCA SCSI: scatter-gather list too long.\n"); |
1945 | while (--i >= 0) { | 1837 | while (--i >= 0) { |
1946 | ld(host_index)[ldn].sge[i].address = (void *) (isa_page_to_bus(sl[i].page) + sl[i].offset); | 1838 | ld(shpnt)[ldn].sge[i].address = (void *) (isa_page_to_bus(sl[i].page) + sl[i].offset); |
1947 | ld(host_index)[ldn].sge[i].byte_length = sl[i].length; | 1839 | ld(shpnt)[ldn].sge[i].byte_length = sl[i].length; |
1948 | } | 1840 | } |
1949 | scb->enable |= IM_POINTER_TO_LIST; | 1841 | scb->enable |= IM_POINTER_TO_LIST; |
1950 | scb->sys_buf_adr = isa_virt_to_bus(&(ld(host_index)[ldn].sge[0])); | 1842 | scb->sys_buf_adr = isa_virt_to_bus(&(ld(shpnt)[ldn].sge[0])); |
1951 | scb->sys_buf_length = cmd->use_sg * sizeof(struct im_sge); | 1843 | scb->sys_buf_length = cmd->use_sg * sizeof(struct im_sge); |
1952 | } else { | 1844 | } else { |
1953 | scb->sys_buf_adr = isa_virt_to_bus(cmd->request_buffer); | 1845 | scb->sys_buf_adr = isa_virt_to_bus(cmd->request_buffer); |
@@ -1982,16 +1874,16 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
1982 | 1874 | ||
1983 | /* for specific device-type debugging: */ | 1875 | /* for specific device-type debugging: */ |
1984 | #ifdef IM_DEBUG_CMD_SPEC_DEV | 1876 | #ifdef IM_DEBUG_CMD_SPEC_DEV |
1985 | if (ld(host_index)[ldn].device_type == IM_DEBUG_CMD_DEVICE) | 1877 | if (ld(shpnt)[ldn].device_type == IM_DEBUG_CMD_DEVICE) |
1986 | printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", ld(host_index)[ldn].device_type, scsi_cmd, ldn); | 1878 | printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", ld(shpnt)[ldn].device_type, scsi_cmd, ldn); |
1987 | #endif | 1879 | #endif |
1988 | 1880 | ||
1989 | /* for possible panics store current command */ | 1881 | /* for possible panics store current command */ |
1990 | last_scsi_command(host_index)[ldn] = scsi_cmd; | 1882 | last_scsi_command(shpnt)[ldn] = scsi_cmd; |
1991 | last_scsi_type(host_index)[ldn] = IM_SCB; | 1883 | last_scsi_type(shpnt)[ldn] = IM_SCB; |
1992 | /* update statistical info */ | 1884 | /* update statistical info */ |
1993 | IBM_DS(host_index).total_accesses++; | 1885 | IBM_DS(shpnt).total_accesses++; |
1994 | IBM_DS(host_index).ldn_access[ldn]++; | 1886 | IBM_DS(shpnt).ldn_access[ldn]++; |
1995 | 1887 | ||
1996 | switch (scsi_cmd) { | 1888 | switch (scsi_cmd) { |
1997 | case READ_6: | 1889 | case READ_6: |
@@ -2003,17 +1895,17 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2003 | /* Distinguish between disk and other devices. Only disks (that are the | 1895 | /* Distinguish between disk and other devices. Only disks (that are the |
2004 | most frequently accessed devices) should be supported by the | 1896 | most frequently accessed devices) should be supported by the |
2005 | IBM-SCSI-Subsystem commands. */ | 1897 | IBM-SCSI-Subsystem commands. */ |
2006 | switch (ld(host_index)[ldn].device_type) { | 1898 | switch (ld(shpnt)[ldn].device_type) { |
2007 | case TYPE_DISK: /* for harddisks enter here ... */ | 1899 | case TYPE_DISK: /* for harddisks enter here ... */ |
2008 | case TYPE_MOD: /* ... try it also for MO-drives (send flames as */ | 1900 | case TYPE_MOD: /* ... try it also for MO-drives (send flames as */ |
2009 | /* you like, if this won't work.) */ | 1901 | /* you like, if this won't work.) */ |
2010 | if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || scsi_cmd == READ_12) { | 1902 | if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || scsi_cmd == READ_12) { |
2011 | /* read command preparations */ | 1903 | /* read command preparations */ |
2012 | scb->enable |= IM_READ_CONTROL; | 1904 | scb->enable |= IM_READ_CONTROL; |
2013 | IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */ | 1905 | IBM_DS(shpnt).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */ |
2014 | scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT; | 1906 | scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT; |
2015 | } else { /* write command preparations */ | 1907 | } else { /* write command preparations */ |
2016 | IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat. */ | 1908 | IBM_DS(shpnt).ldn_write_access[ldn]++; /* increase write-count on ldn stat. */ |
2017 | scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT; | 1909 | scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT; |
2018 | } | 1910 | } |
2019 | if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6) { | 1911 | if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6) { |
@@ -2023,9 +1915,9 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2023 | scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) | (((unsigned) cmd->cmnd[4]) << 8) | (((unsigned) cmd->cmnd[3]) << 16) | (((unsigned) cmd->cmnd[2]) << 24); | 1915 | scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) | (((unsigned) cmd->cmnd[4]) << 8) | (((unsigned) cmd->cmnd[3]) << 16) | (((unsigned) cmd->cmnd[2]) << 24); |
2024 | scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) | (((unsigned) cmd->cmnd[7]) << 8); | 1916 | scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) | (((unsigned) cmd->cmnd[7]) << 8); |
2025 | } | 1917 | } |
2026 | last_scsi_logical_block(host_index)[ldn] = scb->u1.log_blk_adr; | 1918 | last_scsi_logical_block(shpnt)[ldn] = scb->u1.log_blk_adr; |
2027 | last_scsi_blockcount(host_index)[ldn] = scb->u2.blk.count; | 1919 | last_scsi_blockcount(shpnt)[ldn] = scb->u2.blk.count; |
2028 | scb->u2.blk.length = ld(host_index)[ldn].block_length; | 1920 | scb->u2.blk.length = ld(shpnt)[ldn].block_length; |
2029 | break; | 1921 | break; |
2030 | /* for other devices, enter here. Other types are not known by | 1922 | /* for other devices, enter here. Other types are not known by |
2031 | Linux! TYPE_NO_LUN is forbidden as valid device. */ | 1923 | Linux! TYPE_NO_LUN is forbidden as valid device. */ |
@@ -2046,14 +1938,14 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2046 | scb->enable |= IM_BYPASS_BUFFER; | 1938 | scb->enable |= IM_BYPASS_BUFFER; |
2047 | scb->u1.scsi_cmd_length = cmd->cmd_len; | 1939 | scb->u1.scsi_cmd_length = cmd->cmd_len; |
2048 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); | 1940 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); |
2049 | last_scsi_type(host_index)[ldn] = IM_LONG_SCB; | 1941 | last_scsi_type(shpnt)[ldn] = IM_LONG_SCB; |
2050 | /* Read/write on this non-disk devices is also displayworthy, | 1942 | /* Read/write on this non-disk devices is also displayworthy, |
2051 | so flash-up the LED/display. */ | 1943 | so flash-up the LED/display. */ |
2052 | break; | 1944 | break; |
2053 | } | 1945 | } |
2054 | break; | 1946 | break; |
2055 | case INQUIRY: | 1947 | case INQUIRY: |
2056 | IBM_DS(host_index).ldn_inquiry_access[ldn]++; | 1948 | IBM_DS(shpnt).ldn_inquiry_access[ldn]++; |
2057 | scb->command = IM_DEVICE_INQUIRY_CMD; | 1949 | scb->command = IM_DEVICE_INQUIRY_CMD; |
2058 | scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; | 1950 | scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; |
2059 | scb->u1.log_blk_adr = 0; | 1951 | scb->u1.log_blk_adr = 0; |
@@ -2064,7 +1956,7 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2064 | scb->u1.log_blk_adr = 0; | 1956 | scb->u1.log_blk_adr = 0; |
2065 | scb->u1.scsi_cmd_length = 6; | 1957 | scb->u1.scsi_cmd_length = 6; |
2066 | memcpy(scb->u2.scsi_command, cmd->cmnd, 6); | 1958 | memcpy(scb->u2.scsi_command, cmd->cmnd, 6); |
2067 | last_scsi_type(host_index)[ldn] = IM_LONG_SCB; | 1959 | last_scsi_type(shpnt)[ldn] = IM_LONG_SCB; |
2068 | break; | 1960 | break; |
2069 | case READ_CAPACITY: | 1961 | case READ_CAPACITY: |
2070 | /* the length of system memory buffer must be exactly 8 bytes */ | 1962 | /* the length of system memory buffer must be exactly 8 bytes */ |
@@ -2081,12 +1973,12 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2081 | /* Commands that need write-only-mode (system -> device): */ | 1973 | /* Commands that need write-only-mode (system -> device): */ |
2082 | case MODE_SELECT: | 1974 | case MODE_SELECT: |
2083 | case MODE_SELECT_10: | 1975 | case MODE_SELECT_10: |
2084 | IBM_DS(host_index).ldn_modeselect_access[ldn]++; | 1976 | IBM_DS(shpnt).ldn_modeselect_access[ldn]++; |
2085 | scb->command = IM_OTHER_SCSI_CMD_CMD; | 1977 | scb->command = IM_OTHER_SCSI_CMD_CMD; |
2086 | scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; /*Select needs WRITE-enabled */ | 1978 | scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; /*Select needs WRITE-enabled */ |
2087 | scb->u1.scsi_cmd_length = cmd->cmd_len; | 1979 | scb->u1.scsi_cmd_length = cmd->cmd_len; |
2088 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); | 1980 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); |
2089 | last_scsi_type(host_index)[ldn] = IM_LONG_SCB; | 1981 | last_scsi_type(shpnt)[ldn] = IM_LONG_SCB; |
2090 | break; | 1982 | break; |
2091 | /* For other commands, read-only is useful. Most other commands are | 1983 | /* For other commands, read-only is useful. Most other commands are |
2092 | running without an input-data-block. */ | 1984 | running without an input-data-block. */ |
@@ -2095,19 +1987,19 @@ static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
2095 | scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; | 1987 | scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; |
2096 | scb->u1.scsi_cmd_length = cmd->cmd_len; | 1988 | scb->u1.scsi_cmd_length = cmd->cmd_len; |
2097 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); | 1989 | memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len); |
2098 | last_scsi_type(host_index)[ldn] = IM_LONG_SCB; | 1990 | last_scsi_type(shpnt)[ldn] = IM_LONG_SCB; |
2099 | break; | 1991 | break; |
2100 | } | 1992 | } |
2101 | /*issue scb command, and return */ | 1993 | /*issue scb command, and return */ |
2102 | if (++disk_rw_in_progress == 1) | 1994 | if (++disk_rw_in_progress == 1) |
2103 | PS2_DISK_LED_ON(shpnt->host_no, target); | 1995 | PS2_DISK_LED_ON(shpnt->host_no, target); |
2104 | 1996 | ||
2105 | if (last_scsi_type(host_index)[ldn] == IM_LONG_SCB) { | 1997 | if (last_scsi_type(shpnt)[ldn] == IM_LONG_SCB) { |
2106 | issue_cmd(host_index, isa_virt_to_bus(scb), IM_LONG_SCB | ldn); | 1998 | issue_cmd(shpnt, isa_virt_to_bus(scb), IM_LONG_SCB | ldn); |
2107 | IBM_DS(host_index).long_scbs++; | 1999 | IBM_DS(shpnt).long_scbs++; |
2108 | } else { | 2000 | } else { |
2109 | issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn); | 2001 | issue_cmd(shpnt, isa_virt_to_bus(scb), IM_SCB | ldn); |
2110 | IBM_DS(host_index).scbs++; | 2002 | IBM_DS(shpnt).scbs++; |
2111 | } | 2003 | } |
2112 | return 0; | 2004 | return 0; |
2113 | } | 2005 | } |
@@ -2122,7 +2014,6 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd) | |||
2122 | unsigned int ldn; | 2014 | unsigned int ldn; |
2123 | void (*saved_done) (Scsi_Cmnd *); | 2015 | void (*saved_done) (Scsi_Cmnd *); |
2124 | int target; | 2016 | int target; |
2125 | int host_index; | ||
2126 | int max_pun; | 2017 | int max_pun; |
2127 | unsigned long imm_command; | 2018 | unsigned long imm_command; |
2128 | 2019 | ||
@@ -2131,35 +2022,23 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd) | |||
2131 | #endif | 2022 | #endif |
2132 | 2023 | ||
2133 | shpnt = cmd->device->host; | 2024 | shpnt = cmd->device->host; |
2134 | /* search for the right hostadapter */ | ||
2135 | for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++); | ||
2136 | 2025 | ||
2137 | if (!hosts[host_index]) { /* invalid hostadapter descriptor address */ | 2026 | max_pun = subsystem_maxid(shpnt); |
2138 | cmd->result = DID_NO_CONNECT << 16; | ||
2139 | if (cmd->scsi_done) | ||
2140 | (cmd->scsi_done) (cmd); | ||
2141 | shpnt = cmd->device->host; | ||
2142 | #ifdef IM_DEBUG_PROBE | ||
2143 | printk(KERN_DEBUG "IBM MCA SCSI: Abort adapter selection failed!\n"); | ||
2144 | #endif | ||
2145 | return SUCCESS; | ||
2146 | } | ||
2147 | max_pun = subsystem_maxid(host_index); | ||
2148 | if (ibm_ansi_order) { | 2027 | if (ibm_ansi_order) { |
2149 | target = max_pun - 1 - cmd->device->id; | 2028 | target = max_pun - 1 - cmd->device->id; |
2150 | if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index))) | 2029 | if ((target <= subsystem_pun(shpnt)) && (cmd->device->id <= subsystem_pun(shpnt))) |
2151 | target--; | 2030 | target--; |
2152 | else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index))) | 2031 | else if ((target >= subsystem_pun(shpnt)) && (cmd->device->id >= subsystem_pun(shpnt))) |
2153 | target++; | 2032 | target++; |
2154 | } else | 2033 | } else |
2155 | target = cmd->device->id; | 2034 | target = cmd->device->id; |
2156 | 2035 | ||
2157 | /* get logical device number, and disable system interrupts */ | 2036 | /* get logical device number, and disable system interrupts */ |
2158 | printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->device->lun); | 2037 | printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->device->lun); |
2159 | ldn = get_ldn(host_index)[target][cmd->device->lun]; | 2038 | ldn = get_ldn(shpnt)[target][cmd->device->lun]; |
2160 | 2039 | ||
2161 | /*if cmd for this ldn has already finished, no need to abort */ | 2040 | /*if cmd for this ldn has already finished, no need to abort */ |
2162 | if (!ld(host_index)[ldn].cmd) { | 2041 | if (!ld(shpnt)[ldn].cmd) { |
2163 | return SUCCESS; | 2042 | return SUCCESS; |
2164 | } | 2043 | } |
2165 | 2044 | ||
@@ -2170,20 +2049,20 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd) | |||
2170 | saved_done = cmd->scsi_done; | 2049 | saved_done = cmd->scsi_done; |
2171 | cmd->scsi_done = internal_done; | 2050 | cmd->scsi_done = internal_done; |
2172 | cmd->SCp.Status = 0; | 2051 | cmd->SCp.Status = 0; |
2173 | last_scsi_command(host_index)[ldn] = IM_ABORT_IMM_CMD; | 2052 | last_scsi_command(shpnt)[ldn] = IM_ABORT_IMM_CMD; |
2174 | last_scsi_type(host_index)[ldn] = IM_IMM_CMD; | 2053 | last_scsi_type(shpnt)[ldn] = IM_IMM_CMD; |
2175 | imm_command = inl(IM_CMD_REG(host_index)); | 2054 | imm_command = inl(IM_CMD_REG(shpnt)); |
2176 | imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */ | 2055 | imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */ |
2177 | imm_command |= (unsigned long) (IM_ABORT_IMM_CMD); | 2056 | imm_command |= (unsigned long) (IM_ABORT_IMM_CMD); |
2178 | /* must wait for attention reg not busy */ | 2057 | /* must wait for attention reg not busy */ |
2179 | /* FIXME - timeout, politeness */ | 2058 | /* FIXME - timeout, politeness */ |
2180 | while (1) { | 2059 | while (1) { |
2181 | if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY)) | 2060 | if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY)) |
2182 | break; | 2061 | break; |
2183 | } | 2062 | } |
2184 | /* write registers and enable system interrupts */ | 2063 | /* write registers and enable system interrupts */ |
2185 | outl(imm_command, IM_CMD_REG(host_index)); | 2064 | outl(imm_command, IM_CMD_REG(shpnt)); |
2186 | outb(IM_IMM_CMD | ldn, IM_ATTN_REG(host_index)); | 2065 | outb(IM_IMM_CMD | ldn, IM_ATTN_REG(shpnt)); |
2187 | #ifdef IM_DEBUG_PROBE | 2066 | #ifdef IM_DEBUG_PROBE |
2188 | printk("IBM MCA SCSI: Abort queued to adapter...\n"); | 2067 | printk("IBM MCA SCSI: Abort queued to adapter...\n"); |
2189 | #endif | 2068 | #endif |
@@ -2202,7 +2081,7 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd) | |||
2202 | cmd->result |= DID_ABORT << 16; | 2081 | cmd->result |= DID_ABORT << 16; |
2203 | if (cmd->scsi_done) | 2082 | if (cmd->scsi_done) |
2204 | (cmd->scsi_done) (cmd); | 2083 | (cmd->scsi_done) (cmd); |
2205 | ld(host_index)[ldn].cmd = NULL; | 2084 | ld(shpnt)[ldn].cmd = NULL; |
2206 | #ifdef IM_DEBUG_PROBE | 2085 | #ifdef IM_DEBUG_PROBE |
2207 | printk("IBM MCA SCSI: Abort finished with success.\n"); | 2086 | printk("IBM MCA SCSI: Abort finished with success.\n"); |
2208 | #endif | 2087 | #endif |
@@ -2211,7 +2090,7 @@ static int __ibmmca_abort(Scsi_Cmnd * cmd) | |||
2211 | cmd->result |= DID_NO_CONNECT << 16; | 2090 | cmd->result |= DID_NO_CONNECT << 16; |
2212 | if (cmd->scsi_done) | 2091 | if (cmd->scsi_done) |
2213 | (cmd->scsi_done) (cmd); | 2092 | (cmd->scsi_done) (cmd); |
2214 | ld(host_index)[ldn].cmd = NULL; | 2093 | ld(shpnt)[ldn].cmd = NULL; |
2215 | #ifdef IM_DEBUG_PROBE | 2094 | #ifdef IM_DEBUG_PROBE |
2216 | printk("IBM MCA SCSI: Abort failed.\n"); | 2095 | printk("IBM MCA SCSI: Abort failed.\n"); |
2217 | #endif | 2096 | #endif |
@@ -2236,71 +2115,65 @@ static int __ibmmca_host_reset(Scsi_Cmnd * cmd) | |||
2236 | struct Scsi_Host *shpnt; | 2115 | struct Scsi_Host *shpnt; |
2237 | Scsi_Cmnd *cmd_aid; | 2116 | Scsi_Cmnd *cmd_aid; |
2238 | int ticks, i; | 2117 | int ticks, i; |
2239 | int host_index; | ||
2240 | unsigned long imm_command; | 2118 | unsigned long imm_command; |
2241 | 2119 | ||
2242 | BUG_ON(cmd == NULL); | 2120 | BUG_ON(cmd == NULL); |
2243 | 2121 | ||
2244 | ticks = IM_RESET_DELAY * HZ; | 2122 | ticks = IM_RESET_DELAY * HZ; |
2245 | shpnt = cmd->device->host; | 2123 | shpnt = cmd->device->host; |
2246 | /* search for the right hostadapter */ | ||
2247 | for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++); | ||
2248 | |||
2249 | if (!hosts[host_index]) /* invalid hostadapter descriptor address */ | ||
2250 | return FAILED; | ||
2251 | 2124 | ||
2252 | if (local_checking_phase_flag(host_index)) { | 2125 | if (local_checking_phase_flag(shpnt)) { |
2253 | printk(KERN_WARNING "IBM MCA SCSI: unable to reset while checking devices.\n"); | 2126 | printk(KERN_WARNING "IBM MCA SCSI: unable to reset while checking devices.\n"); |
2254 | return FAILED; | 2127 | return FAILED; |
2255 | } | 2128 | } |
2256 | 2129 | ||
2257 | /* issue reset immediate command to subsystem, and wait for interrupt */ | 2130 | /* issue reset immediate command to subsystem, and wait for interrupt */ |
2258 | printk("IBM MCA SCSI: resetting all devices.\n"); | 2131 | printk("IBM MCA SCSI: resetting all devices.\n"); |
2259 | reset_status(host_index) = IM_RESET_IN_PROGRESS; | 2132 | reset_status(shpnt) = IM_RESET_IN_PROGRESS; |
2260 | last_scsi_command(host_index)[0xf] = IM_RESET_IMM_CMD; | 2133 | last_scsi_command(shpnt)[0xf] = IM_RESET_IMM_CMD; |
2261 | last_scsi_type(host_index)[0xf] = IM_IMM_CMD; | 2134 | last_scsi_type(shpnt)[0xf] = IM_IMM_CMD; |
2262 | imm_command = inl(IM_CMD_REG(host_index)); | 2135 | imm_command = inl(IM_CMD_REG(shpnt)); |
2263 | imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */ | 2136 | imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */ |
2264 | imm_command |= (unsigned long) (IM_RESET_IMM_CMD); | 2137 | imm_command |= (unsigned long) (IM_RESET_IMM_CMD); |
2265 | /* must wait for attention reg not busy */ | 2138 | /* must wait for attention reg not busy */ |
2266 | while (1) { | 2139 | while (1) { |
2267 | if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY)) | 2140 | if (!(inb(IM_STAT_REG(shpnt)) & IM_BUSY)) |
2268 | break; | 2141 | break; |
2269 | spin_unlock_irq(shpnt->host_lock); | 2142 | spin_unlock_irq(shpnt->host_lock); |
2270 | yield(); | 2143 | yield(); |
2271 | spin_lock_irq(shpnt->host_lock); | 2144 | spin_lock_irq(shpnt->host_lock); |
2272 | } | 2145 | } |
2273 | /*write registers and enable system interrupts */ | 2146 | /*write registers and enable system interrupts */ |
2274 | outl(imm_command, IM_CMD_REG(host_index)); | 2147 | outl(imm_command, IM_CMD_REG(shpnt)); |
2275 | outb(IM_IMM_CMD | 0xf, IM_ATTN_REG(host_index)); | 2148 | outb(IM_IMM_CMD | 0xf, IM_ATTN_REG(shpnt)); |
2276 | /* wait for interrupt finished or intr_stat register to be set, as the | 2149 | /* wait for interrupt finished or intr_stat register to be set, as the |
2277 | * interrupt will not be executed, while we are in here! */ | 2150 | * interrupt will not be executed, while we are in here! */ |
2278 | 2151 | ||
2279 | /* FIXME: This is really really icky we so want a sleeping version of this ! */ | 2152 | /* FIXME: This is really really icky we so want a sleeping version of this ! */ |
2280 | while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks && ((inb(IM_INTR_REG(host_index)) & 0x8f) != 0x8f)) { | 2153 | while (reset_status(shpnt) == IM_RESET_IN_PROGRESS && --ticks && ((inb(IM_INTR_REG(shpnt)) & 0x8f) != 0x8f)) { |
2281 | udelay((1 + 999 / HZ) * 1000); | 2154 | udelay((1 + 999 / HZ) * 1000); |
2282 | barrier(); | 2155 | barrier(); |
2283 | } | 2156 | } |
2284 | /* if reset did not complete, just return an error */ | 2157 | /* if reset did not complete, just return an error */ |
2285 | if (!ticks) { | 2158 | if (!ticks) { |
2286 | printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY); | 2159 | printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY); |
2287 | reset_status(host_index) = IM_RESET_FINISHED_FAIL; | 2160 | reset_status(shpnt) = IM_RESET_FINISHED_FAIL; |
2288 | return FAILED; | 2161 | return FAILED; |
2289 | } | 2162 | } |
2290 | 2163 | ||
2291 | if ((inb(IM_INTR_REG(host_index)) & 0x8f) == 0x8f) { | 2164 | if ((inb(IM_INTR_REG(shpnt)) & 0x8f) == 0x8f) { |
2292 | /* analysis done by this routine and not by the intr-routine */ | 2165 | /* analysis done by this routine and not by the intr-routine */ |
2293 | if (inb(IM_INTR_REG(host_index)) == 0xaf) | 2166 | if (inb(IM_INTR_REG(shpnt)) == 0xaf) |
2294 | reset_status(host_index) = IM_RESET_FINISHED_OK_NO_INT; | 2167 | reset_status(shpnt) = IM_RESET_FINISHED_OK_NO_INT; |
2295 | else if (inb(IM_INTR_REG(host_index)) == 0xcf) | 2168 | else if (inb(IM_INTR_REG(shpnt)) == 0xcf) |
2296 | reset_status(host_index) = IM_RESET_FINISHED_FAIL; | 2169 | reset_status(shpnt) = IM_RESET_FINISHED_FAIL; |
2297 | else /* failed, 4get it */ | 2170 | else /* failed, 4get it */ |
2298 | reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT; | 2171 | reset_status(shpnt) = IM_RESET_NOT_IN_PROGRESS_NO_INT; |
2299 | outb(IM_EOI | 0xf, IM_ATTN_REG(host_index)); | 2172 | outb(IM_EOI | 0xf, IM_ATTN_REG(shpnt)); |
2300 | } | 2173 | } |
2301 | 2174 | ||
2302 | /* if reset failed, just return an error */ | 2175 | /* if reset failed, just return an error */ |
2303 | if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) { | 2176 | if (reset_status(shpnt) == IM_RESET_FINISHED_FAIL) { |
2304 | printk(KERN_ERR "IBM MCA SCSI: reset failed.\n"); | 2177 | printk(KERN_ERR "IBM MCA SCSI: reset failed.\n"); |
2305 | return FAILED; | 2178 | return FAILED; |
2306 | } | 2179 | } |
@@ -2308,9 +2181,9 @@ static int __ibmmca_host_reset(Scsi_Cmnd * cmd) | |||
2308 | /* so reset finished ok - call outstanding done's, and return success */ | 2181 | /* so reset finished ok - call outstanding done's, and return success */ |
2309 | printk(KERN_INFO "IBM MCA SCSI: Reset successfully completed.\n"); | 2182 | printk(KERN_INFO "IBM MCA SCSI: Reset successfully completed.\n"); |
2310 | for (i = 0; i < MAX_LOG_DEV; i++) { | 2183 | for (i = 0; i < MAX_LOG_DEV; i++) { |
2311 | cmd_aid = ld(host_index)[i].cmd; | 2184 | cmd_aid = ld(shpnt)[i].cmd; |
2312 | if (cmd_aid && cmd_aid->scsi_done) { | 2185 | if (cmd_aid && cmd_aid->scsi_done) { |
2313 | ld(host_index)[i].cmd = NULL; | 2186 | ld(shpnt)[i].cmd = NULL; |
2314 | cmd_aid->result = DID_RESET << 16; | 2187 | cmd_aid->result = DID_RESET << 16; |
2315 | } | 2188 | } |
2316 | } | 2189 | } |
@@ -2351,46 +2224,46 @@ static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev, | |||
2351 | } | 2224 | } |
2352 | 2225 | ||
2353 | /* calculate percentage of total accesses on a ldn */ | 2226 | /* calculate percentage of total accesses on a ldn */ |
2354 | static int ldn_access_load(int host_index, int ldn) | 2227 | static int ldn_access_load(struct Scsi_Host *shpnt, int ldn) |
2355 | { | 2228 | { |
2356 | if (IBM_DS(host_index).total_accesses == 0) | 2229 | if (IBM_DS(shpnt).total_accesses == 0) |
2357 | return (0); | 2230 | return (0); |
2358 | if (IBM_DS(host_index).ldn_access[ldn] == 0) | 2231 | if (IBM_DS(shpnt).ldn_access[ldn] == 0) |
2359 | return (0); | 2232 | return (0); |
2360 | return (IBM_DS(host_index).ldn_access[ldn] * 100) / IBM_DS(host_index).total_accesses; | 2233 | return (IBM_DS(shpnt).ldn_access[ldn] * 100) / IBM_DS(shpnt).total_accesses; |
2361 | } | 2234 | } |
2362 | 2235 | ||
2363 | /* calculate total amount of r/w-accesses */ | 2236 | /* calculate total amount of r/w-accesses */ |
2364 | static int ldn_access_total_read_write(int host_index) | 2237 | static int ldn_access_total_read_write(struct Scsi_Host *shpnt) |
2365 | { | 2238 | { |
2366 | int a; | 2239 | int a; |
2367 | int i; | 2240 | int i; |
2368 | 2241 | ||
2369 | a = 0; | 2242 | a = 0; |
2370 | for (i = 0; i <= MAX_LOG_DEV; i++) | 2243 | for (i = 0; i <= MAX_LOG_DEV; i++) |
2371 | a += IBM_DS(host_index).ldn_read_access[i] + IBM_DS(host_index).ldn_write_access[i]; | 2244 | a += IBM_DS(shpnt).ldn_read_access[i] + IBM_DS(shpnt).ldn_write_access[i]; |
2372 | return (a); | 2245 | return (a); |
2373 | } | 2246 | } |
2374 | 2247 | ||
2375 | static int ldn_access_total_inquiry(int host_index) | 2248 | static int ldn_access_total_inquiry(struct Scsi_Host *shpnt) |
2376 | { | 2249 | { |
2377 | int a; | 2250 | int a; |
2378 | int i; | 2251 | int i; |
2379 | 2252 | ||
2380 | a = 0; | 2253 | a = 0; |
2381 | for (i = 0; i <= MAX_LOG_DEV; i++) | 2254 | for (i = 0; i <= MAX_LOG_DEV; i++) |
2382 | a += IBM_DS(host_index).ldn_inquiry_access[i]; | 2255 | a += IBM_DS(shpnt).ldn_inquiry_access[i]; |
2383 | return (a); | 2256 | return (a); |
2384 | } | 2257 | } |
2385 | 2258 | ||
2386 | static int ldn_access_total_modeselect(int host_index) | 2259 | static int ldn_access_total_modeselect(struct Scsi_Host *shpnt) |
2387 | { | 2260 | { |
2388 | int a; | 2261 | int a; |
2389 | int i; | 2262 | int i; |
2390 | 2263 | ||
2391 | a = 0; | 2264 | a = 0; |
2392 | for (i = 0; i <= MAX_LOG_DEV; i++) | 2265 | for (i = 0; i <= MAX_LOG_DEV; i++) |
2393 | a += IBM_DS(host_index).ldn_modeselect_access[i]; | 2266 | a += IBM_DS(shpnt).ldn_modeselect_access[i]; |
2394 | return (a); | 2267 | return (a); |
2395 | } | 2268 | } |
2396 | 2269 | ||
@@ -2398,19 +2271,14 @@ static int ldn_access_total_modeselect(int host_index) | |||
2398 | static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout) | 2271 | static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout) |
2399 | { | 2272 | { |
2400 | int len = 0; | 2273 | int len = 0; |
2401 | int i, id, lun, host_index; | 2274 | int i, id, lun; |
2402 | unsigned long flags; | 2275 | unsigned long flags; |
2403 | int max_pun; | 2276 | int max_pun; |
2404 | 2277 | ||
2405 | for (i = 0; hosts[i] && hosts[i] != shpnt; i++); | ||
2406 | 2278 | ||
2407 | spin_lock_irqsave(hosts[i]->host_lock, flags); /* Check it */ | 2279 | spin_lock_irqsave(shpnt->host_lock, flags); /* Check it */ |
2408 | host_index = i; | 2280 | |
2409 | if (!shpnt) { | 2281 | max_pun = subsystem_maxid(shpnt); |
2410 | len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter"); | ||
2411 | return len; | ||
2412 | } | ||
2413 | max_pun = subsystem_maxid(host_index); | ||
2414 | 2282 | ||
2415 | len += sprintf(buffer + len, "\n IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n", IBMMCA_SCSI_DRIVER_VERSION); | 2283 | len += sprintf(buffer + len, "\n IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n", IBMMCA_SCSI_DRIVER_VERSION); |
2416 | len += sprintf(buffer + len, " SCSI Access-Statistics:\n"); | 2284 | len += sprintf(buffer + len, " SCSI Access-Statistics:\n"); |
@@ -2421,40 +2289,40 @@ static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, | |||
2421 | len += sprintf(buffer + len, " Multiple LUN probing.....: No\n"); | 2289 | len += sprintf(buffer + len, " Multiple LUN probing.....: No\n"); |
2422 | #endif | 2290 | #endif |
2423 | len += sprintf(buffer + len, " This Hostnumber..........: %d\n", shpnt->host_no); | 2291 | len += sprintf(buffer + len, " This Hostnumber..........: %d\n", shpnt->host_no); |
2424 | len += sprintf(buffer + len, " Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(host_index))); | 2292 | len += sprintf(buffer + len, " Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(shpnt))); |
2425 | len += sprintf(buffer + len, " (Shared) IRQ.............: %d\n", IM_IRQ); | 2293 | len += sprintf(buffer + len, " (Shared) IRQ.............: %d\n", IM_IRQ); |
2426 | len += sprintf(buffer + len, " Total Interrupts.........: %d\n", IBM_DS(host_index).total_interrupts); | 2294 | len += sprintf(buffer + len, " Total Interrupts.........: %d\n", IBM_DS(shpnt).total_interrupts); |
2427 | len += sprintf(buffer + len, " Total SCSI Accesses......: %d\n", IBM_DS(host_index).total_accesses); | 2295 | len += sprintf(buffer + len, " Total SCSI Accesses......: %d\n", IBM_DS(shpnt).total_accesses); |
2428 | len += sprintf(buffer + len, " Total short SCBs.........: %d\n", IBM_DS(host_index).scbs); | 2296 | len += sprintf(buffer + len, " Total short SCBs.........: %d\n", IBM_DS(shpnt).scbs); |
2429 | len += sprintf(buffer + len, " Total long SCBs..........: %d\n", IBM_DS(host_index).long_scbs); | 2297 | len += sprintf(buffer + len, " Total long SCBs..........: %d\n", IBM_DS(shpnt).long_scbs); |
2430 | len += sprintf(buffer + len, " Total SCSI READ/WRITE..: %d\n", ldn_access_total_read_write(host_index)); | 2298 | len += sprintf(buffer + len, " Total SCSI READ/WRITE..: %d\n", ldn_access_total_read_write(shpnt)); |
2431 | len += sprintf(buffer + len, " Total SCSI Inquiries...: %d\n", ldn_access_total_inquiry(host_index)); | 2299 | len += sprintf(buffer + len, " Total SCSI Inquiries...: %d\n", ldn_access_total_inquiry(shpnt)); |
2432 | len += sprintf(buffer + len, " Total SCSI Modeselects.: %d\n", ldn_access_total_modeselect(host_index)); | 2300 | len += sprintf(buffer + len, " Total SCSI Modeselects.: %d\n", ldn_access_total_modeselect(shpnt)); |
2433 | len += sprintf(buffer + len, " Total SCSI other cmds..: %d\n", IBM_DS(host_index).total_accesses - ldn_access_total_read_write(host_index) | 2301 | len += sprintf(buffer + len, " Total SCSI other cmds..: %d\n", IBM_DS(shpnt).total_accesses - ldn_access_total_read_write(shpnt) |
2434 | - ldn_access_total_modeselect(host_index) | 2302 | - ldn_access_total_modeselect(shpnt) |
2435 | - ldn_access_total_inquiry(host_index)); | 2303 | - ldn_access_total_inquiry(shpnt)); |
2436 | len += sprintf(buffer + len, " Total SCSI command fails.: %d\n\n", IBM_DS(host_index).total_errors); | 2304 | len += sprintf(buffer + len, " Total SCSI command fails.: %d\n\n", IBM_DS(shpnt).total_errors); |
2437 | len += sprintf(buffer + len, " Logical-Device-Number (LDN) Access-Statistics:\n"); | 2305 | len += sprintf(buffer + len, " Logical-Device-Number (LDN) Access-Statistics:\n"); |
2438 | len += sprintf(buffer + len, " LDN | Accesses [%%] | READ | WRITE | ASSIGNMENTS\n"); | 2306 | len += sprintf(buffer + len, " LDN | Accesses [%%] | READ | WRITE | ASSIGNMENTS\n"); |
2439 | len += sprintf(buffer + len, " -----|--------------|-----------|-----------|--------------\n"); | 2307 | len += sprintf(buffer + len, " -----|--------------|-----------|-----------|--------------\n"); |
2440 | for (i = 0; i <= MAX_LOG_DEV; i++) | 2308 | for (i = 0; i <= MAX_LOG_DEV; i++) |
2441 | len += sprintf(buffer + len, " %2X | %3d | %8d | %8d | %8d\n", i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i], IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]); | 2309 | len += sprintf(buffer + len, " %2X | %3d | %8d | %8d | %8d\n", i, ldn_access_load(shpnt, i), IBM_DS(shpnt).ldn_read_access[i], IBM_DS(shpnt).ldn_write_access[i], IBM_DS(shpnt).ldn_assignments[i]); |
2442 | len += sprintf(buffer + len, " -----------------------------------------------------------\n\n"); | 2310 | len += sprintf(buffer + len, " -----------------------------------------------------------\n\n"); |
2443 | len += sprintf(buffer + len, " Dynamical-LDN-Assignment-Statistics:\n"); | 2311 | len += sprintf(buffer + len, " Dynamical-LDN-Assignment-Statistics:\n"); |
2444 | len += sprintf(buffer + len, " Number of physical SCSI-devices..: %d (+ Adapter)\n", IBM_DS(host_index).total_scsi_devices); | 2312 | len += sprintf(buffer + len, " Number of physical SCSI-devices..: %d (+ Adapter)\n", IBM_DS(shpnt).total_scsi_devices); |
2445 | len += sprintf(buffer + len, " Dynamical Assignment necessary...: %s\n", IBM_DS(host_index).dyn_flag ? "Yes" : "No "); | 2313 | len += sprintf(buffer + len, " Dynamical Assignment necessary...: %s\n", IBM_DS(shpnt).dyn_flag ? "Yes" : "No "); |
2446 | len += sprintf(buffer + len, " Next LDN to be assigned..........: 0x%x\n", next_ldn(host_index)); | 2314 | len += sprintf(buffer + len, " Next LDN to be assigned..........: 0x%x\n", next_ldn(shpnt)); |
2447 | len += sprintf(buffer + len, " Dynamical assignments done yet...: %d\n", IBM_DS(host_index).dynamical_assignments); | 2315 | len += sprintf(buffer + len, " Dynamical assignments done yet...: %d\n", IBM_DS(shpnt).dynamical_assignments); |
2448 | len += sprintf(buffer + len, "\n Current SCSI-Device-Mapping:\n"); | 2316 | len += sprintf(buffer + len, "\n Current SCSI-Device-Mapping:\n"); |
2449 | len += sprintf(buffer + len, " Physical SCSI-Device Map Logical SCSI-Device Map\n"); | 2317 | len += sprintf(buffer + len, " Physical SCSI-Device Map Logical SCSI-Device Map\n"); |
2450 | len += sprintf(buffer + len, " ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n"); | 2318 | len += sprintf(buffer + len, " ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n"); |
2451 | for (id = 0; id < max_pun; id++) { | 2319 | for (id = 0; id < max_pun; id++) { |
2452 | len += sprintf(buffer + len, " %2d ", id); | 2320 | len += sprintf(buffer + len, " %2d ", id); |
2453 | for (lun = 0; lun < 8; lun++) | 2321 | for (lun = 0; lun < 8; lun++) |
2454 | len += sprintf(buffer + len, "%2s ", ti_p(get_scsi(host_index)[id][lun])); | 2322 | len += sprintf(buffer + len, "%2s ", ti_p(get_scsi(shpnt)[id][lun])); |
2455 | len += sprintf(buffer + len, " %2d ", id); | 2323 | len += sprintf(buffer + len, " %2d ", id); |
2456 | for (lun = 0; lun < 8; lun++) | 2324 | for (lun = 0; lun < 8; lun++) |
2457 | len += sprintf(buffer + len, "%2s ", ti_l(get_ldn(host_index)[id][lun])); | 2325 | len += sprintf(buffer + len, "%2s ", ti_l(get_ldn(shpnt)[id][lun])); |
2458 | len += sprintf(buffer + len, "\n"); | 2326 | len += sprintf(buffer + len, "\n"); |
2459 | } | 2327 | } |
2460 | 2328 | ||
@@ -2488,20 +2356,31 @@ static int option_setup(char *str) | |||
2488 | 2356 | ||
2489 | __setup("ibmmcascsi=", option_setup); | 2357 | __setup("ibmmcascsi=", option_setup); |
2490 | 2358 | ||
2491 | static struct scsi_host_template driver_template = { | 2359 | static struct mca_driver ibmmca_driver = { |
2492 | .proc_name = "ibmmca", | 2360 | .id_table = ibmmca_id_table, |
2493 | .proc_info = ibmmca_proc_info, | 2361 | .driver = { |
2494 | .name = "IBM SCSI-Subsystem", | 2362 | .name = "ibmmca", |
2495 | .detect = ibmmca_detect, | 2363 | .bus = &mca_bus_type, |
2496 | .release = ibmmca_release, | 2364 | .probe = ibmmca_probe, |
2497 | .queuecommand = ibmmca_queuecommand, | 2365 | .remove = __devexit_p(ibmmca_remove), |
2498 | .eh_abort_handler = ibmmca_abort, | 2366 | }, |
2499 | .eh_host_reset_handler = ibmmca_host_reset, | ||
2500 | .bios_param = ibmmca_biosparam, | ||
2501 | .can_queue = 16, | ||
2502 | .this_id = 7, | ||
2503 | .sg_tablesize = 16, | ||
2504 | .cmd_per_lun = 1, | ||
2505 | .use_clustering = ENABLE_CLUSTERING, | ||
2506 | }; | 2367 | }; |
2507 | #include "scsi_module.c" | 2368 | |
2369 | static int __init ibmmca_init(void) | ||
2370 | { | ||
2371 | #ifdef MODULE | ||
2372 | /* If the driver is run as module, read from conf.modules or cmd-line */ | ||
2373 | if (boot_options) | ||
2374 | option_setup(boot_options); | ||
2375 | #endif | ||
2376 | |||
2377 | return mca_register_driver_integrated(&ibmmca_driver, MCA_INTEGSCSI); | ||
2378 | } | ||
2379 | |||
2380 | static void __exit ibmmca_exit(void) | ||
2381 | { | ||
2382 | mca_unregister_driver(&ibmmca_driver); | ||
2383 | } | ||
2384 | |||
2385 | module_init(ibmmca_init); | ||
2386 | module_exit(ibmmca_exit); | ||