OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [ibmmca.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.