- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / scsi / ibmmca.c
blob46591840e9dae117b40b83cbafb8e23912e4af14
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, info and ADF-files for adapters supported by this driver.
13 /******************* HEADER FILE INCLUDES ************************************/
14 #ifndef LINUX_VERSION_CODE
15 #include <linux/version.h>
16 #endif
18 /* choose adaption for Kernellevel */
19 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,65)
20 #define OLDKERN
21 #else
22 #undef OLDKERN
23 #endif
25 #include <linux/kernel.h>
26 #include <linux/types.h>
27 #include <linux/ctype.h>
28 #include <linux/string.h>
29 #include <linux/ioport.h>
30 #include <linux/delay.h>
31 #include <linux/sched.h>
32 #include <linux/blk.h>
33 #include <linux/proc_fs.h>
34 #include <linux/stat.h>
35 #include <linux/mca.h>
36 #include <asm/system.h>
37 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
38 #include <linux/spinlock.h>
39 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
40 #include <asm/spinlock.h>
41 #endif
42 #include <asm/io.h>
43 #include <linux/init.h>
44 #include "sd.h"
45 #include "scsi.h"
46 #include "hosts.h"
47 #include "ibmmca.h"
49 #include <linux/config.h> /* for CONFIG_SCSI_IBMMCA etc. */
51 /******************* LOCAL DEFINES *******************************************/
53 /* milliseconds of delay for timing out reset. */
54 #ifndef mdelay
55 #define mdelay(a) udelay((a) * 1000)
56 #endif
58 /*--------------------------------------------------------------------*/
60 /* current version of this driver-source: */
61 #define IBMMCA_SCSI_DRIVER_VERSION "3.2"
63 /*--------------------------------------------------------------------*/
65 /* driver configuration */
66 #define IM_MAX_HOSTS 8 /* maximum number of host adapters */
67 #define IM_RESET_DELAY 60 /* seconds allowed for a reset */
69 /* driver debugging - #undef all for normal operation */
71 /* if defined: count interrupts and ignore this special one: */
72 #undef IM_DEBUG_TIMEOUT 50
73 #define TIMEOUT_PUN 0
74 #define TIMEOUT_LUN 0
75 /* verbose interrupt: */
76 #undef IM_DEBUG_INT
77 /* verbose queuecommand: */
78 #undef IM_DEBUG_CMD
79 /* verbose queucommand for specific SCSI-device type: */
80 #undef IM_DEBUG_CMD_SPEC_DEV
81 /* verbose device probing */
82 #define IM_DEBUG_PROBE
84 /* device type that shall be displayed on syslog (only during debugging): */
85 #define IM_DEBUG_CMD_DEVICE TYPE_TAPE
87 /* relative addresses of hardware registers on a subsystem */
88 #define IM_CMD_REG(hi) (hosts[(hi)]->io_port) /*Command Interface, (4 bytes long) */
89 #define IM_ATTN_REG(hi) (hosts[(hi)]->io_port+4) /*Attention (1 byte) */
90 #define IM_CTR_REG(hi) (hosts[(hi)]->io_port+5) /*Basic Control (1 byte) */
91 #define IM_INTR_REG(hi) (hosts[(hi)]->io_port+6) /*Interrupt Status (1 byte, r/o) */
92 #define IM_STAT_REG(hi) (hosts[(hi)]->io_port+7) /*Basic Status (1 byte, read only) */
94 /* basic I/O-port of first adapter */
95 #define IM_IO_PORT 0x3540
96 /* maximum number of hosts that can be found */
97 #define IM_N_IO_PORT 8
99 /*requests going into the upper nibble of the Attention register */
100 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
101 #define IM_IMM_CMD 0x10 /*immediate command */
102 #define IM_SCB 0x30 /*Subsystem Control Block command */
103 #define IM_LONG_SCB 0x40 /*long Subsystem Control Block command */
104 #define IM_EOI 0xe0 /*end-of-interrupt request */
106 /*values for bits 7,1,0 of Basic Control reg. (bits 6-2 reserved) */
107 #define IM_HW_RESET 0x80 /*hardware reset */
108 #define IM_ENABLE_DMA 0x02 /*enable subsystem's busmaster DMA */
109 #define IM_ENABLE_INTR 0x01 /*enable interrupts to the system */
111 /*to interpret the upper nibble of Interrupt Status register */
112 /*note: the lower nibble specifies the device(0-14), or subsystem(15) */
113 #define IM_SCB_CMD_COMPLETED 0x10
114 #define IM_SCB_CMD_COMPLETED_WITH_RETRIES 0x50
115 #define IM_LOOP_SCATTER_BUFFER_FULL 0x60
116 #define IM_ADAPTER_HW_FAILURE 0x70
117 #define IM_IMMEDIATE_CMD_COMPLETED 0xa0
118 #define IM_CMD_COMPLETED_WITH_FAILURE 0xc0
119 #define IM_CMD_ERROR 0xe0
120 #define IM_SOFTWARE_SEQUENCING_ERROR 0xf0
122 /*to interpret bits 3-0 of Basic Status register (bits 7-4 reserved) */
123 #define IM_CMD_REG_FULL 0x08
124 #define IM_CMD_REG_EMPTY 0x04
125 #define IM_INTR_REQUEST 0x02
126 #define IM_BUSY 0x01
128 /*immediate commands (word written into low 2 bytes of command reg) */
129 #define IM_RESET_IMM_CMD 0x0400
130 #define IM_FEATURE_CTR_IMM_CMD 0x040c
131 #define IM_DMA_PACING_IMM_CMD 0x040d
132 #define IM_ASSIGN_IMM_CMD 0x040e
133 #define IM_ABORT_IMM_CMD 0x040f
134 #define IM_FORMAT_PREP_IMM_CMD 0x0417
136 /*SCB (Subsystem Control Block) structure */
137 struct im_scb
139 unsigned short command; /*command word (read, etc.) */
140 unsigned short enable; /*enable word, modifies cmd */
141 union
143 unsigned long log_blk_adr; /*block address on SCSI device */
144 unsigned char scsi_cmd_length; /*6,10,12, for other scsi cmd */
147 unsigned long sys_buf_adr; /*physical system memory adr */
148 unsigned long sys_buf_length; /*size of sys mem buffer */
149 unsigned long tsb_adr; /*Termination Status Block adr */
150 unsigned long scb_chain_adr; /*optional SCB chain address */
151 union
153 struct
155 unsigned short count; /*block count, on SCSI device */
156 unsigned short length; /*block length, on SCSI device */
158 blk;
159 unsigned char scsi_command[12]; /*other scsi command */
164 /*structure scatter-gather element (for list of system memory areas) */
165 struct im_sge
167 void *address;
168 unsigned long byte_length;
171 /*structure returned by a get_pos_info command: */
172 struct im_pos_info
174 unsigned short pos_id; /* adapter id */
175 unsigned char pos_3a; /* pos 3 (if pos 6 = 0) */
176 unsigned char pos_2; /* pos 2 */
177 unsigned char int_level; /* interrupt level IRQ 11 or 14 */
178 unsigned char pos_4a; /* pos 4 (if pos 6 = 0) */
179 unsigned short connector_size; /* MCA connector size: 16 or 32 Bit */
180 unsigned char num_luns; /* number of supported luns per device */
181 unsigned char num_puns; /* number of supported puns */
182 unsigned char pacing_factor; /* pacing factor */
183 unsigned char num_ldns; /* number of ldns available */
184 unsigned char eoi_off; /* time EOI and interrupt inactive */
185 unsigned char max_busy; /* time between reset and busy on */
186 unsigned short cache_stat; /* ldn cachestat. Bit=1 = not cached */
187 unsigned short retry_stat; /* retry status of ldns. Bit=1=disabled */
188 unsigned char pos_4b; /* pos 4 (if pos 6 = 1) */
189 unsigned char pos_3b; /* pos 3 (if pos 6 = 1) */
190 unsigned char pos_6; /* pos 6 */
191 unsigned char pos_5; /* pos 5 */
192 unsigned short max_overlap; /* maximum overlapping requests */
193 unsigned short num_bus; /* number of SCSI-busses */
196 /*values for SCB command word */
197 #define IM_NO_SYNCHRONOUS 0x0040 /*flag for any command */
198 #define IM_NO_DISCONNECT 0x0080 /*flag for any command */
199 #define IM_READ_DATA_CMD 0x1c01
200 #define IM_WRITE_DATA_CMD 0x1c02
201 #define IM_READ_VERIFY_CMD 0x1c03
202 #define IM_WRITE_VERIFY_CMD 0x1c04
203 #define IM_REQUEST_SENSE_CMD 0x1c08
204 #define IM_READ_CAPACITY_CMD 0x1c09
205 #define IM_DEVICE_INQUIRY_CMD 0x1c0b
206 #define IM_READ_LOGICAL_CMD 0x1c2a
207 #define IM_OTHER_SCSI_CMD_CMD 0x241f
209 /* unused, but supported, SCB commands */
210 #define IM_GET_COMMAND_COMPLETE_STATUS_CMD 0x1c07 /* command status */
211 #define IM_GET_POS_INFO_CMD 0x1c0a /* returns neat stuff */
212 #define IM_READ_PREFETCH_CMD 0x1c31 /* caching controller only */
213 #define IM_FOMAT_UNIT_CMD 0x1c16 /* format unit */
214 #define IM_REASSIGN_BLOCK_CMD 0x1c18 /* in case of error */
216 /*values to set bits in the enable word of SCB */
217 #define IM_READ_CONTROL 0x8000
218 #define IM_REPORT_TSB_ONLY_ON_ERROR 0x4000
219 #define IM_RETRY_ENABLE 0x2000
220 #define IM_POINTER_TO_LIST 0x1000
221 #define IM_SUPRESS_EXCEPTION_SHORT 0x0400
222 #define IM_BYPASS_BUFFER 0x0200
223 #define IM_CHAIN_ON_NO_ERROR 0x0001
225 /*TSB (Termination Status Block) structure */
226 struct im_tsb
228 unsigned short end_status;
229 unsigned short reserved1;
230 unsigned long residual_byte_count;
231 unsigned long sg_list_element_adr;
232 unsigned short status_length;
233 unsigned char dev_status;
234 unsigned char cmd_status;
235 unsigned char dev_error;
236 unsigned char cmd_error;
237 unsigned short reserved2;
238 unsigned short reserved3;
239 unsigned short low_of_last_scb_adr;
240 unsigned short high_of_last_scb_adr;
243 /*subsystem uses interrupt request level 14 */
244 #define IM_IRQ 14
245 /*SCSI-2 F/W may evade to interrupt 11 */
246 #define IM_IRQ_FW 11
248 /*--------------------------------------------------------------------*/
250 The model 95 doesn't have a standard activity light. Instead it
251 has a row of alphanumerial LEDs on the front. We use the last one
252 as the activity indicator if we think we're on a model 95. I suspect
253 the model id check will be either too narrow or too general, and some
254 machines won't have an activity indicator. Oh well...
256 The regular PS/2 disk led is turned on/off by bits 6,7 of system
257 control port.
260 /* LED display-port (actually, last LED on display) */
261 #define MOD95_LED_PORT 0x108
262 /* system-control-register of PS/2s with diskindicator */
263 #define PS2_SYS_CTR 0x92
264 /* activity displaying methods */
265 #define LED_DISP 1
266 #define LED_ADISP 2
267 #define LED_ACTIVITY 4
269 #define CMD_FAIL 255
271 /* The SCSI-ID(!) of the accessed SCSI-device is shown on PS/2-95 machines' LED
272 displays. ldn is no longer displayed here, because the ldn mapping is now
273 done dynamically and the ldn <-> pun,lun maps can be looked-up at boottime
274 or during uptime in /proc/scsi/ibmmca/<host_no> in case of trouble,
275 interest, debugging or just for having fun. The left number gives the
276 host-adapter number and the right shows the accessed SCSI-ID. */
278 /* display_mode is set by the ibmmcascsi= command line arg */
279 static int display_mode = 0;
280 /* set default adapter timeout */
281 static unsigned int adapter_timeout = 45;
282 /* for probing on feature-command: */
283 static unsigned int global_command_error_excuse = 0;
284 /* global setting by command line for adapter_speed */
285 static int global_adapter_speed = 0; /* full speed by default */
287 /* Panel / LED on, do it right for F/W addressin, too. adisplay will
288 * just ignore ids>7, as the panel has only 7 digits available */
289 #define PS2_DISK_LED_ON(ad,id) {\
290 if (display_mode & LED_DISP) { \
291 if (id>9) \
292 outw((ad+48)|((id+55)<<8), MOD95_LED_PORT ); \
293 else \
294 outw((ad+48)|((id+48)<<8), MOD95_LED_PORT ); } \
295 else if (display_mode & LED_ADISP) { \
296 if (id<7) outb((char)(id+48),MOD95_LED_PORT+1+id); \
297 outb((char)(ad+48), MOD95_LED_PORT); } \
298 if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
299 outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); \
301 /* Panel / LED off */
302 /* bug fixed, Dec 15, 1997, where | was replaced by & here */
303 #define PS2_DISK_LED_OFF() {\
304 if (display_mode & LED_DISP) \
305 outw(0x2020, MOD95_LED_PORT ); \
306 else if (display_mode & LED_ADISP) { \
307 outl(0x20202020,MOD95_LED_PORT); \
308 outl(0x20202020,MOD95_LED_PORT+4); } \
309 if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
310 outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); \
313 /*--------------------------------------------------------------------*/
315 /*list of supported subsystems */
316 struct subsys_list_struct
318 unsigned short mca_id;
319 char *description;
322 /* types of different supported hardware that goes to hostdata special */
323 #define IBM_SCSI2_FW 0
324 #define IBM_7568_WCACHE 1
325 #define IBM_EXP_UNIT 2
326 #define IBM_SCSI_WCACHE 3
327 #define IBM_SCSI 4
329 /* other special flags for hostdata structure */
330 #define FORCED_DETECTION 100
331 #define INTEGRATED_SCSI 101
333 /* List of possible IBM-SCSI-adapters */
334 struct subsys_list_struct subsys_list[] =
336 {0x8efc, "IBM SCSI-2 F/W Adapter"}, /* special = 0 */
337 {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"}, /* special = 1 */
338 {0x8ef8, "IBM Expansion Unit SCSI Controller"},/* special = 2 */
339 {0x8eff, "IBM SCSI Adapter w/Cache"}, /* special = 3 */
340 {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */
343 /*for /proc filesystem, only valid in older kernel releases */
344 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,27)
345 struct proc_dir_entry proc_scsi_ibmmca =
347 PROC_SCSI_IBMMCA, 6, "ibmmca",
348 S_IFDIR | S_IRUGO | S_IXUGO, 2,
349 0, 0, 0, NULL, NULL, NULL, NULL,
350 NULL, NULL, NULL
352 #endif
354 /* Max number of logical devices (can be up from 0 to 14). 15 is the address
355 of the adapter itself. */
356 #define MAX_LOG_DEV 15
358 /*local data for a logical device */
359 struct logical_device
361 struct im_scb scb; /* SCSI-subsystem-control-block structure */
362 struct im_tsb tsb; /* SCSI command complete status block structure */
363 struct im_sge sge[16]; /* scatter gather list structure */
364 unsigned char buf[256]; /* SCSI command return data buffer */
365 Scsi_Cmnd *cmd; /* SCSI-command that is currently in progress */
366 int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
367 for interpretation of the possible values */
368 int block_length;/* blocksize of a particular logical SCSI-device */
369 int cache_flag; /* 1 if this is uncached, 0 if cache is present for ldn */
370 int retry_flag; /* 1 if adapter retry is disabled, 0 if enabled */
373 /* statistics of the driver during operations (for proc_info) */
374 struct Driver_Statistics
376 /* SCSI statistics on the adapter */
377 int ldn_access[MAX_LOG_DEV+1]; /* total accesses on a ldn */
378 int ldn_read_access[MAX_LOG_DEV+1]; /* total read-access on a ldn */
379 int ldn_write_access[MAX_LOG_DEV+1]; /* total write-access on a ldn */
380 int ldn_inquiry_access[MAX_LOG_DEV+1]; /* total inquiries on a ldn */
381 int ldn_modeselect_access[MAX_LOG_DEV+1]; /* total mode selects on ldn */
382 int scbs; /* short SCBs queued */
383 int long_scbs; /* long SCBs queued */
384 int total_accesses; /* total accesses on all ldns */
385 int total_interrupts; /* total interrupts (should be
386 same as total_accesses) */
387 int total_errors; /* command completed with error */
388 /* dynamical assignment statistics */
389 int total_scsi_devices; /* number of physical pun,lun */
390 int dyn_flag; /* flag showing dynamical mode */
391 int dynamical_assignments; /* number of remappings of ldns */
392 int ldn_assignments[MAX_LOG_DEV+1]; /* number of remappings of each
393 ldn */
396 /* data structure for each host adapter */
397 struct ibmmca_hostdata
399 /* array of logical devices: */
400 struct logical_device _ld[MAX_LOG_DEV+1];
401 /* array to convert (pun, lun) into logical device number: */
402 unsigned char _get_ldn[16][8];
403 /*array that contains the information about the physical SCSI-devices
404 attached to this host adapter: */
405 unsigned char _get_scsi[16][8];
406 /* used only when checking logical devices: */
407 int _local_checking_phase_flag;
408 /* report received interrupt: */
409 int _got_interrupt;
410 /* report termination-status of SCSI-command: */
411 int _stat_result;
412 /* reset status (used only when doing reset): */
413 int _reset_status;
414 /* code of the last SCSI command (needed for panic info): */
415 int _last_scsi_command[MAX_LOG_DEV+1];
416 /* identifier of the last SCSI-command type */
417 int _last_scsi_type[MAX_LOG_DEV+1];
418 /* last blockcount */
419 int _last_scsi_blockcount[MAX_LOG_DEV+1];
420 /* last locgical block address */
421 unsigned long _last_scsi_logical_block[MAX_LOG_DEV+1];
422 /* Counter that points on the next reassignable ldn for dynamical
423 remapping. The default value is 7, that is the first reassignable
424 number in the list at boottime: */
425 int _next_ldn;
426 /* Statistics-structure for this IBM-SCSI-host: */
427 struct Driver_Statistics _IBM_DS;
428 /* This hostadapters pos-registers pos2 until pos6 */
429 unsigned _pos2, _pos3, _pos4, _pos5, _pos6;
430 /* assign a special variable, that contains dedicated info about the
431 adaptertype */
432 int _special;
433 /* connector size on the MCA bus */
434 int _connector_size;
435 /* synchronous SCSI transfer rate bitpattern */
436 int _adapter_speed;
439 /* macros to access host data structure */
440 #define subsystem_pun(hi) (hosts[(hi)]->this_id)
441 #define subsystem_maxid(hi) (hosts[(hi)]->max_id)
442 #define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld)
443 #define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn)
444 #define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi)
445 #define local_checking_phase_flag(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_local_checking_phase_flag)
446 #define got_interrupt(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_got_interrupt)
447 #define stat_result(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_stat_result)
448 #define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status)
449 #define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command)
450 #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
451 #define last_scsi_blockcount(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_blockcount)
452 #define last_scsi_logical_block(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_logical_block)
453 #define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
454 #define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn)
455 #define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS)
456 #define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special)
457 #define subsystem_connector_size(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_connector_size)
458 #define adapter_speed(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_adapter_speed)
459 #define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos2)
460 #define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos3)
461 #define pos4(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos4)
462 #define pos5(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos5)
463 #define pos6(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos6)
465 /* Define a arbitrary number as subsystem-marker-type. This number is, as
466 described in the ANSI-SCSI-standard, not occupied by other device-types. */
467 #define TYPE_IBM_SCSI_ADAPTER 0x2F
469 /* Define 0xFF for no device type, because this type is not defined within
470 the ANSI-SCSI-standard, therefore, it can be used and should not cause any
471 harm. */
472 #define TYPE_NO_DEVICE 0xFF
474 /* define medium-changer. If this is not defined previously, e.g. Linux
475 2.0.x, define this type here. */
476 #ifndef TYPE_MEDIUM_CHANGER
477 #define TYPE_MEDIUM_CHANGER 0x08
478 #endif
480 /* define possible operations for the immediate_assign command */
481 #define SET_LDN 0
482 #define REMOVE_LDN 1
484 /* ldn which is used to probe the SCSI devices */
485 #define PROBE_LDN 0
487 /* reset status flag contents */
488 #define IM_RESET_NOT_IN_PROGRESS 0
489 #define IM_RESET_IN_PROGRESS 1
490 #define IM_RESET_FINISHED_OK 2
491 #define IM_RESET_FINISHED_FAIL 3
492 #define IM_RESET_NOT_IN_PROGRESS_NO_INT 4
493 #define IM_RESET_FINISHED_OK_NO_INT 5
495 /* define undefined SCSI-command */
496 #define NO_SCSI 0xffff
498 /*-----------------------------------------------------------------------*/
500 /* if this is nonzero, ibmmcascsi option has been passed to the kernel */
501 static int io_port[IM_MAX_HOSTS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
502 static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
504 /* fill module-parameters only, when this define is present.
505 (that is kernel version 2.1.x) */
506 #if defined(MODULE)
507 static char *boot_options = NULL;
508 #include <linux/module.h>
509 MODULE_PARM(boot_options, "s");
510 MODULE_PARM(io_port, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
511 MODULE_PARM(scsi_id, "1-" __MODULE_STRING(IM_MAX_HOSTS) "i");
512 MODULE_PARM(display, "1i");
513 MODULE_PARM(adisplay, "1i");
514 MODULE_PARM(bypass, "1i");
515 MODULE_PARM(normal, "1i");
516 MODULE_PARM(ansi, "1i");
517 #endif
519 /*counter of concurrent disk read/writes, to turn on/off disk led */
520 static int disk_rw_in_progress = 0;
522 /* spinlock handling to avoid command clash while in operation */
523 #ifndef OLDKERN
524 spinlock_t info_lock = SPIN_LOCK_UNLOCKED;
525 spinlock_t proc_lock = SPIN_LOCK_UNLOCKED;
526 spinlock_t abort_lock = SPIN_LOCK_UNLOCKED;
527 spinlock_t reset_lock = SPIN_LOCK_UNLOCKED;
528 spinlock_t issue_lock = SPIN_LOCK_UNLOCKED;
529 spinlock_t intr_lock = SPIN_LOCK_UNLOCKED;
530 #endif
532 /* host information */
533 static int found = 0;
534 static struct Scsi_Host *hosts[IM_MAX_HOSTS+1] = { NULL, NULL, NULL, NULL,
535 NULL, NULL, NULL, NULL,
536 NULL };
537 static unsigned int pos[8]; /* whole pos register-line for diagnosis */
538 /* Taking into account the additions, made by ZP Gu.
539 * This selects now the preset value from the configfile and
540 * offers the 'normal' commandline option to be accepted */
541 #ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
542 static char ibm_ansi_order = 1;
543 #else
544 static char ibm_ansi_order = 0;
545 #endif
547 /*-----------------------------------------------------------------------*/
549 /******************* FUNCTIONS IN FORWARD DECLARATION ************************/
551 static void interrupt_handler (int, void *, struct pt_regs *);
552 #ifndef OLDKERN
553 static void do_interrupt_handler (int, void *, struct pt_regs *);
554 #endif
555 static void issue_cmd (int, unsigned long, unsigned char);
556 static void internal_done (Scsi_Cmnd * cmd);
557 static void check_devices (int, int);
558 static int immediate_assign(int, unsigned int, unsigned int, unsigned int,
559 unsigned int);
560 static int immediate_feature(int, unsigned int, unsigned int);
561 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
562 static int immediate_reset(int, unsigned int);
563 #endif
564 static int device_inquiry(int, int);
565 static int read_capacity(int, int);
566 static int get_pos_info(int);
567 static char *ti_p(int);
568 static char *ti_l(int);
569 static char *ibmrate(unsigned int, int);
570 static int probe_display(int);
571 static int probe_bus_mode(int);
572 static int device_exists (int, int, int *, int *);
573 static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *,
574 int, int, int, char *);
575 /* local functions needed for proc_info */
576 static int ldn_access_load(int, int);
577 static int ldn_access_total_read_write(int);
579 static int bypass_controller = 0; /* bypass integrated SCSI-cmd set flag */
581 /*--------------------------------------------------------------------*/
583 /******************* LOCAL FUNCTIONS IMPLEMENTATION *************************/
585 #ifndef OLDKERN
586 /* newer Kernels need the spinlock interrupt handler */
587 static void do_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
589 unsigned long flags;
591 spin_lock_irqsave(&io_request_lock, flags);
592 interrupt_handler(irq, dev_id, regs);
593 spin_unlock_irqrestore(&io_request_lock, flags);
594 return;
596 #endif
598 static void interrupt_handler (int irq, void *dev_id, struct pt_regs *regs)
600 int host_index;
601 unsigned int intr_reg;
602 unsigned int cmd_result;
603 unsigned int ldn;
604 unsigned long flags;
605 Scsi_Cmnd *cmd;
606 int lastSCSI;
608 host_index = 0; /* make sure, host_index is 0 */
610 /* search for one adapter-response on shared interrupt */
611 while (hosts[host_index]
612 && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST))
613 host_index++;
615 /* return if some other device on this IRQ caused the interrupt */
616 if (!hosts[host_index]) return;
618 /* the reset-function already did all the job, even ints got
619 renabled on the subsystem, so just return */
620 if ((reset_status(host_index) == IM_RESET_NOT_IN_PROGRESS_NO_INT)||
621 (reset_status(host_index) == IM_RESET_FINISHED_OK_NO_INT))
623 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS;
624 return;
627 /*must wait for attention reg not busy, then send EOI to subsystem */
628 while (1)
630 #ifdef OLDKERN
631 save_flags(flags);
632 cli();
633 #else
634 spin_lock_irqsave(&intr_lock, flags);
635 #endif
636 /* if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY)) */
637 if ((inb(IM_STAT_REG(host_index)) & 0xf) == (IM_CMD_REG_EMPTY | IM_INTR_REQUEST))
638 break;
639 #ifdef OLDKERN
640 restore_flags(flags);
641 #else
642 spin_unlock_irqrestore(&intr_lock, flags);
643 #endif
645 /*get command result and logical device */
646 intr_reg = (unsigned char)(inb (IM_INTR_REG(host_index)));
647 cmd_result = intr_reg & 0xf0;
648 ldn = intr_reg & 0x0f;
650 /* get the last_scsi_command here */
651 lastSCSI = last_scsi_command(host_index)[ldn];
653 /*these should never happen (hw fails, or a local programming bug) */
654 if (!global_command_error_excuse)
656 switch (cmd_result)
657 { /* Prevent from Ooopsing on error to show the real reason */
658 case IM_ADAPTER_HW_FAILURE:
659 case IM_SOFTWARE_SEQUENCING_ERROR:
660 case IM_CMD_ERROR:
661 printk("\nIBM MCA SCSI: Fatal Subsystem ERROR!\n");
662 printk(" Last cmd=0x%x, ena=%x, len=",lastSCSI,
663 ld(host_index)[ldn].scb.enable);
664 if (ld(host_index)[ldn].cmd)
665 printk("%ld/%ld",(long)(ld(host_index)[ldn].cmd->request_bufflen),
666 (long)(ld(host_index)[ldn].scb.sys_buf_length));
667 else
668 printk("none");
669 printk(", ");
670 if (ld(host_index)[ldn].cmd)
671 printk("Blocksize=%d",ld(host_index)[ldn].scb.u2.blk.length);
672 else
673 printk("Blocksize=none");
674 printk(", host=0x%x, ldn=0x%x\n",host_index, ldn);
675 if (ld(host_index)[ldn].cmd)
677 printk("Blockcount=%d/%d\n",last_scsi_blockcount(host_index)[ldn],
678 ld(host_index)[ldn].scb.u2.blk.count);
679 printk("Logical block=%lx/%lx\n",last_scsi_logical_block(host_index)[ldn],
680 ld(host_index)[ldn].scb.u1.log_blk_adr);
682 printk("Reason given: %s\n",
683 (cmd_result==IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" :
684 (cmd_result==IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" :
685 (cmd_result==IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN");
686 /* if errors appear, enter this section to give detailed info */
687 printk("IBM MCA SCSI: Subsystem Error-Status follows:\n");
688 printk(" Command Type................: %x\n",
689 last_scsi_type(host_index)[ldn]);
690 printk(" Attention Register..........: %x\n",
691 inb (IM_ATTN_REG(host_index)));
692 printk(" Basic Control Register......: %x\n",
693 inb (IM_CTR_REG(host_index)));
694 printk(" Interrupt Status Register...: %x\n",
695 intr_reg);
696 printk(" Basic Status Register.......: %x\n",
697 inb (IM_STAT_REG(host_index)));
698 if ((last_scsi_type(host_index)[ldn]==IM_SCB)||
699 (last_scsi_type(host_index)[ldn]==IM_LONG_SCB))
701 printk(" SCB-Command.................: %x\n",
702 ld(host_index)[ldn].scb.command);
703 printk(" SCB-Enable..................: %x\n",
704 ld(host_index)[ldn].scb.enable);
705 printk(" SCB-logical block address...: %lx\n",
706 ld(host_index)[ldn].scb.u1.log_blk_adr);
707 printk(" SCB-system buffer address...: %lx\n",
708 ld(host_index)[ldn].scb.sys_buf_adr);
709 printk(" SCB-system buffer length....: %lx\n",
710 ld(host_index)[ldn].scb.sys_buf_length);
711 printk(" SCB-tsb address.............: %lx\n",
712 ld(host_index)[ldn].scb.tsb_adr);
713 printk(" SCB-Chain address...........: %lx\n",
714 ld(host_index)[ldn].scb.scb_chain_adr);
715 printk(" SCB-block count.............: %x\n",
716 ld(host_index)[ldn].scb.u2.blk.count);
717 printk(" SCB-block length............: %x\n",
718 ld(host_index)[ldn].scb.u2.blk.length);
720 printk(" Send this report to the maintainer.\n");
721 panic("IBM MCA SCSI: Fatal errormessage from the subsystem (0x%X,0x%X)!\n",
722 lastSCSI,cmd_result);
723 break;
726 else
727 { /* The command error handling is made silent, but we tell the
728 * calling function, that there is a reported error from the
729 * adapter. */
730 switch (cmd_result)
732 case IM_ADAPTER_HW_FAILURE:
733 case IM_SOFTWARE_SEQUENCING_ERROR:
734 case IM_CMD_ERROR:
735 global_command_error_excuse = CMD_FAIL;
736 break;
737 default:
738 global_command_error_excuse = 0;
739 break;
743 /* if no panic appeared, increase the interrupt-counter */
744 IBM_DS(host_index).total_interrupts++;
746 /*only for local checking phase */
747 if (local_checking_phase_flag(host_index))
749 stat_result(host_index) = cmd_result;
750 got_interrupt(host_index) = 1;
751 reset_status(host_index) = IM_RESET_FINISHED_OK;
752 last_scsi_command(host_index)[ldn] = NO_SCSI;
754 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
755 #ifdef OLDKERN
756 restore_flags(flags);
757 #else
758 spin_unlock_irqrestore(&intr_lock, flags);
759 #endif
760 return;
762 /*handling of commands coming from upper level of scsi driver */
763 else
765 if (last_scsi_type(host_index)[ldn] == IM_IMM_CMD)
767 /*verify ldn, and may handle rare reset immediate command */
768 if ((reset_status(host_index) == IM_RESET_IN_PROGRESS)&&
769 (last_scsi_command(host_index)[ldn] == IM_RESET_IMM_CMD))
771 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
773 disk_rw_in_progress = 0;
774 PS2_DISK_LED_OFF ();
775 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
777 else
779 /*reset disk led counter, turn off disk led */
780 disk_rw_in_progress = 0;
781 PS2_DISK_LED_OFF ();
782 reset_status(host_index) = IM_RESET_FINISHED_OK;
784 stat_result(host_index) = cmd_result;
785 last_scsi_command(host_index)[ldn] = NO_SCSI;
786 last_scsi_type(host_index)[ldn] = 0;
787 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
788 #ifdef OLDKERN
789 restore_flags(flags);
790 #else
791 spin_unlock_irqrestore(&intr_lock, flags);
792 #endif
793 return;
795 else if (last_scsi_command(host_index)[ldn] == IM_ABORT_IMM_CMD)
796 { /* react on SCSI abort command */
797 #ifdef IM_DEBUG_PROBE
798 printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n");
799 #endif
800 disk_rw_in_progress = 0;
801 PS2_DISK_LED_OFF();
802 cmd = ld(host_index)[ldn].cmd;
803 ld(host_index)[ldn].cmd = NULL;
804 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
805 cmd->result = DID_NO_CONNECT << 16;
806 else
807 cmd->result = DID_ABORT << 16;
808 stat_result(host_index) = cmd_result;
809 last_scsi_command(host_index)[ldn] = NO_SCSI;
810 last_scsi_type(host_index)[ldn] = 0;
811 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
812 #ifdef OLDKERN
813 restore_flags(flags);
814 #else
815 spin_unlock_irqrestore(&intr_lock, flags);
816 #endif
817 if (cmd->scsi_done)
818 (cmd->scsi_done)(cmd); /* should be the internal_done */
819 return;
821 else
823 disk_rw_in_progress = 0;
824 PS2_DISK_LED_OFF ();
825 reset_status(host_index) = IM_RESET_FINISHED_OK;
826 stat_result(host_index) = cmd_result;
827 last_scsi_command(host_index)[ldn] = NO_SCSI;
829 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
830 #ifdef OLDKERN
831 restore_flags(flags);
832 #else
833 spin_unlock_irqrestore(&intr_lock, flags);
834 #endif
835 return;
838 last_scsi_command(host_index)[ldn] = NO_SCSI;
839 last_scsi_type(host_index)[ldn] = 0;
840 cmd = ld(host_index)[ldn].cmd;
841 ld(host_index)[ldn].cmd = NULL;
842 #ifdef IM_DEBUG_TIMEOUT
843 if (cmd)
845 if ((cmd->target == TIMEOUT_PUN)&&
846 (cmd->lun == TIMEOUT_LUN))
848 printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n",
849 cmd->target, cmd->lun);
850 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
851 #ifdef OLDKERN
852 restore_flags(flags);
853 #else
854 spin_unlock_irqrestore(&intr_lock, flags);
855 #endif
856 return;
859 #endif
860 /*if no command structure, just return, else clear cmd */
861 if (!cmd)
863 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
864 #ifdef OLDKERN
865 restore_flags(flags);
866 #else
867 spin_unlock_irqrestore(&intr_lock, flags);
868 #endif
869 return;
872 #ifdef IM_DEBUG_INT
873 printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n",
874 cmd->cmnd[0], intr_reg,
875 ld(host_index)[ldn].tsb.dev_status,
876 ld(host_index)[ldn].tsb.cmd_status,
877 ld(host_index)[ldn].tsb.dev_error,
878 ld(host_index)[ldn].tsb.cmd_error);
879 #endif
881 /*if this is end of media read/write, may turn off PS/2 disk led */
882 if ((ld(host_index)[ldn].device_type!=TYPE_NO_LUN)&&
883 (ld(host_index)[ldn].device_type!=TYPE_NO_DEVICE))
884 { /* only access this, if there was a valid device addressed */
885 switch (cmd->cmnd[0])
887 case READ_6:
888 case WRITE_6:
889 case READ_10:
890 case WRITE_10:
891 case READ_12:
892 case WRITE_12:
893 if (--disk_rw_in_progress == 0)
894 PS2_DISK_LED_OFF ();
898 /* IBM describes the status-mask to be 0x1e, but this is not conform
899 * with SCSI-defintion, I suppose, the reason for it is that IBM
900 * adapters do not support CMD_TERMINATED, TASK_SET_FULL and
901 * ACA_ACTIVE as returning statusbyte information. (ML) */
902 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
904 cmd->result = (unsigned char)(ld(host_index)[ldn].tsb.dev_status & 0x1e);
905 IBM_DS(host_index).total_errors++;
907 else
908 cmd->result = 0;
909 /* write device status into cmd->result, and call done function */
910 if (lastSCSI == NO_SCSI) /* unexpected interrupt :-( */
911 cmd->result |= DID_BAD_INTR << 16;
912 else /* things went right :-) */
913 cmd->result |= DID_OK << 16;
914 outb (IM_EOI | ldn, IM_ATTN_REG(host_index));
915 #ifdef OLDKERN
916 restore_flags(flags);
917 #else
918 spin_unlock_irqrestore(&intr_lock, flags);
919 #endif
920 /* This is for Kernel 2.2.x. Something weired happens here.
921 * Between the command got queued and the interrupt is released,
922 * the flags sometimes contain different values, which must
923 * be a strange thing. E.g. it appears when cold-booting with a
924 * tape drive at id0. */
925 cmd->flags &= 0x3f;
926 if (cmd->scsi_done)
927 (cmd->scsi_done)(cmd);
929 if (lastSCSI == NO_SCSI)
930 printk("IBM MCA SCSI: WARNING - Interrupt from non-pending SCSI-command!\n");
931 return;
934 /*--------------------------------------------------------------------*/
936 static void issue_cmd (int host_index, unsigned long cmd_reg,
937 unsigned char attn_reg)
939 static unsigned long flags;
940 /* must wait for attention reg not busy */
941 while (1)
943 #ifdef OLDKERN
944 save_flags(flags);
945 cli();
946 #else
947 spin_lock_irqsave(&issue_lock, flags);
948 #endif
949 if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
950 break;
951 #ifdef OLDKERN
952 restore_flags(flags);
953 #else
954 spin_unlock_irqrestore(&issue_lock, flags);
955 #endif
957 /*write registers and enable system interrupts */
958 outl (cmd_reg, IM_CMD_REG(host_index));
959 outb (attn_reg, IM_ATTN_REG(host_index));
960 #ifdef OLDKERN
961 restore_flags(flags);
962 #else
963 spin_unlock_irqrestore(&issue_lock, flags);
964 #endif
965 return;
968 /*--------------------------------------------------------------------*/
970 static void internal_done (Scsi_Cmnd * cmd)
972 cmd->SCp.Status++;
973 return;
976 /*--------------------------------------------------------------------*/
978 /* SCSI-SCB-command for device_inquiry */
979 static int device_inquiry(int host_index, int ldn)
981 int retries;
982 Scsi_Cmnd cmd;
983 struct im_scb *scb;
984 struct im_tsb *tsb;
985 unsigned char *buf;
987 scb = &(ld(host_index)[ldn].scb);
988 tsb = &(ld(host_index)[ldn].tsb);
989 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
990 ld(host_index)[ldn].tsb.dev_status = 0; /* prepare stusblock */
992 if (bypass_controller)
993 { /* fill the commonly known field for device-inquiry SCSI cmnd */
994 cmd.cmd_len = 6;
995 memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
996 cmd.cmnd[0] = INQUIRY; /* device inquiry */
997 cmd.cmnd[4] = 0xff; /* return buffer size = 255 */
999 for (retries = 0; retries < 3; retries++)
1001 if (bypass_controller)
1002 { /* bypass the hardware integrated command set */
1003 scb->command = IM_OTHER_SCSI_CMD_CMD | IM_NO_DISCONNECT;
1004 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
1005 scb->u1.scsi_cmd_length = cmd.cmd_len;
1006 memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
1007 last_scsi_command(host_index)[ldn] = INQUIRY;
1008 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
1010 else
1012 /*fill scb with inquiry command */
1013 scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT;
1014 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
1015 last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD;
1016 last_scsi_type(host_index)[ldn] = IM_SCB;
1018 scb->sys_buf_adr = virt_to_bus(buf);
1019 scb->sys_buf_length = 0xff; /* maximum bufferlength gives max info */
1020 scb->tsb_adr = virt_to_bus(tsb);
1022 /*issue scb to passed ldn, and busy wait for interrupt */
1023 got_interrupt(host_index) = 0;
1024 if ((scb->command & IM_OTHER_SCSI_CMD_CMD) == IM_OTHER_SCSI_CMD_CMD)
1025 issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
1026 else
1027 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
1028 while (!got_interrupt(host_index))
1029 barrier ();
1031 /*if command succesful, break */
1032 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
1033 (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
1034 return 1;
1037 /*if all three retries failed, return "no device at this ldn" */
1038 if (retries >= 3)
1039 return 0;
1040 else
1041 return 1;
1044 static int read_capacity(int host_index, int ldn)
1046 int retries;
1047 Scsi_Cmnd cmd;
1048 struct im_scb *scb;
1049 struct im_tsb *tsb;
1050 unsigned char *buf;
1052 scb = &(ld(host_index)[ldn].scb);
1053 tsb = &(ld(host_index)[ldn].tsb);
1054 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
1055 ld(host_index)[ldn].tsb.dev_status = 0;
1057 if (bypass_controller)
1058 { /* read capacity in commonly known default SCSI-format */
1059 cmd.cmd_len = 10;
1060 memset (&(cmd.cmnd), 0x0, sizeof(char) * cmd.cmd_len);
1061 cmd.cmnd[0] = READ_CAPACITY; /* read capacity */
1063 for (retries = 0; retries < 3; retries++)
1065 /*fill scb with read capacity command */
1066 if (bypass_controller)
1067 { /* bypass the SCSI-command */
1068 scb->command = IM_OTHER_SCSI_CMD_CMD;
1069 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
1070 scb->u1.scsi_cmd_length = cmd.cmd_len;
1071 memcpy (scb->u2.scsi_command, &(cmd.cmnd), cmd.cmd_len);
1072 last_scsi_command(host_index)[ldn] = READ_CAPACITY;
1073 last_scsi_type(host_index)[ldn] = IM_SCB;
1075 else
1077 scb->command = IM_READ_CAPACITY_CMD;
1078 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
1079 last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD;
1080 last_scsi_type(host_index)[ldn] = IM_SCB;
1082 scb->sys_buf_adr = virt_to_bus(buf);
1083 scb->sys_buf_length = 8;
1084 scb->tsb_adr = virt_to_bus(tsb);
1086 /*issue scb to passed ldn, and busy wait for interrupt */
1087 got_interrupt(host_index) = 0;
1088 if ((scb->command & IM_OTHER_SCSI_CMD_CMD) == IM_OTHER_SCSI_CMD_CMD)
1089 issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
1090 else
1091 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
1092 while (!got_interrupt(host_index))
1093 barrier ();
1095 /*if got capacity, get block length and return one device found */
1096 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
1097 (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
1098 return 1;
1100 /*if all three retries failed, return "no device at this ldn" */
1101 if (retries >= 3)
1102 return 0;
1103 else
1104 return 1;
1107 static int get_pos_info(int host_index)
1109 int retries;
1110 struct im_scb *scb;
1111 struct im_tsb *tsb;
1112 unsigned char *buf;
1114 scb = &(ld(host_index)[MAX_LOG_DEV].scb);
1115 tsb = &(ld(host_index)[MAX_LOG_DEV].tsb);
1116 buf = (unsigned char *)(&(ld(host_index)[MAX_LOG_DEV].buf));
1117 ld(host_index)[MAX_LOG_DEV].tsb.dev_status = 0;
1119 for (retries = 0; retries < 3; retries++)
1121 /*fill scb with get_pos_info command */
1122 scb->command = IM_GET_POS_INFO_CMD;
1123 scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER | IM_SUPRESS_EXCEPTION_SHORT;
1124 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD;
1125 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_SCB;
1127 scb->sys_buf_adr = virt_to_bus(buf);
1128 if (special(host_index)==IBM_SCSI2_FW)
1129 scb->sys_buf_length = 256; /* get all info from F/W adapter */
1130 else
1131 scb->sys_buf_length = 18; /* get exactly 18 bytes for other SCSI */
1133 scb->tsb_adr = virt_to_bus(tsb);
1135 /*issue scb to ldn=15, and busy wait for interrupt */
1136 got_interrupt(host_index) = 0;
1137 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | MAX_LOG_DEV);
1138 while (!got_interrupt(host_index))
1139 barrier ();
1141 /*if got POS-stuff, get block length and return one device found */
1142 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED)||
1143 (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
1144 return 1;
1146 /* if all three retries failed, return "no device at this ldn" */
1147 if (retries >= 3)
1148 return 0;
1149 else
1150 return 1;
1153 /* SCSI-immediate-command for assign. This functions maps/unmaps specific
1154 ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the
1155 subsystem and for dynamical remapping od ldns. */
1156 static int immediate_assign(int host_index, unsigned int pun,
1157 unsigned int lun, unsigned int ldn,
1158 unsigned int operation)
1160 int retries;
1161 unsigned long imm_command;
1163 for (retries=0; retries<3; retries ++)
1165 /* select mutation level of the SCSI-adapter */
1166 switch (special(host_index))
1168 case IBM_SCSI2_FW:
1169 imm_command = (unsigned long)(IM_ASSIGN_IMM_CMD);
1170 imm_command |= (unsigned long)((lun & 7) << 24);
1171 imm_command |= (unsigned long)((operation & 1) << 23);
1172 imm_command |= (unsigned long)((pun & 7)<< 20)|((pun & 8)<< 24);
1173 imm_command |= (unsigned long)((ldn & 15) << 16);
1174 break;
1175 default:
1176 imm_command = inl(IM_CMD_REG(host_index));
1177 imm_command &= (unsigned long)(0xF8000000); /* keep reserved bits */
1178 imm_command |= (unsigned long)(IM_ASSIGN_IMM_CMD);
1179 imm_command |= (unsigned long)((lun & 7) << 24);
1180 imm_command |= (unsigned long)((operation & 1) << 23);
1181 imm_command |= (unsigned long)((pun & 7) << 20);
1182 imm_command |= (unsigned long)((ldn & 15) << 16);
1183 break;
1185 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD;
1186 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
1187 got_interrupt(host_index) = 0;
1188 issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | MAX_LOG_DEV);
1189 while (!got_interrupt(host_index))
1190 barrier ();
1192 /*if command succesful, break */
1193 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
1194 return 1;
1196 if (retries >= 3)
1197 return 0;
1198 else
1199 return 1;
1202 static int immediate_feature(int host_index, unsigned int speed,
1203 unsigned int timeout)
1205 int retries;
1206 unsigned long imm_command;
1208 for (retries=0; retries<3; retries ++)
1210 /* select mutation level of the SCSI-adapter */
1211 switch (special(host_index))
1213 default:
1214 imm_command = IM_FEATURE_CTR_IMM_CMD;
1215 imm_command |= (unsigned long)((speed & 0x7) << 29);
1216 imm_command |= (unsigned long)((timeout & 0x1fff) << 16);
1217 break;
1219 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD;
1220 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
1221 got_interrupt(host_index) = 0;
1222 /* we need to run into command errors in order to probe for the
1223 * right speed! */
1224 global_command_error_excuse = 1;
1225 issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | MAX_LOG_DEV);
1226 while (!got_interrupt(host_index))
1227 barrier ();
1228 if (global_command_error_excuse == CMD_FAIL)
1230 global_command_error_excuse = 0;
1231 return 2;
1233 else
1234 global_command_error_excuse = 0;
1236 /*if command succesful, break */
1237 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
1238 return 1;
1241 if (retries >= 3)
1242 return 0;
1243 else
1244 return 1;
1247 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
1248 static int immediate_reset(int host_index, unsigned int ldn)
1250 int retries;
1251 int ticks;
1252 unsigned long imm_command;
1254 for (retries=0; retries<3; retries ++)
1256 imm_command = inl(IM_CMD_REG(host_index));
1257 imm_command &= (unsigned long)(0xFFFF0000); /* keep reserved bits */
1258 imm_command |= (unsigned long)(IM_RESET_IMM_CMD);
1259 last_scsi_command(host_index)[ldn] = IM_RESET_IMM_CMD;
1260 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
1262 got_interrupt(host_index) = 0;
1263 reset_status(host_index) = IM_RESET_IN_PROGRESS;
1264 issue_cmd (host_index, (unsigned long)(imm_command), IM_IMM_CMD | ldn);
1265 ticks = IM_RESET_DELAY*HZ;
1266 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks)
1268 mdelay(1+999/HZ);
1269 barrier();
1271 /* if reset did not complete, just claim */
1272 if (!ticks)
1274 printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
1275 IM_RESET_DELAY);
1276 reset_status(host_index) = IM_RESET_FINISHED_OK;
1277 /* did not work, finish */
1278 return 1;
1280 /*if command succesful, break */
1281 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
1282 return 1;
1285 if (retries >= 3)
1286 return 0;
1287 else
1288 return 1;
1290 #endif
1292 /* type-interpreter for physical device numbers */
1293 static char *ti_p(int value)
1295 switch (value)
1297 case TYPE_IBM_SCSI_ADAPTER: return("A"); break;
1298 case TYPE_DISK: return("D"); break;
1299 case TYPE_TAPE: return("T"); break;
1300 case TYPE_PROCESSOR: return("P"); break;
1301 case TYPE_WORM: return("W"); break;
1302 case TYPE_ROM: return("R"); break;
1303 case TYPE_SCANNER: return("S"); break;
1304 case TYPE_MOD: return("M"); break;
1305 case TYPE_MEDIUM_CHANGER: return("C"); break;
1306 case TYPE_NO_LUN: return("+"); break; /* show NO_LUN */
1307 case TYPE_NO_DEVICE:
1308 default: return("-"); break;
1310 return("-");
1313 /* interpreter for logical device numbers (ldn) */
1314 static char *ti_l(int value)
1316 const char hex[16] = "0123456789abcdef";
1317 static char answer[2];
1319 answer[1] = (char)(0x0);
1320 if (value<=MAX_LOG_DEV)
1321 answer[0] = hex[value];
1322 else
1323 answer[0] = '-';
1325 return (char *)&answer;
1328 /* transfers bitpattern of the feature command to values in MHz */
1329 static char *ibmrate(unsigned int speed, int adaptertype)
1331 int i;
1332 i=adaptertype;
1333 switch (speed)
1335 case 0: if (i) return "5.00"; else return "10.00"; break;
1336 case 1: if (i) return "4.00"; else return "8.00"; break;
1337 case 2: if (i) return "3.33"; else return "6.66"; break;
1338 case 3: if (i) return "2.86"; else return "5.00"; break;
1339 case 4: if (i) return "2.50"; else return "4.00"; break;
1340 case 5: if (i) return "2.22"; else return "3.10"; break;
1341 case 6: if (i) return "2.00"; else return "2.50"; break;
1342 case 7: if (i) return "1.82"; else return "2.00"; break;
1344 return "---";
1347 static int probe_display(int what)
1349 static int rotator = 0;
1350 const char rotor[] = "|/-\\";
1352 if (!(display_mode & LED_DISP))
1353 return 0;
1354 if (!what)
1356 outl(0x20202020,MOD95_LED_PORT);
1357 outl(0x20202020,MOD95_LED_PORT+4);
1359 else
1361 outb('S',MOD95_LED_PORT+7);
1362 outb('C',MOD95_LED_PORT+6);
1363 outb('S',MOD95_LED_PORT+5);
1364 outb('I',MOD95_LED_PORT+4);
1365 outb('i',MOD95_LED_PORT+3);
1366 outb('n',MOD95_LED_PORT+2);
1367 outb('i',MOD95_LED_PORT+1);
1368 outb((char)(rotor[rotator]),MOD95_LED_PORT);
1369 rotator++;
1370 if (rotator>3)
1371 rotator=0;
1373 return 0;
1376 static int probe_bus_mode(int host_index)
1378 struct im_pos_info *info;
1379 int num_bus = 0;
1380 int ldn;
1382 info = (struct im_pos_info *)(&(ld(host_index)[MAX_LOG_DEV].buf));
1384 if (get_pos_info(host_index))
1386 if (info->connector_size & 0xf000)
1387 subsystem_connector_size(host_index)=16;
1388 else
1389 subsystem_connector_size(host_index)=32;
1390 num_bus |= (info->pos_4b & 8) >> 3;
1391 for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
1393 if ((special(host_index)==IBM_SCSI_WCACHE)||
1394 (special(host_index)==IBM_7568_WCACHE))
1396 if (!((info->cache_stat >> ldn) & 1))
1397 ld(host_index)[ldn].cache_flag = 0;
1399 if (!((info->retry_stat >> ldn) & 1))
1400 ld(host_index)[ldn].retry_flag = 0;
1402 #ifdef IM_DEBUG_PROBE
1403 printk("IBM MCA SCSI: SCSI-Cache bits: ");
1404 for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
1406 printk("%d",ld(host_index)[ldn].cache_flag);
1408 printk("\nIBM MCA SCSI: SCSI-Retry bits: ");
1409 for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
1411 printk("%d",ld(host_index)[ldn].retry_flag);
1413 printk("\n");
1414 #endif
1416 return num_bus;
1420 The following routine probes the SCSI-devices in four steps:
1421 1. The current ldn -> pun,lun mapping is removed on the SCSI-adapter.
1422 2. ldn 0 is used to go through all possible combinations of pun,lun and
1423 a device_inquiry is done to fiddle out whether there is a device
1424 responding or not. This physical map is stored in get_scsi[][].
1425 3. The 15 available ldns (0-14) are mapped to existing pun,lun.
1426 If there are more devices than ldns, it stops at 14 for the boot
1427 time. Dynamical remapping will be done in ibmmca_queuecommand.
1428 4. If there are less than 15 valid pun,lun, the remaining ldns are
1429 mapped to NON-existing pun,lun to satisfy the adapter. Information
1430 about pun,lun -> ldn is stored as before in get_ldn[][].
1431 This method leads to the result, that the SCSI-pun,lun shown to Linux
1432 mid-level- and higher-level-drivers is exactly corresponding to the
1433 physical reality on the SCSI-bus. Therefore, it is possible that users
1434 of older releases of this driver have to rewrite their fstab-file, because
1435 the /dev/sdXXX could have changed due to the right pun,lun report, now.
1436 The assignment of ALL ldns avoids dynamical remapping by the adapter
1437 itself.
1439 static void check_devices (int host_index, int adaptertype)
1441 int id, lun, ldn, ticks;
1442 int count_devices; /* local counter for connected device */
1443 int max_pun;
1444 int num_bus;
1445 int speedrun; /* local adapter_speed check variable */
1447 /* assign default values to certain variables */
1448 ticks = 0;
1449 count_devices = 0;
1450 IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */
1451 IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */
1452 next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired'*/
1454 /* initialize the very important driver-informational arrays/structs */
1455 memset (ld(host_index), 0,
1456 sizeof(ld(host_index)));
1457 for (ldn=0; ldn<=MAX_LOG_DEV; ldn++)
1459 last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */
1460 last_scsi_type(host_index)[ldn] = 0;
1461 ld(host_index)[ldn].cache_flag = 1;
1462 ld(host_index)[ldn].retry_flag = 1;
1464 memset (get_ldn(host_index), TYPE_NO_DEVICE,
1465 sizeof(get_ldn(host_index))); /* this is essential ! */
1466 memset (get_scsi(host_index), TYPE_NO_DEVICE,
1467 sizeof(get_scsi(host_index))); /* this is essential ! */
1469 for (lun=0; lun<8; lun++) /* mark the adapter at its pun on all luns*/
1471 get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER;
1472 get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV; /* make sure, the subsystem
1473 ldn is active for all
1474 luns. */
1477 probe_display(0); /* Supercool display usage during SCSI-probing. */
1478 /* This makes sense, when booting without any */
1479 /* monitor connected on model XX95. */
1481 /* STEP 1: */
1482 adapter_speed(host_index) = global_adapter_speed;
1483 speedrun = adapter_speed(host_index);
1484 while (immediate_feature(host_index,speedrun,adapter_timeout)==2)
1486 probe_display(1);
1487 if (speedrun==7)
1488 panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n");
1489 speedrun++;
1490 if (speedrun>7)
1491 speedrun=7;
1493 adapter_speed(host_index) = speedrun;
1494 /* Get detailed information about the current adapter, necessary for
1495 * device operations: */
1496 num_bus=probe_bus_mode(host_index);
1498 /* num_bus contains only valid data for the F/W adapter! */
1499 if (adaptertype==IBM_SCSI2_FW) /* F/W SCSI adapter: */
1501 /* F/W adapter PUN-space extension evaluation: */
1502 if (num_bus)
1504 printk("IBM MCA SCSI: Seperate bus mode (wide-addressing enabled)\n");
1505 subsystem_maxid(host_index) = 16;
1507 else
1509 printk("IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
1510 subsystem_maxid(host_index) = 8;
1512 printk("IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n",
1513 ibmrate(speedrun,adaptertype));
1515 else /* all other IBM SCSI adapters: */
1516 printk("IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n",
1517 ibmrate(speedrun,adaptertype));
1519 /* assign correct PUN device space */
1520 max_pun = subsystem_maxid(host_index);
1522 #ifdef IM_DEBUG_PROBE
1523 printk("IBM MCA SCSI: Current SCSI-host index: %d\n",host_index);
1524 #endif
1525 printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");
1526 for (ldn=0; ldn<MAX_LOG_DEV; ldn++)
1528 probe_display(1);
1529 #ifdef IM_DEBUG_PROBE
1530 printk(".");
1531 #endif
1532 immediate_assign(host_index,0,0,ldn,REMOVE_LDN); /* remove ldn (wherever)*/
1535 lun = 0; /* default lun is 0 */
1537 /* STEP 2: */
1538 printk("\nIBM MCA SCSI: Probing SCSI-devices");
1539 #ifndef IM_DEBUG_PROBE
1540 printk(" (this can take up to 2 minutes)");
1541 #endif
1542 printk(".");
1544 for (id=0; id<max_pun ; id++)
1545 #ifdef CONFIG_SCSI_MULTI_LUN
1546 for (lun=0; lun<8; lun++)
1547 #endif
1549 probe_display(1);
1550 #ifdef IM_DEBUG_PROBE
1551 printk(".");
1552 #endif
1553 if (id != subsystem_pun(host_index))
1554 { /* if pun is not the adapter: */
1555 /*set ldn=0 to pun,lun*/
1556 immediate_assign(host_index,id,lun,PROBE_LDN,SET_LDN);
1557 if (device_inquiry(host_index, PROBE_LDN)) /* probe device */
1559 get_scsi(host_index)[id][lun]=
1560 (unsigned char)(ld(host_index)[PROBE_LDN].buf[0]);
1561 /* entry, even for NO_LUN */
1562 if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN)
1563 count_devices++; /* a existing device is found */
1565 /* remove ldn */
1566 immediate_assign(host_index,id,lun,PROBE_LDN,REMOVE_LDN);
1570 /* STEP 3: */
1571 printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
1573 ldn = 0;
1574 lun = 0;
1576 #ifdef CONFIG_SCSI_MULTI_LUN
1577 for (lun=0; lun<8 && ldn<MAX_LOG_DEV; lun++)
1578 #endif
1579 for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++)
1581 probe_display(1);
1582 #ifdef IM_DEBUG_PROBE
1583 printk(".");
1584 #endif
1585 if (id != subsystem_pun(host_index))
1587 if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN &&
1588 get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE)
1590 /* Only map if accepted type. Always enter for
1591 lun == 0 to get no gaps into ldn-mapping for ldn<7. */
1592 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1593 get_ldn(host_index)[id][lun]=ldn; /* map ldn */
1594 if (device_exists (host_index, ldn,
1595 &ld(host_index)[ldn].block_length,
1596 &ld(host_index)[ldn].device_type))
1598 #ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
1599 printk("resetting device at ldn=%x ... ",ldn);
1600 immediate_reset(host_index,ldn);
1601 #endif
1602 ldn++;
1604 else
1606 /* device vanished, probably because we don't know how to
1607 * handle it or because it has problems */
1608 if (lun > 0)
1610 /* remove mapping */
1611 get_ldn(host_index)[id][lun]=TYPE_NO_DEVICE;
1612 immediate_assign(host_index,0,0,ldn,REMOVE_LDN);
1614 else ldn++;
1617 else if (lun == 0)
1619 /* map lun == 0, even if no device exists */
1620 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1621 get_ldn(host_index)[id][lun]=ldn; /* map ldn */
1622 ldn++;
1627 /* STEP 4: */
1629 /* map remaining ldns to non-existing devices */
1630 for (lun=1; lun<8 && ldn<MAX_LOG_DEV; lun++)
1631 for (id=0; id<max_pun && ldn<MAX_LOG_DEV; id++)
1633 if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN ||
1634 get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE)
1636 probe_display(1);
1637 /* Map remaining ldns only to NON-existing pun,lun
1638 combinations to make sure an inquiry will fail.
1639 For MULTI_LUN, it is needed to avoid adapter autonome
1640 SCSI-remapping. */
1641 immediate_assign(host_index,id,lun,ldn,SET_LDN);
1642 get_ldn(host_index)[id][lun]=ldn;
1643 ldn++;
1647 printk("\n");
1648 if (ibm_ansi_order)
1649 printk("IBM MCA SCSI: Device order: IBM/ANSI (pun=7 is first).\n");
1650 else
1651 printk("IBM MCA SCSI: Device order: New Industry Standard (pun=0 is first).\n");
1653 #ifdef IM_DEBUG_PROBE
1654 /* Show the physical and logical mapping during boot. */
1655 printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
1656 printk(" Physical SCSI-Device Map Logical SCSI-Device Map\n");
1657 printk("ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n");
1658 for (id=0; id<max_pun; id++)
1660 printk("%2d ",id);
1661 for (lun=0; lun<8; lun++)
1662 printk("%2s ",ti_p(get_scsi(host_index)[id][lun]));
1663 printk(" %2d ",id);
1664 for (lun=0; lun<8; lun++)
1665 printk("%2s ",ti_l(get_ldn(host_index)[id][lun]));
1666 printk("\n");
1668 #endif
1670 /* assign total number of found SCSI-devices to the statistics struct */
1671 IBM_DS(host_index).total_scsi_devices = count_devices;
1673 /* decide for output in /proc-filesystem, if the configuration of
1674 SCSI-devices makes dynamical reassignment of devices necessary */
1675 if (count_devices>=MAX_LOG_DEV)
1676 IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */
1677 else
1678 IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */
1680 /* If no SCSI-devices are assigned, return 1 in order to cause message. */
1681 if (ldn == 0)
1682 printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n");
1684 /* reset the counters for statistics on the current adapter */
1685 IBM_DS(host_index).scbs = 0;
1686 IBM_DS(host_index).long_scbs = 0;
1687 IBM_DS(host_index).total_accesses = 0;
1688 IBM_DS(host_index).total_interrupts = 0;
1689 IBM_DS(host_index).dynamical_assignments = 0;
1690 memset (IBM_DS(host_index).ldn_access, 0x0,
1691 sizeof (IBM_DS(host_index).ldn_access));
1692 memset (IBM_DS(host_index).ldn_read_access, 0x0,
1693 sizeof (IBM_DS(host_index).ldn_read_access));
1694 memset (IBM_DS(host_index).ldn_write_access, 0x0,
1695 sizeof (IBM_DS(host_index).ldn_write_access));
1696 memset (IBM_DS(host_index).ldn_inquiry_access, 0x0,
1697 sizeof (IBM_DS(host_index).ldn_inquiry_access));
1698 memset (IBM_DS(host_index).ldn_modeselect_access, 0x0,
1699 sizeof (IBM_DS(host_index).ldn_modeselect_access));
1700 memset (IBM_DS(host_index).ldn_assignments, 0x0,
1701 sizeof (IBM_DS(host_index).ldn_assignments));
1702 probe_display(0);
1703 return;
1706 /*--------------------------------------------------------------------*/
1708 static int device_exists (int host_index, int ldn, int *block_length,
1709 int *device_type)
1711 unsigned char *buf;
1713 /* if no valid device found, return immediately with 0 */
1714 if (!(device_inquiry(host_index, ldn)))
1715 return 0;
1717 buf = (unsigned char *)(&(ld(host_index)[ldn].buf));
1719 /*if device is CD_ROM, assume block size 2048 and return */
1720 if (*buf == TYPE_ROM)
1722 *device_type = TYPE_ROM;
1723 *block_length = 2048; /* (standard blocksize for yellow-/red-book) */
1724 return 1;
1727 if (*buf == TYPE_WORM) /* CD-burner, WORM, Linux handles this as CD-ROM
1728 therefore, the block_length is also 2048. */
1730 *device_type = TYPE_WORM;
1731 *block_length = 2048;
1732 return 1;
1735 /* if device is disk, use "read capacity" to find its block size */
1736 if (*buf == TYPE_DISK)
1738 *device_type = TYPE_DISK;
1739 if (read_capacity( host_index, ldn))
1741 *block_length = *(buf+7) + (*(buf+6) << 8) +
1742 (*(buf+5) << 16) + (*(buf+4) << 24);
1743 return 1;
1745 else
1746 return 0;
1749 /* if this is a magneto-optical drive, treat it like a harddisk */
1750 if (*buf == TYPE_MOD)
1752 *device_type = TYPE_MOD;
1753 if (read_capacity( host_index, ldn))
1755 *block_length = *(buf+7) + (*(buf+6) << 8) +
1756 (*(buf+5) << 16) + (*(buf+4) << 24);
1757 return 1;
1759 else
1760 return 0;
1763 if (*buf == TYPE_TAPE) /* TAPE-device found */
1765 *device_type = TYPE_TAPE;
1766 *block_length = 0; /* not in use (setting by mt and mtst in op.) */
1767 return 1;
1770 if (*buf == TYPE_PROCESSOR) /* HP-Scanners, diverse SCSI-processing units*/
1772 *device_type = TYPE_PROCESSOR;
1773 *block_length = 0; /* they set their stuff on drivers */
1774 return 1;
1777 if (*buf == TYPE_SCANNER) /* other SCSI-scanners */
1779 *device_type = TYPE_SCANNER;
1780 *block_length = 0; /* they set their stuff on drivers */
1781 return 1;
1784 if (*buf == TYPE_MEDIUM_CHANGER) /* Medium-Changer */
1786 *device_type = TYPE_MEDIUM_CHANGER;
1787 *block_length = 0; /* One never knows, what to expect on a medium
1788 changer device. */
1789 return 1;
1792 /* Up to now, no SCSI-devices that are known up to kernel 2.1.31 are
1793 ignored! MO-drives are now supported and treated as harddisk. */
1794 return 0;
1797 /*--------------------------------------------------------------------*/
1799 void internal_ibmmca_scsi_setup (char *str, int *ints)
1801 int i, j, io_base, id_base;
1802 char *token;
1804 io_base = 0;
1805 id_base = 0;
1807 if (str)
1809 token = strtok(str,",");
1810 j = 0;
1811 while (token)
1813 if (!strcmp(token,"activity"))
1814 display_mode |= LED_ACTIVITY;
1815 if (!strcmp(token,"display"))
1816 display_mode |= LED_DISP;
1817 if (!strcmp(token,"adisplay"))
1818 display_mode |= LED_ADISP;
1819 if (!strcmp(token,"bypass"))
1820 bypass_controller = 1;
1821 if (!strcmp(token,"normal"))
1822 ibm_ansi_order = 0;
1823 if (!strcmp(token,"ansi"))
1824 ibm_ansi_order = 1;
1825 if (!strcmp(token,"fast"))
1826 global_adapter_speed = 0;
1827 if (!strcmp(token,"medium"))
1828 global_adapter_speed = 4;
1829 if (!strcmp(token,"slow"))
1830 global_adapter_speed = 7;
1831 if ( (*token == '-') || (isdigit(*token)) )
1833 if (!(j%2) && (io_base < IM_MAX_HOSTS))
1834 io_port[io_base++] = simple_strtoul(token,NULL,0);
1835 if ((j%2) && (id_base < IM_MAX_HOSTS))
1836 scsi_id[id_base++] = simple_strtoul(token,NULL,0);
1837 j++;
1839 token = strtok(NULL,",");
1842 else if (ints)
1844 for (i = 0; i < IM_MAX_HOSTS && 2*i+2 < ints[0]; i++)
1846 io_port[i] = ints[2*i+2];
1847 scsi_id[i] = ints[2*i+2];
1850 return;
1853 /*--------------------------------------------------------------------*/
1855 static int ibmmca_getinfo (char *buf, int slot, void *dev)
1857 struct Scsi_Host *shpnt;
1858 int len, speciale,connectore;
1859 unsigned int pos2, pos3;
1860 static unsigned long flags;
1862 #ifdef OLDKERN
1863 save_flags(flags);
1864 cli();
1865 #else
1866 spin_lock_irqsave(&info_lock, flags);
1867 #endif
1869 shpnt = dev; /* assign host-structure to local pointer */
1870 len = 0; /* set filled text-buffer index to 0 */
1871 /* get the _special contents of the hostdata structure */
1872 speciale = ((struct ibmmca_hostdata *)shpnt->hostdata)->_special;
1873 connectore = ((struct ibmmca_hostdata *)shpnt->hostdata)->_connector_size;
1874 pos2 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2;
1875 pos3 = ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3;
1877 if (speciale == FORCED_DETECTION) /* forced detection */
1879 len += sprintf (buf + len, "Adapter category: forced detected\n");
1880 len += sprintf(buf + len, "***************************************\n");
1881 len += sprintf(buf + len, "*** Forced detected SCSI Adapter ***\n");
1882 len += sprintf(buf + len, "*** No chip-information available ***\n");
1883 len += sprintf(buf + len, "***************************************\n");
1885 else if (speciale == INTEGRATED_SCSI)
1886 { /* if the integrated subsystem has been found automatically: */
1887 len += sprintf (buf + len, "Adapter category: integrated\n");
1888 len += sprintf (buf + len, "Chip revision level: %d\n",
1889 ((pos2 & 0xf0) >> 4));
1890 len += sprintf (buf + len, "Chip status: %s\n",
1891 (pos2 & 1) ? "enabled" : "disabled");
1892 len += sprintf (buf + len, "8 kByte NVRAM status: %s\n",
1893 (pos2 & 2) ? "locked" : "accessible");
1895 else if ((speciale>=0)&&
1896 (speciale<(sizeof(subsys_list)/sizeof(struct subsys_list_struct))))
1897 { /* if the subsystem is a slot adapter */
1898 len += sprintf (buf + len, "Adapter category: slot-card\n");
1899 len += sprintf (buf + len, "ROM Segment Address: ");
1900 if ((pos2 & 0xf0) == 0xf0)
1901 len += sprintf (buf + len, "off\n");
1902 else
1903 len += sprintf (buf + len, "0x%x\n",
1904 ((pos2 & 0xf0) << 13) + 0xc0000);
1905 len += sprintf (buf + len, "Chip status: %s\n",
1906 (pos2 & 1) ? "enabled" : "disabled");
1907 len += sprintf (buf + len, "Adapter I/O Offset: 0x%x\n",
1908 ((pos2 & 0x0e) << 2));
1910 else
1912 len += sprintf (buf + len, "Adapter category: unknown\n");
1914 /* common subsystem information to write to the slotn file */
1915 len += sprintf (buf + len, "Subsystem PUN: %d\n", shpnt->this_id);
1916 len += sprintf (buf + len, "I/O base address range: 0x%x-0x%x\n",
1917 (unsigned int)(shpnt->io_port),
1918 (unsigned int)(shpnt->io_port+7));
1919 len += sprintf (buf + len, "MCA-slot size: %d bits",connectore);
1920 /* Now make sure, the bufferlength is devidable by 4 to avoid
1921 * paging problems of the buffer. */
1922 while ( len % sizeof( int ) != ( sizeof ( int ) - 1 ) )
1924 len += sprintf (buf + len, " ");
1926 len += sprintf (buf + len, "\n");
1928 #ifdef OLDKERN
1929 restore_flags(flags);
1930 #else
1931 spin_unlock_irqrestore(&info_lock, flags);
1932 #endif
1933 return len;
1936 int ibmmca_detect (Scsi_Host_Template * scsi_template)
1938 struct Scsi_Host *shpnt;
1939 int port, id, i, j, list_size, slot;
1940 int devices_on_irq_11 = 0;
1941 int devices_on_irq_14 = 0;
1942 int IRQ14_registered = 0;
1943 int IRQ11_registered = 0;
1945 found = 0; /* make absolutely sure, that found is set to 0 */
1947 /* First of all, print the version number of the driver. This is
1948 * important to allow better user bugreports in case of already
1949 * having problems with the MCA_bus probing. */
1950 printk("IBM MCA SCSI: Version %s\n",IBMMCA_SCSI_DRIVER_VERSION);
1951 /* if this is not MCA machine, return "nothing found" */
1952 if (!MCA_bus)
1954 printk("IBM MCA SCSI: No Microchannel-bus present --> Aborting.\n");
1955 printk(" This machine does not have any IBM MCA-bus\n");
1956 printk(" or the MCA-Kernel-support is not enabled!\n");
1957 return 0;
1960 #ifdef MODULE
1961 /* If the driver is run as module, read from conf.modules or cmd-line */
1962 if (boot_options)
1963 option_setup(boot_options);
1964 #endif
1966 /* get interrupt request level */
1967 #ifdef OLDKERN
1968 if (request_irq (IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi",
1969 hosts))
1970 #else
1971 if (request_irq (IM_IRQ, do_interrupt_handler, SA_SHIRQ, "ibmmcascsi",
1972 hosts))
1973 #endif
1975 printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
1976 return 0;
1978 else
1979 IRQ14_registered++;
1981 /* if ibmmcascsi setup option was passed to kernel, return "found" */
1982 for (i = 0; i < IM_MAX_HOSTS; i++)
1983 if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8)
1985 printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n",
1986 io_port[i], scsi_id[i]);
1987 if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i],
1988 FORCED_DETECTION,
1989 "forced detected SCSI Adapter")))
1991 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = 0;
1992 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = 0;
1993 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = 0;
1994 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = 0;
1995 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = 0;
1996 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
1997 FORCED_DETECTION;
1998 mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");
1999 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
2000 shpnt);
2001 mca_mark_as_used(MCA_INTEGSCSI);
2002 devices_on_irq_14++;
2005 if (found) return found;
2007 /* The POS2-register of all PS/2 model SCSI-subsystems has the following
2008 * interpretation of bits:
2009 * Bit 7 - 4 : Chip Revision ID (Release)
2010 * Bit 3 - 2 : Reserved
2011 * Bit 1 : 8k NVRAM Disabled
2012 * Bit 0 : Chip Enable (EN-Signal)
2013 * The POS3-register is interpreted as follows:
2014 * Bit 7 - 5 : SCSI ID
2015 * Bit 4 : Reserved = 0
2016 * Bit 3 - 0 : Reserved = 0
2017 * (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common
2018 * Interfaces (1991)").
2019 * In short words, this means, that IBM PS/2 machines only support
2020 * 1 single subsystem by default. The slot-adapters must have another
2021 * configuration on pos2. Here, one has to assume the following
2022 * things for POS2-register:
2023 * Bit 7 - 4 : Chip Revision ID (Release)
2024 * Bit 3 - 1 : port offset factor
2025 * Bit 0 : Chip Enable (EN-Signal)
2026 * As I found a patch here, setting the IO-registers to 0x3540 forced,
2027 * as there was a 0x05 in POS2 on a model 56, I assume, that the
2028 * port 0x3540 must be fix for integrated SCSI-controllers.
2029 * Ok, this discovery leads to the following implementation: (M.Lang) */
2031 /* first look for the IBM SCSI integrated subsystem on the motherboard */
2032 for (j=0;j<8;j++) /* read the pos-information */
2033 pos[j] = mca_read_stored_pos(MCA_INTEGSCSI,j);
2034 /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present */
2035 /* if (( pos[2] != 0xff) || (pos[3] != 0xff )) */
2036 /* Previous if-arguments do fail! Therefore, we use now the following to
2037 * make sure, we see a real integrated onboard SCSI-interface: */
2038 if ((!pos[0] && !pos[1] && pos[2]>0 && pos[3]>0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) ||
2039 (pos[0]==0xff && pos[1]==0xff && pos[2]<0xff && pos[3]<0xff && pos[4]==0xff && pos[5]==0xff && pos[6]==0xff && pos[7]==0xff))
2041 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
2042 port = IM_IO_PORT;
2043 else
2044 { /* if disabled, no IRQs will be generated, as the chip won't
2045 * listen to the incomming commands and will do really nothing,
2046 * except for listening to the pos-register settings. If this
2047 * happens, I need to hugely think about it, as one has to
2048 * write something to the MCA-Bus pos register in order to
2049 * enable the chip. Normally, IBM-SCSI won't pass the POST,
2050 * when the chip is disabled (see IBM tech. ref.). */
2051 port = IM_IO_PORT; /* anyway, set the portnumber and warn */
2052 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
2053 printk(" SCSI-operations may not work.\n");
2055 id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */
2057 /* give detailed information on the subsystem. This helps me
2058 * additionally during debugging and analyzing bug-reports. */
2059 printk("IBM MCA SCSI: IBM Integrated SCSI Controller found, io=0x%x, scsi id=%d,\n",
2060 port, id);
2061 printk(" chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n",
2062 ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible",
2063 (pos[2] & 1) ? "enabled." : "disabled.");
2065 /* register the found integrated SCSI-subsystem */
2066 if ((shpnt = ibmmca_register(scsi_template, port, id,
2067 INTEGRATED_SCSI,
2068 "IBM Integrated SCSI Controller")))
2070 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
2071 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
2072 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
2073 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
2074 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
2075 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special =
2076 INTEGRATED_SCSI;
2077 mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");
2078 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo,
2079 shpnt);
2080 mca_mark_as_used(MCA_INTEGSCSI);
2081 devices_on_irq_14++;
2085 /* now look for other adapters in MCA slots, */
2086 /* determine the number of known IBM-SCSI-subsystem types */
2087 /* see the pos[2] dependence to get the adapter port-offset. */
2088 list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
2089 for (i = 0; i < list_size; i++)
2090 { /* scan each slot for a fitting adapter id */
2091 slot = 0; /* start at slot 0 */
2092 while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
2093 != MCA_NOTFOUND)
2094 { /* scan through all slots */
2095 for (j=0;j<8;j++) /* read the pos-information */
2096 pos[j] = mca_read_stored_pos(slot, j);
2097 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
2098 { /* (explanations see above) */
2099 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
2101 else
2102 { /* anyway, set the portnumber and warn */
2103 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
2104 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
2105 printk(" SCSI-operations may not work.\n");
2107 if ((i==IBM_SCSI2_FW)&&(pos[6]!=0))
2109 printk("IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
2110 printk(" Impossible to determine adapter PUN!\n");
2111 printk(" Guessing adapter PUN = 7.\n");
2112 id = 7;
2114 else
2116 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
2117 if (i==IBM_SCSI2_FW)
2119 id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
2120 * for F/W adapters */
2123 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
2124 { /* IRQ11 is used by SCSI-2 F/W Adapter/A */
2125 printk("IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
2126 /* get interrupt request level */
2127 #ifdef OLDKERN
2128 if (request_irq (IM_IRQ_FW, interrupt_handler, SA_SHIRQ,
2129 "ibmmcascsi", hosts))
2130 #else
2131 if (request_irq (IM_IRQ_FW, do_interrupt_handler, SA_SHIRQ,
2132 "ibmmcascsi", hosts))
2133 #endif
2135 printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n",
2136 IM_IRQ_FW);
2138 else
2139 IRQ11_registered++;
2141 printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",
2142 subsys_list[i].description, slot + 1, port, id);
2143 if ((pos[2] & 0xf0) == 0xf0)
2144 printk(" ROM Addr.=off,");
2145 else
2146 printk(" ROM Addr.=0x%x,",
2147 ((pos[2] & 0xf0) << 13) + 0xc0000);
2148 printk(" port-offset=0x%x, subsystem=%s\n",
2149 ((pos[2] & 0x0e) << 2),
2150 (pos[2] & 1) ? "enabled." : "disabled.");
2152 /* register the hostadapter */
2153 if ((shpnt = ibmmca_register(scsi_template, port, id, i,
2154 subsys_list[i].description)))
2156 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
2157 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
2158 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
2159 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
2160 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
2161 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = i;
2163 mca_set_adapter_name (slot, subsys_list[i].description);
2164 mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
2165 shpnt);
2166 mca_mark_as_used(slot);
2167 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
2168 devices_on_irq_11++;
2169 else
2170 devices_on_irq_14++;
2172 slot++; /* advance to next slot */
2173 } /* advance to next adapter id in the list of IBM-SCSI-subsystems*/
2177 /* now look for SCSI-adapters, by bugs mapped to the integrated SCSI
2178 * area. E.g. a W/Cache in MCA-slot 9 ???? Arrrrgh!! */
2179 list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
2180 for (i = 0; i < list_size; i++)
2181 { /* scan each slot for a fitting adapter id */
2182 slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
2183 if (slot != MCA_NOTFOUND)
2184 { /* scan through all slots */
2185 for (j=0;j<8;j++) /* read the pos-information */
2186 pos[j] = mca_read_stored_pos(slot, j);
2187 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
2188 { /* (explanations see above) */
2189 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
2191 else
2192 { /* anyway, set the portnumber and warn */
2193 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
2194 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
2195 printk(" SCSI-operations may not work.\n");
2197 if ((i==IBM_SCSI2_FW)&&(pos[6]!=0))
2199 printk("IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
2200 printk(" Impossible to determine adapter PUN!\n");
2201 printk(" Guessing adapter PUN = 7.\n");
2202 id = 7;
2204 else
2206 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
2207 if (i==IBM_SCSI2_FW)
2209 id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
2210 * for F/W adapters */
2213 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
2214 { /* IRQ11 is used by SCSI-2 F/W Adapter/A */
2215 printk("IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
2216 /* get interrupt request level */
2217 #ifdef OLDKERN
2218 if (request_irq (IM_IRQ_FW, interrupt_handler, SA_SHIRQ,
2219 "ibmmcascsi", hosts))
2220 #else
2221 if (request_irq (IM_IRQ_FW, do_interrupt_handler, SA_SHIRQ,
2222 "ibmmcascsi", hosts))
2223 #endif
2225 printk("IBM MCA SCSI: Unable to get shared IRQ %d.\n",
2226 IM_IRQ_FW);
2228 else
2229 IRQ11_registered++;
2231 printk("IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n",
2232 subsys_list[i].description, slot + 1, port, id);
2233 if ((pos[2] & 0xf0) == 0xf0)
2234 printk(" ROM Addr.=off,");
2235 else
2236 printk(" ROM Addr.=0x%x,",
2237 ((pos[2] & 0xf0) << 13) + 0xc0000);
2238 printk(" port-offset=0x%x, subsystem=%s\n",
2239 ((pos[2] & 0x0e) << 2),
2240 (pos[2] & 1) ? "enabled." : "disabled.");
2242 /* register the hostadapter */
2243 if ((shpnt = ibmmca_register(scsi_template, port, id, i,
2244 subsys_list[i].description)))
2246 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos2 = pos[2];
2247 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos3 = pos[3];
2248 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos4 = pos[4];
2249 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos5 = pos[5];
2250 ((struct ibmmca_hostdata *)shpnt->hostdata)->_pos6 = pos[6];
2251 ((struct ibmmca_hostdata *)shpnt->hostdata)->_special = i;
2253 mca_set_adapter_name (slot, subsys_list[i].description);
2254 mca_set_adapter_procfn (slot, (MCA_ProcFn) ibmmca_getinfo,
2255 shpnt);
2256 mca_mark_as_used(slot);
2257 if ((i==IBM_SCSI2_FW)&&(pos[4] & 0x01)&&(pos[6]==0))
2258 devices_on_irq_11++;
2259 else
2260 devices_on_irq_14++;
2262 slot++; /* advance to next slot */
2263 } /* advance to next adapter id in the list of IBM-SCSI-subsystems*/
2266 if ( IRQ11_registered && !devices_on_irq_11 )
2267 free_irq(IM_IRQ_FW, hosts); /* no devices on IRQ 11 */
2268 if ( IRQ14_registered && !devices_on_irq_14 )
2269 free_irq(IM_IRQ, hosts); /* no devices on IRQ 14 */
2270 if ( !devices_on_irq_11 && !devices_on_irq_14 )
2271 printk("IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
2272 return found; /* return the number of found SCSI hosts. Should be 1 or 0. */
2275 static struct Scsi_Host *
2276 ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id,
2277 int adaptertype, char *hostname)
2279 struct Scsi_Host *shpnt;
2280 int i, j;
2281 unsigned int ctrl;
2283 /* check I/O region */
2284 if (check_region(port, IM_N_IO_PORT))
2286 printk("IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n",
2287 port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT);
2288 return NULL;
2291 /* register host */
2292 shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata));
2293 if (!shpnt)
2295 printk("IBM MCA SCSI: Unable to register host.\n");
2296 return NULL;
2299 /* request I/O region */
2300 request_region(port, IM_N_IO_PORT, hostname);
2302 hosts[found] = shpnt; /* add new found hostadapter to the list */
2303 special(found) = adaptertype; /* important assignment or else crash! */
2304 subsystem_connector_size(found) = 0; /* preset slot-size */
2305 shpnt->irq = IM_IRQ; /* assign necessary stuff for the adapter */
2306 shpnt->io_port = port;
2307 shpnt->n_io_port = IM_N_IO_PORT;
2308 shpnt->this_id = id;
2309 shpnt->max_id = 8; /* 8 PUNs are default */
2310 /* now, the SCSI-subsystem is connected to Linux */
2312 ctrl = (unsigned int)(inb(IM_CTR_REG(found))); /* get control-register status */
2313 #ifdef IM_DEBUG_PROBE
2314 printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n",
2315 ctrl,inb(IM_STAT_REG(found)));
2316 printk("IBM MCA SCSI: This adapters' POS-registers: ");
2317 for (i=0;i<8;i++)
2318 printk("%x ",pos[i]);
2319 printk("\n");
2320 if (bypass_controller)
2321 printk("IBM MCA SCSI: Subsystem SCSI-commands get bypassed.\n");
2322 #endif
2324 reset_status(found) = IM_RESET_NOT_IN_PROGRESS;
2326 for (i = 0; i < 16; i++) /* reset the tables */
2327 for (j = 0; j < 8; j++)
2328 get_ldn(found)[i][j] = MAX_LOG_DEV;
2330 /* check which logical devices exist */
2331 /* after this line, local interrupting is possible: */
2332 local_checking_phase_flag(found) = 1;
2333 check_devices(found,adaptertype); /* call by value, using the global variable hosts*/
2334 local_checking_phase_flag(found) = 0;
2336 found++; /* now increase index to be prepared for next found subsystem */
2337 /* an ibm mca subsystem has been detected */
2338 return shpnt;
2341 /*--------------------------------------------------------------------*/
2343 int ibmmca_command (Scsi_Cmnd * cmd)
2345 ibmmca_queuecommand (cmd, internal_done);
2346 cmd->SCp.Status = 0;
2347 while (!cmd->SCp.Status)
2348 barrier ();
2349 return cmd->result;
2352 /*--------------------------------------------------------------------*/
2354 int ibmmca_release(struct Scsi_Host *shpnt)
2356 release_region(shpnt->io_port, shpnt->n_io_port);
2357 if (!(--found))
2358 free_irq(shpnt->irq, hosts);
2359 return 0;
2362 /*--------------------------------------------------------------------*/
2364 /* The following routine is the SCSI command queue. The old edition is
2365 now improved by dynamical reassignment of ldn numbers that are
2366 currently not assigned. The mechanism works in a way, that first
2367 the physical structure is checked. If at a certain pun,lun a device
2368 should be present, the routine proceeds to the ldn check from
2369 get_ldn. An answer of 0xff would show-up, that the aimed device is
2370 currently not assigned any ldn. At this point, the dynamical
2371 remapping algorithm is called. It works in a way, that it goes in
2372 cyclic order through the ldns from 7 to 14. If a ldn is assigned,
2373 it takes 8 dynamical reassignment calls, until a device looses its
2374 ldn again. With this method it is assured, that while doing
2375 intense I/O between up to eight devices, no dynamical remapping is
2376 done there. ldns 0 through 6(!) are left untouched, which means, that
2377 puns 0 through 7(!) on lun=0 are always accessible without remapping.
2378 These ldns are statically assigned by this driver. The subsystem always
2379 occupies at least one pun, therefore 7 ldns (at lun=0) for other devices
2380 are sufficient. (The adapter uses always ldn=15, at whatever pun it is.) */
2381 int ibmmca_queuecommand (Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
2383 unsigned int ldn;
2384 unsigned int scsi_cmd;
2385 struct im_scb *scb;
2386 struct Scsi_Host *shpnt;
2387 int current_ldn;
2388 int id,lun;
2389 int target;
2390 int host_index;
2391 int max_pun;
2392 int i;
2393 struct scatterlist *sl;
2395 shpnt = cmd->host;
2397 /* search for the right hostadapter */
2398 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2400 if (!hosts[host_index])
2401 { /* invalid hostadapter descriptor address */
2402 cmd->result = DID_NO_CONNECT << 16;
2403 if (done)
2404 done (cmd);
2405 return 0;
2408 max_pun = subsystem_maxid(host_index);
2410 if (ibm_ansi_order)
2412 target = max_pun - 1 - cmd->target;
2413 if ((target <= subsystem_pun(host_index))&&(cmd->target <= subsystem_pun(host_index)))
2414 target--;
2415 else if ((target >= subsystem_pun(host_index))&&(cmd->target >= subsystem_pun(host_index)))
2416 target++;
2418 else
2419 target = cmd->target;
2421 /*if (target,lun) is NO LUN or not existing at all, return error */
2422 if ((get_scsi(host_index)[target][cmd->lun] == TYPE_NO_LUN)||
2423 (get_scsi(host_index)[target][cmd->lun] == TYPE_NO_DEVICE))
2425 cmd->result = DID_NO_CONNECT << 16;
2426 if (done)
2427 done (cmd);
2428 return 0;
2431 /*if (target,lun) unassigned, do further checks... */
2432 ldn = get_ldn(host_index)[target][cmd->lun];
2433 if (ldn >= MAX_LOG_DEV) /* on invalid ldn do special stuff */
2435 if (ldn > MAX_LOG_DEV) /* dynamical remapping if ldn unassigned */
2437 current_ldn = next_ldn(host_index); /* stop-value for one circle */
2438 while (ld(host_index)[next_ldn(host_index)].cmd) /* search for a occupied, but not in */
2439 { /* command-processing ldn. */
2440 next_ldn(host_index)++;
2441 if (next_ldn(host_index)>=MAX_LOG_DEV)
2442 next_ldn(host_index) = 7;
2443 if (current_ldn == next_ldn(host_index)) /* One circle done ? */
2444 { /* no non-processing ldn found */
2445 printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n");
2446 printk(" On ldn 7-14 SCSI-commands everywhere in progress.\n");
2447 printk(" Reporting DID_NO_CONNECT for device (%d,%d).\n",
2448 target, cmd->lun);
2449 cmd->result = DID_NO_CONNECT << 16;/* return no connect*/
2450 if (done)
2451 done (cmd);
2452 return 0;
2456 /* unmap non-processing ldn */
2457 for (id=0; id<max_pun; id ++)
2458 for (lun=0; lun<8; lun++)
2460 if (get_ldn(host_index)[id][lun] == next_ldn(host_index))
2462 get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
2463 /* unmap entry */
2466 /* set reduced interrupt_handler-mode for checking */
2467 local_checking_phase_flag(host_index) = 1;
2468 /* unassign found ldn (pun,lun does not matter for remove) */
2469 immediate_assign(host_index,0,0,next_ldn(host_index),REMOVE_LDN);
2470 /* assign found ldn to aimed pun,lun */
2471 immediate_assign(host_index,target,cmd->lun,next_ldn(host_index),SET_LDN);
2472 /* map found ldn to pun,lun */
2473 get_ldn(host_index)[target][cmd->lun] = next_ldn(host_index);
2474 /* change ldn to the right value, that is now next_ldn */
2475 ldn = next_ldn(host_index);
2476 /* get device information for ld[ldn] */
2477 if (device_exists (host_index, ldn,
2478 &ld(host_index)[ldn].block_length,
2479 &ld(host_index)[ldn].device_type))
2481 ld(host_index)[ldn].cmd = 0; /* To prevent panic set 0, because
2482 devices that were not assigned,
2483 should have nothing in progress. */
2485 /* increase assignment counters for statistics in /proc */
2486 IBM_DS(host_index).dynamical_assignments++;
2487 IBM_DS(host_index).ldn_assignments[ldn]++;
2489 else
2490 /* panic here, because a device, found at boottime has
2491 vanished */
2492 panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n",
2493 ldn, target, cmd->lun);
2495 /* set back to normal interrupt_handling */
2496 local_checking_phase_flag(host_index) = 0;
2498 /* Information on syslog terminal */
2499 printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n",
2500 ldn, target, cmd->lun);
2502 /* increase next_ldn for next dynamical assignment */
2503 next_ldn(host_index)++;
2504 if (next_ldn(host_index)>=MAX_LOG_DEV)
2505 next_ldn(host_index) = 7;
2507 else
2508 { /* wall against Linux accesses to the subsystem adapter */
2509 cmd->result = DID_BAD_TARGET << 16;
2510 if (done)
2511 done (cmd);
2512 return 0;
2516 /*verify there is no command already in progress for this log dev */
2517 if (ld(host_index)[ldn].cmd)
2518 panic ("IBM MCA SCSI: cmd already in progress for this ldn.\n");
2520 /*save done in cmd, and save cmd for the interrupt handler */
2521 cmd->scsi_done = done;
2522 ld(host_index)[ldn].cmd = cmd;
2524 /*fill scb information independent of the scsi command */
2525 scb = &(ld(host_index)[ldn].scb);
2526 ld(host_index)[ldn].tsb.dev_status = 0;
2527 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE;
2528 scb->tsb_adr = virt_to_bus(&(ld(host_index)[ldn].tsb));
2529 scsi_cmd = cmd->cmnd[0];
2531 if (cmd->use_sg)
2533 i = cmd->use_sg;
2534 sl = (struct scatterlist *)(cmd->request_buffer);
2535 if (i > 16)
2536 panic ("IBM MCA SCSI: scatter-gather list too long.\n");
2537 while (--i >= 0)
2539 ld(host_index)[ldn].sge[i].address = (void *)(virt_to_bus(sl[i].address));
2540 ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
2542 scb->enable |= IM_POINTER_TO_LIST;
2543 scb->sys_buf_adr = virt_to_bus(&(ld(host_index)[ldn].sge[0]));
2544 scb->sys_buf_length = cmd->use_sg * sizeof (struct im_sge);
2546 else
2548 scb->sys_buf_adr = virt_to_bus(cmd->request_buffer);
2549 /* recent Linux midlevel SCSI places 1024 byte for inquiry
2550 * command. Far too much for old PS/2 hardware. */
2551 switch (scsi_cmd)
2552 { /* avoid command errors by setting bufferlengths to
2553 * ANSI-standard. */
2554 case INQUIRY:
2555 case REQUEST_SENSE:
2556 case MODE_SENSE:
2557 case MODE_SELECT:
2558 scb->sys_buf_length = 255;
2559 break;
2560 case TEST_UNIT_READY:
2561 scb->sys_buf_length = 0;
2562 break;
2563 default:
2564 scb->sys_buf_length = cmd->request_bufflen;
2565 break;
2568 /*fill scb information dependent on scsi command */
2570 #ifdef IM_DEBUG_CMD
2571 printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
2572 #endif
2574 /* for specific device-type debugging: */
2575 #ifdef IM_DEBUG_CMD_SPEC_DEV
2576 if (ld(host_index)[ldn].device_type==IM_DEBUG_CMD_DEVICE)
2577 printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n",
2578 ld(host_index)[ldn].device_type, scsi_cmd, ldn);
2579 #endif
2581 /* for possible panics store current command */
2582 last_scsi_command(host_index)[ldn] = scsi_cmd;
2583 last_scsi_type(host_index)[ldn] = IM_SCB;
2584 /* update statistical info */
2585 IBM_DS(host_index).total_accesses++;
2586 IBM_DS(host_index).ldn_access[ldn]++;
2588 switch (scsi_cmd)
2590 case READ_6:
2591 case WRITE_6:
2592 case READ_10:
2593 case WRITE_10:
2594 case READ_12:
2595 case WRITE_12:
2596 /* Distinguish between disk and other devices. Only disks (that are the
2597 most frequently accessed devices) should be supported by the
2598 IBM-SCSI-Subsystem commands. */
2599 switch (ld(host_index)[ldn].device_type)
2601 case TYPE_DISK: /* for harddisks enter here ... */
2602 case TYPE_MOD: /* ... try it also for MO-drives (send flames as */
2603 /* you like, if this won't work.) */
2604 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
2605 scsi_cmd == READ_12)
2606 { /* read command preparations */
2607 scb->enable |= IM_READ_CONTROL;
2608 IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */
2609 if (bypass_controller)
2611 scb->command = IM_OTHER_SCSI_CMD_CMD;
2612 scb->enable |= IM_BYPASS_BUFFER;
2613 scb->u1.scsi_cmd_length = cmd->cmd_len;
2614 memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
2615 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2617 else
2618 scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT;
2620 else
2621 { /* write command preparations */
2622 IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat.*/
2623 if (bypass_controller)
2625 scb->command = IM_OTHER_SCSI_CMD_CMD;
2626 scb->enable |= IM_BYPASS_BUFFER;
2627 scb->u1.scsi_cmd_length = cmd->cmd_len;
2628 memcpy(scb->u2.scsi_command,cmd->cmnd,cmd->cmd_len);
2629 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2631 else
2632 scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT;
2635 if (!bypass_controller)
2637 if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6)
2639 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[3]) << 0) |
2640 (((unsigned) cmd->cmnd[2]) << 8) |
2641 ((((unsigned) cmd->cmnd[1]) & 0x1f) << 16);
2642 scb->u2.blk.count = (unsigned) cmd->cmnd[4];
2644 else
2646 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) |
2647 (((unsigned) cmd->cmnd[4]) << 8) |
2648 (((unsigned) cmd->cmnd[3]) << 16) |
2649 (((unsigned) cmd->cmnd[2]) << 24);
2650 scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) |
2651 (((unsigned) cmd->cmnd[7]) << 8);
2653 last_scsi_logical_block(host_index)[ldn] = scb->u1.log_blk_adr;
2654 last_scsi_blockcount(host_index)[ldn] = scb->u2.blk.count;
2655 scb->u2.blk.length = ld(host_index)[ldn].block_length;
2657 if (++disk_rw_in_progress == 1)
2658 PS2_DISK_LED_ON (shpnt->host_no, target);
2659 break;
2661 /* for other devices, enter here. Other types are not known by
2662 Linux! TYPE_NO_LUN is forbidden as valid device. */
2663 case TYPE_ROM:
2664 case TYPE_TAPE:
2665 case TYPE_PROCESSOR:
2666 case TYPE_WORM:
2667 case TYPE_SCANNER:
2668 case TYPE_MEDIUM_CHANGER:
2669 /* If there is a sequential-device, IBM recommends to use
2670 IM_OTHER_SCSI_CMD_CMD instead of subsystem READ/WRITE.
2671 Good/modern CD-ROM-drives are capable of
2672 reading sequential AND random-access. This leads to the problem,
2673 that random-accesses are covered by the subsystem, but
2674 sequentials are not, as like for tape-drives. Therefore, it is
2675 the easiest way to use IM_OTHER_SCSI_CMD_CMD for all read-ops
2676 on CD-ROM-drives in order not to run into timing problems and
2677 to have a stable state. In addition, data-access on CD-ROMs
2678 works faster like that. Strange, but obvious. */
2680 scb->command = IM_OTHER_SCSI_CMD_CMD;
2681 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 ||
2682 scsi_cmd == READ_12) /* enable READ */
2683 scb->enable |= IM_READ_CONTROL;
2684 scb->enable |= IM_BYPASS_BUFFER;
2685 scb->u1.scsi_cmd_length = cmd->cmd_len;
2686 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2687 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2689 /* Read/write on this non-disk devices is also displayworthy,
2690 so flash-up the LED/display. */
2691 if (++disk_rw_in_progress == 1)
2692 PS2_DISK_LED_ON (shpnt->host_no, target);
2693 break;
2695 break;
2696 case INQUIRY:
2697 IBM_DS(host_index).ldn_inquiry_access[ldn]++;
2698 if (bypass_controller)
2700 scb->command = IM_OTHER_SCSI_CMD_CMD;
2701 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2702 scb->u1.log_blk_adr = 0;
2703 scb->u1.scsi_cmd_length = cmd->cmd_len;
2704 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2705 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2707 else
2709 scb->command = IM_DEVICE_INQUIRY_CMD;
2710 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2711 scb->u1.log_blk_adr = 0;
2713 break;
2714 case TEST_UNIT_READY:
2715 scb->command = IM_OTHER_SCSI_CMD_CMD;
2716 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2717 scb->u1.log_blk_adr = 0;
2718 scb->u1.scsi_cmd_length = 6;
2719 memcpy (scb->u2.scsi_command, cmd->cmnd, 6);
2720 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2721 break;
2722 case READ_CAPACITY:
2723 /* the length of system memory buffer must be exactly 8 bytes */
2724 if (scb->sys_buf_length > 8)
2725 scb->sys_buf_length = 8;
2726 if (bypass_controller)
2728 scb->command = IM_OTHER_SCSI_CMD_CMD;
2729 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2730 scb->u1.scsi_cmd_length = cmd->cmd_len;
2731 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2732 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2734 else
2736 scb->command = IM_READ_CAPACITY_CMD;
2737 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2739 break;
2741 /* Commands that need read-only-mode (system <- device): */
2742 case REQUEST_SENSE:
2743 if (bypass_controller)
2745 scb->command = IM_OTHER_SCSI_CMD_CMD;
2746 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2747 scb->u1.scsi_cmd_length = cmd->cmd_len;
2748 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2749 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2751 else
2753 scb->command = IM_REQUEST_SENSE_CMD;
2754 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT;
2756 break;
2758 /* Commands that need write-only-mode (system -> device): */
2759 case MODE_SELECT:
2760 case MODE_SELECT_10:
2761 IBM_DS(host_index).ldn_modeselect_access[ldn]++;
2762 scb->command = IM_OTHER_SCSI_CMD_CMD;
2763 scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; /*Select needs WRITE-enabled*/
2764 scb->u1.scsi_cmd_length = cmd->cmd_len;
2765 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2766 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2767 break;
2769 /* For other commands, read-only is useful. Most other commands are
2770 running without an input-data-block. */
2771 default:
2772 scb->command = IM_OTHER_SCSI_CMD_CMD;
2773 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2774 scb->u1.scsi_cmd_length = cmd->cmd_len;
2775 memcpy (scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2776 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2777 break;
2779 /*issue scb command, and return */
2780 if (last_scsi_type(host_index)[ldn] == IM_LONG_SCB)
2782 issue_cmd (host_index, virt_to_bus(scb), IM_LONG_SCB | ldn);
2783 IBM_DS(host_index).long_scbs++;
2785 else
2787 issue_cmd (host_index, virt_to_bus(scb), IM_SCB | ldn);
2788 IBM_DS(host_index).scbs++;
2790 return 0;
2793 /*--------------------------------------------------------------------*/
2795 int ibmmca_abort (Scsi_Cmnd * cmd)
2797 /* Abort does not work, as the adapter never generates an interrupt on
2798 * whatever situation is simulated, even when really pending commands
2799 * are running on the adapters' hardware ! */
2801 struct Scsi_Host *shpnt;
2802 unsigned int ldn;
2803 void (*saved_done) (Scsi_Cmnd *);
2804 int target;
2805 int host_index;
2806 int max_pun;
2807 static unsigned long flags;
2808 unsigned long imm_command;
2810 /* return SCSI_ABORT_SNOOZE ; */
2812 #ifdef OLDKERN
2813 save_flags(flags);
2814 cli();
2815 #else
2816 spin_lock_irqsave(&abort_lock, flags);
2817 #endif
2818 shpnt = cmd->host;
2820 /* search for the right hostadapter */
2821 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2823 if (!hosts[host_index])
2824 { /* invalid hostadapter descriptor address */
2825 cmd->result = DID_NO_CONNECT << 16;
2826 if (cmd->scsi_done)
2827 (cmd->scsi_done) (cmd);
2828 return SCSI_ABORT_SNOOZE;
2831 max_pun = subsystem_maxid(host_index);
2833 if (ibm_ansi_order)
2835 target = max_pun - 1 - cmd->target;
2836 if ((target <= subsystem_pun(host_index))&&(cmd->target <= subsystem_pun(host_index)))
2837 target--;
2838 else if ((target >= subsystem_pun(host_index))&&(cmd->target >= subsystem_pun(host_index)))
2839 target++;
2841 else
2842 target = cmd->target;
2844 /*get logical device number, and disable system interrupts */
2845 printk ("IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n",
2846 target, cmd->lun);
2847 ldn = get_ldn(host_index)[target][cmd->lun];
2849 /*if cmd for this ldn has already finished, no need to abort */
2850 if (!ld(host_index)[ldn].cmd)
2852 #ifdef OLDKERN
2853 restore_flags(flags);
2854 #else
2855 spin_unlock_irqrestore(&abort_lock, flags);
2856 #endif
2857 return SCSI_ABORT_NOT_RUNNING;
2860 /* Clear ld.cmd, save done function, install internal done,
2861 * send abort immediate command (this enables sys. interrupts),
2862 * and wait until the interrupt arrives.
2864 saved_done = cmd->scsi_done;
2865 cmd->scsi_done = internal_done;
2866 cmd->SCp.Status = 0;
2867 last_scsi_command(host_index)[ldn] = IM_ABORT_IMM_CMD;
2868 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
2869 imm_command = inl(IM_CMD_REG(host_index));
2870 imm_command &= (unsigned long)(0xffff0000); /* mask reserved stuff */
2871 imm_command |= (unsigned long)(IM_ABORT_IMM_CMD);
2872 /* must wait for attention reg not busy */
2873 while (1)
2875 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
2876 break;
2877 #ifdef OLDKERN
2878 restore_flags (flags);
2879 #else
2880 spin_unlock_irqrestore(&abort_lock, flags);
2881 #endif
2882 #ifdef OLDKERN
2883 save_flags(flags);
2884 cli();
2885 #else
2886 spin_lock_irqsave(&abort_lock, flags);
2887 #endif
2889 /*write registers and enable system interrupts */
2890 outl (imm_command, IM_CMD_REG(host_index));
2891 outb (IM_IMM_CMD | ldn, IM_ATTN_REG(host_index));
2892 #ifdef OLDKERN
2893 restore_flags (flags);
2894 #else
2895 spin_unlock_irqrestore(&abort_lock, flags);
2896 #endif
2898 #ifdef IM_DEBUG_PROBE
2899 printk("IBM MCA SCSI: Abort submitted, waiting for adapter response...\n");
2900 #endif
2901 while (!cmd->SCp.Status)
2902 barrier ();
2903 cmd->scsi_done = saved_done;
2904 /*if abort went well, call saved done, then return success or error */
2905 if (cmd->result == (DID_ABORT << 16))
2907 cmd->result |= DID_ABORT << 16;
2908 if (cmd->scsi_done)
2909 (cmd->scsi_done) (cmd);
2910 ld(host_index)[ldn].cmd = NULL;
2911 #ifdef IM_DEBUG_PROBE
2912 printk("IBM MCA SCSI: Abort finished with success.\n");
2913 #endif
2914 return SCSI_ABORT_SUCCESS;
2916 else
2918 cmd->result |= DID_NO_CONNECT << 16;
2919 if (cmd->scsi_done)
2920 (cmd->scsi_done) (cmd);
2921 ld(host_index)[ldn].cmd = NULL;
2922 #ifdef IM_DEBUG_PROBE
2923 printk("IBM MCA SCSI: Abort failed.\n");
2924 #endif
2925 return SCSI_ABORT_ERROR;
2929 /*--------------------------------------------------------------------*/
2931 int ibmmca_reset (Scsi_Cmnd * cmd, unsigned int reset_flags)
2933 struct Scsi_Host *shpnt;
2934 Scsi_Cmnd *cmd_aid;
2935 int ticks,i;
2936 int host_index;
2937 static unsigned long flags;
2938 unsigned long imm_command;
2940 if (cmd == NULL)
2942 printk("IBM MCA SCSI: Reset called with NULL-command!\n");
2943 return(SCSI_RESET_SNOOZE);
2945 #ifdef OLDKERN
2946 save_flags(flags);
2947 cli();
2948 #else
2949 spin_lock_irqsave(&reset_lock, flags);
2950 #endif
2951 ticks = IM_RESET_DELAY*HZ;
2952 shpnt = cmd->host;
2953 /* search for the right hostadapter */
2954 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2956 if (!hosts[host_index])
2957 { /* invalid hostadapter descriptor address */
2958 if (!local_checking_phase_flag(host_index))
2960 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
2961 if (flags & SCSI_RESET_SYNCHRONOUS)
2963 #ifdef OLDKERN
2964 restore_flags(flags);
2965 #else
2966 spin_unlock_irqrestore(&reset_lock, flags);
2967 #endif
2968 cmd->result = DID_NO_CONNECT << 16;
2969 if (cmd->scsi_done)
2970 (cmd->scsi_done) (cmd);
2972 #endif
2974 return SCSI_ABORT_SNOOZE;
2977 if (local_checking_phase_flag(host_index))
2979 printk("IBM MCA SCSI: unable to reset while checking devices.\n");
2980 #ifdef OLDKERN
2981 restore_flags(flags);
2982 #else
2983 spin_unlock_irqrestore(&reset_lock, flags);
2984 #endif
2985 return SCSI_RESET_SNOOZE;
2988 /* issue reset immediate command to subsystem, and wait for interrupt */
2989 printk("IBM MCA SCSI: resetting all devices.\n");
2990 reset_status(host_index) = IM_RESET_IN_PROGRESS;
2991 last_scsi_command(host_index)[0xf] = IM_RESET_IMM_CMD;
2992 last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
2993 imm_command = inl(IM_CMD_REG(host_index));
2994 imm_command &= (unsigned long)(0xffff0000); /* mask reserved stuff */
2995 imm_command |= (unsigned long)(IM_RESET_IMM_CMD);
2996 /* must wait for attention reg not busy */
2997 while (1)
2999 if (!(inb (IM_STAT_REG(host_index)) & IM_BUSY))
3000 break;
3001 #ifdef OLDKERN
3002 restore_flags(flags);
3003 #else
3004 spin_unlock_irqrestore(&reset_lock, flags);
3005 #endif
3006 #ifdef OLDKERN
3007 save_flags(flags);
3008 cli();
3009 #else
3010 spin_lock_irqsave(&reset_lock, flags);
3011 #endif
3013 /*write registers and enable system interrupts */
3014 outl (imm_command, IM_CMD_REG(host_index));
3015 outb (IM_IMM_CMD | 0xf, IM_ATTN_REG(host_index));
3016 /* wait for interrupt finished or intr_stat register to be set, as the
3017 * interrupt will not be executed, while we are in here! */
3018 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks
3019 && ((inb(IM_INTR_REG(host_index)) & 0x8f)!=0x8f)) {
3020 mdelay(1+999/HZ);
3021 barrier();
3023 /* if reset did not complete, just return an error*/
3024 if (!ticks) {
3025 printk("IBM MCA SCSI: reset did not complete within %d seconds.\n",
3026 IM_RESET_DELAY);
3027 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
3028 #ifdef OLDKERN
3029 restore_flags(flags);
3030 #else
3031 spin_unlock_irqrestore(&reset_lock, flags);
3032 #endif
3033 return SCSI_RESET_ERROR;
3036 if ((inb(IM_INTR_REG(host_index)) & 0x8f)==0x8f)
3037 { /* analysis done by this routine and not by the intr-routine */
3038 if (inb(IM_INTR_REG(host_index))==0xaf)
3039 reset_status(host_index) = IM_RESET_FINISHED_OK_NO_INT;
3040 else if (inb(IM_INTR_REG(host_index))==0xcf)
3041 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
3042 else /* failed, 4get it */
3043 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
3044 outb (IM_EOI | 0xf, IM_ATTN_REG(host_index));
3047 /* if reset failed, just return an error */
3048 if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) {
3049 printk("IBM MCA SCSI: reset failed.\n");
3050 #ifdef OLDKERN
3051 restore_flags(flags);
3052 #else
3053 spin_unlock_irqrestore(&reset_lock, flags);
3054 #endif
3055 return SCSI_RESET_ERROR;
3058 /* so reset finished ok - call outstanding done's, and return success */
3059 printk ("IBM MCA SCSI: Reset successfully completed.\n");
3060 #ifdef OLDKERN
3061 restore_flags(flags);
3062 #else
3063 spin_unlock_irqrestore(&reset_lock, flags);
3064 #endif
3065 for (i = 0; i < MAX_LOG_DEV; i++)
3067 cmd_aid = ld(host_index)[i].cmd;
3068 if (cmd_aid && cmd_aid->scsi_done)
3070 ld(host_index)[i].cmd = NULL;
3071 cmd_aid->result = DID_RESET << 16;
3072 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,132)
3073 if (flags & SCSI_RESET_SYNCHRONOUS)
3075 cmd_aid->result = DID_BUS_BUSY << 16;
3076 if (cmd_aid->scsi_done)
3077 (cmd_aid->scsi_done) (cmd_aid);
3079 #endif
3082 if (flags & SCSI_RESET_SUGGEST_HOST_RESET)
3083 return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
3084 else if (flags & SCSI_RESET_SUGGEST_BUS_RESET)
3085 return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
3086 else
3087 return SCSI_RESET_SUCCESS;
3090 /*--------------------------------------------------------------------*/
3092 int ibmmca_biosparam (Disk * disk, kdev_t dev, int *info)
3094 info[0] = 64;
3095 info[1] = 32;
3096 info[2] = disk->capacity / (info[0] * info[1]);
3097 if (info[2] >= 1024)
3099 info[0] = 128;
3100 info[1] = 63;
3101 info[2] = disk->capacity / (info[0] * info[1]);
3102 if (info[2] >= 1024)
3104 info[0] = 255;
3105 info[1] = 63;
3106 info[2] = disk->capacity / (info[0] * info[1]);
3107 if (info[2] >= 1024)
3108 info[2] = 1023;
3111 return 0;
3114 /* calculate percentage of total accesses on a ldn */
3115 static int ldn_access_load(int host_index, int ldn)
3117 if (IBM_DS(host_index).total_accesses == 0) return (0);
3118 if (IBM_DS(host_index).ldn_access[ldn] == 0) return (0);
3119 return (IBM_DS(host_index).ldn_access[ldn] * 100) / IBM_DS(host_index).total_accesses;
3122 /* calculate total amount of r/w-accesses */
3123 static int ldn_access_total_read_write(int host_index)
3125 int a;
3126 int i;
3128 a = 0;
3129 for (i=0; i<=MAX_LOG_DEV; i++)
3130 a+=IBM_DS(host_index).ldn_read_access[i]+IBM_DS(host_index).ldn_write_access[i];
3131 return(a);
3134 static int ldn_access_total_inquiry(int host_index)
3136 int a;
3137 int i;
3139 a = 0;
3140 for (i=0; i<=MAX_LOG_DEV; i++)
3141 a+=IBM_DS(host_index).ldn_inquiry_access[i];
3142 return(a);
3145 static int ldn_access_total_modeselect(int host_index)
3147 int a;
3148 int i;
3150 a = 0;
3151 for (i=0; i<=MAX_LOG_DEV; i++)
3152 a+=IBM_DS(host_index).ldn_modeselect_access[i];
3153 return(a);
3156 /* routine to display info in the proc-fs-structure (a deluxe feature) */
3157 int ibmmca_proc_info (char *buffer, char **start, off_t offset, int length,
3158 int hostno, int inout)
3160 int len=0;
3161 int i,id,lun,host_index;
3162 struct Scsi_Host *shpnt;
3163 unsigned long flags;
3164 int max_pun;
3166 #ifdef OLDKERN
3167 save_flags(flags);
3168 cli();
3169 #else
3170 spin_lock_irqsave(&proc_lock, flags);
3171 #endif
3173 for (i = 0; hosts[i] && hosts[i]->host_no != hostno; i++);
3174 shpnt = hosts[i];
3175 host_index = i;
3176 if (!shpnt) {
3177 len += sprintf(buffer+len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n", hostno);
3178 return len;
3180 max_pun = subsystem_maxid(host_index);
3182 len += sprintf(buffer+len, "\n IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n",
3183 IBMMCA_SCSI_DRIVER_VERSION);
3184 len += sprintf(buffer+len, " SCSI Access-Statistics:\n");
3185 len += sprintf(buffer+len, " Device Scanning Order....: %s\n",
3186 (ibm_ansi_order) ? "IBM/ANSI" : "New Industry Standard");
3187 #ifdef CONFIG_SCSI_MULTI_LUN
3188 len += sprintf(buffer+len, " Multiple LUN probing.....: Yes\n");
3189 #else
3190 len += sprintf(buffer+len, " Multiple LUN probing.....: No\n");
3191 #endif
3192 len += sprintf(buffer+len, " This Hostnumber..........: %d\n",
3193 hostno);
3194 len += sprintf(buffer+len, " Base I/O-Port............: 0x%x\n",
3195 (unsigned int)(IM_CMD_REG(host_index)));
3196 len += sprintf(buffer+len, " (Shared) IRQ.............: %d\n",
3197 IM_IRQ);
3198 len += sprintf(buffer+len, " SCSI-command set used....: %s\n",
3199 (bypass_controller) ? "software" : "hardware integrated");
3200 len += sprintf(buffer+len, " Total Interrupts.........: %d\n",
3201 IBM_DS(host_index).total_interrupts);
3202 len += sprintf(buffer+len, " Total SCSI Accesses......: %d\n",
3203 IBM_DS(host_index).total_accesses);
3204 len += sprintf(buffer+len, " Total short SCBs.........: %d\n",
3205 IBM_DS(host_index).scbs);
3206 len += sprintf(buffer+len, " Total long SCBs..........: %d\n",
3207 IBM_DS(host_index).long_scbs);
3208 len += sprintf(buffer+len, " Total SCSI READ/WRITE..: %d\n",
3209 ldn_access_total_read_write(host_index));
3210 len += sprintf(buffer+len, " Total SCSI Inquiries...: %d\n",
3211 ldn_access_total_inquiry(host_index));
3212 len += sprintf(buffer+len, " Total SCSI Modeselects.: %d\n",
3213 ldn_access_total_modeselect(host_index));
3214 len += sprintf(buffer+len, " Total SCSI other cmds..: %d\n",
3215 IBM_DS(host_index).total_accesses - ldn_access_total_read_write(host_index)
3216 - ldn_access_total_modeselect(host_index)
3217 - ldn_access_total_inquiry(host_index));
3218 len += sprintf(buffer+len, " Total SCSI command fails.: %d\n\n",
3219 IBM_DS(host_index).total_errors);
3220 len += sprintf(buffer+len, " Logical-Device-Number (LDN) Access-Statistics:\n");
3221 len += sprintf(buffer+len, " LDN | Accesses [%%] | READ | WRITE | ASSIGNMENTS\n");
3222 len += sprintf(buffer+len, " -----|--------------|-----------|-----------|--------------\n");
3223 for (i=0; i<=MAX_LOG_DEV; i++)
3224 len += sprintf(buffer+len, " %2X | %3d | %8d | %8d | %8d\n",
3225 i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i],
3226 IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]);
3227 len += sprintf(buffer+len, " -----------------------------------------------------------\n\n");
3229 len += sprintf(buffer+len, " Dynamical-LDN-Assignment-Statistics:\n");
3230 len += sprintf(buffer+len, " Number of physical SCSI-devices..: %d (+ Adapter)\n",
3231 IBM_DS(host_index).total_scsi_devices);
3232 len += sprintf(buffer+len, " Dynamical Assignment necessary...: %s\n",
3233 IBM_DS(host_index).dyn_flag ? "Yes" : "No ");
3234 len += sprintf(buffer+len, " Next LDN to be assigned..........: 0x%x\n",
3235 next_ldn(host_index));
3236 len += sprintf(buffer+len, " Dynamical assignments done yet...: %d\n",
3237 IBM_DS(host_index).dynamical_assignments);
3239 len += sprintf(buffer+len, "\n Current SCSI-Device-Mapping:\n");
3240 len += sprintf(buffer+len, " Physical SCSI-Device Map Logical SCSI-Device Map\n");
3241 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");
3242 for (id=0; id<max_pun; id++)
3244 len += sprintf(buffer+len, " %2d ",id);
3245 for (lun=0; lun<8; lun++)
3246 len += sprintf(buffer+len,"%2s ",ti_p(get_scsi(host_index)[id][lun]));
3247 len += sprintf(buffer+len, " %2d ",id);
3248 for (lun=0; lun<8; lun++)
3249 len += sprintf(buffer+len,"%2s ",ti_l(get_ldn(host_index)[id][lun]));
3250 len += sprintf(buffer+len,"\n");
3253 len += sprintf(buffer+len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
3254 len += sprintf(buffer+len, " R = CD-ROM, S = Scanner, M = MO-Drive, C = Medium-Changer, + = unprovided LUN,\n");
3255 len += sprintf(buffer+len, " - = nothing found, nothing assigned or unprobed LUN)\n\n");
3257 *start = buffer + offset;
3258 len -= offset;
3259 if (len > length)
3260 len = length;
3261 #ifdef OLDKERN
3262 restore_flags(flags);
3263 #else
3264 spin_unlock_irqrestore(&proc_lock, flags);
3265 #endif
3266 return len;
3269 void ibmmca_scsi_setup (char *str, int *ints)
3271 internal_ibmmca_scsi_setup (str, ints);
3274 static int option_setup(char *str)
3276 int ints[IM_MAX_HOSTS];
3277 char *cur = str;
3278 int i = 1;
3280 while (cur && isdigit(*cur) && i <= IM_MAX_HOSTS) {
3281 ints[i++] = simple_strtoul(cur, NULL, 0);
3282 if ((cur = strchr(cur,',')) != NULL) cur++;
3284 ints[0] = i - 1;
3285 internal_ibmmca_scsi_setup(cur, ints);
3286 return 0;
3289 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,18)
3290 __setup("ibmmcascsi=", option_setup);
3291 #endif
3293 /* Eventually this will go into an include file, but this will be later */
3294 static Scsi_Host_Template driver_template = IBMMCA;
3296 #include "scsi_module.c"
3298 /*--------------------------------------------------------------------*/