aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ibmmca.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/scsi/ibmmca.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/scsi/ibmmca.c')
-rw-r--r--drivers/scsi/ibmmca.c2491
1 files changed, 2491 insertions, 0 deletions
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
new file mode 100644
index 000000000000..a3fdead9bce9
--- /dev/null
+++ b/drivers/scsi/ibmmca.c
@@ -0,0 +1,2491 @@
1/*
2 Low Level Linux Driver for the IBM Microchannel SCSI Subsystem for
3 Linux Kernel >= 2.4.0.
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 Documentation/scsi/ibmmca.txt for a detailed description
8 of this driver, the commandline arguments and the history of its
9 development.
10 See the WWW-page: http://www.uni-mainz.de/~langm000/linux.html for latest
11 updates, info and ADF-files for adapters supported by this driver.
12
13 Alan Cox <alan@redhat.com>
14 Updated for Linux 2.5.45 to use the new error handler, cleaned up the
15 lock macros and did a few unavoidable locking tweaks, plus one locking
16 fix in the irq and completion path.
17
18 */
19
20#include <linux/config.h>
21#ifndef LINUX_VERSION_CODE
22#include <linux/version.h>
23#endif
24#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
25#error "This driver works only with kernel 2.5.45 or higher!"
26#endif
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/types.h>
30#include <linux/ctype.h>
31#include <linux/string.h>
32#include <linux/interrupt.h>
33#include <linux/ioport.h>
34#include <linux/delay.h>
35#include <linux/blkdev.h>
36#include <linux/proc_fs.h>
37#include <linux/stat.h>
38#include <linux/mca.h>
39#include <linux/string.h>
40#include <linux/spinlock.h>
41#include <linux/init.h>
42#include <linux/mca-legacy.h>
43
44#include <asm/system.h>
45#include <asm/io.h>
46
47#include "scsi.h"
48#include <scsi/scsi_host.h>
49#include "ibmmca.h"
50
51/* current version of this driver-source: */
52#define IBMMCA_SCSI_DRIVER_VERSION "4.0b-ac"
53
54/* driver configuration */
55#define IM_MAX_HOSTS 8 /* maximum number of host adapters */
56#define IM_RESET_DELAY 60 /* seconds allowed for a reset */
57
58/* driver debugging - #undef all for normal operation */
59/* if defined: count interrupts and ignore this special one: */
60#undef IM_DEBUG_TIMEOUT //50
61#define TIMEOUT_PUN 0
62#define TIMEOUT_LUN 0
63/* verbose interrupt: */
64#undef IM_DEBUG_INT
65/* verbose queuecommand: */
66#undef IM_DEBUG_CMD
67/* verbose queucommand for specific SCSI-device type: */
68#undef IM_DEBUG_CMD_SPEC_DEV
69/* verbose device probing */
70#undef IM_DEBUG_PROBE
71
72/* device type that shall be displayed on syslog (only during debugging): */
73#define IM_DEBUG_CMD_DEVICE TYPE_TAPE
74
75/* relative addresses of hardware registers on a subsystem */
76#define IM_CMD_REG(hi) (hosts[(hi)]->io_port) /*Command Interface, (4 bytes long) */
77#define IM_ATTN_REG(hi) (hosts[(hi)]->io_port+4) /*Attention (1 byte) */
78#define IM_CTR_REG(hi) (hosts[(hi)]->io_port+5) /*Basic Control (1 byte) */
79#define IM_INTR_REG(hi) (hosts[(hi)]->io_port+6) /*Interrupt Status (1 byte, r/o) */
80#define IM_STAT_REG(hi) (hosts[(hi)]->io_port+7) /*Basic Status (1 byte, read only) */
81
82/* basic I/O-port of first adapter */
83#define IM_IO_PORT 0x3540
84/* maximum number of hosts that can be found */
85#define IM_N_IO_PORT 8
86
87/*requests going into the upper nibble of the Attention register */
88/*note: the lower nibble specifies the device(0-14), or subsystem(15) */
89#define IM_IMM_CMD 0x10 /*immediate command */
90#define IM_SCB 0x30 /*Subsystem Control Block command */
91#define IM_LONG_SCB 0x40 /*long Subsystem Control Block command */
92#define IM_EOI 0xe0 /*end-of-interrupt request */
93
94/*values for bits 7,1,0 of Basic Control reg. (bits 6-2 reserved) */
95#define IM_HW_RESET 0x80 /*hardware reset */
96#define IM_ENABLE_DMA 0x02 /*enable subsystem's busmaster DMA */
97#define IM_ENABLE_INTR 0x01 /*enable interrupts to the system */
98
99/*to interpret the upper nibble of Interrupt Status register */
100/*note: the lower nibble specifies the device(0-14), or subsystem(15) */
101#define IM_SCB_CMD_COMPLETED 0x10
102#define IM_SCB_CMD_COMPLETED_WITH_RETRIES 0x50
103#define IM_LOOP_SCATTER_BUFFER_FULL 0x60
104#define IM_ADAPTER_HW_FAILURE 0x70
105#define IM_IMMEDIATE_CMD_COMPLETED 0xa0
106#define IM_CMD_COMPLETED_WITH_FAILURE 0xc0
107#define IM_CMD_ERROR 0xe0
108#define IM_SOFTWARE_SEQUENCING_ERROR 0xf0
109
110/*to interpret bits 3-0 of Basic Status register (bits 7-4 reserved) */
111#define IM_CMD_REG_FULL 0x08
112#define IM_CMD_REG_EMPTY 0x04
113#define IM_INTR_REQUEST 0x02
114#define IM_BUSY 0x01
115
116/*immediate commands (word written into low 2 bytes of command reg) */
117#define IM_RESET_IMM_CMD 0x0400
118#define IM_FEATURE_CTR_IMM_CMD 0x040c
119#define IM_DMA_PACING_IMM_CMD 0x040d
120#define IM_ASSIGN_IMM_CMD 0x040e
121#define IM_ABORT_IMM_CMD 0x040f
122#define IM_FORMAT_PREP_IMM_CMD 0x0417
123
124/*SCB (Subsystem Control Block) structure */
125struct im_scb {
126 unsigned short command; /*command word (read, etc.) */
127 unsigned short enable; /*enable word, modifies cmd */
128 union {
129 unsigned long log_blk_adr; /*block address on SCSI device */
130 unsigned char scsi_cmd_length; /*6,10,12, for other scsi cmd */
131 } u1;
132 unsigned long sys_buf_adr; /*physical system memory adr */
133 unsigned long sys_buf_length; /*size of sys mem buffer */
134 unsigned long tsb_adr; /*Termination Status Block adr */
135 unsigned long scb_chain_adr; /*optional SCB chain address */
136 union {
137 struct {
138 unsigned short count; /*block count, on SCSI device */
139 unsigned short length; /*block length, on SCSI device */
140 } blk;
141 unsigned char scsi_command[12]; /*other scsi command */
142 } u2;
143};
144
145/*structure scatter-gather element (for list of system memory areas) */
146struct im_sge {
147 void *address;
148 unsigned long byte_length;
149};
150
151/*structure returned by a get_pos_info command: */
152struct im_pos_info {
153 unsigned short pos_id; /* adapter id */
154 unsigned char pos_3a; /* pos 3 (if pos 6 = 0) */
155 unsigned char pos_2; /* pos 2 */
156 unsigned char int_level; /* interrupt level IRQ 11 or 14 */
157 unsigned char pos_4a; /* pos 4 (if pos 6 = 0) */
158 unsigned short connector_size; /* MCA connector size: 16 or 32 Bit */
159 unsigned char num_luns; /* number of supported luns per device */
160 unsigned char num_puns; /* number of supported puns */
161 unsigned char pacing_factor; /* pacing factor */
162 unsigned char num_ldns; /* number of ldns available */
163 unsigned char eoi_off; /* time EOI and interrupt inactive */
164 unsigned char max_busy; /* time between reset and busy on */
165 unsigned short cache_stat; /* ldn cachestat. Bit=1 = not cached */
166 unsigned short retry_stat; /* retry status of ldns. Bit=1=disabled */
167 unsigned char pos_4b; /* pos 4 (if pos 6 = 1) */
168 unsigned char pos_3b; /* pos 3 (if pos 6 = 1) */
169 unsigned char pos_6; /* pos 6 */
170 unsigned char pos_5; /* pos 5 */
171 unsigned short max_overlap; /* maximum overlapping requests */
172 unsigned short num_bus; /* number of SCSI-busses */
173};
174
175/*values for SCB command word */
176#define IM_NO_SYNCHRONOUS 0x0040 /*flag for any command */
177#define IM_NO_DISCONNECT 0x0080 /*flag for any command */
178#define IM_READ_DATA_CMD 0x1c01
179#define IM_WRITE_DATA_CMD 0x1c02
180#define IM_READ_VERIFY_CMD 0x1c03
181#define IM_WRITE_VERIFY_CMD 0x1c04
182#define IM_REQUEST_SENSE_CMD 0x1c08
183#define IM_READ_CAPACITY_CMD 0x1c09
184#define IM_DEVICE_INQUIRY_CMD 0x1c0b
185#define IM_READ_LOGICAL_CMD 0x1c2a
186#define IM_OTHER_SCSI_CMD_CMD 0x241f
187
188/* unused, but supported, SCB commands */
189#define IM_GET_COMMAND_COMPLETE_STATUS_CMD 0x1c07 /* command status */
190#define IM_GET_POS_INFO_CMD 0x1c0a /* returns neat stuff */
191#define IM_READ_PREFETCH_CMD 0x1c31 /* caching controller only */
192#define IM_FOMAT_UNIT_CMD 0x1c16 /* format unit */
193#define IM_REASSIGN_BLOCK_CMD 0x1c18 /* in case of error */
194
195/*values to set bits in the enable word of SCB */
196#define IM_READ_CONTROL 0x8000
197#define IM_REPORT_TSB_ONLY_ON_ERROR 0x4000
198#define IM_RETRY_ENABLE 0x2000
199#define IM_POINTER_TO_LIST 0x1000
200#define IM_SUPRESS_EXCEPTION_SHORT 0x0400
201#define IM_BYPASS_BUFFER 0x0200
202#define IM_CHAIN_ON_NO_ERROR 0x0001
203
204/*TSB (Termination Status Block) structure */
205struct im_tsb {
206 unsigned short end_status;
207 unsigned short reserved1;
208 unsigned long residual_byte_count;
209 unsigned long sg_list_element_adr;
210 unsigned short status_length;
211 unsigned char dev_status;
212 unsigned char cmd_status;
213 unsigned char dev_error;
214 unsigned char cmd_error;
215 unsigned short reserved2;
216 unsigned short reserved3;
217 unsigned short low_of_last_scb_adr;
218 unsigned short high_of_last_scb_adr;
219};
220
221/*subsystem uses interrupt request level 14 */
222#define IM_IRQ 14
223/*SCSI-2 F/W may evade to interrupt 11 */
224#define IM_IRQ_FW 11
225
226/* Model 95 has an additional alphanumeric display, which can be used
227 to display SCSI-activities. 8595 models do not have any disk led, which
228 makes this feature quite useful.
229 The regular PS/2 disk led is turned on/off by bits 6,7 of system
230 control port. */
231
232/* LED display-port (actually, last LED on display) */
233#define MOD95_LED_PORT 0x108
234/* system-control-register of PS/2s with diskindicator */
235#define PS2_SYS_CTR 0x92
236/* activity displaying methods */
237#define LED_DISP 1
238#define LED_ADISP 2
239#define LED_ACTIVITY 4
240/* failed intr */
241#define CMD_FAIL 255
242
243/* The SCSI-ID(!) of the accessed SCSI-device is shown on PS/2-95 machines' LED
244 displays. ldn is no longer displayed here, because the ldn mapping is now
245 done dynamically and the ldn <-> pun,lun maps can be looked-up at boottime
246 or during uptime in /proc/scsi/ibmmca/<host_no> in case of trouble,
247 interest, debugging or just for having fun. The left number gives the
248 host-adapter number and the right shows the accessed SCSI-ID. */
249
250/* display_mode is set by the ibmmcascsi= command line arg */
251static int display_mode = 0;
252/* set default adapter timeout */
253static unsigned int adapter_timeout = 45;
254/* for probing on feature-command: */
255static unsigned int global_command_error_excuse = 0;
256/* global setting by command line for adapter_speed */
257static int global_adapter_speed = 0; /* full speed by default */
258
259/* Panel / LED on, do it right for F/W addressin, too. adisplay will
260 * just ignore ids>7, as the panel has only 7 digits available */
261#define PS2_DISK_LED_ON(ad,id) { if (display_mode & LED_DISP) { if (id>9) \
262 outw((ad+48)|((id+55)<<8), MOD95_LED_PORT ); else \
263 outw((ad+48)|((id+48)<<8), MOD95_LED_PORT ); } else \
264 if (display_mode & LED_ADISP) { if (id<7) outb((char)(id+48),MOD95_LED_PORT+1+id); \
265 outb((char)(ad+48), MOD95_LED_PORT); } \
266 if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
267 outb(inb(PS2_SYS_CTR) | 0xc0, PS2_SYS_CTR); }
268
269/* Panel / LED off */
270/* bug fixed, Dec 15, 1997, where | was replaced by & here */
271#define PS2_DISK_LED_OFF() { if (display_mode & LED_DISP) \
272 outw(0x2020, MOD95_LED_PORT ); else if (display_mode & LED_ADISP) { \
273 outl(0x20202020,MOD95_LED_PORT); outl(0x20202020,MOD95_LED_PORT+4); } \
274 if ((display_mode & LED_ACTIVITY)||(!display_mode)) \
275 outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); }
276
277/*list of supported subsystems */
278struct subsys_list_struct {
279 unsigned short mca_id;
280 char *description;
281};
282
283/* types of different supported hardware that goes to hostdata special */
284#define IBM_SCSI2_FW 0
285#define IBM_7568_WCACHE 1
286#define IBM_EXP_UNIT 2
287#define IBM_SCSI_WCACHE 3
288#define IBM_SCSI 4
289
290/* other special flags for hostdata structure */
291#define FORCED_DETECTION 100
292#define INTEGRATED_SCSI 101
293
294/* List of possible IBM-SCSI-adapters */
295static struct subsys_list_struct subsys_list[] = {
296 {0x8efc, "IBM SCSI-2 F/W Adapter"}, /* special = 0 */
297 {0x8efd, "IBM 7568 Industrial Computer SCSI Adapter w/Cache"}, /* special = 1 */
298 {0x8ef8, "IBM Expansion Unit SCSI Controller"}, /* special = 2 */
299 {0x8eff, "IBM SCSI Adapter w/Cache"}, /* special = 3 */
300 {0x8efe, "IBM SCSI Adapter"}, /* special = 4 */
301};
302
303/* Max number of logical devices (can be up from 0 to 14). 15 is the address
304of the adapter itself. */
305#define MAX_LOG_DEV 15
306
307/*local data for a logical device */
308struct logical_device {
309 struct im_scb scb; /* SCSI-subsystem-control-block structure */
310 struct im_tsb tsb; /* SCSI command complete status block structure */
311 struct im_sge sge[16]; /* scatter gather list structure */
312 unsigned char buf[256]; /* SCSI command return data buffer */
313 Scsi_Cmnd *cmd; /* SCSI-command that is currently in progress */
314 int device_type; /* type of the SCSI-device. See include/scsi/scsi.h
315 for interpretation of the possible values */
316 int block_length; /* blocksize of a particular logical SCSI-device */
317 int cache_flag; /* 1 if this is uncached, 0 if cache is present for ldn */
318 int retry_flag; /* 1 if adapter retry is disabled, 0 if enabled */
319};
320
321/* statistics of the driver during operations (for proc_info) */
322struct Driver_Statistics {
323 /* SCSI statistics on the adapter */
324 int ldn_access[MAX_LOG_DEV + 1]; /* total accesses on a ldn */
325 int ldn_read_access[MAX_LOG_DEV + 1]; /* total read-access on a ldn */
326 int ldn_write_access[MAX_LOG_DEV + 1]; /* total write-access on a ldn */
327 int ldn_inquiry_access[MAX_LOG_DEV + 1]; /* total inquiries on a ldn */
328 int ldn_modeselect_access[MAX_LOG_DEV + 1]; /* total mode selects on ldn */
329 int scbs; /* short SCBs queued */
330 int long_scbs; /* long SCBs queued */
331 int total_accesses; /* total accesses on all ldns */
332 int total_interrupts; /* total interrupts (should be
333 same as total_accesses) */
334 int total_errors; /* command completed with error */
335 /* dynamical assignment statistics */
336 int total_scsi_devices; /* number of physical pun,lun */
337 int dyn_flag; /* flag showing dynamical mode */
338 int dynamical_assignments; /* number of remappings of ldns */
339 int ldn_assignments[MAX_LOG_DEV + 1]; /* number of remappings of each
340 ldn */
341};
342
343/* data structure for each host adapter */
344struct ibmmca_hostdata {
345 /* array of logical devices: */
346 struct logical_device _ld[MAX_LOG_DEV + 1];
347 /* array to convert (pun, lun) into logical device number: */
348 unsigned char _get_ldn[16][8];
349 /*array that contains the information about the physical SCSI-devices
350 attached to this host adapter: */
351 unsigned char _get_scsi[16][8];
352 /* used only when checking logical devices: */
353 int _local_checking_phase_flag;
354 /* report received interrupt: */
355 int _got_interrupt;
356 /* report termination-status of SCSI-command: */
357 int _stat_result;
358 /* reset status (used only when doing reset): */
359 int _reset_status;
360 /* code of the last SCSI command (needed for panic info): */
361 int _last_scsi_command[MAX_LOG_DEV + 1];
362 /* identifier of the last SCSI-command type */
363 int _last_scsi_type[MAX_LOG_DEV + 1];
364 /* last blockcount */
365 int _last_scsi_blockcount[MAX_LOG_DEV + 1];
366 /* last locgical block address */
367 unsigned long _last_scsi_logical_block[MAX_LOG_DEV + 1];
368 /* Counter that points on the next reassignable ldn for dynamical
369 remapping. The default value is 7, that is the first reassignable
370 number in the list at boottime: */
371 int _next_ldn;
372 /* Statistics-structure for this IBM-SCSI-host: */
373 struct Driver_Statistics _IBM_DS;
374 /* This hostadapters pos-registers pos2 until pos6 */
375 unsigned int _pos[8];
376 /* assign a special variable, that contains dedicated info about the
377 adaptertype */
378 int _special;
379 /* connector size on the MCA bus */
380 int _connector_size;
381 /* synchronous SCSI transfer rate bitpattern */
382 int _adapter_speed;
383};
384
385/* macros to access host data structure */
386#define subsystem_pun(hi) (hosts[(hi)]->this_id)
387#define subsystem_maxid(hi) (hosts[(hi)]->max_id)
388#define ld(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_ld)
389#define get_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_ldn)
390#define get_scsi(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_get_scsi)
391#define local_checking_phase_flag(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_local_checking_phase_flag)
392#define got_interrupt(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_got_interrupt)
393#define stat_result(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_stat_result)
394#define reset_status(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_reset_status)
395#define last_scsi_command(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_command)
396#define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
397#define last_scsi_blockcount(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_blockcount)
398#define last_scsi_logical_block(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_logical_block)
399#define last_scsi_type(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_last_scsi_type)
400#define next_ldn(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_next_ldn)
401#define IBM_DS(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_IBM_DS)
402#define special(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_special)
403#define subsystem_connector_size(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_connector_size)
404#define adapter_speed(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_adapter_speed)
405#define pos2(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[2])
406#define pos3(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[3])
407#define pos4(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[4])
408#define pos5(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[5])
409#define pos6(hi) (((struct ibmmca_hostdata *) hosts[(hi)]->hostdata)->_pos[6])
410
411/* Define a arbitrary number as subsystem-marker-type. This number is, as
412 described in the ANSI-SCSI-standard, not occupied by other device-types. */
413#define TYPE_IBM_SCSI_ADAPTER 0x2F
414
415/* Define 0xFF for no device type, because this type is not defined within
416 the ANSI-SCSI-standard, therefore, it can be used and should not cause any
417 harm. */
418#define TYPE_NO_DEVICE 0xFF
419
420/* define medium-changer. If this is not defined previously, e.g. Linux
421 2.0.x, define this type here. */
422#ifndef TYPE_MEDIUM_CHANGER
423#define TYPE_MEDIUM_CHANGER 0x08
424#endif
425
426/* define possible operations for the immediate_assign command */
427#define SET_LDN 0
428#define REMOVE_LDN 1
429
430/* ldn which is used to probe the SCSI devices */
431#define PROBE_LDN 0
432
433/* reset status flag contents */
434#define IM_RESET_NOT_IN_PROGRESS 0
435#define IM_RESET_IN_PROGRESS 1
436#define IM_RESET_FINISHED_OK 2
437#define IM_RESET_FINISHED_FAIL 3
438#define IM_RESET_NOT_IN_PROGRESS_NO_INT 4
439#define IM_RESET_FINISHED_OK_NO_INT 5
440
441/* define undefined SCSI-command */
442#define NO_SCSI 0xffff
443
444/*-----------------------------------------------------------------------*/
445
446/* if this is nonzero, ibmmcascsi option has been passed to the kernel */
447static int io_port[IM_MAX_HOSTS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
448static int scsi_id[IM_MAX_HOSTS] = { 7, 7, 7, 7, 7, 7, 7, 7 };
449
450/* fill module-parameters only, when this define is present.
451 (that is kernel version 2.1.x) */
452#if defined(MODULE)
453static char *boot_options = NULL;
454module_param(boot_options, charp, 0);
455module_param_array(io_port, int, NULL, 0);
456module_param_array(scsi_id, int, NULL, 0);
457
458#if 0 /* FIXME: No longer exist? --RR */
459MODULE_PARM(display, "1i");
460MODULE_PARM(adisplay, "1i");
461MODULE_PARM(normal, "1i");
462MODULE_PARM(ansi, "1i");
463#endif
464#endif
465/*counter of concurrent disk read/writes, to turn on/off disk led */
466static int disk_rw_in_progress = 0;
467
468/* host information */
469static int found = 0;
470static struct Scsi_Host *hosts[IM_MAX_HOSTS + 1] = {
471 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
472};
473static unsigned int pos[8]; /* whole pos register-line for diagnosis */
474/* Taking into account the additions, made by ZP Gu.
475 * This selects now the preset value from the configfile and
476 * offers the 'normal' commandline option to be accepted */
477#ifdef CONFIG_IBMMCA_SCSI_ORDER_STANDARD
478static char ibm_ansi_order = 1;
479#else
480static char ibm_ansi_order = 0;
481#endif
482
483static void issue_cmd(int, unsigned long, unsigned char);
484static void internal_done(Scsi_Cmnd * cmd);
485static void check_devices(int, int);
486static int immediate_assign(int, unsigned int, unsigned int, unsigned int, unsigned int);
487static int immediate_feature(int, unsigned int, unsigned int);
488#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
489static int immediate_reset(int, unsigned int);
490#endif
491static int device_inquiry(int, int);
492static int read_capacity(int, int);
493static int get_pos_info(int);
494static char *ti_p(int);
495static char *ti_l(int);
496static char *ibmrate(unsigned int, int);
497static int probe_display(int);
498static int probe_bus_mode(int);
499static int device_exists(int, int, int *, int *);
500static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *, int, int, int, char *);
501static int option_setup(char *);
502/* local functions needed for proc_info */
503static int ldn_access_load(int, int);
504static int ldn_access_total_read_write(int);
505
506static irqreturn_t interrupt_handler(int irq, void *dev_id,
507 struct pt_regs *regs)
508{
509 int host_index, ihost_index;
510 unsigned int intr_reg;
511 unsigned int cmd_result;
512 unsigned int ldn;
513 Scsi_Cmnd *cmd;
514 int lastSCSI;
515 struct Scsi_Host *dev = dev_id;
516
517 spin_lock(dev->host_lock);
518 /* search for one adapter-response on shared interrupt */
519 for (host_index = 0; hosts[host_index] && !(inb(IM_STAT_REG(host_index)) & IM_INTR_REQUEST); host_index++);
520 /* return if some other device on this IRQ caused the interrupt */
521 if (!hosts[host_index]) {
522 spin_unlock(dev->host_lock);
523 return IRQ_NONE;
524 }
525
526 /* the reset-function already did all the job, even ints got
527 renabled on the subsystem, so just return */
528 if ((reset_status(host_index) == IM_RESET_NOT_IN_PROGRESS_NO_INT) || (reset_status(host_index) == IM_RESET_FINISHED_OK_NO_INT)) {
529 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS;
530 spin_unlock(dev->host_lock);
531 return IRQ_HANDLED;
532 }
533
534 /*must wait for attention reg not busy, then send EOI to subsystem */
535 while (1) {
536 if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
537 break;
538 cpu_relax();
539 }
540 ihost_index = host_index;
541 /*get command result and logical device */
542 intr_reg = (unsigned char) (inb(IM_INTR_REG(ihost_index)));
543 cmd_result = intr_reg & 0xf0;
544 ldn = intr_reg & 0x0f;
545 /* get the last_scsi_command here */
546 lastSCSI = last_scsi_command(ihost_index)[ldn];
547 outb(IM_EOI | ldn, IM_ATTN_REG(ihost_index));
548
549 /*these should never happen (hw fails, or a local programming bug) */
550 if (!global_command_error_excuse) {
551 switch (cmd_result) {
552 /* Prevent from Ooopsing on error to show the real reason */
553 case IM_ADAPTER_HW_FAILURE:
554 case IM_SOFTWARE_SEQUENCING_ERROR:
555 case IM_CMD_ERROR:
556 printk(KERN_ERR "IBM MCA SCSI: Fatal Subsystem ERROR!\n");
557 printk(KERN_ERR " Last cmd=0x%x, ena=%x, len=", lastSCSI, ld(ihost_index)[ldn].scb.enable);
558 if (ld(ihost_index)[ldn].cmd)
559 printk("%ld/%ld,", (long) (ld(ihost_index)[ldn].cmd->request_bufflen), (long) (ld(ihost_index)[ldn].scb.sys_buf_length));
560 else
561 printk("none,");
562 if (ld(ihost_index)[ldn].cmd)
563 printk("Blocksize=%d", ld(ihost_index)[ldn].scb.u2.blk.length);
564 else
565 printk("Blocksize=none");
566 printk(", host=0x%x, ldn=0x%x\n", ihost_index, ldn);
567 if (ld(ihost_index)[ldn].cmd) {
568 printk(KERN_ERR "Blockcount=%d/%d\n", last_scsi_blockcount(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u2.blk.count);
569 printk(KERN_ERR "Logical block=%lx/%lx\n", last_scsi_logical_block(ihost_index)[ldn], ld(ihost_index)[ldn].scb.u1.log_blk_adr);
570 }
571 printk(KERN_ERR "Reason given: %s\n", (cmd_result == IM_ADAPTER_HW_FAILURE) ? "HARDWARE FAILURE" : (cmd_result == IM_SOFTWARE_SEQUENCING_ERROR) ? "SOFTWARE SEQUENCING ERROR" : (cmd_result == IM_CMD_ERROR) ? "COMMAND ERROR" : "UNKNOWN");
572 /* if errors appear, enter this section to give detailed info */
573 printk(KERN_ERR "IBM MCA SCSI: Subsystem Error-Status follows:\n");
574 printk(KERN_ERR " Command Type................: %x\n", last_scsi_type(ihost_index)[ldn]);
575 printk(KERN_ERR " Attention Register..........: %x\n", inb(IM_ATTN_REG(ihost_index)));
576 printk(KERN_ERR " Basic Control Register......: %x\n", inb(IM_CTR_REG(ihost_index)));
577 printk(KERN_ERR " Interrupt Status Register...: %x\n", intr_reg);
578 printk(KERN_ERR " Basic Status Register.......: %x\n", inb(IM_STAT_REG(ihost_index)));
579 if ((last_scsi_type(ihost_index)[ldn] == IM_SCB) || (last_scsi_type(ihost_index)[ldn] == IM_LONG_SCB)) {
580 printk(KERN_ERR " SCB-Command.................: %x\n", ld(ihost_index)[ldn].scb.command);
581 printk(KERN_ERR " SCB-Enable..................: %x\n", ld(ihost_index)[ldn].scb.enable);
582 printk(KERN_ERR " SCB-logical block address...: %lx\n", ld(ihost_index)[ldn].scb.u1.log_blk_adr);
583 printk(KERN_ERR " SCB-system buffer address...: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_adr);
584 printk(KERN_ERR " SCB-system buffer length....: %lx\n", ld(ihost_index)[ldn].scb.sys_buf_length);
585 printk(KERN_ERR " SCB-tsb address.............: %lx\n", ld(ihost_index)[ldn].scb.tsb_adr);
586 printk(KERN_ERR " SCB-Chain address...........: %lx\n", ld(ihost_index)[ldn].scb.scb_chain_adr);
587 printk(KERN_ERR " SCB-block count.............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.count);
588 printk(KERN_ERR " SCB-block length............: %x\n", ld(ihost_index)[ldn].scb.u2.blk.length);
589 }
590 printk(KERN_ERR " Send this report to the maintainer.\n");
591 panic("IBM MCA SCSI: Fatal error message from the subsystem (0x%X,0x%X)!\n", lastSCSI, cmd_result);
592 break;
593 }
594 } else {
595 /* The command error handling is made silent, but we tell the
596 * calling function, that there is a reported error from the
597 * adapter. */
598 switch (cmd_result) {
599 case IM_ADAPTER_HW_FAILURE:
600 case IM_SOFTWARE_SEQUENCING_ERROR:
601 case IM_CMD_ERROR:
602 global_command_error_excuse = CMD_FAIL;
603 break;
604 default:
605 global_command_error_excuse = 0;
606 break;
607 }
608 }
609 /* if no panic appeared, increase the interrupt-counter */
610 IBM_DS(ihost_index).total_interrupts++;
611 /*only for local checking phase */
612 if (local_checking_phase_flag(ihost_index)) {
613 stat_result(ihost_index) = cmd_result;
614 got_interrupt(ihost_index) = 1;
615 reset_status(ihost_index) = IM_RESET_FINISHED_OK;
616 last_scsi_command(ihost_index)[ldn] = NO_SCSI;
617 spin_unlock(dev->host_lock);
618 return IRQ_HANDLED;
619 }
620 /* handling of commands coming from upper level of scsi driver */
621 if (last_scsi_type(ihost_index)[ldn] == IM_IMM_CMD) {
622 /* verify ldn, and may handle rare reset immediate command */
623 if ((reset_status(ihost_index) == IM_RESET_IN_PROGRESS) && (last_scsi_command(ihost_index)[ldn] == IM_RESET_IMM_CMD)) {
624 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) {
625 disk_rw_in_progress = 0;
626 PS2_DISK_LED_OFF();
627 reset_status(ihost_index) = IM_RESET_FINISHED_FAIL;
628 } else {
629 /*reset disk led counter, turn off disk led */
630 disk_rw_in_progress = 0;
631 PS2_DISK_LED_OFF();
632 reset_status(ihost_index) = IM_RESET_FINISHED_OK;
633 }
634 stat_result(ihost_index) = cmd_result;
635 last_scsi_command(ihost_index)[ldn] = NO_SCSI;
636 last_scsi_type(ihost_index)[ldn] = 0;
637 spin_unlock(dev->host_lock);
638 return IRQ_HANDLED;
639 } else if (last_scsi_command(ihost_index)[ldn] == IM_ABORT_IMM_CMD) {
640 /* react on SCSI abort command */
641#ifdef IM_DEBUG_PROBE
642 printk("IBM MCA SCSI: Interrupt from SCSI-abort.\n");
643#endif
644 disk_rw_in_progress = 0;
645 PS2_DISK_LED_OFF();
646 cmd = ld(ihost_index)[ldn].cmd;
647 ld(ihost_index)[ldn].cmd = NULL;
648 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE)
649 cmd->result = DID_NO_CONNECT << 16;
650 else
651 cmd->result = DID_ABORT << 16;
652 stat_result(ihost_index) = cmd_result;
653 last_scsi_command(ihost_index)[ldn] = NO_SCSI;
654 last_scsi_type(ihost_index)[ldn] = 0;
655 if (cmd->scsi_done)
656 (cmd->scsi_done) (cmd); /* should be the internal_done */
657 spin_unlock(dev->host_lock);
658 return IRQ_HANDLED;
659 } else {
660 disk_rw_in_progress = 0;
661 PS2_DISK_LED_OFF();
662 reset_status(ihost_index) = IM_RESET_FINISHED_OK;
663 stat_result(ihost_index) = cmd_result;
664 last_scsi_command(ihost_index)[ldn] = NO_SCSI;
665 spin_unlock(dev->host_lock);
666 return IRQ_HANDLED;
667 }
668 }
669 last_scsi_command(ihost_index)[ldn] = NO_SCSI;
670 last_scsi_type(ihost_index)[ldn] = 0;
671 cmd = ld(ihost_index)[ldn].cmd;
672 ld(ihost_index)[ldn].cmd = NULL;
673#ifdef IM_DEBUG_TIMEOUT
674 if (cmd) {
675 if ((cmd->target == TIMEOUT_PUN) && (cmd->device->lun == TIMEOUT_LUN)) {
676 printk("IBM MCA SCSI: Ignoring interrupt from pun=%x, lun=%x.\n", cmd->target, cmd->device->lun);
677 return IRQ_HANDLED;
678 }
679 }
680#endif
681 /*if no command structure, just return, else clear cmd */
682 if (!cmd)
683 {
684 spin_unlock(dev->host_lock);
685 return IRQ_HANDLED;
686 }
687
688#ifdef IM_DEBUG_INT
689 printk("cmd=%02x ireg=%02x ds=%02x cs=%02x de=%02x ce=%02x\n", cmd->cmnd[0], intr_reg, ld(ihost_index)[ldn].tsb.dev_status, ld(ihost_index)[ldn].tsb.cmd_status, ld(ihost_index)[ldn].tsb.dev_error, ld(ihost_index)[ldn].tsb.cmd_error);
690#endif
691 /*if this is end of media read/write, may turn off PS/2 disk led */
692 if ((ld(ihost_index)[ldn].device_type != TYPE_NO_LUN) && (ld(ihost_index)[ldn].device_type != TYPE_NO_DEVICE)) {
693 /* only access this, if there was a valid device addressed */
694 if (--disk_rw_in_progress == 0)
695 PS2_DISK_LED_OFF();
696 }
697
698 /* IBM describes the status-mask to be 0x1e, but this is not conform
699 * with SCSI-definition, I suppose, the reason for it is that IBM
700 * adapters do not support CMD_TERMINATED, TASK_SET_FULL and
701 * ACA_ACTIVE as returning statusbyte information. (ML) */
702 if (cmd_result == IM_CMD_COMPLETED_WITH_FAILURE) {
703 cmd->result = (unsigned char) (ld(ihost_index)[ldn].tsb.dev_status & 0x1e);
704 IBM_DS(ihost_index).total_errors++;
705 } else
706 cmd->result = 0;
707 /* write device status into cmd->result, and call done function */
708 if (lastSCSI == NO_SCSI) { /* unexpected interrupt :-( */
709 cmd->result |= DID_BAD_INTR << 16;
710 printk("IBM MCA SCSI: WARNING - Interrupt from non-pending SCSI-command!\n");
711 } else /* things went right :-) */
712 cmd->result |= DID_OK << 16;
713 if (cmd->scsi_done)
714 (cmd->scsi_done) (cmd);
715 spin_unlock(dev->host_lock);
716 return IRQ_HANDLED;
717}
718
719static void issue_cmd(int host_index, unsigned long cmd_reg, unsigned char attn_reg)
720{
721 unsigned long flags;
722 /* must wait for attention reg not busy */
723 while (1) {
724 spin_lock_irqsave(hosts[host_index]->host_lock, flags);
725 if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
726 break;
727 spin_unlock_irqrestore(hosts[host_index]->host_lock, flags);
728 }
729 /* write registers and enable system interrupts */
730 outl(cmd_reg, IM_CMD_REG(host_index));
731 outb(attn_reg, IM_ATTN_REG(host_index));
732 spin_unlock_irqrestore(hosts[host_index]->host_lock, flags);
733}
734
735static void internal_done(Scsi_Cmnd * cmd)
736{
737 cmd->SCp.Status++;
738 return;
739}
740
741/* SCSI-SCB-command for device_inquiry */
742static int device_inquiry(int host_index, int ldn)
743{
744 int retr;
745 struct im_scb *scb;
746 struct im_tsb *tsb;
747 unsigned char *buf;
748
749 scb = &(ld(host_index)[ldn].scb);
750 tsb = &(ld(host_index)[ldn].tsb);
751 buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
752 ld(host_index)[ldn].tsb.dev_status = 0; /* prepare statusblock */
753 for (retr = 0; retr < 3; retr++) {
754 /* fill scb with inquiry command */
755 scb->command = IM_DEVICE_INQUIRY_CMD | IM_NO_DISCONNECT;
756 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
757 last_scsi_command(host_index)[ldn] = IM_DEVICE_INQUIRY_CMD;
758 last_scsi_type(host_index)[ldn] = IM_SCB;
759 scb->sys_buf_adr = isa_virt_to_bus(buf);
760 scb->sys_buf_length = 255; /* maximum bufferlength gives max info */
761 scb->tsb_adr = isa_virt_to_bus(tsb);
762 /* issue scb to passed ldn, and busy wait for interrupt */
763 got_interrupt(host_index) = 0;
764 issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
765 while (!got_interrupt(host_index))
766 barrier();
767
768 /*if command succesful, break */
769 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
770 return 1;
771 }
772 /*if all three retries failed, return "no device at this ldn" */
773 if (retr >= 3)
774 return 0;
775 else
776 return 1;
777}
778
779static int read_capacity(int host_index, int ldn)
780{
781 int retr;
782 struct im_scb *scb;
783 struct im_tsb *tsb;
784 unsigned char *buf;
785
786 scb = &(ld(host_index)[ldn].scb);
787 tsb = &(ld(host_index)[ldn].tsb);
788 buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
789 ld(host_index)[ldn].tsb.dev_status = 0;
790 for (retr = 0; retr < 3; retr++) {
791 /*fill scb with read capacity command */
792 scb->command = IM_READ_CAPACITY_CMD;
793 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_READ_CONTROL | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
794 last_scsi_command(host_index)[ldn] = IM_READ_CAPACITY_CMD;
795 last_scsi_type(host_index)[ldn] = IM_SCB;
796 scb->sys_buf_adr = isa_virt_to_bus(buf);
797 scb->sys_buf_length = 8;
798 scb->tsb_adr = isa_virt_to_bus(tsb);
799 /*issue scb to passed ldn, and busy wait for interrupt */
800 got_interrupt(host_index) = 0;
801 issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
802 while (!got_interrupt(host_index))
803 barrier();
804
805 /*if got capacity, get block length and return one device found */
806 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
807 return 1;
808 }
809 /*if all three retries failed, return "no device at this ldn" */
810 if (retr >= 3)
811 return 0;
812 else
813 return 1;
814}
815
816static int get_pos_info(int host_index)
817{
818 int retr;
819 struct im_scb *scb;
820 struct im_tsb *tsb;
821 unsigned char *buf;
822
823 scb = &(ld(host_index)[MAX_LOG_DEV].scb);
824 tsb = &(ld(host_index)[MAX_LOG_DEV].tsb);
825 buf = (unsigned char *) (&(ld(host_index)[MAX_LOG_DEV].buf));
826 ld(host_index)[MAX_LOG_DEV].tsb.dev_status = 0;
827 for (retr = 0; retr < 3; retr++) {
828 /*fill scb with get_pos_info command */
829 scb->command = IM_GET_POS_INFO_CMD;
830 scb->enable = IM_READ_CONTROL | IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE | IM_BYPASS_BUFFER;
831 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_GET_POS_INFO_CMD;
832 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_SCB;
833 scb->sys_buf_adr = isa_virt_to_bus(buf);
834 if (special(host_index) == IBM_SCSI2_FW)
835 scb->sys_buf_length = 256; /* get all info from F/W adapter */
836 else
837 scb->sys_buf_length = 18; /* get exactly 18 bytes for other SCSI */
838 scb->tsb_adr = isa_virt_to_bus(tsb);
839 /*issue scb to ldn=15, and busy wait for interrupt */
840 got_interrupt(host_index) = 0;
841 issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | MAX_LOG_DEV);
842
843 /* FIXME: timeout */
844 while (!got_interrupt(host_index))
845 barrier();
846
847 /*if got POS-stuff, get block length and return one device found */
848 if ((stat_result(host_index) == IM_SCB_CMD_COMPLETED) || (stat_result(host_index) == IM_SCB_CMD_COMPLETED_WITH_RETRIES))
849 return 1;
850 }
851 /* if all three retries failed, return "no device at this ldn" */
852 if (retr >= 3)
853 return 0;
854 else
855 return 1;
856}
857
858/* SCSI-immediate-command for assign. This functions maps/unmaps specific
859 ldn-numbers on SCSI (PUN,LUN). It is needed for presetting of the
860 subsystem and for dynamical remapping od ldns. */
861static int immediate_assign(int host_index, unsigned int pun, unsigned int lun, unsigned int ldn, unsigned int operation)
862{
863 int retr;
864 unsigned long imm_cmd;
865
866 for (retr = 0; retr < 3; retr++) {
867 /* select mutation level of the SCSI-adapter */
868 switch (special(host_index)) {
869 case IBM_SCSI2_FW:
870 imm_cmd = (unsigned long) (IM_ASSIGN_IMM_CMD);
871 imm_cmd |= (unsigned long) ((lun & 7) << 24);
872 imm_cmd |= (unsigned long) ((operation & 1) << 23);
873 imm_cmd |= (unsigned long) ((pun & 7) << 20) | ((pun & 8) << 24);
874 imm_cmd |= (unsigned long) ((ldn & 15) << 16);
875 break;
876 default:
877 imm_cmd = inl(IM_CMD_REG(host_index));
878 imm_cmd &= (unsigned long) (0xF8000000); /* keep reserved bits */
879 imm_cmd |= (unsigned long) (IM_ASSIGN_IMM_CMD);
880 imm_cmd |= (unsigned long) ((lun & 7) << 24);
881 imm_cmd |= (unsigned long) ((operation & 1) << 23);
882 imm_cmd |= (unsigned long) ((pun & 7) << 20);
883 imm_cmd |= (unsigned long) ((ldn & 15) << 16);
884 break;
885 }
886 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_ASSIGN_IMM_CMD;
887 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
888 got_interrupt(host_index) = 0;
889 issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
890 while (!got_interrupt(host_index))
891 barrier();
892
893 /*if command succesful, break */
894 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
895 return 1;
896 }
897 if (retr >= 3)
898 return 0;
899 else
900 return 1;
901}
902
903static int immediate_feature(int host_index, unsigned int speed, unsigned int timeout)
904{
905 int retr;
906 unsigned long imm_cmd;
907
908 for (retr = 0; retr < 3; retr++) {
909 /* select mutation level of the SCSI-adapter */
910 imm_cmd = IM_FEATURE_CTR_IMM_CMD;
911 imm_cmd |= (unsigned long) ((speed & 0x7) << 29);
912 imm_cmd |= (unsigned long) ((timeout & 0x1fff) << 16);
913 last_scsi_command(host_index)[MAX_LOG_DEV] = IM_FEATURE_CTR_IMM_CMD;
914 last_scsi_type(host_index)[MAX_LOG_DEV] = IM_IMM_CMD;
915 got_interrupt(host_index) = 0;
916 /* we need to run into command errors in order to probe for the
917 * right speed! */
918 global_command_error_excuse = 1;
919 issue_cmd(host_index, (unsigned long) (imm_cmd), IM_IMM_CMD | MAX_LOG_DEV);
920
921 /* FIXME: timeout */
922 while (!got_interrupt(host_index))
923 barrier();
924 if (global_command_error_excuse == CMD_FAIL) {
925 global_command_error_excuse = 0;
926 return 2;
927 } else
928 global_command_error_excuse = 0;
929 /*if command succesful, break */
930 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
931 return 1;
932 }
933 if (retr >= 3)
934 return 0;
935 else
936 return 1;
937}
938
939#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
940static int immediate_reset(int host_index, unsigned int ldn)
941{
942 int retries;
943 int ticks;
944 unsigned long imm_command;
945
946 for (retries = 0; retries < 3; retries++) {
947 imm_command = inl(IM_CMD_REG(host_index));
948 imm_command &= (unsigned long) (0xFFFF0000); /* keep reserved bits */
949 imm_command |= (unsigned long) (IM_RESET_IMM_CMD);
950 last_scsi_command(host_index)[ldn] = IM_RESET_IMM_CMD;
951 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
952 got_interrupt(host_index) = 0;
953 reset_status(host_index) = IM_RESET_IN_PROGRESS;
954 issue_cmd(host_index, (unsigned long) (imm_command), IM_IMM_CMD | ldn);
955 ticks = IM_RESET_DELAY * HZ;
956 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks) {
957 udelay((1 + 999 / HZ) * 1000);
958 barrier();
959 }
960 /* if reset did not complete, just complain */
961 if (!ticks) {
962 printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY);
963 reset_status(host_index) = IM_RESET_FINISHED_OK;
964 /* did not work, finish */
965 return 1;
966 }
967 /*if command succesful, break */
968 if (stat_result(host_index) == IM_IMMEDIATE_CMD_COMPLETED)
969 return 1;
970 }
971 if (retries >= 3)
972 return 0;
973 else
974 return 1;
975}
976#endif
977
978/* type-interpreter for physical device numbers */
979static char *ti_p(int dev)
980{
981 switch (dev) {
982 case TYPE_IBM_SCSI_ADAPTER:
983 return ("A");
984 case TYPE_DISK:
985 return ("D");
986 case TYPE_TAPE:
987 return ("T");
988 case TYPE_PROCESSOR:
989 return ("P");
990 case TYPE_WORM:
991 return ("W");
992 case TYPE_ROM:
993 return ("R");
994 case TYPE_SCANNER:
995 return ("S");
996 case TYPE_MOD:
997 return ("M");
998 case TYPE_MEDIUM_CHANGER:
999 return ("C");
1000 case TYPE_NO_LUN:
1001 return ("+"); /* show NO_LUN */
1002 }
1003 return ("-"); /* TYPE_NO_DEVICE and others */
1004}
1005
1006/* interpreter for logical device numbers (ldn) */
1007static char *ti_l(int val)
1008{
1009 const char hex[16] = "0123456789abcdef";
1010 static char answer[2];
1011
1012 answer[1] = (char) (0x0);
1013 if (val <= MAX_LOG_DEV)
1014 answer[0] = hex[val];
1015 else
1016 answer[0] = '-';
1017 return (char *) &answer;
1018}
1019
1020/* transfers bitpattern of the feature command to values in MHz */
1021static char *ibmrate(unsigned int speed, int i)
1022{
1023 switch (speed) {
1024 case 0:
1025 return i ? "5.00" : "10.00";
1026 case 1:
1027 return i ? "4.00" : "8.00";
1028 case 2:
1029 return i ? "3.33" : "6.66";
1030 case 3:
1031 return i ? "2.86" : "5.00";
1032 case 4:
1033 return i ? "2.50" : "4.00";
1034 case 5:
1035 return i ? "2.22" : "3.10";
1036 case 6:
1037 return i ? "2.00" : "2.50";
1038 case 7:
1039 return i ? "1.82" : "2.00";
1040 }
1041 return "---";
1042}
1043
1044static int probe_display(int what)
1045{
1046 static int rotator = 0;
1047 const char rotor[] = "|/-\\";
1048
1049 if (!(display_mode & LED_DISP))
1050 return 0;
1051 if (!what) {
1052 outl(0x20202020, MOD95_LED_PORT);
1053 outl(0x20202020, MOD95_LED_PORT + 4);
1054 } else {
1055 outb('S', MOD95_LED_PORT + 7);
1056 outb('C', MOD95_LED_PORT + 6);
1057 outb('S', MOD95_LED_PORT + 5);
1058 outb('I', MOD95_LED_PORT + 4);
1059 outb('i', MOD95_LED_PORT + 3);
1060 outb('n', MOD95_LED_PORT + 2);
1061 outb('i', MOD95_LED_PORT + 1);
1062 outb((char) (rotor[rotator]), MOD95_LED_PORT);
1063 rotator++;
1064 if (rotator > 3)
1065 rotator = 0;
1066 }
1067 return 0;
1068}
1069
1070static int probe_bus_mode(int host_index)
1071{
1072 struct im_pos_info *info;
1073 int num_bus = 0;
1074 int ldn;
1075
1076 info = (struct im_pos_info *) (&(ld(host_index)[MAX_LOG_DEV].buf));
1077 if (get_pos_info(host_index)) {
1078 if (info->connector_size & 0xf000)
1079 subsystem_connector_size(host_index) = 16;
1080 else
1081 subsystem_connector_size(host_index) = 32;
1082 num_bus |= (info->pos_4b & 8) >> 3;
1083 for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
1084 if ((special(host_index) == IBM_SCSI_WCACHE) || (special(host_index) == IBM_7568_WCACHE)) {
1085 if (!((info->cache_stat >> ldn) & 1))
1086 ld(host_index)[ldn].cache_flag = 0;
1087 }
1088 if (!((info->retry_stat >> ldn) & 1))
1089 ld(host_index)[ldn].retry_flag = 0;
1090 }
1091#ifdef IM_DEBUG_PROBE
1092 printk("IBM MCA SCSI: SCSI-Cache bits: ");
1093 for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
1094 printk("%d", ld(host_index)[ldn].cache_flag);
1095 }
1096 printk("\nIBM MCA SCSI: SCSI-Retry bits: ");
1097 for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
1098 printk("%d", ld(host_index)[ldn].retry_flag);
1099 }
1100 printk("\n");
1101#endif
1102 }
1103 return num_bus;
1104}
1105
1106/* probing scsi devices */
1107static void check_devices(int host_index, int adaptertype)
1108{
1109 int id, lun, ldn, ticks;
1110 int count_devices; /* local counter for connected device */
1111 int max_pun;
1112 int num_bus;
1113 int speedrun; /* local adapter_speed check variable */
1114
1115 /* assign default values to certain variables */
1116 ticks = 0;
1117 count_devices = 0;
1118 IBM_DS(host_index).dyn_flag = 0; /* normally no need for dynamical ldn management */
1119 IBM_DS(host_index).total_errors = 0; /* set errorcounter to 0 */
1120 next_ldn(host_index) = 7; /* next ldn to be assigned is 7, because 0-6 is 'hardwired' */
1121
1122 /* initialize the very important driver-informational arrays/structs */
1123 memset(ld(host_index), 0, sizeof(ld(host_index)));
1124 for (ldn = 0; ldn <= MAX_LOG_DEV; ldn++) {
1125 last_scsi_command(host_index)[ldn] = NO_SCSI; /* emptify last SCSI-command storage */
1126 last_scsi_type(host_index)[ldn] = 0;
1127 ld(host_index)[ldn].cache_flag = 1;
1128 ld(host_index)[ldn].retry_flag = 1;
1129 }
1130 memset(get_ldn(host_index), TYPE_NO_DEVICE, sizeof(get_ldn(host_index))); /* this is essential ! */
1131 memset(get_scsi(host_index), TYPE_NO_DEVICE, sizeof(get_scsi(host_index))); /* this is essential ! */
1132 for (lun = 0; lun < 8; lun++) {
1133 /* mark the adapter at its pun on all luns */
1134 get_scsi(host_index)[subsystem_pun(host_index)][lun] = TYPE_IBM_SCSI_ADAPTER;
1135 get_ldn(host_index)[subsystem_pun(host_index)][lun] = MAX_LOG_DEV; /* make sure, the subsystem
1136 ldn is active for all
1137 luns. */
1138 }
1139 probe_display(0); /* Supercool display usage during SCSI-probing. */
1140 /* This makes sense, when booting without any */
1141 /* monitor connected on model XX95. */
1142
1143 /* STEP 1: */
1144 adapter_speed(host_index) = global_adapter_speed;
1145 speedrun = adapter_speed(host_index);
1146 while (immediate_feature(host_index, speedrun, adapter_timeout) == 2) {
1147 probe_display(1);
1148 if (speedrun == 7)
1149 panic("IBM MCA SCSI: Cannot set Synchronous-Transfer-Rate!\n");
1150 speedrun++;
1151 if (speedrun > 7)
1152 speedrun = 7;
1153 }
1154 adapter_speed(host_index) = speedrun;
1155 /* Get detailed information about the current adapter, necessary for
1156 * device operations: */
1157 num_bus = probe_bus_mode(host_index);
1158
1159 /* num_bus contains only valid data for the F/W adapter! */
1160 if (adaptertype == IBM_SCSI2_FW) { /* F/W SCSI adapter: */
1161 /* F/W adapter PUN-space extension evaluation: */
1162 if (num_bus) {
1163 printk(KERN_INFO "IBM MCA SCSI: Separate bus mode (wide-addressing enabled)\n");
1164 subsystem_maxid(host_index) = 16;
1165 } else {
1166 printk(KERN_INFO "IBM MCA SCSI: Combined bus mode (wide-addressing disabled)\n");
1167 subsystem_maxid(host_index) = 8;
1168 }
1169 printk(KERN_INFO "IBM MCA SCSI: Sync.-Rate (F/W: 20, Int.: 10, Ext.: %s) MBytes/s\n", ibmrate(speedrun, adaptertype));
1170 } else /* all other IBM SCSI adapters: */
1171 printk(KERN_INFO "IBM MCA SCSI: Synchronous-SCSI-Transfer-Rate: %s MBytes/s\n", ibmrate(speedrun, adaptertype));
1172
1173 /* assign correct PUN device space */
1174 max_pun = subsystem_maxid(host_index);
1175
1176#ifdef IM_DEBUG_PROBE
1177 printk("IBM MCA SCSI: Current SCSI-host index: %d\n", host_index);
1178 printk("IBM MCA SCSI: Removing default logical SCSI-device mapping.");
1179#else
1180 printk(KERN_INFO "IBM MCA SCSI: Dev. Order: %s, Mapping (takes <2min): ", (ibm_ansi_order) ? "ANSI" : "New");
1181#endif
1182 for (ldn = 0; ldn < MAX_LOG_DEV; ldn++) {
1183 probe_display(1);
1184#ifdef IM_DEBUG_PROBE
1185 printk(".");
1186#endif
1187 immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN); /* remove ldn (wherever) */
1188 }
1189 lun = 0; /* default lun is 0 */
1190#ifndef IM_DEBUG_PROBE
1191 printk("cleared,");
1192#endif
1193 /* STEP 2: */
1194#ifdef IM_DEBUG_PROBE
1195 printk("\nIBM MCA SCSI: Scanning SCSI-devices.");
1196#endif
1197 for (id = 0; id < max_pun; id++)
1198#ifdef CONFIG_SCSI_MULTI_LUN
1199 for (lun = 0; lun < 8; lun++)
1200#endif
1201 {
1202 probe_display(1);
1203#ifdef IM_DEBUG_PROBE
1204 printk(".");
1205#endif
1206 if (id != subsystem_pun(host_index)) {
1207 /* if pun is not the adapter: */
1208 /* set ldn=0 to pun,lun */
1209 immediate_assign(host_index, id, lun, PROBE_LDN, SET_LDN);
1210 if (device_inquiry(host_index, PROBE_LDN)) { /* probe device */
1211 get_scsi(host_index)[id][lun] = (unsigned char) (ld(host_index)[PROBE_LDN].buf[0]);
1212 /* entry, even for NO_LUN */
1213 if (ld(host_index)[PROBE_LDN].buf[0] != TYPE_NO_LUN)
1214 count_devices++; /* a existing device is found */
1215 }
1216 /* remove ldn */
1217 immediate_assign(host_index, id, lun, PROBE_LDN, REMOVE_LDN);
1218 }
1219 }
1220#ifndef IM_DEBUG_PROBE
1221 printk("scanned,");
1222#endif
1223 /* STEP 3: */
1224#ifdef IM_DEBUG_PROBE
1225 printk("\nIBM MCA SCSI: Mapping SCSI-devices.");
1226#endif
1227 ldn = 0;
1228 lun = 0;
1229#ifdef CONFIG_SCSI_MULTI_LUN
1230 for (lun = 0; lun < 8 && ldn < MAX_LOG_DEV; lun++)
1231#endif
1232 for (id = 0; id < max_pun && ldn < MAX_LOG_DEV; id++) {
1233 probe_display(1);
1234#ifdef IM_DEBUG_PROBE
1235 printk(".");
1236#endif
1237 if (id != subsystem_pun(host_index)) {
1238 if (get_scsi(host_index)[id][lun] != TYPE_NO_LUN && get_scsi(host_index)[id][lun] != TYPE_NO_DEVICE) {
1239 /* Only map if accepted type. Always enter for
1240 lun == 0 to get no gaps into ldn-mapping for ldn<7. */
1241 immediate_assign(host_index, id, lun, ldn, SET_LDN);
1242 get_ldn(host_index)[id][lun] = ldn; /* map ldn */
1243 if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {
1244#ifdef CONFIG_IBMMCA_SCSI_DEV_RESET
1245 printk("resetting device at ldn=%x ... ", ldn);
1246 immediate_reset(host_index, ldn);
1247#endif
1248 ldn++;
1249 } else {
1250 /* device vanished, probably because we don't know how to
1251 * handle it or because it has problems */
1252 if (lun > 0) {
1253 /* remove mapping */
1254 get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
1255 immediate_assign(host_index, 0, 0, ldn, REMOVE_LDN);
1256 } else
1257 ldn++;
1258 }
1259 } else if (lun == 0) {
1260 /* map lun == 0, even if no device exists */
1261 immediate_assign(host_index, id, lun, ldn, SET_LDN);
1262 get_ldn(host_index)[id][lun] = ldn; /* map ldn */
1263 ldn++;
1264 }
1265 }
1266 }
1267 /* STEP 4: */
1268
1269 /* map remaining ldns to non-existing devices */
1270 for (lun = 1; lun < 8 && ldn < MAX_LOG_DEV; lun++)
1271 for (id = 0; id < max_pun && ldn < MAX_LOG_DEV; id++) {
1272 if (get_scsi(host_index)[id][lun] == TYPE_NO_LUN || get_scsi(host_index)[id][lun] == TYPE_NO_DEVICE) {
1273 probe_display(1);
1274 /* Map remaining ldns only to NON-existing pun,lun
1275 combinations to make sure an inquiry will fail.
1276 For MULTI_LUN, it is needed to avoid adapter autonome
1277 SCSI-remapping. */
1278 immediate_assign(host_index, id, lun, ldn, SET_LDN);
1279 get_ldn(host_index)[id][lun] = ldn;
1280 ldn++;
1281 }
1282 }
1283#ifndef IM_DEBUG_PROBE
1284 printk("mapped.");
1285#endif
1286 printk("\n");
1287#ifdef IM_DEBUG_PROBE
1288 if (ibm_ansi_order)
1289 printk("IBM MCA SCSI: Device order: IBM/ANSI (pun=7 is first).\n");
1290 else
1291 printk("IBM MCA SCSI: Device order: New Industry Standard (pun=0 is first).\n");
1292#endif
1293
1294#ifdef IM_DEBUG_PROBE
1295 /* Show the physical and logical mapping during boot. */
1296 printk("IBM MCA SCSI: Determined SCSI-device-mapping:\n");
1297 printk(" Physical SCSI-Device Map Logical SCSI-Device Map\n");
1298 printk("ID\\LUN 0 1 2 3 4 5 6 7 ID\\LUN 0 1 2 3 4 5 6 7\n");
1299 for (id = 0; id < max_pun; id++) {
1300 printk("%2d ", id);
1301 for (lun = 0; lun < 8; lun++)
1302 printk("%2s ", ti_p(get_scsi(host_index)[id][lun]));
1303 printk(" %2d ", id);
1304 for (lun = 0; lun < 8; lun++)
1305 printk("%2s ", ti_l(get_ldn(host_index)[id][lun]));
1306 printk("\n");
1307 }
1308#endif
1309
1310 /* assign total number of found SCSI-devices to the statistics struct */
1311 IBM_DS(host_index).total_scsi_devices = count_devices;
1312
1313 /* decide for output in /proc-filesystem, if the configuration of
1314 SCSI-devices makes dynamical reassignment of devices necessary */
1315 if (count_devices >= MAX_LOG_DEV)
1316 IBM_DS(host_index).dyn_flag = 1; /* dynamical assignment is necessary */
1317 else
1318 IBM_DS(host_index).dyn_flag = 0; /* dynamical assignment is not necessary */
1319
1320 /* If no SCSI-devices are assigned, return 1 in order to cause message. */
1321 if (ldn == 0)
1322 printk("IBM MCA SCSI: Warning: No SCSI-devices found/assigned!\n");
1323
1324 /* reset the counters for statistics on the current adapter */
1325 IBM_DS(host_index).scbs = 0;
1326 IBM_DS(host_index).long_scbs = 0;
1327 IBM_DS(host_index).total_accesses = 0;
1328 IBM_DS(host_index).total_interrupts = 0;
1329 IBM_DS(host_index).dynamical_assignments = 0;
1330 memset(IBM_DS(host_index).ldn_access, 0x0, sizeof(IBM_DS(host_index).ldn_access));
1331 memset(IBM_DS(host_index).ldn_read_access, 0x0, sizeof(IBM_DS(host_index).ldn_read_access));
1332 memset(IBM_DS(host_index).ldn_write_access, 0x0, sizeof(IBM_DS(host_index).ldn_write_access));
1333 memset(IBM_DS(host_index).ldn_inquiry_access, 0x0, sizeof(IBM_DS(host_index).ldn_inquiry_access));
1334 memset(IBM_DS(host_index).ldn_modeselect_access, 0x0, sizeof(IBM_DS(host_index).ldn_modeselect_access));
1335 memset(IBM_DS(host_index).ldn_assignments, 0x0, sizeof(IBM_DS(host_index).ldn_assignments));
1336 probe_display(0);
1337 return;
1338}
1339
1340static int device_exists(int host_index, int ldn, int *block_length, int *device_type)
1341{
1342 unsigned char *buf;
1343 /* if no valid device found, return immediately with 0 */
1344 if (!(device_inquiry(host_index, ldn)))
1345 return 0;
1346 buf = (unsigned char *) (&(ld(host_index)[ldn].buf));
1347 if (*buf == TYPE_ROM) {
1348 *device_type = TYPE_ROM;
1349 *block_length = 2048; /* (standard blocksize for yellow-/red-book) */
1350 return 1;
1351 }
1352 if (*buf == TYPE_WORM) {
1353 *device_type = TYPE_WORM;
1354 *block_length = 2048;
1355 return 1;
1356 }
1357 if (*buf == TYPE_DISK) {
1358 *device_type = TYPE_DISK;
1359 if (read_capacity(host_index, ldn)) {
1360 *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24);
1361 return 1;
1362 } else
1363 return 0;
1364 }
1365 if (*buf == TYPE_MOD) {
1366 *device_type = TYPE_MOD;
1367 if (read_capacity(host_index, ldn)) {
1368 *block_length = *(buf + 7) + (*(buf + 6) << 8) + (*(buf + 5) << 16) + (*(buf + 4) << 24);
1369 return 1;
1370 } else
1371 return 0;
1372 }
1373 if (*buf == TYPE_TAPE) {
1374 *device_type = TYPE_TAPE;
1375 *block_length = 0; /* not in use (setting by mt and mtst in op.) */
1376 return 1;
1377 }
1378 if (*buf == TYPE_PROCESSOR) {
1379 *device_type = TYPE_PROCESSOR;
1380 *block_length = 0; /* they set their stuff on drivers */
1381 return 1;
1382 }
1383 if (*buf == TYPE_SCANNER) {
1384 *device_type = TYPE_SCANNER;
1385 *block_length = 0; /* they set their stuff on drivers */
1386 return 1;
1387 }
1388 if (*buf == TYPE_MEDIUM_CHANGER) {
1389 *device_type = TYPE_MEDIUM_CHANGER;
1390 *block_length = 0; /* One never knows, what to expect on a medium
1391 changer device. */
1392 return 1;
1393 }
1394 return 0;
1395}
1396
1397static void internal_ibmmca_scsi_setup(char *str, int *ints)
1398{
1399 int i, j, io_base, id_base;
1400 char *token;
1401
1402 io_base = 0;
1403 id_base = 0;
1404 if (str) {
1405 j = 0;
1406 while ((token = strsep(&str, ",")) != NULL) {
1407 if (!strcmp(token, "activity"))
1408 display_mode |= LED_ACTIVITY;
1409 if (!strcmp(token, "display"))
1410 display_mode |= LED_DISP;
1411 if (!strcmp(token, "adisplay"))
1412 display_mode |= LED_ADISP;
1413 if (!strcmp(token, "normal"))
1414 ibm_ansi_order = 0;
1415 if (!strcmp(token, "ansi"))
1416 ibm_ansi_order = 1;
1417 if (!strcmp(token, "fast"))
1418 global_adapter_speed = 0;
1419 if (!strcmp(token, "medium"))
1420 global_adapter_speed = 4;
1421 if (!strcmp(token, "slow"))
1422 global_adapter_speed = 7;
1423 if ((*token == '-') || (isdigit(*token))) {
1424 if (!(j % 2) && (io_base < IM_MAX_HOSTS))
1425 io_port[io_base++] = simple_strtoul(token, NULL, 0);
1426 if ((j % 2) && (id_base < IM_MAX_HOSTS))
1427 scsi_id[id_base++] = simple_strtoul(token, NULL, 0);
1428 j++;
1429 }
1430 }
1431 } else if (ints) {
1432 for (i = 0; i < IM_MAX_HOSTS && 2 * i + 2 < ints[0]; i++) {
1433 io_port[i] = ints[2 * i + 2];
1434 scsi_id[i] = ints[2 * i + 2];
1435 }
1436 }
1437 return;
1438}
1439
1440static int ibmmca_getinfo(char *buf, int slot, void *dev_id)
1441{
1442 struct Scsi_Host *shpnt;
1443 int len, speciale, connectore, k;
1444 unsigned int pos[8];
1445 unsigned long flags;
1446 struct Scsi_Host *dev = dev_id;
1447
1448 spin_lock_irqsave(dev->host_lock, flags);
1449
1450 shpnt = dev; /* assign host-structure to local pointer */
1451 len = 0; /* set filled text-buffer index to 0 */
1452 /* get the _special contents of the hostdata structure */
1453 speciale = ((struct ibmmca_hostdata *) shpnt->hostdata)->_special;
1454 connectore = ((struct ibmmca_hostdata *) shpnt->hostdata)->_connector_size;
1455 for (k = 2; k < 4; k++)
1456 pos[k] = ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k];
1457 if (speciale == FORCED_DETECTION) { /* forced detection */
1458 len += sprintf(buf + len,
1459 "Adapter category: forced detected\n" "***************************************\n" "*** Forced detected SCSI Adapter ***\n" "*** No chip-information available ***\n" "***************************************\n");
1460 } else if (speciale == INTEGRATED_SCSI) {
1461 /* if the integrated subsystem has been found automatically: */
1462 len += sprintf(buf + len,
1463 "Adapter category: integrated\n" "Chip revision level: %d\n" "Chip status: %s\n" "8 kByte NVRAM status: %s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 1) ? "enabled" : "disabled", (pos[2] & 2) ? "locked" : "accessible");
1464 } else if ((speciale >= 0) && (speciale < (sizeof(subsys_list) / sizeof(struct subsys_list_struct)))) {
1465 /* if the subsystem is a slot adapter */
1466 len += sprintf(buf + len, "Adapter category: slot-card\n" "ROM Segment Address: ");
1467 if ((pos[2] & 0xf0) == 0xf0)
1468 len += sprintf(buf + len, "off\n");
1469 else
1470 len += sprintf(buf + len, "0x%x\n", ((pos[2] & 0xf0) << 13) + 0xc0000);
1471 len += sprintf(buf + len, "Chip status: %s\n", (pos[2] & 1) ? "enabled" : "disabled");
1472 len += sprintf(buf + len, "Adapter I/O Offset: 0x%x\n", ((pos[2] & 0x0e) << 2));
1473 } else {
1474 len += sprintf(buf + len, "Adapter category: unknown\n");
1475 }
1476 /* common subsystem information to write to the slotn file */
1477 len += sprintf(buf + len, "Subsystem PUN: %d\n", shpnt->this_id);
1478 len += sprintf(buf + len, "I/O base address range: 0x%x-0x%x\n", (unsigned int) (shpnt->io_port), (unsigned int) (shpnt->io_port + 7));
1479 len += sprintf(buf + len, "MCA-slot size: %d bits", connectore);
1480 /* Now make sure, the bufferlength is devidable by 4 to avoid
1481 * paging problems of the buffer. */
1482 while (len % sizeof(int) != (sizeof(int) - 1))
1483 len += sprintf(buf + len, " ");
1484 len += sprintf(buf + len, "\n");
1485
1486 spin_unlock_irqrestore(shpnt->host_lock, flags);
1487
1488 return len;
1489}
1490
1491int ibmmca_detect(Scsi_Host_Template * scsi_template)
1492{
1493 struct Scsi_Host *shpnt;
1494 int port, id, i, j, k, list_size, slot;
1495 int devices_on_irq_11 = 0;
1496 int devices_on_irq_14 = 0;
1497 int IRQ14_registered = 0;
1498 int IRQ11_registered = 0;
1499
1500 found = 0; /* make absolutely sure, that found is set to 0 */
1501
1502 /* First of all, print the version number of the driver. This is
1503 * important to allow better user bugreports in case of already
1504 * having problems with the MCA_bus probing. */
1505 printk(KERN_INFO "IBM MCA SCSI: Version %s\n", IBMMCA_SCSI_DRIVER_VERSION);
1506 /* if this is not MCA machine, return "nothing found" */
1507 if (!MCA_bus) {
1508 printk(KERN_INFO "IBM MCA SCSI: No Microchannel-bus present --> Aborting.\n" " This machine does not have any IBM MCA-bus\n" " or the MCA-Kernel-support is not enabled!\n");
1509 return 0;
1510 }
1511
1512#ifdef MODULE
1513 /* If the driver is run as module, read from conf.modules or cmd-line */
1514 if (boot_options)
1515 option_setup(boot_options);
1516#endif
1517
1518 /* get interrupt request level */
1519 if (request_irq(IM_IRQ, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts)) {
1520 printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ);
1521 return 0;
1522 } else
1523 IRQ14_registered++;
1524
1525 /* if ibmmcascsi setup option was passed to kernel, return "found" */
1526 for (i = 0; i < IM_MAX_HOSTS; i++)
1527 if (io_port[i] > 0 && scsi_id[i] >= 0 && scsi_id[i] < 8) {
1528 printk("IBM MCA SCSI: forced detected SCSI Adapter, io=0x%x, scsi id=%d.\n", io_port[i], scsi_id[i]);
1529 if ((shpnt = ibmmca_register(scsi_template, io_port[i], scsi_id[i], FORCED_DETECTION, "forced detected SCSI Adapter"))) {
1530 for (k = 2; k < 7; k++)
1531 ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = 0;
1532 ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = FORCED_DETECTION;
1533 mca_set_adapter_name(MCA_INTEGSCSI, "forced detected SCSI Adapter");
1534 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt);
1535 mca_mark_as_used(MCA_INTEGSCSI);
1536 devices_on_irq_14++;
1537 }
1538 }
1539 if (found)
1540 return found;
1541
1542 /* The POS2-register of all PS/2 model SCSI-subsystems has the following
1543 * interpretation of bits:
1544 * Bit 7 - 4 : Chip Revision ID (Release)
1545 * Bit 3 - 2 : Reserved
1546 * Bit 1 : 8k NVRAM Disabled
1547 * Bit 0 : Chip Enable (EN-Signal)
1548 * The POS3-register is interpreted as follows:
1549 * Bit 7 - 5 : SCSI ID
1550 * Bit 4 : Reserved = 0
1551 * Bit 3 - 0 : Reserved = 0
1552 * (taken from "IBM, PS/2 Hardware Interface Technical Reference, Common
1553 * Interfaces (1991)").
1554 * In short words, this means, that IBM PS/2 machines only support
1555 * 1 single subsystem by default. The slot-adapters must have another
1556 * configuration on pos2. Here, one has to assume the following
1557 * things for POS2-register:
1558 * Bit 7 - 4 : Chip Revision ID (Release)
1559 * Bit 3 - 1 : port offset factor
1560 * Bit 0 : Chip Enable (EN-Signal)
1561 * As I found a patch here, setting the IO-registers to 0x3540 forced,
1562 * as there was a 0x05 in POS2 on a model 56, I assume, that the
1563 * port 0x3540 must be fix for integrated SCSI-controllers.
1564 * Ok, this discovery leads to the following implementation: (M.Lang) */
1565
1566 /* first look for the IBM SCSI integrated subsystem on the motherboard */
1567 for (j = 0; j < 8; j++) /* read the pos-information */
1568 pos[j] = mca_read_stored_pos(MCA_INTEGSCSI, j);
1569 /* pos2 = pos3 = 0xff if there is no integrated SCSI-subsystem present, but
1570 * if we ignore the settings of all surrounding pos registers, it is not
1571 * completely sufficient to only check pos2 and pos3. */
1572 /* Therefore, now the following if statement is used to
1573 * make sure, we see a real integrated onboard SCSI-interface and no
1574 * internal system information, which gets mapped to some pos registers
1575 * on models 95xx. */
1576 if ((!pos[0] && !pos[1] && pos[2] > 0 && pos[3] > 0 && !pos[4] && !pos[5] && !pos[6] && !pos[7]) || (pos[0] == 0xff && pos[1] == 0xff && pos[2] < 0xff && pos[3] < 0xff && pos[4] == 0xff && pos[5] == 0xff && pos[6] == 0xff && pos[7] == 0xff)) {
1577 if ((pos[2] & 1) == 1) /* is the subsystem chip enabled ? */
1578 port = IM_IO_PORT;
1579 else { /* if disabled, no IRQs will be generated, as the chip won't
1580 * listen to the incoming commands and will do really nothing,
1581 * except for listening to the pos-register settings. If this
1582 * happens, I need to hugely think about it, as one has to
1583 * write something to the MCA-Bus pos register in order to
1584 * enable the chip. Normally, IBM-SCSI won't pass the POST,
1585 * when the chip is disabled (see IBM tech. ref.). */
1586 port = IM_IO_PORT; /* anyway, set the portnumber and warn */
1587 printk("IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n" " SCSI-operations may not work.\n");
1588 }
1589 id = (pos[3] & 0xe0) >> 5; /* this is correct and represents the PUN */
1590 /* give detailed information on the subsystem. This helps me
1591 * additionally during debugging and analyzing bug-reports. */
1592 printk(KERN_INFO "IBM MCA SCSI: IBM Integrated SCSI Controller ffound, io=0x%x, scsi id=%d,\n", port, id);
1593 printk(KERN_INFO " chip rev.=%d, 8K NVRAM=%s, subsystem=%s\n", ((pos[2] & 0xf0) >> 4), (pos[2] & 2) ? "locked" : "accessible", (pos[2] & 1) ? "enabled." : "disabled.");
1594
1595 /* register the found integrated SCSI-subsystem */
1596 if ((shpnt = ibmmca_register(scsi_template, port, id, INTEGRATED_SCSI, "IBM Integrated SCSI Controller")))
1597 {
1598 for (k = 2; k < 7; k++)
1599 ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
1600 ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = INTEGRATED_SCSI;
1601 mca_set_adapter_name(MCA_INTEGSCSI, "IBM Integrated SCSI Controller");
1602 mca_set_adapter_procfn(MCA_INTEGSCSI, (MCA_ProcFn) ibmmca_getinfo, shpnt);
1603 mca_mark_as_used(MCA_INTEGSCSI);
1604 devices_on_irq_14++;
1605 }
1606 }
1607
1608 /* now look for other adapters in MCA slots, */
1609 /* determine the number of known IBM-SCSI-subsystem types */
1610 /* see the pos[2] dependence to get the adapter port-offset. */
1611 list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
1612 for (i = 0; i < list_size; i++) {
1613 /* scan each slot for a fitting adapter id */
1614 slot = 0; /* start at slot 0 */
1615 while ((slot = mca_find_adapter(subsys_list[i].mca_id, slot))
1616 != MCA_NOTFOUND) { /* scan through all slots */
1617 for (j = 0; j < 8; j++) /* read the pos-information */
1618 pos[j] = mca_read_stored_pos(slot, j);
1619 if ((pos[2] & 1) == 1)
1620 /* is the subsystem chip enabled ? */
1621 /* (explanations see above) */
1622 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1623 else {
1624 /* anyway, set the portnumber and warn */
1625 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1626 printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
1627 printk(KERN_WARNING " SCSI-operations may not work.\n");
1628 }
1629 if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) {
1630 printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
1631 printk(KERN_ERR " Impossible to determine adapter PUN!\n");
1632 printk(KERN_ERR " Guessing adapter PUN = 7.\n");
1633 id = 7;
1634 } else {
1635 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
1636 if (i == IBM_SCSI2_FW) {
1637 id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
1638 * for F/W adapters */
1639 }
1640 }
1641 if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) {
1642 /* IRQ11 is used by SCSI-2 F/W Adapter/A */
1643 printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
1644 /* get interrupt request level */
1645 if (request_irq(IM_IRQ_FW, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts)) {
1646 printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
1647 } else
1648 IRQ11_registered++;
1649 }
1650 printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id);
1651 if ((pos[2] & 0xf0) == 0xf0)
1652 printk(KERN_DEBUG" ROM Addr.=off,");
1653 else
1654 printk(KERN_DEBUG " ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000);
1655 printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled.");
1656
1657 /* register the hostadapter */
1658 if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) {
1659 for (k = 2; k < 8; k++)
1660 ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
1661 ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i;
1662 mca_set_adapter_name(slot, subsys_list[i].description);
1663 mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt);
1664 mca_mark_as_used(slot);
1665 if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0))
1666 devices_on_irq_11++;
1667 else
1668 devices_on_irq_14++;
1669 }
1670 slot++; /* advance to next slot */
1671 } /* advance to next adapter id in the list of IBM-SCSI-subsystems */
1672 }
1673
1674 /* now check for SCSI-adapters, mapped to the integrated SCSI
1675 * area. E.g. a W/Cache in MCA-slot 9(!). Do the check correct here,
1676 * as this is a known effect on some models 95xx. */
1677 list_size = sizeof(subsys_list) / sizeof(struct subsys_list_struct);
1678 for (i = 0; i < list_size; i++) {
1679 /* scan each slot for a fitting adapter id */
1680 slot = mca_find_adapter(subsys_list[i].mca_id, MCA_INTEGSCSI);
1681 if (slot != MCA_NOTFOUND) { /* scan through all slots */
1682 for (j = 0; j < 8; j++) /* read the pos-information */
1683 pos[j] = mca_read_stored_pos(slot, j);
1684 if ((pos[2] & 1) == 1) { /* is the subsystem chip enabled ? */
1685 /* (explanations see above) */
1686 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1687 } else { /* anyway, set the portnumber and warn */
1688 port = IM_IO_PORT + ((pos[2] & 0x0e) << 2);
1689 printk(KERN_WARNING "IBM MCA SCSI: WARNING - Your SCSI-subsystem is disabled!\n");
1690 printk(KERN_WARNING " SCSI-operations may not work.\n");
1691 }
1692 if ((i == IBM_SCSI2_FW) && (pos[6] != 0)) {
1693 printk(KERN_ERR "IBM MCA SCSI: ERROR - Wrong POS(6)-register setting!\n");
1694 printk(KERN_ERR " Impossible to determine adapter PUN!\n");
1695 printk(KERN_ERR " Guessing adapter PUN = 7.\n");
1696 id = 7;
1697 } else {
1698 id = (pos[3] & 0xe0) >> 5; /* get subsystem PUN */
1699 if (i == IBM_SCSI2_FW)
1700 id |= (pos[3] & 0x10) >> 1; /* get subsystem PUN high-bit
1701 * for F/W adapters */
1702 }
1703 if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0)) {
1704 /* IRQ11 is used by SCSI-2 F/W Adapter/A */
1705 printk(KERN_DEBUG "IBM MCA SCSI: SCSI-2 F/W adapter needs IRQ 11.\n");
1706 /* get interrupt request level */
1707 if (request_irq(IM_IRQ_FW, interrupt_handler, SA_SHIRQ, "ibmmcascsi", hosts))
1708 printk(KERN_ERR "IBM MCA SCSI: Unable to get shared IRQ %d.\n", IM_IRQ_FW);
1709 else
1710 IRQ11_registered++;
1711 }
1712 printk(KERN_INFO "IBM MCA SCSI: %s found in slot %d, io=0x%x, scsi id=%d,\n", subsys_list[i].description, slot + 1, port, id);
1713 if ((pos[2] & 0xf0) == 0xf0)
1714 printk(KERN_DEBUG " ROM Addr.=off,");
1715 else
1716 printk(KERN_DEBUG " ROM Addr.=0x%x,", ((pos[2] & 0xf0) << 13) + 0xc0000);
1717 printk(KERN_DEBUG " port-offset=0x%x, subsystem=%s\n", ((pos[2] & 0x0e) << 2), (pos[2] & 1) ? "enabled." : "disabled.");
1718
1719 /* register the hostadapter */
1720 if ((shpnt = ibmmca_register(scsi_template, port, id, i, subsys_list[i].description))) {
1721 for (k = 2; k < 7; k++)
1722 ((struct ibmmca_hostdata *) shpnt->hostdata)->_pos[k] = pos[k];
1723 ((struct ibmmca_hostdata *) shpnt->hostdata)->_special = i;
1724 mca_set_adapter_name(slot, subsys_list[i].description);
1725 mca_set_adapter_procfn(slot, (MCA_ProcFn) ibmmca_getinfo, shpnt);
1726 mca_mark_as_used(slot);
1727 if ((i == IBM_SCSI2_FW) && (pos[4] & 0x01) && (pos[6] == 0))
1728 devices_on_irq_11++;
1729 else
1730 devices_on_irq_14++;
1731 }
1732 slot++; /* advance to next slot */
1733 } /* advance to next adapter id in the list of IBM-SCSI-subsystems */
1734 }
1735 if (IRQ11_registered && !devices_on_irq_11)
1736 free_irq(IM_IRQ_FW, hosts); /* no devices on IRQ 11 */
1737 if (IRQ14_registered && !devices_on_irq_14)
1738 free_irq(IM_IRQ, hosts); /* no devices on IRQ 14 */
1739 if (!devices_on_irq_11 && !devices_on_irq_14)
1740 printk(KERN_WARNING "IBM MCA SCSI: No IBM SCSI-subsystem adapter attached.\n");
1741 return found; /* return the number of found SCSI hosts. Should be 1 or 0. */
1742}
1743
1744static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id, int adaptertype, char *hostname)
1745{
1746 struct Scsi_Host *shpnt;
1747 int i, j;
1748 unsigned int ctrl;
1749
1750 /* check I/O region */
1751 if (!request_region(port, IM_N_IO_PORT, hostname)) {
1752 printk(KERN_ERR "IBM MCA SCSI: Unable to get I/O region 0x%x-0x%x (%d ports).\n", port, port + IM_N_IO_PORT - 1, IM_N_IO_PORT);
1753 return NULL;
1754 }
1755
1756 /* register host */
1757 shpnt = scsi_register(scsi_template, sizeof(struct ibmmca_hostdata));
1758 if (!shpnt) {
1759 printk(KERN_ERR "IBM MCA SCSI: Unable to register host.\n");
1760 release_region(port, IM_N_IO_PORT);
1761 return NULL;
1762 }
1763
1764 /* request I/O region */
1765 hosts[found] = shpnt; /* add new found hostadapter to the list */
1766 special(found) = adaptertype; /* important assignment or else crash! */
1767 subsystem_connector_size(found) = 0; /* preset slot-size */
1768 shpnt->irq = IM_IRQ; /* assign necessary stuff for the adapter */
1769 shpnt->io_port = port;
1770 shpnt->n_io_port = IM_N_IO_PORT;
1771 shpnt->this_id = id;
1772 shpnt->max_id = 8; /* 8 PUNs are default */
1773 /* now, the SCSI-subsystem is connected to Linux */
1774
1775 ctrl = (unsigned int) (inb(IM_CTR_REG(found))); /* get control-register status */
1776#ifdef IM_DEBUG_PROBE
1777 printk("IBM MCA SCSI: Control Register contents: %x, status: %x\n", ctrl, inb(IM_STAT_REG(found)));
1778 printk("IBM MCA SCSI: This adapters' POS-registers: ");
1779 for (i = 0; i < 8; i++)
1780 printk("%x ", pos[i]);
1781 printk("\n");
1782#endif
1783 reset_status(found) = IM_RESET_NOT_IN_PROGRESS;
1784
1785 for (i = 0; i < 16; i++) /* reset the tables */
1786 for (j = 0; j < 8; j++)
1787 get_ldn(found)[i][j] = MAX_LOG_DEV;
1788
1789 /* check which logical devices exist */
1790 /* after this line, local interrupting is possible: */
1791 local_checking_phase_flag(found) = 1;
1792 check_devices(found, adaptertype); /* call by value, using the global variable hosts */
1793 local_checking_phase_flag(found) = 0;
1794 found++; /* now increase index to be prepared for next found subsystem */
1795 /* an ibm mca subsystem has been detected */
1796 return shpnt;
1797}
1798
1799static int ibmmca_release(struct Scsi_Host *shpnt)
1800{
1801 release_region(shpnt->io_port, shpnt->n_io_port);
1802 if (!(--found))
1803 free_irq(shpnt->irq, hosts);
1804 return 0;
1805}
1806
1807/* The following routine is the SCSI command queue for the midlevel driver */
1808static int ibmmca_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
1809{
1810 unsigned int ldn;
1811 unsigned int scsi_cmd;
1812 struct im_scb *scb;
1813 struct Scsi_Host *shpnt;
1814 int current_ldn;
1815 int id, lun;
1816 int target;
1817 int host_index;
1818 int max_pun;
1819 int i;
1820 struct scatterlist *sl;
1821
1822 shpnt = cmd->device->host;
1823 /* search for the right hostadapter */
1824 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
1825
1826 if (!hosts[host_index]) { /* invalid hostadapter descriptor address */
1827 cmd->result = DID_NO_CONNECT << 16;
1828 if (done)
1829 done(cmd);
1830 return 0;
1831 }
1832 max_pun = subsystem_maxid(host_index);
1833 if (ibm_ansi_order) {
1834 target = max_pun - 1 - cmd->device->id;
1835 if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
1836 target--;
1837 else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
1838 target++;
1839 } else
1840 target = cmd->device->id;
1841
1842 /* if (target,lun) is NO LUN or not existing at all, return error */
1843 if ((get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_LUN) || (get_scsi(host_index)[target][cmd->device->lun] == TYPE_NO_DEVICE)) {
1844 cmd->result = DID_NO_CONNECT << 16;
1845 if (done)
1846 done(cmd);
1847 return 0;
1848 }
1849
1850 /*if (target,lun) unassigned, do further checks... */
1851 ldn = get_ldn(host_index)[target][cmd->device->lun];
1852 if (ldn >= MAX_LOG_DEV) { /* on invalid ldn do special stuff */
1853 if (ldn > MAX_LOG_DEV) { /* dynamical remapping if ldn unassigned */
1854 current_ldn = next_ldn(host_index); /* stop-value for one circle */
1855 while (ld(host_index)[next_ldn(host_index)].cmd) { /* search for a occupied, but not in */
1856 /* command-processing ldn. */
1857 next_ldn(host_index)++;
1858 if (next_ldn(host_index) >= MAX_LOG_DEV)
1859 next_ldn(host_index) = 7;
1860 if (current_ldn == next_ldn(host_index)) { /* One circle done ? */
1861 /* no non-processing ldn found */
1862 printk("IBM MCA SCSI: Cannot assign SCSI-device dynamically!\n" " On ldn 7-14 SCSI-commands everywhere in progress.\n" " Reporting DID_NO_CONNECT for device (%d,%d).\n", target, cmd->device->lun);
1863 cmd->result = DID_NO_CONNECT << 16; /* return no connect */
1864 if (done)
1865 done(cmd);
1866 return 0;
1867 }
1868 }
1869
1870 /* unmap non-processing ldn */
1871 for (id = 0; id < max_pun; id++)
1872 for (lun = 0; lun < 8; lun++) {
1873 if (get_ldn(host_index)[id][lun] == next_ldn(host_index)) {
1874 get_ldn(host_index)[id][lun] = TYPE_NO_DEVICE;
1875 get_scsi(host_index)[id][lun] = TYPE_NO_DEVICE;
1876 /* unmap entry */
1877 }
1878 }
1879 /* set reduced interrupt_handler-mode for checking */
1880 local_checking_phase_flag(host_index) = 1;
1881 /* map found ldn to pun,lun */
1882 get_ldn(host_index)[target][cmd->device->lun] = next_ldn(host_index);
1883 /* change ldn to the right value, that is now next_ldn */
1884 ldn = next_ldn(host_index);
1885 /* unassign all ldns (pun,lun,ldn does not matter for remove) */
1886 immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
1887 /* set only LDN for remapped device */
1888 immediate_assign(host_index, target, cmd->device->lun, ldn, SET_LDN);
1889 /* get device information for ld[ldn] */
1890 if (device_exists(host_index, ldn, &ld(host_index)[ldn].block_length, &ld(host_index)[ldn].device_type)) {
1891 ld(host_index)[ldn].cmd = NULL; /* To prevent panic set 0, because
1892 devices that were not assigned,
1893 should have nothing in progress. */
1894 get_scsi(host_index)[target][cmd->device->lun] = ld(host_index)[ldn].device_type;
1895 /* increase assignment counters for statistics in /proc */
1896 IBM_DS(host_index).dynamical_assignments++;
1897 IBM_DS(host_index).ldn_assignments[ldn]++;
1898 } else
1899 /* panic here, because a device, found at boottime has
1900 vanished */
1901 panic("IBM MCA SCSI: ldn=0x%x, SCSI-device on (%d,%d) vanished!\n", ldn, target, cmd->device->lun);
1902 /* unassign again all ldns (pun,lun,ldn does not matter for remove) */
1903 immediate_assign(host_index, 0, 0, 0, REMOVE_LDN);
1904 /* remap all ldns, as written in the pun/lun table */
1905 lun = 0;
1906#ifdef CONFIG_SCSI_MULTI_LUN
1907 for (lun = 0; lun < 8; lun++)
1908#endif
1909 for (id = 0; id < max_pun; id++) {
1910 if (get_ldn(host_index)[id][lun] <= MAX_LOG_DEV)
1911 immediate_assign(host_index, id, lun, get_ldn(host_index)[id][lun], SET_LDN);
1912 }
1913 /* set back to normal interrupt_handling */
1914 local_checking_phase_flag(host_index) = 0;
1915#ifdef IM_DEBUG_PROBE
1916 /* Information on syslog terminal */
1917 printk("IBM MCA SCSI: ldn=0x%x dynamically reassigned to (%d,%d).\n", ldn, target, cmd->device->lun);
1918#endif
1919 /* increase next_ldn for next dynamical assignment */
1920 next_ldn(host_index)++;
1921 if (next_ldn(host_index) >= MAX_LOG_DEV)
1922 next_ldn(host_index) = 7;
1923 } else { /* wall against Linux accesses to the subsystem adapter */
1924 cmd->result = DID_BAD_TARGET << 16;
1925 if (done)
1926 done(cmd);
1927 return 0;
1928 }
1929 }
1930
1931 /*verify there is no command already in progress for this log dev */
1932 if (ld(host_index)[ldn].cmd)
1933 panic("IBM MCA SCSI: cmd already in progress for this ldn.\n");
1934
1935 /*save done in cmd, and save cmd for the interrupt handler */
1936 cmd->scsi_done = done;
1937 ld(host_index)[ldn].cmd = cmd;
1938
1939 /*fill scb information independent of the scsi command */
1940 scb = &(ld(host_index)[ldn].scb);
1941 ld(host_index)[ldn].tsb.dev_status = 0;
1942 scb->enable = IM_REPORT_TSB_ONLY_ON_ERROR | IM_RETRY_ENABLE;
1943 scb->tsb_adr = isa_virt_to_bus(&(ld(host_index)[ldn].tsb));
1944 scsi_cmd = cmd->cmnd[0];
1945
1946 if (cmd->use_sg) {
1947 i = cmd->use_sg;
1948 sl = (struct scatterlist *) (cmd->request_buffer);
1949 if (i > 16)
1950 panic("IBM MCA SCSI: scatter-gather list too long.\n");
1951 while (--i >= 0) {
1952 ld(host_index)[ldn].sge[i].address = (void *) (isa_page_to_bus(sl[i].page) + sl[i].offset);
1953 ld(host_index)[ldn].sge[i].byte_length = sl[i].length;
1954 }
1955 scb->enable |= IM_POINTER_TO_LIST;
1956 scb->sys_buf_adr = isa_virt_to_bus(&(ld(host_index)[ldn].sge[0]));
1957 scb->sys_buf_length = cmd->use_sg * sizeof(struct im_sge);
1958 } else {
1959 scb->sys_buf_adr = isa_virt_to_bus(cmd->request_buffer);
1960 /* recent Linux midlevel SCSI places 1024 byte for inquiry
1961 * command. Far too much for old PS/2 hardware. */
1962 switch (scsi_cmd) {
1963 /* avoid command errors by setting bufferlengths to
1964 * ANSI-standard. Beware of forcing it to 255,
1965 * this could SEGV the kernel!!! */
1966 case INQUIRY:
1967 case REQUEST_SENSE:
1968 case MODE_SENSE:
1969 case MODE_SELECT:
1970 if (cmd->request_bufflen > 255)
1971 scb->sys_buf_length = 255;
1972 else
1973 scb->sys_buf_length = cmd->request_bufflen;
1974 break;
1975 case TEST_UNIT_READY:
1976 scb->sys_buf_length = 0;
1977 break;
1978 default:
1979 scb->sys_buf_length = cmd->request_bufflen;
1980 break;
1981 }
1982 }
1983 /*fill scb information dependent on scsi command */
1984
1985#ifdef IM_DEBUG_CMD
1986 printk("issue scsi cmd=%02x to ldn=%d\n", scsi_cmd, ldn);
1987#endif
1988
1989 /* for specific device-type debugging: */
1990#ifdef IM_DEBUG_CMD_SPEC_DEV
1991 if (ld(host_index)[ldn].device_type == IM_DEBUG_CMD_DEVICE)
1992 printk("(SCSI-device-type=0x%x) issue scsi cmd=%02x to ldn=%d\n", ld(host_index)[ldn].device_type, scsi_cmd, ldn);
1993#endif
1994
1995 /* for possible panics store current command */
1996 last_scsi_command(host_index)[ldn] = scsi_cmd;
1997 last_scsi_type(host_index)[ldn] = IM_SCB;
1998 /* update statistical info */
1999 IBM_DS(host_index).total_accesses++;
2000 IBM_DS(host_index).ldn_access[ldn]++;
2001
2002 switch (scsi_cmd) {
2003 case READ_6:
2004 case WRITE_6:
2005 case READ_10:
2006 case WRITE_10:
2007 case READ_12:
2008 case WRITE_12:
2009 /* Distinguish between disk and other devices. Only disks (that are the
2010 most frequently accessed devices) should be supported by the
2011 IBM-SCSI-Subsystem commands. */
2012 switch (ld(host_index)[ldn].device_type) {
2013 case TYPE_DISK: /* for harddisks enter here ... */
2014 case TYPE_MOD: /* ... try it also for MO-drives (send flames as */
2015 /* you like, if this won't work.) */
2016 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || scsi_cmd == READ_12) {
2017 /* read command preparations */
2018 scb->enable |= IM_READ_CONTROL;
2019 IBM_DS(host_index).ldn_read_access[ldn]++; /* increase READ-access on ldn stat. */
2020 scb->command = IM_READ_DATA_CMD | IM_NO_DISCONNECT;
2021 } else { /* write command preparations */
2022 IBM_DS(host_index).ldn_write_access[ldn]++; /* increase write-count on ldn stat. */
2023 scb->command = IM_WRITE_DATA_CMD | IM_NO_DISCONNECT;
2024 }
2025 if (scsi_cmd == READ_6 || scsi_cmd == WRITE_6) {
2026 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[3]) << 0) | (((unsigned) cmd->cmnd[2]) << 8) | ((((unsigned) cmd->cmnd[1]) & 0x1f) << 16);
2027 scb->u2.blk.count = (unsigned) cmd->cmnd[4];
2028 } else {
2029 scb->u1.log_blk_adr = (((unsigned) cmd->cmnd[5]) << 0) | (((unsigned) cmd->cmnd[4]) << 8) | (((unsigned) cmd->cmnd[3]) << 16) | (((unsigned) cmd->cmnd[2]) << 24);
2030 scb->u2.blk.count = (((unsigned) cmd->cmnd[8]) << 0) | (((unsigned) cmd->cmnd[7]) << 8);
2031 }
2032 last_scsi_logical_block(host_index)[ldn] = scb->u1.log_blk_adr;
2033 last_scsi_blockcount(host_index)[ldn] = scb->u2.blk.count;
2034 scb->u2.blk.length = ld(host_index)[ldn].block_length;
2035 break;
2036 /* for other devices, enter here. Other types are not known by
2037 Linux! TYPE_NO_LUN is forbidden as valid device. */
2038 case TYPE_ROM:
2039 case TYPE_TAPE:
2040 case TYPE_PROCESSOR:
2041 case TYPE_WORM:
2042 case TYPE_SCANNER:
2043 case TYPE_MEDIUM_CHANGER:
2044 /* If there is a sequential-device, IBM recommends to use
2045 IM_OTHER_SCSI_CMD_CMD instead of subsystem READ/WRITE.
2046 This includes CD-ROM devices, too, due to the partial sequential
2047 read capabilities. */
2048 scb->command = IM_OTHER_SCSI_CMD_CMD;
2049 if (scsi_cmd == READ_6 || scsi_cmd == READ_10 || scsi_cmd == READ_12)
2050 /* enable READ */
2051 scb->enable |= IM_READ_CONTROL;
2052 scb->enable |= IM_BYPASS_BUFFER;
2053 scb->u1.scsi_cmd_length = cmd->cmd_len;
2054 memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2055 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2056 /* Read/write on this non-disk devices is also displayworthy,
2057 so flash-up the LED/display. */
2058 break;
2059 }
2060 break;
2061 case INQUIRY:
2062 IBM_DS(host_index).ldn_inquiry_access[ldn]++;
2063 scb->command = IM_DEVICE_INQUIRY_CMD;
2064 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2065 scb->u1.log_blk_adr = 0;
2066 break;
2067 case TEST_UNIT_READY:
2068 scb->command = IM_OTHER_SCSI_CMD_CMD;
2069 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2070 scb->u1.log_blk_adr = 0;
2071 scb->u1.scsi_cmd_length = 6;
2072 memcpy(scb->u2.scsi_command, cmd->cmnd, 6);
2073 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2074 break;
2075 case READ_CAPACITY:
2076 /* the length of system memory buffer must be exactly 8 bytes */
2077 scb->command = IM_READ_CAPACITY_CMD;
2078 scb->enable |= IM_READ_CONTROL | IM_BYPASS_BUFFER;
2079 if (scb->sys_buf_length > 8)
2080 scb->sys_buf_length = 8;
2081 break;
2082 /* Commands that need read-only-mode (system <- device): */
2083 case REQUEST_SENSE:
2084 scb->command = IM_REQUEST_SENSE_CMD;
2085 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2086 break;
2087 /* Commands that need write-only-mode (system -> device): */
2088 case MODE_SELECT:
2089 case MODE_SELECT_10:
2090 IBM_DS(host_index).ldn_modeselect_access[ldn]++;
2091 scb->command = IM_OTHER_SCSI_CMD_CMD;
2092 scb->enable |= IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER; /*Select needs WRITE-enabled */
2093 scb->u1.scsi_cmd_length = cmd->cmd_len;
2094 memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2095 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2096 break;
2097 /* For other commands, read-only is useful. Most other commands are
2098 running without an input-data-block. */
2099 default:
2100 scb->command = IM_OTHER_SCSI_CMD_CMD;
2101 scb->enable |= IM_READ_CONTROL | IM_SUPRESS_EXCEPTION_SHORT | IM_BYPASS_BUFFER;
2102 scb->u1.scsi_cmd_length = cmd->cmd_len;
2103 memcpy(scb->u2.scsi_command, cmd->cmnd, cmd->cmd_len);
2104 last_scsi_type(host_index)[ldn] = IM_LONG_SCB;
2105 break;
2106 }
2107 /*issue scb command, and return */
2108 if (++disk_rw_in_progress == 1)
2109 PS2_DISK_LED_ON(shpnt->host_no, target);
2110
2111 if (last_scsi_type(host_index)[ldn] == IM_LONG_SCB) {
2112 issue_cmd(host_index, isa_virt_to_bus(scb), IM_LONG_SCB | ldn);
2113 IBM_DS(host_index).long_scbs++;
2114 } else {
2115 issue_cmd(host_index, isa_virt_to_bus(scb), IM_SCB | ldn);
2116 IBM_DS(host_index).scbs++;
2117 }
2118 return 0;
2119}
2120
2121static int ibmmca_abort(Scsi_Cmnd * cmd)
2122{
2123 /* Abort does not work, as the adapter never generates an interrupt on
2124 * whatever situation is simulated, even when really pending commands
2125 * are running on the adapters' hardware ! */
2126
2127 struct Scsi_Host *shpnt;
2128 unsigned int ldn;
2129 void (*saved_done) (Scsi_Cmnd *);
2130 int target;
2131 int host_index;
2132 int max_pun;
2133 unsigned long imm_command;
2134
2135#ifdef IM_DEBUG_PROBE
2136 printk("IBM MCA SCSI: Abort subroutine called...\n");
2137#endif
2138
2139 shpnt = cmd->device->host;
2140 /* search for the right hostadapter */
2141 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2142
2143 if (!hosts[host_index]) { /* invalid hostadapter descriptor address */
2144 cmd->result = DID_NO_CONNECT << 16;
2145 if (cmd->scsi_done)
2146 (cmd->scsi_done) (cmd);
2147 shpnt = cmd->device->host;
2148#ifdef IM_DEBUG_PROBE
2149 printk(KERN_DEBUG "IBM MCA SCSI: Abort adapter selection failed!\n");
2150#endif
2151 return SUCCESS;
2152 }
2153 max_pun = subsystem_maxid(host_index);
2154 if (ibm_ansi_order) {
2155 target = max_pun - 1 - cmd->device->id;
2156 if ((target <= subsystem_pun(host_index)) && (cmd->device->id <= subsystem_pun(host_index)))
2157 target--;
2158 else if ((target >= subsystem_pun(host_index)) && (cmd->device->id >= subsystem_pun(host_index)))
2159 target++;
2160 } else
2161 target = cmd->device->id;
2162
2163 /* get logical device number, and disable system interrupts */
2164 printk(KERN_WARNING "IBM MCA SCSI: Sending abort to device pun=%d, lun=%d.\n", target, cmd->device->lun);
2165 ldn = get_ldn(host_index)[target][cmd->device->lun];
2166
2167 /*if cmd for this ldn has already finished, no need to abort */
2168 if (!ld(host_index)[ldn].cmd) {
2169 return SUCCESS;
2170 }
2171
2172 /* Clear ld.cmd, save done function, install internal done,
2173 * send abort immediate command (this enables sys. interrupts),
2174 * and wait until the interrupt arrives.
2175 */
2176 saved_done = cmd->scsi_done;
2177 cmd->scsi_done = internal_done;
2178 cmd->SCp.Status = 0;
2179 last_scsi_command(host_index)[ldn] = IM_ABORT_IMM_CMD;
2180 last_scsi_type(host_index)[ldn] = IM_IMM_CMD;
2181 imm_command = inl(IM_CMD_REG(host_index));
2182 imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */
2183 imm_command |= (unsigned long) (IM_ABORT_IMM_CMD);
2184 /* must wait for attention reg not busy */
2185 /* FIXME - timeout, politeness */
2186 while (1) {
2187 if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
2188 break;
2189 }
2190 /* write registers and enable system interrupts */
2191 outl(imm_command, IM_CMD_REG(host_index));
2192 outb(IM_IMM_CMD | ldn, IM_ATTN_REG(host_index));
2193#ifdef IM_DEBUG_PROBE
2194 printk("IBM MCA SCSI: Abort queued to adapter...\n");
2195#endif
2196 spin_unlock_irq(shpnt->host_lock);
2197 while (!cmd->SCp.Status)
2198 yield();
2199 spin_lock_irq(shpnt->host_lock);
2200 cmd->scsi_done = saved_done;
2201#ifdef IM_DEBUG_PROBE
2202 printk("IBM MCA SCSI: Abort returned with adapter response...\n");
2203#endif
2204
2205 /*if abort went well, call saved done, then return success or error */
2206 if (cmd->result == (DID_ABORT << 16))
2207 {
2208 cmd->result |= DID_ABORT << 16;
2209 if (cmd->scsi_done)
2210 (cmd->scsi_done) (cmd);
2211 ld(host_index)[ldn].cmd = NULL;
2212#ifdef IM_DEBUG_PROBE
2213 printk("IBM MCA SCSI: Abort finished with success.\n");
2214#endif
2215 return SUCCESS;
2216 } else {
2217 cmd->result |= DID_NO_CONNECT << 16;
2218 if (cmd->scsi_done)
2219 (cmd->scsi_done) (cmd);
2220 ld(host_index)[ldn].cmd = NULL;
2221#ifdef IM_DEBUG_PROBE
2222 printk("IBM MCA SCSI: Abort failed.\n");
2223#endif
2224 return FAILED;
2225 }
2226}
2227
2228static int ibmmca_host_reset(Scsi_Cmnd * cmd)
2229{
2230 struct Scsi_Host *shpnt;
2231 Scsi_Cmnd *cmd_aid;
2232 int ticks, i;
2233 int host_index;
2234 unsigned long imm_command;
2235
2236 if (cmd == NULL)
2237 BUG();
2238
2239 ticks = IM_RESET_DELAY * HZ;
2240 shpnt = cmd->device->host;
2241 /* search for the right hostadapter */
2242 for (host_index = 0; hosts[host_index] && hosts[host_index]->host_no != shpnt->host_no; host_index++);
2243
2244 if (!hosts[host_index]) /* invalid hostadapter descriptor address */
2245 return FAILED;
2246
2247 if (local_checking_phase_flag(host_index)) {
2248 printk(KERN_WARNING "IBM MCA SCSI: unable to reset while checking devices.\n");
2249 return FAILED;
2250 }
2251
2252 /* issue reset immediate command to subsystem, and wait for interrupt */
2253 printk("IBM MCA SCSI: resetting all devices.\n");
2254 reset_status(host_index) = IM_RESET_IN_PROGRESS;
2255 last_scsi_command(host_index)[0xf] = IM_RESET_IMM_CMD;
2256 last_scsi_type(host_index)[0xf] = IM_IMM_CMD;
2257 imm_command = inl(IM_CMD_REG(host_index));
2258 imm_command &= (unsigned long) (0xffff0000); /* mask reserved stuff */
2259 imm_command |= (unsigned long) (IM_RESET_IMM_CMD);
2260 /* must wait for attention reg not busy */
2261 while (1) {
2262 if (!(inb(IM_STAT_REG(host_index)) & IM_BUSY))
2263 break;
2264 spin_unlock_irq(shpnt->host_lock);
2265 yield();
2266 spin_lock_irq(shpnt->host_lock);
2267 }
2268 /*write registers and enable system interrupts */
2269 outl(imm_command, IM_CMD_REG(host_index));
2270 outb(IM_IMM_CMD | 0xf, IM_ATTN_REG(host_index));
2271 /* wait for interrupt finished or intr_stat register to be set, as the
2272 * interrupt will not be executed, while we are in here! */
2273
2274 /* FIXME: This is really really icky we so want a sleeping version of this ! */
2275 while (reset_status(host_index) == IM_RESET_IN_PROGRESS && --ticks && ((inb(IM_INTR_REG(host_index)) & 0x8f) != 0x8f)) {
2276 udelay((1 + 999 / HZ) * 1000);
2277 barrier();
2278 }
2279 /* if reset did not complete, just return an error */
2280 if (!ticks) {
2281 printk(KERN_ERR "IBM MCA SCSI: reset did not complete within %d seconds.\n", IM_RESET_DELAY);
2282 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
2283 return FAILED;
2284 }
2285
2286 if ((inb(IM_INTR_REG(host_index)) & 0x8f) == 0x8f) {
2287 /* analysis done by this routine and not by the intr-routine */
2288 if (inb(IM_INTR_REG(host_index)) == 0xaf)
2289 reset_status(host_index) = IM_RESET_FINISHED_OK_NO_INT;
2290 else if (inb(IM_INTR_REG(host_index)) == 0xcf)
2291 reset_status(host_index) = IM_RESET_FINISHED_FAIL;
2292 else /* failed, 4get it */
2293 reset_status(host_index) = IM_RESET_NOT_IN_PROGRESS_NO_INT;
2294 outb(IM_EOI | 0xf, IM_ATTN_REG(host_index));
2295 }
2296
2297 /* if reset failed, just return an error */
2298 if (reset_status(host_index) == IM_RESET_FINISHED_FAIL) {
2299 printk(KERN_ERR "IBM MCA SCSI: reset failed.\n");
2300 return FAILED;
2301 }
2302
2303 /* so reset finished ok - call outstanding done's, and return success */
2304 printk(KERN_INFO "IBM MCA SCSI: Reset successfully completed.\n");
2305 for (i = 0; i < MAX_LOG_DEV; i++) {
2306 cmd_aid = ld(host_index)[i].cmd;
2307 if (cmd_aid && cmd_aid->scsi_done) {
2308 ld(host_index)[i].cmd = NULL;
2309 cmd_aid->result = DID_RESET << 16;
2310 }
2311 }
2312 return SUCCESS;
2313}
2314
2315static int ibmmca_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info)
2316{
2317 int size = capacity;
2318 info[0] = 64;
2319 info[1] = 32;
2320 info[2] = size / (info[0] * info[1]);
2321 if (info[2] >= 1024) {
2322 info[0] = 128;
2323 info[1] = 63;
2324 info[2] = size / (info[0] * info[1]);
2325 if (info[2] >= 1024) {
2326 info[0] = 255;
2327 info[1] = 63;
2328 info[2] = size / (info[0] * info[1]);
2329 if (info[2] >= 1024)
2330 info[2] = 1023;
2331 }
2332 }
2333 return 0;
2334}
2335
2336/* calculate percentage of total accesses on a ldn */
2337static int ldn_access_load(int host_index, int ldn)
2338{
2339 if (IBM_DS(host_index).total_accesses == 0)
2340 return (0);
2341 if (IBM_DS(host_index).ldn_access[ldn] == 0)
2342 return (0);
2343 return (IBM_DS(host_index).ldn_access[ldn] * 100) / IBM_DS(host_index).total_accesses;
2344}
2345
2346/* calculate total amount of r/w-accesses */
2347static int ldn_access_total_read_write(int host_index)
2348{
2349 int a;
2350 int i;
2351
2352 a = 0;
2353 for (i = 0; i <= MAX_LOG_DEV; i++)
2354 a += IBM_DS(host_index).ldn_read_access[i] + IBM_DS(host_index).ldn_write_access[i];
2355 return (a);
2356}
2357
2358static int ldn_access_total_inquiry(int host_index)
2359{
2360 int a;
2361 int i;
2362
2363 a = 0;
2364 for (i = 0; i <= MAX_LOG_DEV; i++)
2365 a += IBM_DS(host_index).ldn_inquiry_access[i];
2366 return (a);
2367}
2368
2369static int ldn_access_total_modeselect(int host_index)
2370{
2371 int a;
2372 int i;
2373
2374 a = 0;
2375 for (i = 0; i <= MAX_LOG_DEV; i++)
2376 a += IBM_DS(host_index).ldn_modeselect_access[i];
2377 return (a);
2378}
2379
2380/* routine to display info in the proc-fs-structure (a deluxe feature) */
2381static int ibmmca_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start, off_t offset, int length, int inout)
2382{
2383 int len = 0;
2384 int i, id, lun, host_index;
2385 unsigned long flags;
2386 int max_pun;
2387
2388 for (i = 0; hosts[i] && hosts[i] != shpnt; i++);
2389
2390 spin_lock_irqsave(hosts[i]->host_lock, flags); /* Check it */
2391 host_index = i;
2392 if (!shpnt) {
2393 len += sprintf(buffer + len, "\nIBM MCA SCSI: Can't find adapter for host number %d\n",
2394 shpnt->host_no);
2395 return len;
2396 }
2397 max_pun = subsystem_maxid(host_index);
2398
2399 len += sprintf(buffer + len, "\n IBM-SCSI-Subsystem-Linux-Driver, Version %s\n\n\n", IBMMCA_SCSI_DRIVER_VERSION);
2400 len += sprintf(buffer + len, " SCSI Access-Statistics:\n");
2401 len += sprintf(buffer + len, " Device Scanning Order....: %s\n", (ibm_ansi_order) ? "IBM/ANSI" : "New Industry Standard");
2402#ifdef CONFIG_SCSI_MULTI_LUN
2403 len += sprintf(buffer + len, " Multiple LUN probing.....: Yes\n");
2404#else
2405 len += sprintf(buffer + len, " Multiple LUN probing.....: No\n");
2406#endif
2407 len += sprintf(buffer + len, " This Hostnumber..........: %d\n", shpnt->host_no);
2408 len += sprintf(buffer + len, " Base I/O-Port............: 0x%x\n", (unsigned int) (IM_CMD_REG(host_index)));
2409 len += sprintf(buffer + len, " (Shared) IRQ.............: %d\n", IM_IRQ);
2410 len += sprintf(buffer + len, " Total Interrupts.........: %d\n", IBM_DS(host_index).total_interrupts);
2411 len += sprintf(buffer + len, " Total SCSI Accesses......: %d\n", IBM_DS(host_index).total_accesses);
2412 len += sprintf(buffer + len, " Total short SCBs.........: %d\n", IBM_DS(host_index).scbs);
2413 len += sprintf(buffer + len, " Total long SCBs..........: %d\n", IBM_DS(host_index).long_scbs);
2414 len += sprintf(buffer + len, " Total SCSI READ/WRITE..: %d\n", ldn_access_total_read_write(host_index));
2415 len += sprintf(buffer + len, " Total SCSI Inquiries...: %d\n", ldn_access_total_inquiry(host_index));
2416 len += sprintf(buffer + len, " Total SCSI Modeselects.: %d\n", ldn_access_total_modeselect(host_index));
2417 len += sprintf(buffer + len, " Total SCSI other cmds..: %d\n", IBM_DS(host_index).total_accesses - ldn_access_total_read_write(host_index)
2418 - ldn_access_total_modeselect(host_index)
2419 - ldn_access_total_inquiry(host_index));
2420 len += sprintf(buffer + len, " Total SCSI command fails.: %d\n\n", IBM_DS(host_index).total_errors);
2421 len += sprintf(buffer + len, " Logical-Device-Number (LDN) Access-Statistics:\n");
2422 len += sprintf(buffer + len, " LDN | Accesses [%%] | READ | WRITE | ASSIGNMENTS\n");
2423 len += sprintf(buffer + len, " -----|--------------|-----------|-----------|--------------\n");
2424 for (i = 0; i <= MAX_LOG_DEV; i++)
2425 len += sprintf(buffer + len, " %2X | %3d | %8d | %8d | %8d\n", i, ldn_access_load(host_index, i), IBM_DS(host_index).ldn_read_access[i], IBM_DS(host_index).ldn_write_access[i], IBM_DS(host_index).ldn_assignments[i]);
2426 len += sprintf(buffer + len, " -----------------------------------------------------------\n\n");
2427 len += sprintf(buffer + len, " Dynamical-LDN-Assignment-Statistics:\n");
2428 len += sprintf(buffer + len, " Number of physical SCSI-devices..: %d (+ Adapter)\n", IBM_DS(host_index).total_scsi_devices);
2429 len += sprintf(buffer + len, " Dynamical Assignment necessary...: %s\n", IBM_DS(host_index).dyn_flag ? "Yes" : "No ");
2430 len += sprintf(buffer + len, " Next LDN to be assigned..........: 0x%x\n", next_ldn(host_index));
2431 len += sprintf(buffer + len, " Dynamical assignments done yet...: %d\n", IBM_DS(host_index).dynamical_assignments);
2432 len += sprintf(buffer + len, "\n Current SCSI-Device-Mapping:\n");
2433 len += sprintf(buffer + len, " Physical SCSI-Device Map Logical SCSI-Device Map\n");
2434 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");
2435 for (id = 0; id < max_pun; id++) {
2436 len += sprintf(buffer + len, " %2d ", id);
2437 for (lun = 0; lun < 8; lun++)
2438 len += sprintf(buffer + len, "%2s ", ti_p(get_scsi(host_index)[id][lun]));
2439 len += sprintf(buffer + len, " %2d ", id);
2440 for (lun = 0; lun < 8; lun++)
2441 len += sprintf(buffer + len, "%2s ", ti_l(get_ldn(host_index)[id][lun]));
2442 len += sprintf(buffer + len, "\n");
2443 }
2444
2445 len += sprintf(buffer + len, "(A = IBM-Subsystem, D = Harddisk, T = Tapedrive, P = Processor, W = WORM,\n");
2446 len += sprintf(buffer + len, " R = CD-ROM, S = Scanner, M = MO-Drive, C = Medium-Changer, + = unprovided LUN,\n");
2447 len += sprintf(buffer + len, " - = nothing found, nothing assigned or unprobed LUN)\n\n");
2448
2449 *start = buffer + offset;
2450 len -= offset;
2451 if (len > length)
2452 len = length;
2453 spin_unlock_irqrestore(shpnt->host_lock, flags);
2454 return len;
2455}
2456
2457static int option_setup(char *str)
2458{
2459 int ints[IM_MAX_HOSTS];
2460 char *cur = str;
2461 int i = 1;
2462
2463 while (cur && isdigit(*cur) && i <= IM_MAX_HOSTS) {
2464 ints[i++] = simple_strtoul(cur, NULL, 0);
2465 if ((cur = strchr(cur, ',')) != NULL)
2466 cur++;
2467 }
2468 ints[0] = i - 1;
2469 internal_ibmmca_scsi_setup(cur, ints);
2470 return 0;
2471}
2472
2473__setup("ibmmcascsi=", option_setup);
2474
2475static Scsi_Host_Template driver_template = {
2476 .proc_name = "ibmmca",
2477 .proc_info = ibmmca_proc_info,
2478 .name = "IBM SCSI-Subsystem",
2479 .detect = ibmmca_detect,
2480 .release = ibmmca_release,
2481 .queuecommand = ibmmca_queuecommand,
2482 .eh_abort_handler = ibmmca_abort,
2483 .eh_host_reset_handler = ibmmca_host_reset,
2484 .bios_param = ibmmca_biosparam,
2485 .can_queue = 16,
2486 .this_id = 7,
2487 .sg_tablesize = 16,
2488 .cmd_per_lun = 1,
2489 .use_clustering = ENABLE_CLUSTERING,
2490};
2491#include "scsi_module.c"