Import 2.3.18pre1
[davej-history.git] / drivers / scsi / ibmmca.c
blobf1b3eadc91b106301a6617e15031561b85a8f74f
1 /*
2 * Low Level Driver for the IBM Microchannel SCSI Subsystem
4 * Copyright (c) 1995 Strom Systems, Inc. under the terms of the GNU
5 * General Public License. Written by Martin Kolinek, December 1995.
6 * Further development by: Chris Beauregard, Klaus Kudielka, Michael Lang
7 * See the file README.ibmmca for a detailed description of this driver,
8 * the commandline arguments and the history of its development.
9 * See the WWW-page: http://www.uni-mainz.de/~langm000/linux.html for latest
10 * updates and info.
13 /******************* HEADER FILE INCLUDES ************************************/
14 #ifndef LINUX_VERSION_CODE
15 #include <linux/version.h>
16 #endif
18 /* choose adaption for Kernellevel */
19 #define local_LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
20 #if LINUX_VERSION_CODE < local_LinuxVersionCode(2,1,0)
21 #define OLDKERN
22 #else
23 #undef OLDKERN
24 #endif
26 #include <linux/module.h>
27 #include <linux/kernel.h>
28 #include <linux/types.h>
29 #include <linux/ctype.h>
30 #include <linux/string.h>
31 #include <linux/ioport.h>
32 #include <linux/delay.h>
33 #include <linux/sched.h>
34 #include <linux/blk.h>
35 #include <linux/proc_fs.h>
36 #include <linux/stat.h>
37 #include <linux/mca.h>
38 #include <asm/system.h>
39 #ifndef OLDKERN
40 #include <linux/spinlock.h>
41 #endif
42 #include <asm/io.h>
43 #include "sd.h"
44 #include "scsi.h"
45 #include "hosts.h"
46 #include "ibmmca.h"
48 #include <linux/config.h> /* for CONFIG_SCSI_IBMMCA etc. */
50 /******************* LOCAL DEFINES *******************************************/
52 #ifndef mdelay
53 #define mdelay(a) udelay((a) * 1000)
54 #endif
56 /*--------------------------------------------------------------------*/
58 /* current version of this driver-source: */
59 #define IBMMCA_SCSI_DRIVER_VERSION "3.1e"
61 /*--------------------------------------------------------------------*/
63 /* driver configuration */
64 #define IM_MAX_HOSTS 8 /* maximum number of host adapters */
65 #define IM_RESET_DELAY 60 /* seconds allowed for a reset */
67 /* driver debugging - #undef all for normal operation */
69 /* if defined: count interrupts and ignore this special one: */
70 #undef IM_DEBUG_TIMEOUT 50
71 #define TIMEOUT_PUN 0
72 #define TIMEOUT_LUN 0
73 /* verbose interrupt: */
74 #undef IM_DEBUG_INT
75 /* verbose queuecommand: */
76 #undef IM_DEBUG_CMD
77 /* verbose queucommand for specific SCSI-device type: */
78 #undef IM_DEBUG_CMD_SPEC_DEV
79 /* verbose device probing */
80 #undef IM_DEBUG_PROBE
82 /* device type that shall be displayed on syslog (only during debugging): */
83 #define IM_DEBUG_CMD_DEVICE TYPE_TAPE
85 /* relative addresses of hardware registers on a subsystem */
86 #define IM_CMD_REG(hi) (hosts[(hi)]->io_port) /*Command Interface, (4 bytes long) */
87 #define IM_ATTN_REG(hi) (hosts[(hi)]->io_port+4) /*Attention (1 byte) */
88 #define IM_CTR_REG(hi) (hosts[(hi)]->io_port+5) /*Basic Control (1 byte) */
89 #define IM_INTR_REG(hi) (hosts[(hi)]->io_port+6) /*Interrupt Status (1 byte, r/o) */
90 #define IM_STAT_REG(hi) (hosts[(hi)]->io_port+7) /*Basic Status (1 byte, read only) */
92 /* basic I/O-port of first adapter */
93 #define IM_IO_PORT 0x3540
94 /* maximum number of hosts that can be found */
95 #define IM_N_IO_PORT 8
97 /*requests going into the upper nibble of the Attention register */
98 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
99 #define IM_IMM_CMD 0x10 /*immediate command */
100 #define IM_SCB 0x30 /*Subsystem Control Block command */
101 #define IM_LONG_SCB 0x40 /*long Subsystem Control Block command */
102 #define IM_EOI 0xe0 /*end-of-interrupt request */
104 /*values for bits 7,1,0 of Basic Control reg. (bits 6-2 reserved) */
105 #define IM_HW_RESET 0x80 /*hardware reset */
106 #define IM_ENABLE_DMA 0x02 /*enable subsystem's busmaster DMA */
107 #define IM_ENABLE_INTR 0x01 /*enable interrupts to the system */
109 /*to interpret the upper nibble of Interrupt Status register */
110 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
111 #define IM_SCB_CMD_COMPLETED 0x10
112 #define IM_SCB_CMD_COMPLETED_WITH_RETRIES 0x50
113 #define IM_ADAPTER_HW_FAILURE 0x70
114 #define IM_IMMEDIATE_CMD_COMPLETED 0xa0
115 #define IM_CMD_COMPLETED_WITH_FAILURE 0xc0
116 #define IM_CMD_ERROR 0xe0
117 #define IM_SOFTWARE_SEQUENCING_ERROR 0xf0
119 /*to interpret bits 3-0 of Basic Status register (bits 7-4 reserved) */
120 #define IM_CMD_REG_FULL 0x08
121 #define IM_CMD_REG_EMPTY 0x04
122 #define IM_INTR_REQUEST 0x02
123 #define IM_BUSY 0x01
125 /*immediate commands (word written into low 2 bytes of command reg) */
126 #define IM_RESET_IMM_CMD 0x0400
127 #define IM_FEATURE_CTR_IMM_CMD 0x040c
128 #define IM_DMA_PACING_IMM_CMD 0x040d
129 #define IM_ASSIGN_IMM_CMD 0x040e
130 #define IM_ABORT_IMM_CMD 0x040f
131 #define IM_FORMAT_PREP_IMM_CMD 0x0417
133 /*SCB (Subsystem Control Block) structure */
134 struct im_scb
136 unsigned short command; /*command word (read, etc.) */
137 unsigned short enable; /*enable word, modifies cmd */
138 union
140 unsigned long log_blk_adr; /*block address on SCSI device */
141 unsigned char scsi_cmd_length; /*6,10,12, for other scsi cmd */
144 unsigned long sys_buf_adr; /*physical system memory adr */
145 unsigned long sys_buf_length; /*size of sys mem buffer */
146 unsigned long tsb_adr; /*Termination Status Block adr */
147 unsigned long scb_chain_adr; /*optional SCB chain address */
148 union
150 struct
152 unsigned short count; /*block count, on SCSI device */
153 unsigned short length; /*block length, on SCSI device */
155 blk;
156 unsigned char scsi_command[12]; /*other scsi command */
161 /*structure scatter-gather element (for list of system memory areas) */
162 struct im_sge
164 void *address;
165 unsigned long byte_length;
168 /*values for SCB command word */
169 #define IM_NO_SYNCHRONOUS 0x0040 /*flag for any command */
170 #define IM_NO_DISCONNECT 0x0080 /*flag for any command */
171 #define IM_READ_DATA_CMD 0x1c01
172 #define IM_WRITE_DATA_CMD 0x1c02
173 #define IM_READ_VERIFY_CMD 0x1c03
174 #define IM_WRITE_VERIFY_CMD 0x1c04
175 #define IM_REQUEST_SENSE_CMD 0x1c08
176 #define IM_READ_CAPACITY_CMD 0x1c09
177 #define IM_DEVICE_INQUIRY_CMD 0x1c0b
178 #define IM_OTHER_SCSI_CMD_CMD 0x241f
180 /* unused, but supported, SCB commands */
181 #define IM_GET_COMMAND_COMPLETE_STATUS_CMD 0x1c07 /* command status */
182 #define IM_GET_POS_INFO_CMD 0x1c0a /* returns neat stuff */
183 #define IM_READ_PREFETCH_CMD 0x1c31 /* caching controller only */
184 #define IM_FOMAT_UNIT_CMD 0x1c16 /* format unit */
185 #define IM_REASSIGN_BLOCK_CMD 0x1c18 /* in case of error */
187 /*values to set bits in the enable word of SCB */
188 #define IM_READ_CONTROL 0x8000
189 #define IM_REPORT_TSB_ONLY_ON_ERROR 0x4000
190 #define IM_RETRY_ENABLE 0x2000
191 #define IM_POINTER_TO_LIST 0x1000
192 #define IM_SUPRESS_EXCEPTION_SHORT 0x0400
193 #define IM_CHAIN_ON_NO_ERROR 0x0001
195 /*TSB (Termination Status Block) structure */
196 struct im_tsb
198 unsigned short end_status;
199 unsigned short reserved1;
200 unsigned long residual_byte_count;
201 unsigned long sg_list_element_adr;
202 unsigned short status_length;
203 unsigned char dev_status;
204 unsigned char cmd_status;
205 unsigned char dev_error;
206 unsigned char cmd_error;
207 unsigned short reserved2;
208 unsigned short reserved3;
209 unsigned short low_of_last_scb_adr;
210 unsigned short high_of_last_scb_adr;
213 /*subsystem uses interrupt request level 14 */
214 #define IM_IRQ 14
216 /*--------------------------------------------------------------------*/
218 The model 95 doesn't have a standard activity light. Instead it
219 has a row of LEDs on the front. We use the last one as the activity
220 indicator if we think we're on a model 95. I suspect the model id
221 check will be either too narrow or too general, and some machines
222 won't have an activity indicator. Oh well...
224 The regular PS/2 disk led is turned on/off by bits 6,7 of system
225 control port.
228 /* LED display-port (actually, last LED on display) */
229 #define MOD95_LED_PORT 0x108
230 /* system-control-register of PS/2s with diskindicator */
231 #define PS2_SYS_CTR 0x92
233 /* The SCSI-ID(!) of the accessed SCSI-device is shown on PS/2-95 machines' LED
234 displays. ldn is no longer displayed here, because the ldn mapping is now
235 done dynamically and the ldn <-> pun,lun maps can be looked-up at boottime
236 or during uptime in /proc/scsi/ibmmca/<host_no> in case of trouble,
237 interest, debugging or just for having fun. The left number gives the
238 host-adapter number and the right shows the accessed SCSI-ID. */
240 /* use_display is set by the ibmmcascsi=display command line arg */
241 static int use_display = 0;
242 /* use_adisplay is set by ibmmcascsi=adisplay, which offers a higher
243 * level of displayed luxus on PS/2 95 (really fancy! :-))) */
244 static int use_adisplay = 0;
246 #define PS2_DISK_LED_ON(ad,id) {\
247 if( use_display ) { outb((char)(id+48), MOD95_LED_PORT ); \
248 outb((char)(ad+48), MOD95_LED_PORT+1); } \
249 else if( use_adisplay ) { if (id<7) outb((char)(id+48), \
250 MOD95_LED_PORT+1+id); outb((char)(ad+48), MOD95_LED_PORT); } \
251 else outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
254 /* bug fixed, Dec 15, 1997, where | was replaced by & here */
255 #define PS2_DISK_LED_OFF() {\
256 if( use_display ) { outb( ' ', MOD95_LED_PORT ); \
257 outb(' ', MOD95_LED_PORT+1); } \
258 if ( use_adisplay ) { outb(' ',MOD95_LED_PORT ); \
259 outb(' ',MOD95_LED_PORT+1); outb(' ',MOD95_LED_PORT+2); \
260 outb(' ',MOD95_LED_PORT+3); outb(' ',MOD95_LED_PORT+4); \
261 outb(' ',MOD95_LED_PORT+5); outb(' ',MOD95_LED_PORT+6); \
262 outb(' ',MOD95_LED_PORT+7); } \
263 else outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
266 /*--------------------------------------------------------------------*/
268 /*list of supported subsystems */
269 struct subsys_list_struct
271 unsigned short mca_id;
272 char *description;
275 /* List of possible IBM-SCSI-adapters */
276 struct subsys_list_struct subsys_list[] =
278 {0x8efc, "IBM Fast SCSI-2 Adapter"}, /* special = 0 */
279 {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/cache"}, /* special = 1 */
280 {0x8ef8, "IBM Expansion Unit SCSI Controller"},/* special = 2 */
281 {0x8eff, "IBM SCSI Adapter w/Cache"}, /* special = 3 */
282 {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */
285 /*for /proc filesystem */
286 struct proc_dir_entry proc_scsi_ibmmca =
288 PROC_SCSI_IBMMCA, 6, "ibmmca",
289 S_IFDIR | S_IRUGO | S_IXUGO, 2,
290 0, 0, 0, NULL, NULL, NULL, NULL,
291 NULL, NULL, NULL
294 /* Max number of logical devices (can be up from 0 to 14). 15 is the address
295 of the adapter itself. */
296 #define MAX_LOG_DEV 15
298 /*local data for a logical device */
299 struct logical_device
301 struct im_scb scb; /* SCSI-subsystem-control-block structure */
302 struct im_tsb tsb; /* SCSI command complete status block structure */
303 struct im_sge sge[16]; /* scatter gather list structure */
304 unsigned char buf[256]; /* SCSI command return data buffer */
305 Scsi_Cmnd *cmd; /* SCSI-command that is currently in progress */
307 int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
308 for interpretation of the possible values */
309 int block_length;/* blocksize of a particular logical SCSI-device */
312 /* statistics of the driver during operations (for proc_info) */
313 struct Driver_Statistics
315 /* SCSI statistics on the adapter */
316 int ldn_access[MAX_LOG_DEV+1]; /* total accesses on a ldn */
317 int ldn_read_access[MAX_LOG_DEV+1]; /* total read-access on a ldn */
318 int ldn_write_access[MAX_LOG_DEV+1]; /* total write-access on a ldn */
319 int ldn_inquiry_access[MAX_LOG_DEV+1]; /* total inquiries on a ldn */
320 int ldn_modeselect_access[MAX_LOG_DEV+1]; /* total mode selects on ldn */
321 int total_accesses; /* total accesses on all ldns */
322 int total_interrupts; /* total interrupts (should be
323 same as total_accesses) */
324 int total_errors; /* command completed with error */
325 /* dynamical assignment statistics */
326 int total_scsi_devices; /* number of physical pun,lun */
327 int dyn_flag; /* flag showing dynamical mode */
328 int dynamical_assignments; /* number of remappings of ldns */
329 int ldn_assignments[MAX_LOG_DEV+1]; /* number of remappings of each
330 ldn */
333 /* data structure for each host adapter */
334 struct ibmmca_hostdata
336 /* array of logical devices: */
337 struct logical_device _ld[MAX_LOG_DEV+1];
338 /* array to convert (pun, lun) into logical device number: */
339 unsigned char _get_ldn[8][8];
340 /*array that contains the information about the physical SCSI-devices
341 attached to this host adapter: */
342 unsigned char _get_scsi[8][8];
343 /* used only when checking logical devices: */
344 int _local_checking_phase_flag;
345 /* report received interrupt: */
346 int _got_interrupt;
347 /* report termination-status of SCSI-command: */
348 int _stat_result;
349 /* reset status (used only when doing reset): */
350 int _reset_status;
351 /* code of the last SCSI command (needed for panic info): */
352 int _last_scsi_command[MAX_LOG_DEV+1];
353 /* identifier of the last SCSI-command type */
354 int _last_scsi_type[MAX_LOG_DEV+1];
355 /* Counter that points on the next reassignable ldn for dynamical
356 remapping. The default value is 7, that is the first reassignable
357 number in the list at boottime: */
358 int _next_ldn;
359 /* Statistics-structure for this IBM-SCSI-host: */
360 struct Driver_Statistics _IBM_DS;
361 /* This hostadapters pos-registers pos2 and pos3 */
362 unsigned _pos2, _pos3;
363 /* assign a special variable, that contains dedicated info about the
364 adaptertype */
365 int _special;
368 /* macros to access host data structure */
369 #define subsystem_pun(hi) (hosts[(hi)]->this_id)
370 #define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld)
371 #define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn)
372 #define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi)
373 #define local_checking_phase_flag(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_local_checking_phase_flag)
374 #define got_interrupt(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_got_interrupt)
375 #define stat_result(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_stat_result)
376 #define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status)
377 #define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command)
378 #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
379 #define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn)
380 #define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS)
381 #define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special)
382 #define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos2)
383 #define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos3)
385 /* Define a arbitrary number as subsystem-marker-type. This number is, as
386 described in the ANSI-SCSI-standard, not occupied by other device-types. */
387 #define TYPE_IBM_SCSI_ADAPTER 0x2F
389 /* Define 0xFF for no device type, because this type is not defined within
390 the ANSI-SCSI-standard, therefore, it can be used and should not cause any
391 harm. */
392 #define TYPE_NO_DEVICE 0xFF
394 /* define medium-changer. If this is not defined previously, e.g. Linux
395 2.0.x, define this type here. */
396 #ifndef TYPE_MEDIUM_CHANGER
397 #define TYPE_MEDIUM_CHANGER 0x08
398 #endif
400 /* define possible operations for the immediate_assign command */
401 #define SET_LDN 0
402 #define REMOVE_LDN 1
404 /* ldn which is used to probe the SCSI devices */
405 #define PROBE_LDN 0
407 /* reset status flag contents */
408 #define IM_RESET_NOT_IN_PROGRESS 0
409 #define IM_RESET_IN_PROGRESS 1
410 #define IM_RESET_FINISHED_OK 2
411 #define IM_RESET_FINISHED_FAIL 3
412 #define IM_RESET_NOT_IN_PROGRESS_NO_INT 4
413 #define IM_RESET_FINISHED_OK_NO_INT 5
415 /* special flags for hostdata structure */
416 #define FORCED_DETECTION 100
417 #define INTEGRATED_SCSI 101
419 /* define undefined SCSI-command */
420 #define NO_SCSI 0xffff
422 /*-----------------------------------------------------------------------*/
424 /* if this is nonzero, ibmmcascsi option has been passed to the kernel */
425 static int io_port[IM_MAX_HOSTS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
426 static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
428 /* fill module-parameters only, when this define is present.
429 (that is kernel version 2.1.x) */
430 #ifdef MODULE_PARM
431 MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
432 MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
433 MODULE_PARM(display, "1i");
434 MODULE_PARM(adisplay, "1i");
435 MODULE_PARM(bypass, "1i");
436 MODULE_PARM(normal, "1i");
437 MODULE_PARM(ansi, "1i");
438 #endif
440 /*counter of concurrent disk read/writes, to turn on/off disk led */
441 static int disk_rw_in_progress = 0;
443 /* spinlock handling to avoid command clash while in operation */
444 #ifndef OLDKERN
445 spinlock_t info_lock = SPIN_LOCK_UNLOCKED;
446 spinlock_t proc_lock = SPIN_LOCK_UNLOCKED;
447 spinlock_t abort_lock = SPIN_LOCK_UNLOCKED;
448 spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
449 spinlock_t issue_lock = SPIN_LOCK_UNLOCKED;
450 spinlock_t intr_lock = SPIN_LOCK_UNLOCKED;
451 #endif
453 /* host information */
454 static int found = 0;
455 static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL };
456 static unsigned int pos[8]; /* whole pos register-line */
457 /* Taking into account the additions, made by ZP Gu.
458 * This selects now the preset value from the configfile and
459 * offers the 'normal' commandline option to be accepted */
460 #ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
461 static char ibm_ansi_order = 1;
462 #else
463 static char ibm_ansi_order = 0;
464 #endif
466 /*-----------------------------------------------------------------------*/
468 /******************* FUNCTIONS IN FORWARD DECLARATION ************************/
470 static void interrupt_handler (int, void *, struct pt_regs *);
471 #ifndef OLDKERN
472 static void do_interrupt_handler (int, void *, struct pt_regs *);
473 #endif
474 static void issue_cmd (int, unsigned long, unsigned char);
475 static void internal_done (Scsi_Cmnd * cmd);
476 static void check_devices (int);
477 static int immediate_assign(int, unsigned int, unsigned int, unsigned int,
478 unsigned int);
479 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
480 static int immediate_reset(int, unsigned int);
481 #endif
482 static int device_inquiry(int, int);
483 static int read_capacity(int, int);
484 static char *ti_p(int);
485 static char *ti_l(int);
486 static int device_exists (int, int, int *, int *);
487 static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *,
488 int, int, char *);
490 /* local functions needed for proc_info */
491 static int ldn_access_load(int, int);
492 static int ldn_access_total_read_write(int);
494 static int bypass_controller = 0; /* bypass integrated SCSI-cmd set flag */
495 /*--------------------------------------------------------------------*/
497 /******************* LOCAL FUNCTIONS IMPLEMENTATION *************************/
499 #ifndef OLDKERN
500 /* newer Kernels need the spinlock interrupt handler */
501 static void do_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
503 unsigned long flags;
505 spin_lock_irqsave(&io_request_lock, flags);
506 interrupt_handler(irq, dev_id, regs);
507 spin_unlock_irqrestore(&io_request_lock, flags);
508 return;
510 #endif
512 static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
514 int host_index;
515 unsigned int intr_reg;
516 unsigned int cmd_result;
517 unsigned int ldn;
518 static unsigned long flags;
519 Scsi_Cmnd *cmd;
520 int errorflag;
521 int interror;
523 host_index=0; /* make sure, host_index is 0, else this won't work and
524 never dare to ask, what happens, if an interrupt-handler
525 does not work :-((( .... */
527 /* search for one adapter-response on shared interrupt */
528 while (hosts[host_index]
529 && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST))
530 host_index++;
532 /* return if some other device on this IRQ caused the interrupt */
533 if (!hosts[host_index]) return;
535 /* the reset-function already did all the job, even ints got
536 renabled on the subsystem, so just return */
537 if ((reset_status(host_index) == IM_RESET_NOT_IN_PROGRESS_NO_INT)||
538 (reset_status(host_index) == IM_RESET_FINISHED_OK_NO_INT))
540 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS;
541 return;
544 /*get command result and logical device */
545 intr_reg = inb (IM_INTR_REG(host_index));
546 cmd_result = intr_reg & 0xf0;
547 ldn = intr_reg & 0x0f;
549 /*must wait for attention reg not busy, then send EOI to subsystem */
550 while (1)
552 #ifdef OLDKERN
553 save_flags(flags);
554 cli();
555 #else
556 spin_lock_irqsave(&intr_lock, flags);
557 #endif
558 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
559 break;
560 #ifdef OLDKERN
561 restore_flags(flags);
562 #else
563 spin_unlock_irqrestore(&intr_lock, flags);
564 #endif
566 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
567 /* get the last_scsi_command here */
568 interror = last_scsi_command(host_index)[ldn];
569 #ifdef OLDKERN
570 restore_flags(flags);
571 #else
572 spin_unlock_irqrestore(&intr_lock, flags);
573 #endif
574 errorflag = 0; /* no errors by default */
575 /*these should never happen (hw fails, or a local programming bug) */
576 if (cmd_result == IM_ADAPTER_HW_FAILURE)
578 printk("\n");
579 printk("IBM MCA SCSI: ERROR - subsystem hardware failure!\n");
580 printk(" Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
581 last_scsi_command(host_index)[ldn],ldn,host_index);
582 errorflag = 1;
584 if (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR)
586 printk("\n");
587 printk("IBM MCA SCSI: ERROR - software sequencing error!\n");
588 printk(" Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
589 last_scsi_command(host_index)[ldn],ldn,host_index);
590 errorflag = 1;
592 if (cmd_result == IM_CMD_ERROR)
594 printk("\n");
595 printk("IBM MCA SCSI: ERROR - command error!\n");
596 printk(" Last SCSI-command=0x%X, ldn=%d, host=%d.\n",
597 last_scsi_command(host_index)[ldn],ldn,host_index);
598 errorflag = 1;
600 if (errorflag)
601 { /* if errors appear, enter this section to give detailed info */
602 printk("IBM MCA SCSI: Subsystem Error-Status follows:\n");
603 printk(" Command Type................: %x\n",
604 last_scsi_type(host_index)[ldn]);
605 printk(" Attention Register..........: %x\n",
606 inb (IM_ATTN_REG(host_index)));
607 printk(" Basic Control Register......: %x\n",
608 inb (IM_CTR_REG(host_index)));
609 printk(" Interrupt Status Register...: %x\n",
610 intr_reg);
611 printk(" Basic Status Register.......: %x\n",
612 inb (IM_STAT_REG(host_index)));
613 if ((last_scsi_type(host_index)[ldn]==IM_SCB)||
614 (last_scsi_type(host_index)[ldn]==IM_LONG_SCB))
616 printk(" SCB End Status Word.........: %x\n",
617 ld(host_index)[ldn].tsb.end_status);
618 printk(" Command Status..............: %x\n",
619 ld(host_index)[ldn].tsb.cmd_status);
620 printk(" Device Status...............: %x\n",
621 ld(host_index)[ldn].tsb.dev_status);
622 printk(" Command Error...............: %x\n",
623 ld(host_index)[ldn].tsb.cmd_error);
624 printk(" Device Error................: %x\n",
625 ld(host_index)[ldn].tsb.dev_error);
626 printk(" Last SCB Address (LSW)......: %x\n",
627 ld(host_index)[ldn].tsb.low_of_last_scb_adr);
628 printk(" Last SCB Address (MSW)......: %x\n",
629 ld(host_index)[ldn].tsb.high_of_last_scb_adr);
631 printk(" Send report to the maintainer.\n");
632 panic("IBM MCA SCSI: Fatal errormessage from the subsystem!\n");
635 /* if no panic appeared, increase the interrupt-counter */
636 IBM_DS(host_index).total_interrupts++;
638 /*only for local checking phase */
639 if (local_checking_phase_flag(host_index))
641 stat_result(host_index) = cmd_result;
642 got_interrupt(host_index) = 1;
643 reset_status(host_index) = IM_RESET_FINISHED_OK;
644 last_scsi_command(host_index)[ldn] = NO_SCSI;
645 return;
647 /*handling of commands coming from upper level of scsi driver */
648 else
650 if (last_scsi_type(host_index)[ldn] == IM_IMM_CMD)
652 /*verify ldn, and may handle rare reset immediate command */
653 if ((reset_status(host_index) == IM_RESET_IN_PROGRESS)&&
654 (last_scsi_command(host_index)[ldn] == IM_RESET_IMM_CMD))
656 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
658 disk_rw_in_progress = 0;
659 PS2_DISK_LED_OFF ();
660 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
662 else
664 /*reset disk led counter, turn off disk led */
665 disk_rw_in_progress = 0;
666 PS2_DISK_LED_OFF ();
667 reset_status(host_index) = IM_RESET_FINISHED_OK;
669 stat_result(host_index) = cmd_result;
670 last_scsi_command(host_index)[ldn] = NO_SCSI;
671 return;
673 else if (last_scsi_command(host_index)[ldn] == IM_ABORT_IMM_CMD)
674 { /* react on SCSI abort command */
675 #ifdef IM_DEBUG_PROBE
676 printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n");
677 #endif
678 disk_rw_in_progress = 0;
679 PS2_DISK_LED_OFF();
680 cmd = ld(host_index)[ldn].cmd;
681 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
682 cmd->result = DID_NO_CONNECT << 16;
683 else
684 cmd->result = DID_ABORT << 16;
685 stat_result(host_index) = cmd_result;
686 last_scsi_command(host_index)[ldn] = NO_SCSI;
687 if (cmd->scsi_done)
688 (cmd->scsi_done) (cmd); /* should be the internal_done */
689 return;
691 else
693 disk_rw_in_progress = 0;
694 PS2_DISK_LED_OFF ();
695 reset_status(host_index) = IM_RESET_FINISHED_OK;
696 stat_result(host_index) = cmd_result;
697 last_scsi_command(host_index)[ldn] = NO_SCSI;
698 return;
701 last_scsi_command(host_index)[ldn] = NO_SCSI;
702 cmd = ld(host_index)[ldn].cmd;
703 #ifdef IM_DEBUG_TIMEOUT
704 if (cmd)
706 if ((cmd->target == TIMEOUT_PUN)&&(cmd->lun == TIMEOUT_LUN))
708 printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n",
709 cmd->target, cmd->lun);
710 return;
713 #endif
714 /*if no command structure, just return, else clear cmd */
715 if (!cmd)
716 return;
717 ld(host_index)[ldn].cmd = NULL;
719 #ifdef IM_DEBUG_INT
720 printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n",
721 cmd->cmnd[0], intr_reg,
722 ld(host_index)[ldn].tsb.dev_status,
723 ld(host_index)[ldn].tsb.cmd_status,
724 ld(host_index)[ldn].tsb.dev_error,
725 ld(host_index)[ldn].tsb.cmd_error);
726 #endif
728 /*if this is end of media read/write, may turn off PS/2 disk led */
729 if ((ld(host_index)[ldn].device_type!=TYPE_NO_LUN)&&
730 (ld(host_index)[ldn].device_type!=TYPE_NO_DEVICE))
731 { /* only access this, if there was a valid device addressed */
732 switch (cmd->cmnd[0])
734 case READ_6:
735 case WRITE_6:
736 case READ_10:
737 case WRITE_10:
738 case READ_12:
739 case WRITE_12:
740 if (--disk_rw_in_progress == 0)
741 PS2_DISK_LED_OFF ();
745 /* IBM describes the status-mask to be 0x1e, but this is not conform
746 * with SCSI-defintion, I suppose, it is a printing error in the
747 * technical reference and assume as mask 0x3e. (ML) */
748 cmd->result = (ld(host_index)[ldn].tsb.dev_status & 0x3e);
749 /* write device status into cmd->result, and call done function */
750 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
751 IBM_DS(host_index).total_errors++;
752 if (interror == NO_SCSI) /* unexpected interrupt :-( */
753 cmd->result |= DID_BAD_INTR << 16;
754 else
755 cmd->result |= DID_OK << 16;
756 (cmd->scsi_done) (cmd);
758 if (interror == NO_SCSI)
759 printk("IBM MCA SCSI: WARNING - Interrupt from non-pending SCSI-command!\n");
760 return;
763 /*--------------------------------------------------------------------*/
765 static void issue_cmd (int host_index, unsigned long cmd_reg,
766 unsigned char attn_reg)
768 static unsigned long flags;
769 /* must wait for attention reg not busy */
770 while (1)
772 #ifdef OLDKERN
773 save_flags(flags);
774 cli();
775 #else
776 spin_lock_irqsave(&issue_lock, flags);
777 #endif
778 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
779 break;
780 #ifdef OLDKERN
781 restore_flags(flags);
782 #else
783 spin_unlock_irqrestore(&issue_lock, flags);
784 #endif
786 /*write registers and enable system interrupts */
787 outl (cmd_reg, IM_CMD_REG(host_index));
788 outb (attn_reg, IM_ATTN_REG(host_index));
789 #ifdef OLDKERN
790 restore_flags(flags);
791 #else
792 spin_unlock_irqrestore(&issue_lock, flags);
793 #endif
796 /*--------------------------------------------------------------------*/
798 static void internal_done (Scsi_Cmnd * cmd)
800 cmd->SCp.Status++;
803 /*--------------------------------------------------------------------*/
805 /* SCSI-SCB-command for device_inquiry */
806 static int device_inquiry(int host_index, int ldn)
808 int retries;
809 Scsi_Cmnd cmd;
810 struct im_scb *scb;
811 struct im_tsb *tsb;
812 unsigned char *buf;
814 scb = &(ld(host_index)[ldn].scb);
815 tsb = &(ld(host_index)[ldn].tsb);
816 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
817 ld(host_index)[ldn].tsb.dev_status = 0; /* prepare stusblock */
819 if (bypass_controller)
820 { /* fill the commonly known field for device-inquiry SCSI cmnd */
821 cmd.cmd_len = 6;
822 memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
823 cmd.cmnd[0] = INQUIRY; /* device inquiry */
824 cmd.cmnd[4] = 0xff; /* return buffer size = 255 */
826 for (retries = 0; retries < 3; retries++)
828 if (bypass_controller)
829 { /* bypass the hardware integrated command set */
830 scb->command = IM_OTHER_SCSI_CMD_CMD;
831 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
832 scb->u1.scsi_cmd_length = cmd.cmd_len;
833 memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
834 last_scsi_command(host_index)[ldn] = INQUIRY;
835 last_scsi_type(host_index)[ldn] = IM_SCB;
837 else
839 /*fill scb with inquiry command */
840 scb->command = IM_DEVICE_INQUIRY_CMD;
841 scb->enable = IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
842 last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD;
843 last_scsi_type(host_index)[ldn] = IM_SCB;
845 scb->sys_buf_adr = virt_to_bus(buf);
846 scb->sys_buf_length = 0xff; /* maximum bufferlength gives max info */
847 scb->tsb_adr = virt_to_bus(tsb);
849 /*issue scb to passed ldn, and busy wait for interrupt */
850 got_interrupt(host_index) = 0;
851 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
852 while (!got_interrupt(host_index))
853 barrier ();
855 /*if command succesful, break */
856 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
857 (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
859 return 1;
863 /*if all three retries failed, return "no device at this ldn" */
864 if (retries >= 3)
865 return 0;
866 else
867 return 1;
870 static int read_capacity(int host_index, int ldn)
872 int retries;
873 Scsi_Cmnd cmd;
874 struct im_scb *scb;
875 struct im_tsb *tsb;
876 unsigned char *buf;
878 scb = &(ld(host_index)[ldn].scb);
879 tsb = &(ld(host_index)[ldn].tsb);
880 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
881 ld(host_index)[ldn].tsb.dev_status = 0;
883 if (bypass_controller)
884 { /* read capacity in commonly known default SCSI-format */
885 cmd.cmd_len = 10;
886 memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
887 cmd.cmnd[0] = READ_CAPACITY; /* read capacity */
889 for (retries = 0; retries < 3; retries++)
891 /*fill scb with read capacity command */
892 if (bypass_controller)
893 { /* bypass the SCSI-command */
894 scb->command = IM_OTHER_SCSI_CMD_CMD;
895 scb->enable |= IM_READ_CONTROL;
896 scb->u1.scsi_cmd_length = cmd.cmd_len;
897 memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
898 last_scsi_command(host_index)[ldn] = READ_CAPACITY;
899 last_scsi_type(host_index)[ldn] = IM_SCB;
901 else
903 scb->command = IM_READ_CAPACITY_CMD;
904 scb->enable = IM_READ_CONTROL;
905 last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD;
906 last_scsi_type(host_index)[ldn] = IM_SCB;
908 scb->sys_buf_adr = virt_to_bus(buf);
909 scb->sys_buf_length = 8;
910 scb->tsb_adr = virt_to_bus(tsb);
912 /*issue scb to passed ldn, and busy wait for interrupt */
913 got_interrupt(host_index) = 0;
914 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
915 while (!got_interrupt(host_index))
916 barrier ();
918 /*if got capacity, get block length and return one device found */
919 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
920 (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
922 return 1;
925 /*if all three retries failed, return "no device at this ldn" */
926 if (retries >= 3)
927 return 0;
928 else
929 return 1;
932 /* SCSI-immediate-command for assign. This functions maps/unmaps specific
933 ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the
934 subsystem and for dynamical remapping od ldns. */
935 static int immediate_assign(int host_index, unsigned int pun,
936 unsigned int lun, unsigned int ldn,
937 unsigned int operation)
939 int retries;
940 unsigned long imm_command;
942 for (retries=0; retries<3; retries ++)
944 imm_command = inl(IM_CMD_REG(host_index));
945 imm_command &= (unsigned long)(0xF8000000); /* keep reserved bits */
946 imm_command |= (unsigned long)(IM_ASSIGN_IMM_CMD);
947 imm_command |= (unsigned long)((lun & 7) << 24);
948 imm_command |= (unsigned long)((operation & 1) << 23);
949 imm_command |= (unsigned long)((pun & 7) << 20);
950 imm_command |= (unsigned long)((ldn & 15) << 16);
952 last_scsi_command(host_index)[0xf] = IM_ASSIGN_IMM_CMD;
953 last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
954 got_interrupt(host_index) = 0;
955 issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | 0xf);
956 while (!got_interrupt(host_index))
957 barrier ();
959 /*if command succesful, break */
960 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
962 return 1;
966 if (retries >= 3)
967 return 0;
968 else
969 return 1;
972 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
973 static int immediate_reset(int host_index, unsigned int ldn)
975 int retries;
976 int ticks;
977 unsigned long imm_command;
979 for (retries=0; retries<3; retries ++)
981 imm_command = inl(IM_CMD_REG(host_index));
982 imm_command &= (unsigned long)(0xFFFF0000); /* keep reserved bits */
983 imm_command |= (unsigned long)(IM_RESET_IMM_CMD);
984 last_scsi_command(host_index)[ldn] = IM_RESET_IMM_CMD;
985 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
987 got_interrupt(host_index) = 0;
988 reset_status(host_index) = IM_RESET_IN_PROGRESS;
989 issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | ldn);
990 ticks = IM_RESET_DELAY*HZ;
991 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks)
993 mdelay(1+999/HZ);
994 barrier();
996 /* if reset did not complete, just claim */
997 if (!ticks)
999 printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
1000 IM_RESET_DELAY);
1001 reset_status(host_index) = IM_RESET_FINISHED_OK;
1002 /* did not work, finish */
1003 return 1;
1005 /*if command succesful, break */
1006 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
1008 return 1;
1012 if (retries >= 3)
1013 return 0;
1014 else
1015 return 1;
1017 #endif
1019 /* type-interpreter for physical device numbers */
1020 static char *ti_p(int value)
1022 switch (value)
1024 case TYPE_IBM_SCSI_ADAPTER: return("A"); break;
1025 case TYPE_DISK: return("D"); break;
1026 case TYPE_TAPE: return("T"); break;
1027 case TYPE_PROCESSOR: return("P"); break;
1028 case TYPE_WORM: return("W"); break;
1029 case TYPE_ROM: return("R"); break;
1030 case TYPE_SCANNER: return("S"); break;
1031 case TYPE_MOD: return("M"); break;
1032 case TYPE_MEDIUM_CHANGER: return("C"); break;
1033 case TYPE_NO_LUN: return("+"); break; /* show NO_LUN */
1034 case TYPE_NO_DEVICE:
1035 default: return("-"); break;
1037 return("-");
1040 /* interpreter for logical device numbers (ldn) */
1041 static char *ti_l(int value)
1043 const char hex[16] = "0123456789abcdef";
1044 static char answer[2];
1046 answer[1] = (char)(0x0);
1047 if (value<=MAX_LOG_DEV)
1048 answer[0] = hex[value];
1049 else
1050 answer[0] = '-';
1052 return (char *)&answer;
1056 The following routine probes the SCSI-devices in four steps:
1057 1. The current ldn -> pun,lun mapping is removed on the SCSI-adapter.
1058 2. ldn 0 is used to go through all possible combinations of pun,lun and
1059 a device_inquiry is done to fiddle out whether there is a device
1060 responding or not. This physical map is stored in get_scsi[][].
1061 3. The 15 available ldns (0-14) are mapped to existing pun,lun.
1062 If there are more devices than ldns, it stops at 14 for the boot
1063 time. Dynamical remapping will be done in ibmmca_queuecommand.
1064 4. If there are less than 15 valid pun,lun, the remaining ldns are
1065 mapped to NON-existing pun,lun to satisfy the adapter. Information
1066 about pun,lun -> ldn is stored as before in get_ldn[][].
1067 This method leads to the result, that the SCSI-pun,lun shown to Linux
1068 mid-level- and higher-level-drivers is exactly corresponding to the
1069 physical reality on the SCSI-bus. Therefore, it is possible that users
1070 of older releases of this driver have to rewrite their fstab-file, because
1071 the /dev/sdXXX could have changed due to the right pun,lun report, now.
1072 The assignment of ALL ldns avoids dynamical remapping by the adapter
1073 itself.
1075 static void check_devices (int host_index)
1077 int id, lun, ldn, ticks;
1078 int count_devices; /* local counter for connected device */
1080 /* assign default values to certain variables */
1082 ticks = 0;
1083 count_devices = 0;
1084 IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */
1085 IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */
1086 next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired'*/
1087 for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
1089 last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */
1090 last_scsi_type(host_index)[ldn] = 0;
1093 /* initialize the very important driver-informational arrays/structs */
1094 memset (ld(host_index), 0,
1095 sizeof(ld(host_index)));
1096 memset (get_ldn(host_index), TYPE_NO_DEVICE,
1097 sizeof(get_ldn(host_index))); /* this is essential ! */
1098 memset (get_scsi(host_index), TYPE_NO_DEVICE,
1099 sizeof(get_scsi(host_index))); /* this is essential ! */
1101 for (lun=0; lun<8; lun++) /* mark the adapter at its pun on all luns*/
1103 get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER;
1104 get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV; /* make sure, the subsystem
1105 ldn is active for all
1106 luns. */
1109 /* STEP 1: */
1110 #ifdef IM_DEBUG_PROBE
1111 printk("IBM MCA SCSI: Current SCSI-host index: %d\n",host_index);
1112 #endif
1113 printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");
1114 for (ldn=0; ldn<MAX_LOG_DEV; ldn++)
1116 #ifdef IM_DEBUG_PROBE
1117 printk(".");
1118 #endif
1119 immediate_assign(host_index,0,0,ldn,REMOVE_LDN); /* remove ldn (wherever)*/
1122 lun = 0; /* default lun is 0 */
1124 /* STEP 2: */
1125 printk("\nIBM MCA SCSI: Probing SCSI-devices.");
1126 for (id=0; id<8; id++)
1127 #ifdef CONFIG_SCSI_MULTI_LUN
1128 for (lun=0; lun<8; lun++)
1129 #endif
1131 #ifdef IM_DEBUG_PROBE
1132 printk(".");
1133 #endif
1134 if (id != subsystem_pun(host_index))
1135 { /* if pun is not the adapter: */
1136 /*set ldn=0 to pun,lun*/
1137 immediate_assign(host_index,id,lun,PROBE_LDN,SET_LDN);
1138 if (device_inquiry(host_index, PROBE_LDN)) /* probe device */
1140 get_scsi(host_index)[id][lun]=
1141 (unsigned char)(ld(host_index)[PROBE_LDN].buf[0]);
1142 /* entry, even for NO_LUN */
1143 if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN)
1144 count_devices++; /* a existing device is found */
1146 /* remove ldn */
1147 immediate_assign(host_index,id,lun,PROBE_LDN,REMOVE_LDN);
1151 /* STEP 3: */
1152 printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
1154 ldn = 0;
1155 lun = 0;
1157 #ifdef CONFIG_SCSI_MULTI_LUN
1158 for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)
1159 #endif
1160 for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
1162 #ifdef IM_DEBUG_PROBE
1163 printk(".");
1164 #endif
1165 if (id != subsystem_pun(host_index))
1167 if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN &&
1168 get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE)
1170 /* Only map if accepted type. Always enter for
1171 lun == 0 to get no gaps into ldn-mapping for ldn<7. */
1172 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1173 get_ldn(host_index)[id][lun]=ldn; /* map ldn */
1174 if (device_exists (host_index, ldn,
1175 &ld(host_index)[ldn].block_length,
1176 &ld(host_index)[ldn].device_type))
1178 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
1179 printk("resetting device at ldn=%x ... ",ldn);
1180 immediate_reset(host_index,ldn);
1181 #endif
1182 ldn++;
1184 else
1186 /* device vanished, probably because we don't know how to
1187 * handle it or because it has problems */
1188 if (lun > 0)
1190 /* remove mapping */
1191 get_ldn(host_index)[id][lun]=TYPE_NO_DEVICE;
1192 immediate_assign(host_index,0,0,ldn,REMOVE_LDN);
1194 else ldn++;
1197 else if (lun == 0)
1199 /* map lun == 0, even if no device exists */
1200 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1201 get_ldn(host_index)[id][lun]=ldn; /* map ldn */
1202 ldn++;
1207 /* STEP 4: */
1209 /* map remaining ldns to non-existing devices */
1210 for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++)
1211 for (id=0; id<8 && ldn<MAX_LOG_DEV; id++)
1213 if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN ||
1214 get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE)
1216 /* Map remaining ldns only to NON-existing pun,lun
1217 combinations to make sure an inquiry will fail.
1218 For MULTI_LUN, it is needed to avoid adapter autonome
1219 SCSI-remapping. */
1220 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1221 get_ldn(host_index)[id][lun]=ldn;
1222 ldn++;
1226 printk("\n");
1227 if (ibm_ansi_order)
1228 printk("IBM MCA SCSI: Device order: IBM/ANSI (pun=7 is first).\n");
1229 else
1230 printk("IBM MCA SCSI: Device order: New Industry Standard (pun=0 is first).\n");
1232 #ifdef IM_DEBUG_PROBE
1233 /* Show the physical and logical mapping during boot. */
1234 printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
1235 printk(" Physical SCSI-Device Map Logical SCSI-Device Map\n");
1236 printk("ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n");
1237 for (id=0; id<8; id++)
1239 printk("%2d ",id);
1240 for (lun=0; lun<8; lun++)
1241 printk("%2s ",ti_p(get_scsi(host_index)[id][lun]));
1242 printk(" %2d ",id);
1243 for (lun=0; lun<8; lun++)
1244 printk("%2s ",ti_l(get_ldn(host_index)[id][lun]));
1245 printk("\n");
1247 #endif
1249 /* assign total number of found SCSI-devices to the statistics struct */
1250 IBM_DS(host_index).total_scsi_devices = count_devices;
1252 /* decide for output in /proc-filesystem, if the configuration of
1253 SCSI-devices makes dynamical reassignment of devices necessary */
1254 if (count_devices>=MAX_LOG_DEV)
1255 IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */
1256 else
1257 IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */
1259 /* If no SCSI-devices are assigned, return 1 in order to cause message. */
1260 if (ldn == 0)
1261 printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n");
1263 /* reset the counters for statistics on the current adapter */
1264 IBM_DS(host_index).total_accesses = 0;
1265 IBM_DS(host_index).total_interrupts = 0;
1266 IBM_DS(host_index).dynamical_assignments = 0;
1267 memset (IBM_DS(host_index).ldn_access, 0x0,
1268 sizeof (IBM_DS(host_index).ldn_access));
1269 memset (IBM_DS(host_index).ldn_read_access, 0x0,
1270 sizeof (IBM_DS(host_index).ldn_read_access));
1271 memset (IBM_DS(host_index).ldn_write_access, 0x0,
1272 sizeof (IBM_DS(host_index).ldn_write_access));
1273 memset (IBM_DS(host_index).ldn_inquiry_access, 0x0,
1274 sizeof (IBM_DS(host_index).ldn_inquiry_access));
1275 memset (IBM_DS(host_index).ldn_modeselect_access, 0x0,
1276 sizeof (IBM_DS(host_index).ldn_modeselect_access));
1277 memset (IBM_DS(host_index).ldn_assignments, 0x0,
1278 sizeof (IBM_DS(host_index).ldn_assignments));
1280 return;
1283 /*--------------------------------------------------------------------*/
1285 static int device_exists (int host_index, int ldn, int *block_length,
1286 int *device_type)
1288 unsigned char *buf;
1290 /* if no valid device found, return immediately with 0 */
1291 if (!(device_inquiry(host_index, ldn)))
1292 return 0;
1294 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
1296 /*if device is CD_ROM, assume block size 2048 and return */
1297 if (*buf == TYPE_ROM)
1299 *device_type = TYPE_ROM;
1300 *block_length = 2048; /* (standard blocksize for yellow-/red-book) */
1301 return 1;
1304 if (*buf == TYPE_WORM) /* CD-burner, WORM, Linux handles this as CD-ROM
1305 therefore, the block_length is also 2048. */
1307 *device_type = TYPE_WORM;
1308 *block_length = 2048;
1309 return 1;
1312 /* if device is disk, use "read capacity" to find its block size */
1313 if (*buf == TYPE_DISK)
1315 *device_type = TYPE_DISK;
1316 if (read_capacity( host_index, ldn))
1318 *block_length = *(buf+7) + (*(buf+6) << 8) +
1319 (*(buf+5) << 16) + (*(buf+4) << 24);
1320 return 1;
1322 else
1323 return 0;
1326 /* if this is a magneto-optical drive, treat it like a harddisk */
1327 if (*buf == TYPE_MOD)
1329 *device_type = TYPE_MOD;
1330 if (read_capacity( host_index, ldn))
1332 *block_length = *(buf+7) + (*(buf+6) << 8) +
1333 (*(buf+5) << 16) + (*(buf+4) << 24);
1334 return 1;
1336 else
1337 return 0;
1340 if (*buf == TYPE_TAPE) /* TAPE-device found */
1342 *device_type = TYPE_TAPE;
1343 *block_length = 0; /* not in use (setting by mt and mtst in op.) */
1344 return 1;
1347 if (*buf == TYPE_PROCESSOR) /* HP-Scanners, diverse SCSI-processing units*/
1349 *device_type = TYPE_PROCESSOR;
1350 *block_length = 0; /* they set their stuff on drivers */
1351 return 1;
1354 if (*buf == TYPE_SCANNER) /* other SCSI-scanners */
1356 *device_type = TYPE_SCANNER;
1357 *block_length = 0; /* they set their stuff on drivers */
1358 return 1;
1361 if (*buf == TYPE_MEDIUM_CHANGER) /* Medium-Changer */
1363 *device_type = TYPE_MEDIUM_CHANGER;
1364 *block_length = 0; /* One never knows, what to expect on a medium
1365 changer device. */
1366 return 1;
1369 /* Up to now, no SCSI-devices that are known up to kernel 2.1.31 are
1370 ignored! MO-drives are now supported and treated as harddisk. */
1371 return 0;
1374 /*--------------------------------------------------------------------*/
1376 #ifdef CONFIG_SCSI_IBMMCA
1378 void ibmmca_scsi_setup (char *str, int *ints)
1380 int i, j, io_base, id_base;
1381 char *token;
1383 io_base = 0;
1384 id_base = 0;
1386 if (str)
1388 token = strtok(str,",");
1389 j = 0;
1390 while (token)
1392 if (!strcmp(token,"display"))
1394 use_display = 1;
1396 if (!strcmp(token,"adisplay"))
1398 use_adisplay = 1;
1400 if (!strcmp(token,"bypass"))
1402 bypass_controller = 1;
1404 if (!strcmp(token,"normal"))
1406 ibm_ansi_order = 0;
1408 if (!strcmp(token,"ansi"))
1410 ibm_ansi_order = 1;
1412 if ( (*token == '-') || (isdigit(*token)) )
1414 if (!(j%2) && (io_base < IM_MAX_HOSTS))
1416 io_port[io_base++] = simple_strtoul(token,NULL,0);
1418 if ((j%2) && (id_base < IM_MAX_HOSTS))
1420 scsi_id[id_base++] = simple_strtoul(token,NULL,0);
1422 j++;
1424 token = strtok(NULL,",");
1427 else if (ints)
1429 for (i = 0; i < IM_MAX_HOSTS && 2*i+2 < ints[0]; i++)
1431 io_port[i] = ints[2*i+2];
1432 scsi_id[i] = ints[2*i+2];
1435 return;
1438 #endif
1440 /*--------------------------------------------------------------------*/
1442 static int ibmmca_getinfo (char *buf, int slot, void *dev)
1444 struct Scsi_Host *shpnt;
1445 int len, special;
1446 unsigned int pos2, pos3;
1447 static unsigned long flags;
1449 #ifdef OLDKERN
1450 save_flags(flags);
1451 cli();
1452 #else
1453 spin_lock_irqsave(&info_lock, flags);
1454 #endif
1456 shpnt = dev; /* assign host-structure to local pointer */
1457 len = 0; /* set filled text-buffer index to 0 */
1458 /* get the _special contents of the hostdata structure */
1459 special = ((struct ibmmca_hostdata *)shpnt->hostdata)->_special;
1460 pos2 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2;
1461 pos3 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3;
1463 if (special == FORCED_DETECTION) /* forced detection */
1465 len += sprintf (buf + len, "Adapter cathegory: forced detected\n");
1466 len += sprintf(buf + len, "***************************************\n");
1467 len += sprintf(buf + len, "*** Forced detected SCSI Adapter ***\n");
1468 len += sprintf(buf + len, "*** No chip-information available ***\n");
1469 len += sprintf(buf + len, "***************************************\n");
1471 else if (special == INTEGRATED_SCSI)
1472 { /* if the integrated subsystem has been found automatically: */
1473 len += sprintf (buf + len, "Adapter cathegory: integrated\n");
1474 len += sprintf (buf + len, "Chip revision level: %d\n",
1475 ((pos2 & 0xf0) >> 4));
1476 len += sprintf (buf + len, "Chip status: %s\n",
1477 (pos2 & 1) ? "enabled" : "disabled");
1478 len += sprintf (buf + len, "8 kByte NVRAM status: %s\n",
1479 (pos2 & 2) ? "locked" : "accessible");
1481 else if ((special>=0)&&
1482 (special<(sizeof(subsys_list)/sizeof(struct subsys_list_struct))))
1483 { /* if the subsystem is a slot adapter */
1484 len += sprintf (buf + len, "Adapter cathegory: slot-card\n");
1485 len += sprintf (buf + len, "Chip revision level: %d\n",
1486 ((pos2 & 0xf0) >> 4));
1487 len += sprintf (buf + len, "Chip status: %s\n",
1488 (pos2 & 1) ? "enabled" : "disabled");
1489 len += sprintf (buf + len, "Port offset: 0x%x\n",
1490 ((pos2 & 0x0e) << 2));
1492 else
1494 len += sprintf (buf + len, "Adapter cathegory: unknown\n");
1496 /* common subsystem information to write to the slotn file */
1497 len += sprintf (buf + len, "Subsystem PUN: %d\n", shpnt->this_id);
1498 len += sprintf (buf + len, "I/O base address range: 0x%x-0x%x",
1499 (unsigned int)(shpnt->io_port),
1500 (unsigned int)(shpnt->io_port+7));
1501 /* Now make sure, the bufferlength is devideable by 4 to avoid
1502 * paging problems of the buffer. */
1503 while ( len % sizeof( int ) != ( sizeof ( int ) - 1 ) )
1505 len += sprintf (buf + len, " ");
1507 len += sprintf (buf + len, "\n");
1509 #ifdef OLDKERN
1510 restore_flags(flags);
1511 #else
1512 spin_unlock_irqrestore(&info_lock, flags);
1513 #endif
1514 return len;
1517 int ibmmca_detect (Scsi_Host_Template * scsi_template)
1519 struct Scsi_Host *shpnt;
1520 int port, id, i, j, list_size, slot;
1522 found = 0; /* make absolutely sure, that found is set to 0 */
1524 /* if this is not MCA machine, return "nothing found" */
1525 if (!MCA_bus)
1527 printk("IBM MCA SCSI: No Microchannel-bus support present -> Aborting.\n");
1528 return 0;
1530 else
1531 printk("IBM MCA SCSI: Version %s\n",IBMMCA_SCSI_DRIVER_VERSION);
1533 /* get interrupt request level */
1534 #ifdef OLDKERN
1535 if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi",
1536 hosts))
1537 #else
1538 if (request_irq (IM_IRQ, do_interrupt_handler, SA_SHIRQ, "ibmmcascsi",
1539 hosts))
1540 #endif
1542 printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
1543 return 0;
1546 /* if ibmmcascsi setup option was passed to kernel, return "found" */
1547 for (i = 0; i < IM_MAX_HOSTS; i++)
1548 if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8)
1550 printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n",
1551 io_port[i], scsi_id[i]);
1552 if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i],
1553 "forced detected SCSI Adapter")))
1555 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = 0;
1556 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = 0;
1557 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
1558 FORCED_DETECTION;
1559 mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");
1560 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
1561 shpnt);
1562 mca_mark_as_used(MCA_INTEGSCSI);
1565 if (found) return found;
1567 /* The POS2-register of all PS/2 model SCSI-subsystems has the following
1568 * interpretation of bits:
1569 * Bit 7 - 4 : Chip Revision ID (Release)
1570 * Bit 3 - 2 : Reserved
1571 * Bit 1 : 8k NVRAM Disabled
1572 * Bit 0 : Chip Enable (EN-Signal)
1573 * The POS3-register is interpreted as follows:
1574 * Bit 7 - 5 : SCSI ID
1575 * Bit 4 : Reserved = 0
1576 * Bit 3 - 0 : Reserved = 0
1577 * (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common
1578 * Interfaces (1991)").
1579 * In short words, this means, that IBM PS/2 machines only support
1580 * 1 single subsystem by default. The slot-adapters must have another
1581 * configuration on pos2. Here, one has to assume the following
1582 * things for POS2-register:
1583 * Bit 7 - 4 : Chip Revision ID (Release)
1584 * Bit 3 - 1 : port offset factor
1585 * Bit 0 : Chip Enable (EN-Signal)
1586 * As I found a patch here, setting the IO-registers to 0x3540 forced,
1587 * as there was a 0x05 in POS2 on a model 56, I assume, that the
1588 * port 0x3540 must be fix for integrated SCSI-controllers.
1589 * Ok, this discovery leads to the following implementation: (M.Lang) */
1591 /* first look for the IBM SCSI integrated subsystem on the motherboard */
1592 for (j=0;j<8;j++) /* read the pos-information */
1593 pos[j] = mca_read_stored_pos(MCA_INTEGSCSI,j);
1594 /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present */
1595 if (( pos[2] != 0xff) || (pos[3] != 0xff ))
1597 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
1599 port = IM_IO_PORT;
1601 else
1602 { /* if disabled, no IRQs will be generated, as the chip won't
1603 * listen to the incomming commands and will do really nothing,
1604 * except for listening to the pos-register settings. If this
1605 * happens, I need to hugely think about it, as one has to
1606 * write something to the MCA-Bus pos register in order to
1607 * enable the chip. Normally, IBM-SCSI won't pass the POST,
1608 * when the chip is disabled (see IBM tech. ref.). */
1609 port = IM_IO_PORT; /* anyway, set the portnumber and warn */
1610 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
1611 printk(" SCSI-operations may not work.\n");
1613 id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */
1615 /* give detailed information on the subsystem. This helps me
1616 * additionally during debugging and analyzing bug-reports. */
1617 printk("IBM MCA SCSI: IBM Integrated SCSI Controller found, io=0x%x, scsi id=%d,\n",
1618 port, id);
1619 printk(" chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n",
1620 ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible",
1621 (pos[2] & 1) ? "enabled." : "disabled.");
1623 /* register the found integrated SCSI-subsystem */
1624 if ((shpnt = ibmmca_register(scsi_template, port, id,
1625 "IBM Integrated SCSI Controller")))
1627 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
1628 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
1629 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
1630 INTEGRATED_SCSI;
1631 mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");
1632 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
1633 shpnt);
1634 mca_mark_as_used(MCA_INTEGSCSI);
1638 /* now look for other adapters in MCA slots, */
1639 /* determine the number of known IBM-SCSI-subsystem types */
1640 /* see the pos[2] dependence to get the adapter port-offset. */
1641 list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
1642 for (i = 0; i < list_size; i++)
1643 { /* scan each slot for a fitting adapter id */
1644 slot = 0; /* start at slot 0 */
1645 while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
1646 != MCA_NOTFOUND)
1647 { /* scan through all slots */
1648 for (j=0;j<8;j++) /* read the pos-information */
1649 pos[j] = mca_read_stored_pos(slot, j);
1650 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
1651 { /* (explanations see above) */
1652 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1654 else
1655 { /* anyway, set the portnumber and warn */
1656 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1657 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
1658 printk(" SCSI-operations may not work.\n");
1660 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
1661 printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",
1662 subsys_list[i].description, slot + 1, port, id);
1663 printk(" chip rev.=%d, port-offset=0x%x, subsystem=%s\n",
1664 ((pos[2] & 0xf0) >> 4),
1665 ((pos[2] & 0x0e) << 2),
1666 (pos[2] & 1) ? "enabled." : "disabled.");
1668 /* register the hostadapter */
1669 if ((shpnt = ibmmca_register(scsi_template, port, id,
1670 subsys_list[i].description)))
1672 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
1673 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
1674 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = i;
1676 mca_set_adapter_name (slot, subsys_list[i].description);
1677 mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
1678 shpnt);
1679 mca_mark_as_used(slot);
1681 slot++; /* advance to next slot */
1682 } /* advance to next adapter id in the list of IBM-SCSI-subsystems*/
1685 if (!found)
1686 { /* maybe ESDI, or other producers' SCSI-hosts */
1687 free_irq (IM_IRQ, hosts);
1688 printk("IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
1690 return found; /* return the number of found SCSI hosts. Should be 1 or 0. */
1693 static struct Scsi_Host *
1694 ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
1695 char *hostname)
1697 struct Scsi_Host *shpnt;
1698 int i, j;
1699 unsigned int ctrl;
1701 /* check I/O region */
1702 if (check_region(port, IM_N_IO_PORT))
1704 printk("IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n",
1705 port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT);
1706 return NULL;
1709 /* register host */
1710 shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata));
1711 if (!shpnt)
1713 printk("IBM MCA SCSI: Unable to register host.\n");
1714 return NULL;
1717 /* request I/O region */
1718 request_region(port, IM_N_IO_PORT, hostname);
1720 hosts[found] = shpnt; /* add new found hostadapter to the list */
1721 shpnt->irq = IM_IRQ; /* assign necessary stuff for the adapter */
1722 shpnt->io_port = port;
1723 shpnt->n_io_port = IM_N_IO_PORT;
1724 shpnt->this_id = id;
1725 /* now, the SCSI-subsystem is connected to Linux */
1727 ctrl = (unsigned int)(inb(IM_CTR_REG(found))); /* get control-register status */
1728 #ifdef IM_DEBUG_PROBE
1729 printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n",
1730 ctrl,inb(IM_STAT_REG(found)));
1731 printk("IBM MCA SCSI: This adapters' POS-registers: ");
1732 for (i=0;i<8;i++)
1733 printk("%x ",pos[i]);
1734 printk("\n");
1735 if (bypass_controller)
1736 printk("IBM MCA SCSI: Subsystem SCSI-commands get bypassed.\n");
1737 #endif
1739 reset_status(found) = IM_RESET_NOT_IN_PROGRESS;
1741 for (i = 0; i < 8; i++) /* reset the tables */
1742 for (j = 0; j < 8; j++)
1743 get_ldn(found)[i][j] = MAX_LOG_DEV;
1745 /* check which logical devices exist */
1746 local_checking_phase_flag(found) = 1;
1747 check_devices(found); /* call by value, using the global variable hosts*/
1748 local_checking_phase_flag(found) = 0;
1750 found++; /* now increase index to be prepared for next found subsystem */
1751 /* an ibm mca subsystem has been detected */
1752 return shpnt;
1755 /*--------------------------------------------------------------------*/
1757 int ibmmca_command (Scsi_Cmnd * cmd)
1759 ibmmca_queuecommand (cmd, internal_done);
1760 cmd->SCp.Status = 0;
1761 while (!cmd->SCp.Status)
1762 barrier ();
1763 return cmd->result;
1766 /*--------------------------------------------------------------------*/
1768 int ibmmca_release(struct Scsi_Host *shpnt)
1770 release_region(shpnt->io_port, shpnt->n_io_port);
1771 if (!(--found))
1772 free_irq(shpnt->irq, hosts);
1773 return 0;
1776 /*--------------------------------------------------------------------*/
1778 /* The following routine is the SCSI command queue. The old edition is
1779 now improved by dynamical reassignment of ldn numbers that are
1780 currently not assigned. The mechanism works in a way, that first
1781 the physical structure is checked. If at a certain pun,lun a device
1782 should be present, the routine proceeds to the ldn check from
1783 get_ldn. An answer of 0xff would show-up, that the aimed device is
1784 currently not assigned any ldn. At this point, the dynamical
1785 remapping algorithm is called. It works in a way, that it goes in
1786 cyclic order through the ldns from 7 to 14. If a ldn is assigned,
1787 it takes 8 dynamical reassignment calls, until a device looses its
1788 ldn again. With this method it is assured, that while doing
1789 intense I/O between up to eight devices, no dynamical remapping is
1790 done there. ldns 0 through 6(!) are left untouched, which means, that
1791 puns 0 through 7(!) on lun=0 are always accessible without remapping.
1792 These ldns are statically assigned by this driver. The subsystem always
1793 occupies at least one pun, therefore 7 ldns (at lun=0) for other devices
1794 are sufficient. (The adapter uses always ldn=15, at whatever pun it is.) */
1795 int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
1797 unsigned int ldn;
1798 unsigned int scsi_cmd;
1799 struct im_scb *scb;
1800 struct Scsi_Host *shpnt;
1801 int current_ldn;
1802 int id,lun;
1803 int target;
1804 int host_index;
1806 if (ibm_ansi_order)
1807 target = 6 - cmd->target;
1808 else
1809 target = cmd->target;
1811 shpnt = cmd->host;
1813 /* search for the right hostadapter */
1814 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
1816 if (!hosts[host_index])
1817 { /* invalid hostadapter descriptor address */
1818 cmd->result = DID_NO_CONNECT << 16;
1819 done (cmd);
1820 return 0;
1823 /*if (target,lun) is NO LUN or not existing at all, return error */
1824 if ((get_scsi(host_index)[target][cmd->lun] == TYPE_NO_LUN)||
1825 (get_scsi(host_index)[target][cmd->lun] == TYPE_NO_DEVICE))
1827 cmd->result = DID_NO_CONNECT << 16;
1828 done (cmd);
1829 return 0;
1832 /*if (target,lun) unassigned, do further checks... */
1833 ldn = get_ldn(host_index)[target][cmd->lun];
1834 if (ldn >= MAX_LOG_DEV) /* on invalid ldn do special stuff */
1836 if (ldn > MAX_LOG_DEV) /* dynamical remapping if ldn unassigned */
1838 current_ldn = next_ldn(host_index); /* stop-value for one circle */
1839 while (ld(host_index)[next_ldn(host_index)].cmd) /* search for a occupied, but not in */
1840 { /* command-processing ldn. */
1841 next_ldn(host_index)++;
1842 if (next_ldn(host_index)>=MAX_LOG_DEV)
1843 next_ldn(host_index) = 7;
1844 if (current_ldn == next_ldn(host_index)) /* One circle done ? */
1845 { /* no non-processing ldn found */
1846 printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n");
1847 printk(" On ldn 7-14 SCSI-commands everywhere in progress.\n");
1848 printk(" Reporting DID_NO_CONNECT for device (%d,%d).\n",
1849 target, cmd->lun);
1850 cmd->result = DID_NO_CONNECT << 16;/* return no connect*/
1851 done (cmd);
1852 return 0;
1856 /* unmap non-processing ldn */
1857 for (id=0; id<8; id ++)
1858 for (lun=0; lun<8; lun++)
1860 if (get_ldn(host_index)[id][lun] == next_ldn(host_index))
1862 get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
1863 /* unmap entry */
1866 /* set reduced interrupt_handler-mode for checking */
1867 local_checking_phase_flag(host_index) = 1;
1868 /* unassign found ldn (pun,lun does not matter for remove) */
1869 immediate_assign(host_index,0,0,next_ldn(host_index),REMOVE_LDN);
1870 /* assign found ldn to aimed pun,lun */
1871 immediate_assign(host_index,target,cmd->lun,next_ldn(host_index),SET_LDN);
1872 /* map found ldn to pun,lun */
1873 get_ldn(host_index)[target][cmd->lun] = next_ldn(host_index);
1874 /* change ldn to the right value, that is now next_ldn */
1875 ldn = next_ldn(host_index);
1876 /* get device information for ld[ldn] */
1877 if (device_exists (host_index, ldn,
1878 &ld(host_index)[ldn].block_length,
1879 &ld(host_index)[ldn].device_type))
1881 ld(host_index)[ldn].cmd = 0; /* To prevent panic set 0, because
1882 devices that were not assigned,
1883 should have nothing in progress. */
1885 /* increase assignment counters for statistics in /proc */
1886 IBM_DS(host_index).dynamical_assignments++;
1887 IBM_DS(host_index).ldn_assignments[ldn]++;
1889 else
1890 /* panic here, because a device, found at boottime has
1891 vanished */
1892 panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n",
1893 ldn, target, cmd->lun);
1895 /* set back to normal interrupt_handling */
1896 local_checking_phase_flag(host_index) = 0;
1898 /* Information on syslog terminal */
1899 printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n",
1900 ldn, target, cmd->lun);
1902 /* increase next_ldn for next dynamical assignment */
1903 next_ldn(host_index)++;
1904 if (next_ldn(host_index)>=MAX_LOG_DEV)
1905 next_ldn(host_index) = 7;
1907 else
1908 { /* wall against Linux accesses to the subsystem adapter */
1909 cmd->result = DID_BAD_TARGET << 16;
1910 done (cmd);
1911 return 0;
1915 /*verify there is no command already in progress for this log dev */
1916 if (ld(host_index)[ldn].cmd)
1917 panic ("IBM MCA SCSI: cmd already in progress for this ldn.\n");
1919 /*save done in cmd, and save cmd for the interrupt handler */
1920 cmd->scsi_done = done;
1921 ld(host_index)[ldn].cmd = cmd;
1923 /*fill scb information independent of the scsi command */
1924 scb = &(ld(host_index)[ldn].scb);
1925 ld(host_index)[ldn].tsb.dev_status = 0;
1926 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR;
1927 scb->tsb_adr = virt_to_bus(&(ld(host_index)[ldn].tsb));
1928 if (cmd->use_sg)
1930 int i = cmd->use_sg;
1931 struct scatterlist *sl = (struct scatterlist *) cmd->request_buffer;
1932 if (i > 16)
1933 panic ("IBM MCA SCSI: scatter-gather list too long.\n");
1934 while (--i >= 0)
1936 ld(host_index)[ldn].sge[i].address = (void *) virt_to_bus(sl[i].address);
1937 ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
1939 scb->enable |= IM_POINTER_TO_LIST;
1940 scb->sys_buf_adr = virt_to_bus(&(ld(host_index)[ldn].sge[0]));
1941 scb->sys_buf_length = cmd->use_sg * sizeof (struct im_sge);
1943 else
1945 scb->sys_buf_adr = virt_to_bus(cmd->request_buffer);
1946 scb->sys_buf_length = cmd->request_bufflen;
1949 /*fill scb information dependent on scsi command */
1950 scsi_cmd = cmd->cmnd[0];
1952 #ifdef IM_DEBUG_CMD
1953 printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
1954 #endif
1956 /* for specific device-type debugging: */
1957 #ifdef IM_DEBUG_CMD_SPEC_DEV
1958 if (ld(host_index)[ldn].device_type==IM_DEBUG_CMD_DEVICE)
1959 printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n",
1960 ld(host_index)[ldn].device_type, scsi_cmd, ldn);
1961 #endif
1963 /* for possible panics store current command */
1964 last_scsi_command(host_index)[ldn] = scsi_cmd;
1965 last_scsi_type(host_index)[ldn] = IM_SCB;
1967 /* update statistical info */
1968 IBM_DS(host_index).total_accesses++;
1969 IBM_DS(host_index).ldn_access[ldn]++;
1971 switch (scsi_cmd)
1973 case READ_6:
1974 case WRITE_6:
1975 case READ_10:
1976 case WRITE_10:
1977 case READ_12:
1978 case WRITE_12:
1979 /* statistics for proc_info */
1980 if ((scsi_cmd == READ_6)||(scsi_cmd == READ_10)||(scsi_cmd == READ_12))
1981 IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */
1982 else if ((scsi_cmd == WRITE_6)||(scsi_cmd == WRITE_10)||
1983 (scsi_cmd == WRITE_12))
1984 IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat.*/
1986 /* Distinguish between disk and other devices. Only disks (that are the
1987 most frequently accessed devices) should be supported by the
1988 IBM-SCSI-Subsystem commands. */
1989 switch (ld(host_index)[ldn].device_type)
1991 case TYPE_DISK: /* for harddisks enter here ... */
1992 case TYPE_MOD: /* ... try it also for MO-drives (send flames as */
1993 /* you like, if this won't work.) */
1994 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
1995 scsi_cmd == READ_12)
1996 { /* read command preparations */
1997 if (bypass_controller)
1999 scb->command = IM_OTHER_SCSI_CMD_CMD;
2000 scb->enable |= IM_READ_CONTROL;
2001 scb->u1.scsi_cmd_length = cmd->cmd_len;
2002 memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
2004 else
2006 scb->command = IM_READ_DATA_CMD;
2007 scb->enable |= IM_READ_CONTROL;
2010 else
2011 { /* write command preparations */
2012 if (bypass_controller)
2014 scb->command = IM_OTHER_SCSI_CMD_CMD;
2015 scb->u1.scsi_cmd_length = cmd->cmd_len;
2016 memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
2018 else
2020 scb->command = IM_WRITE_DATA_CMD;
2024 if (!bypass_controller)
2026 if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6)
2028 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[3]) << 0) |
2029 (((unsigned) cmd->cmnd[2]) << 8) |
2030 ((((unsigned) cmd->cmnd[1]) & 0x1f) << 16);
2031 scb->u2.blk.count = (unsigned) cmd->cmnd[4];
2033 else
2035 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) |
2036 (((unsigned) cmd->cmnd[4]) << 8) |
2037 (((unsigned) cmd->cmnd[3]) << 16) |
2038 (((unsigned) cmd->cmnd[2]) << 24);
2039 scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) |
2040 (((unsigned) cmd->cmnd[7]) << 8);
2042 scb->u2.blk.length = ld(host_index)[ldn].block_length;
2044 if (++disk_rw_in_progress == 1)
2045 PS2_DISK_LED_ON (shpnt->host_no, target);
2046 break;
2048 /* for other devices, enter here. Other types are not known by
2049 Linux! TYPE_NO_LUN is forbidden as valid device. */
2050 case TYPE_ROM:
2051 case TYPE_TAPE:
2052 case TYPE_PROCESSOR:
2053 case TYPE_WORM:
2054 case TYPE_SCANNER:
2055 case TYPE_MEDIUM_CHANGER:
2057 /* If there is a sequential-device, IBM recommends to use
2058 IM_OTHER_SCSI_CMD_CMD instead of subsystem READ/WRITE.
2059 Good/modern CD-ROM-drives are capable of
2060 reading sequential AND random-access. This leads to the problem,
2061 that random-accesses are covered by the subsystem, but
2062 sequentials are not, as like for tape-drives. Therefore, it is
2063 the easiest way to use IM_OTHER_SCSI_CMD_CMD for all read-ops
2064 on CD-ROM-drives in order not to run into timing problems and
2065 to have a stable state. In addition, data-access on CD-ROMs
2066 works faster like that. Strange, but obvious. */
2068 scb->command = IM_OTHER_SCSI_CMD_CMD;
2069 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
2070 scsi_cmd == READ_12) /* enable READ */
2072 scb->enable |= IM_READ_CONTROL;
2075 scb->u1.scsi_cmd_length = cmd->cmd_len;
2076 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2078 /* Read/write on this non-disk devices is also displayworthy,
2079 so flash-up the LED/display. */
2080 if (++disk_rw_in_progress == 1)
2081 PS2_DISK_LED_ON (shpnt->host_no, target);
2082 break;
2084 break;
2085 case INQUIRY:
2086 IBM_DS(host_index).ldn_inquiry_access[ldn]++;
2087 if (bypass_controller)
2089 scb->command = IM_OTHER_SCSI_CMD_CMD;
2090 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2091 scb->u1.scsi_cmd_length = cmd->cmd_len;
2092 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2094 else
2096 scb->command = IM_DEVICE_INQUIRY_CMD;
2097 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2099 break;
2101 case READ_CAPACITY:
2102 /* the length of system memory buffer must be exactly 8 bytes */
2103 if (scb->sys_buf_length > 8)
2104 scb->sys_buf_length = 8;
2105 if (bypass_controller)
2107 scb->command = IM_OTHER_SCSI_CMD_CMD;
2108 scb->enable |= IM_READ_CONTROL;
2109 scb->u1.scsi_cmd_length = cmd->cmd_len;
2110 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2112 else
2114 scb->command = IM_READ_CAPACITY_CMD;
2115 scb->enable |= IM_READ_CONTROL;
2117 break;
2119 /* Commands that need read-only-mode (system <- device): */
2120 case REQUEST_SENSE:
2121 if (bypass_controller)
2123 scb->command = IM_OTHER_SCSI_CMD_CMD;
2124 scb->enable |= IM_READ_CONTROL;
2125 scb->u1.scsi_cmd_length = cmd->cmd_len;
2126 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2128 else
2130 scb->command = IM_REQUEST_SENSE_CMD;
2131 scb->enable |= IM_READ_CONTROL;
2133 break;
2135 /* Commands that need write-only-mode (system -> device): */
2136 case MODE_SELECT:
2137 case MODE_SELECT_10:
2138 IBM_DS(host_index).ldn_modeselect_access[ldn]++;
2139 scb->command = IM_OTHER_SCSI_CMD_CMD;
2140 scb->enable |= IM_SUPRESS_EXCEPTION_SHORT; /*Select needs WRITE-enabled*/
2141 scb->u1.scsi_cmd_length = cmd->cmd_len;
2142 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2143 break;
2145 /* For other commands, read-only is useful. Most other commands are
2146 running without an input-data-block. */
2147 default:
2148 scb->command = IM_OTHER_SCSI_CMD_CMD;
2149 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2150 scb->u1.scsi_cmd_length = cmd->cmd_len;
2151 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2152 break;
2155 /*issue scb command, and return */
2156 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
2157 return 0;
2160 /*--------------------------------------------------------------------*/
2162 int ibmmca_abort (Scsi_Cmnd * cmd)
2164 /* Abort does not work, as the adapter never generates an interrupt on
2165 * whatever situation is simulated, even when really pending commands
2166 * are running on the adapters' hardware ! */
2168 struct Scsi_Host *shpnt;
2169 unsigned int ldn;
2170 void (*saved_done) (Scsi_Cmnd *);
2171 int target;
2172 int host_index;
2173 static unsigned long flags;
2174 unsigned long imm_command;
2176 /* return SCSI_ABORT_SNOOZE ; */
2178 #ifdef OLDKERN
2179 save_flags(flags);
2180 cli();
2181 #else
2182 spin_lock_irqsave(&abort_lock, flags);
2183 #endif
2184 if (ibm_ansi_order)
2185 target = 6 - cmd->target;
2186 else
2187 target = cmd->target;
2189 shpnt = cmd->host;
2191 /* search for the right hostadapter */
2192 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2194 if (!hosts[host_index])
2195 { /* invalid hostadapter descriptor address */
2196 cmd->result = DID_NO_CONNECT << 16;
2197 if (cmd->scsi_done)
2198 (cmd->done) (cmd);
2199 return SCSI_ABORT_SNOOZE;
2202 /*get logical device number, and disable system interrupts */
2203 printk ("IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n",
2204 target, cmd->lun);
2205 ldn = get_ldn(host_index)[target][cmd->lun];
2207 /*if cmd for this ldn has already finished, no need to abort */
2208 if (!ld(host_index)[ldn].cmd)
2210 #ifdef OLDKERN
2211 restore_flags(flags);
2212 #else
2213 spin_unlock_irqrestore(&abort_lock, flags);
2214 #endif
2215 return SCSI_ABORT_NOT_RUNNING;
2218 /* Clear ld.cmd, save done function, install internal done,
2219 * send abort immediate command (this enables sys. interrupts),
2220 * and wait until the interrupt arrives.
2222 saved_done = cmd->scsi_done;
2223 cmd->scsi_done = internal_done;
2224 cmd->SCp.Status = 0;
2225 last_scsi_command(host_index)[ldn] = IM_ABORT_IMM_CMD;
2226 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
2227 imm_command = inl(IM_CMD_REG(host_index));
2228 imm_command &= (unsigned long)(0xffff0000); /* mask reserved stuff */
2229 imm_command |= (unsigned long)(IM_ABORT_IMM_CMD);
2230 /* must wait for attention reg not busy */
2231 while (1)
2233 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
2234 break;
2235 #ifdef OLDKERN
2236 restore_flags (flags);
2237 #else
2238 spin_unlock_irqrestore(&abort_lock, flags);
2239 #endif
2240 #ifdef OLDKERN
2241 save_flags(flags);
2242 cli();
2243 #else
2244 spin_lock_irqsave(&abort_lock, flags);
2245 #endif
2247 /*write registers and enable system interrupts */
2248 outl (imm_command, IM_CMD_REG(host_index));
2249 outb (IM_IMM_CMD | ldn, IM_ATTN_REG(host_index));
2250 #ifdef OLDKERN
2251 restore_flags (flags);
2252 #else
2253 spin_unlock_irqrestore(&abort_lock, flags);
2254 #endif
2256 #ifdef IM_DEBUG_PROBE
2257 printk("IBM MCA SCSI: Abort submitted, waiting for adapter response...\n");
2258 #endif
2259 while (!cmd->SCp.Status)
2260 barrier ();
2261 cmd->scsi_done = saved_done;
2262 /*if abort went well, call saved done, then return success or error */
2263 if (cmd->result == (DID_ABORT << 16))
2265 cmd->result |= DID_ABORT << 16;
2266 if (cmd->scsi_done)
2267 (cmd->scsi_done) (cmd);
2268 ld(host_index)[ldn].cmd = NULL;
2269 #ifdef IM_DEBUG_PROBE
2270 printk("IBM MCA SCSI: Abort finished with success.\n");
2271 #endif
2272 return SCSI_ABORT_SUCCESS;
2274 else
2276 cmd->result |= DID_NO_CONNECT << 16;
2277 if (cmd->scsi_done)
2278 (cmd->scsi_done) (cmd);
2279 ld(host_index)[ldn].cmd = NULL;
2280 #ifdef IM_DEBUG_PROBE
2281 printk("IBM MCA SCSI: Abort failed.\n");
2282 #endif
2283 return SCSI_ABORT_ERROR;
2287 /*--------------------------------------------------------------------*/
2289 int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
2291 struct Scsi_Host *shpnt;
2292 Scsi_Cmnd *cmd_aid;
2293 int ticks,i;
2294 int host_index;
2295 static unsigned long flags;
2296 unsigned long imm_command;
2298 #ifdef OLDKERN
2299 save_flags(flags);
2300 cli();
2301 #else
2302 spin_lock_irqsave(&reset_lock, flags);
2303 #endif
2304 ticks = IM_RESET_DELAY*HZ;
2305 shpnt = cmd->host;
2306 /* search for the right hostadapter */
2307 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2309 if (!hosts[host_index])
2310 { /* invalid hostadapter descriptor address */
2311 if (!local_checking_phase_flag(host_index))
2313 cmd->result = DID_NO_CONNECT << 16;
2314 if (cmd->scsi_done)
2315 (cmd->done) (cmd);
2317 return SCSI_ABORT_SNOOZE;
2320 if (local_checking_phase_flag(host_index))
2322 printk("IBM MCA SCSI: unable to reset while checking devices.\n");
2323 #ifdef OLDKERN
2324 restore_flags(flags);
2325 #else
2326 spin_unlock_irqrestore(&reset_lock, flags);
2327 #endif
2328 return SCSI_RESET_SNOOZE;
2331 /* issue reset immediate command to subsystem, and wait for interrupt */
2332 printk("IBM MCA SCSI: resetting all devices.\n");
2333 reset_status(host_index) = IM_RESET_IN_PROGRESS;
2334 last_scsi_command(host_index)[0xf] = IM_RESET_IMM_CMD;
2335 last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
2336 imm_command = inl(IM_CMD_REG(host_index));
2337 imm_command &= (unsigned long)(0xffff0000); /* mask reserved stuff */
2338 imm_command |= (unsigned long)(IM_RESET_IMM_CMD);
2339 /* must wait for attention reg not busy */
2340 while (1)
2342 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
2343 break;
2344 #ifdef OLDKERN
2345 restore_flags(flags);
2346 #else
2347 spin_unlock_irqrestore(&reset_lock, flags);
2348 #endif
2349 #ifdef OLDKERN
2350 save_flags(flags);
2351 cli();
2352 #else
2353 spin_lock_irqsave(&reset_lock, flags);
2354 #endif
2356 /*write registers and enable system interrupts */
2357 outl (imm_command, IM_CMD_REG(host_index));
2358 outb (IM_IMM_CMD | 0xf, IM_ATTN_REG(host_index));
2359 /* wait for interrupt finished or intr_stat register to be set, as the
2360 * interrupt will not be executed, while we are in here! */
2361 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks
2362 && ((inb(IM_INTR_REG(host_index)) & 0x8f)!=0x8f)) {
2363 mdelay(1+999/HZ);
2364 barrier();
2366 /* if reset did not complete, just return an error*/
2367 if (!ticks) {
2368 printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
2369 IM_RESET_DELAY);
2370 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
2371 #ifdef OLDKERN
2372 restore_flags(flags);
2373 #else
2374 spin_unlock_irqrestore(&reset_lock, flags);
2375 #endif
2376 return SCSI_RESET_ERROR;
2379 if ((inb(IM_INTR_REG(host_index)) & 0x8f)==0x8f)
2380 { /* analysis done by this routine and not by the intr-routine */
2381 if (inb(IM_INTR_REG(host_index))==0xaf)
2382 reset_status(host_index) = IM_RESET_FINISHED_OK_NO_INT;
2383 else if (inb(IM_INTR_REG(host_index))==0xcf)
2384 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
2385 else /* failed, 4get it */
2386 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
2387 outb (IM_EOI | 0xf, IM_ATTN_REG(host_index));
2390 /* if reset failed, just return an error */
2391 if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) {
2392 printk("IBM MCA SCSI: reset failed.\n");
2393 #ifdef OLDKERN
2394 restore_flags(flags);
2395 #else
2396 spin_unlock_irqrestore(&reset_lock, flags);
2397 #endif
2398 return SCSI_RESET_ERROR;
2401 /* so reset finished ok - call outstanding done's, and return success */
2402 printk ("IBM MCA SCSI: Reset completed without known error.\n");
2403 #ifdef OLDKERN
2404 restore_flags(flags);
2405 #else
2406 spin_unlock_irqrestore(&reset_lock, flags);
2407 #endif
2408 for (i = 0; i < MAX_LOG_DEV; i++)
2410 cmd_aid = ld(host_index)[i].cmd;
2411 if (cmd_aid && cmd_aid->scsi_done)
2413 ld(host_index)[i].cmd = NULL;
2414 cmd_aid->result = DID_RESET << 16;
2415 (cmd_aid->scsi_done) (cmd_aid);
2418 return SCSI_RESET_SUCCESS;
2421 /*--------------------------------------------------------------------*/
2423 int ibmmca_biosparam (Disk * disk, kdev_t dev, int *info)
2425 info[0] = 64;
2426 info[1] = 32;
2427 info[2] = disk->capacity / (info[0] * info[1]);
2428 if (info[2] >= 1024)
2430 info[0] = 128;
2431 info[1] = 63;
2432 info[2] = disk->capacity / (info[0] * info[1]);
2433 if (info[2] >= 1024)
2435 info[0] = 255;
2436 info[1] = 63;
2437 info[2] = disk->capacity / (info[0] * info[1]);
2438 if (info[2] >= 1024)
2439 info[2] = 1023;
2442 return 0;
2445 /* calculate percentage of total accesses on a ldn */
2446 static int ldn_access_load(int host_index, int ldn)
2448 if (IBM_DS(host_index).total_accesses == 0) return (0);
2449 if (IBM_DS(host_index).ldn_access[ldn] == 0) return (0);
2450 return (IBM_DS(host_index).ldn_access[ldn] * 100) / IBM_DS(host_index).total_accesses;
2453 /* calculate total amount of r/w-accesses */
2454 static int ldn_access_total_read_write(int host_index)
2456 int a;
2457 int i;
2459 a = 0;
2460 for (i=0; i<=MAX_LOG_DEV; i++)
2461 a+=IBM_DS(host_index).ldn_read_access[i]+IBM_DS(host_index).ldn_write_access[i];
2462 return(a);
2465 static int ldn_access_total_inquiry(int host_index)
2467 int a;
2468 int i;
2470 a = 0;
2471 for (i=0; i<=MAX_LOG_DEV; i++)
2472 a+=IBM_DS(host_index).ldn_inquiry_access[i];
2473 return(a);
2476 static int ldn_access_total_modeselect(int host_index)
2478 int a;
2479 int i;
2481 a = 0;
2482 for (i=0; i<=MAX_LOG_DEV; i++)
2483 a+=IBM_DS(host_index).ldn_modeselect_access[i];
2484 return(a);
2487 /* routine to display info in the proc-fs-structure (a deluxe feature) */
2488 int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
2489 int hostno, int inout)
2491 int len=0;
2492 int i,id,lun,host_index;
2493 struct Scsi_Host *shpnt;
2494 unsigned long flags;
2496 #ifdef OLDKERN
2497 save_flags(flags);
2498 cli();
2499 #else
2500 spin_lock_irqsave(&proc_lock, flags);
2501 #endif
2503 for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
2504 shpnt = hosts[i];
2505 host_index = i;
2506 if (!shpnt) {
2507 len += sprintf(buffer+len, "\nCan't find adapter for host number %d\n", hostno);
2508 return len;
2511 len += sprintf(buffer+len, "\n IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n",
2512 IBMMCA_SCSI_DRIVER_VERSION);
2513 len += sprintf(buffer+len, " SCSI Access-Statistics:\n");
2514 len += sprintf(buffer+len, " Device Scanning Order....: %s\n",
2515 (ibm_ansi_order) ? "IBM/ANSI" : "New Industry Standard");
2516 #ifdef CONFIG_SCSI_MULTI_LUN
2517 len += sprintf(buffer+len, " Multiple LUN probing.....: Yes\n");
2518 #else
2519 len += sprintf(buffer+len, " Multiple LUN probing.....: No\n");
2520 #endif
2521 len += sprintf(buffer+len, " This Hostnumber..........: %d\n",
2522 hostno);
2523 len += sprintf(buffer+len, " Base I/O-Port............: 0x%x\n",
2524 (unsigned int)(IM_CMD_REG(host_index)));
2525 len += sprintf(buffer+len, " (Shared) IRQ.............: %d\n",
2526 IM_IRQ);
2527 len += sprintf(buffer+len, " SCSI-command set used....: %s\n",
2528 (bypass_controller) ? "software" : "hardware integrated");
2529 len += sprintf(buffer+len, " Total Interrupts.........: %d\n",
2530 IBM_DS(host_index).total_interrupts);
2531 len += sprintf(buffer+len, " Total SCSI Accesses......: %d\n",
2532 IBM_DS(host_index).total_accesses);
2533 len += sprintf(buffer+len, " Total SCSI READ/WRITE..: %d\n",
2534 ldn_access_total_read_write(host_index));
2535 len += sprintf(buffer+len, " Total SCSI Inquiries...: %d\n",
2536 ldn_access_total_inquiry(host_index));
2537 len += sprintf(buffer+len, " Total SCSI Modeselects.: %d\n",
2538 ldn_access_total_modeselect(host_index));
2539 len += sprintf(buffer+len, " Total SCSI other cmds..: %d\n",
2540 IBM_DS(host_index).total_accesses - ldn_access_total_read_write(host_index)
2541 - ldn_access_total_modeselect(host_index)
2542 - ldn_access_total_inquiry(host_index));
2543 len += sprintf(buffer+len, " Total SCSI command fails.: %d\n\n",
2544 IBM_DS(host_index).total_errors);
2545 len += sprintf(buffer+len, " Logical-Device-Number (LDN) Access-Statistics:\n");
2546 len += sprintf(buffer+len, " LDN | Accesses [%%] | READ | WRITE | ASSIGNMENTS\n");
2547 len += sprintf(buffer+len, " -----|--------------|-----------|-----------|--------------\n");
2548 for (i=0; i<=MAX_LOG_DEV; i++)
2549 len += sprintf(buffer+len, " %2X | %3d | %8d | %8d | %8d\n",
2550 i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i],
2551 IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]);
2552 len += sprintf(buffer+len, " -----------------------------------------------------------\n\n");
2554 len += sprintf(buffer+len, " Dynamical-LDN-Assignment-Statistics:\n");
2555 len += sprintf(buffer+len, " Number of physical SCSI-devices..: %d (+ Adapter)\n",
2556 IBM_DS(host_index).total_scsi_devices);
2557 len += sprintf(buffer+len, " Dynamical Assignment necessaray..: %s\n",
2558 IBM_DS(host_index).dyn_flag ? "Yes" : "No ");
2559 len += sprintf(buffer+len, " Next LDN to be assigned..........: 0x%x\n",
2560 next_ldn(host_index));
2561 len += sprintf(buffer+len, " Dynamical assignments done yet...: %d\n",
2562 IBM_DS(host_index).dynamical_assignments);
2564 len += sprintf(buffer+len, "\n Current SCSI-Device-Mapping:\n");
2565 len += sprintf(buffer+len, " Physical SCSI-Device Map Logical SCSI-Device Map\n");
2566 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");
2567 for (id=0; id<=7; id++)
2569 len += sprintf(buffer+len, " %2d ",id);
2570 for (lun=0; lun<8; lun++)
2571 len += sprintf(buffer+len,"%2s ",ti_p(get_scsi(host_index)[id][lun]));
2572 len += sprintf(buffer+len, " %2d ",id);
2573 for (lun=0; lun<8; lun++)
2574 len += sprintf(buffer+len,"%2s ",ti_l(get_ldn(host_index)[id][lun]));
2575 len += sprintf(buffer+len,"\n");
2578 len += sprintf(buffer+len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
2579 len += sprintf(buffer+len, " R = CD-ROM, S = Scanner, M = MO-Drive, C = Medium-Changer, + = unprovided LUN,\n");
2580 len += sprintf(buffer+len, " - = nothing found, nothing assigned or unprobed LUN)\n\n");
2582 *start = buffer + offset;
2583 len -= offset;
2584 if (len > length)
2585 len = length;
2586 #ifdef OLDKERN
2587 restore_flags(flags);
2588 #else
2589 spin_unlock_irqrestore(&proc_lock, flags);
2590 #endif
2591 return len;
2594 #ifdef MODULE
2595 /* Eventually this will go into an include file, but this will be later */
2596 Scsi_Host_Template driver_template = IBMMCA;
2598 #include "scsi_module.c"
2599 #endif
2601 /*--------------------------------------------------------------------*/