1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun The author respectfully requests that any modifications to this software be
10*4882a593Smuzhiyun sent directly to him for evaluation and testing.
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
13*4882a593Smuzhiyun advice has been invaluable, to David Gentzel, for writing the original Linux
14*4882a593Smuzhiyun BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
17*4882a593Smuzhiyun Manager available as freely redistributable source code.
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun */
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #ifndef _BUSLOGIC_H
22*4882a593Smuzhiyun #define _BUSLOGIC_H
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #ifndef PACKED
26*4882a593Smuzhiyun #define PACKED __attribute__((packed))
27*4882a593Smuzhiyun #endif
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun /*
30*4882a593Smuzhiyun Define the maximum number of BusLogic Host Adapters supported by this driver.
31*4882a593Smuzhiyun */
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define BLOGIC_MAX_ADAPTERS 16
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun /*
37*4882a593Smuzhiyun Define the maximum number of Target Devices supported by this driver.
38*4882a593Smuzhiyun */
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define BLOGIC_MAXDEV 16
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /*
44*4882a593Smuzhiyun Define the maximum number of Scatter/Gather Segments used by this driver.
45*4882a593Smuzhiyun For optimal performance, it is important that this limit be at least as
46*4882a593Smuzhiyun large as the largest single request generated by the I/O Subsystem.
47*4882a593Smuzhiyun */
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define BLOGIC_SG_LIMIT 128
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun /*
53*4882a593Smuzhiyun Define the maximum, maximum automatic, minimum automatic, and default Queue
54*4882a593Smuzhiyun Depth to allow for Target Devices depending on whether or not they support
55*4882a593Smuzhiyun Tagged Queuing and whether or not ISA Bounce Buffers are required.
56*4882a593Smuzhiyun */
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define BLOGIC_MAX_TAG_DEPTH 64
59*4882a593Smuzhiyun #define BLOGIC_MAX_AUTO_TAG_DEPTH 28
60*4882a593Smuzhiyun #define BLOGIC_MIN_AUTO_TAG_DEPTH 7
61*4882a593Smuzhiyun #define BLOGIC_TAG_DEPTH_BB 3
62*4882a593Smuzhiyun #define BLOGIC_UNTAG_DEPTH 3
63*4882a593Smuzhiyun #define BLOGIC_UNTAG_DEPTH_BB 2
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun Define the default amount of time in seconds to wait between a Host Adapter
68*4882a593Smuzhiyun Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands.
69*4882a593Smuzhiyun Some SCSI devices get confused if they receive SCSI commands too soon after
70*4882a593Smuzhiyun a SCSI Bus Reset.
71*4882a593Smuzhiyun */
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun #define BLOGIC_BUS_SETTLE_TIME 2
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /*
77*4882a593Smuzhiyun Define the maximum number of Mailboxes that should be used for MultiMaster
78*4882a593Smuzhiyun Host Adapters. This number is chosen to be larger than the maximum Host
79*4882a593Smuzhiyun Adapter Queue Depth and small enough so that the Host Adapter structure
80*4882a593Smuzhiyun does not cross an allocation block size boundary.
81*4882a593Smuzhiyun */
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define BLOGIC_MAX_MAILBOX 211
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun /*
87*4882a593Smuzhiyun Define the number of CCBs that should be allocated as a group to optimize
88*4882a593Smuzhiyun Kernel memory allocation.
89*4882a593Smuzhiyun */
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun #define BLOGIC_CCB_GRP_ALLOCSIZE 7
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /*
95*4882a593Smuzhiyun Define the Host Adapter Line and Message Buffer Sizes.
96*4882a593Smuzhiyun */
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun #define BLOGIC_LINEBUF_SIZE 100
99*4882a593Smuzhiyun #define BLOGIC_MSGBUF_SIZE 9700
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /*
103*4882a593Smuzhiyun Define the Driver Message Levels.
104*4882a593Smuzhiyun */
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun enum blogic_msglevel {
107*4882a593Smuzhiyun BLOGIC_ANNOUNCE_LEVEL = 0,
108*4882a593Smuzhiyun BLOGIC_INFO_LEVEL = 1,
109*4882a593Smuzhiyun BLOGIC_NOTICE_LEVEL = 2,
110*4882a593Smuzhiyun BLOGIC_WARN_LEVEL = 3,
111*4882a593Smuzhiyun BLOGIC_ERR_LEVEL = 4
112*4882a593Smuzhiyun };
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun static char *blogic_msglevelmap[] = { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR };
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /*
118*4882a593Smuzhiyun Define Driver Message macros.
119*4882a593Smuzhiyun */
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun #define blogic_announce(format, args...) \
122*4882a593Smuzhiyun blogic_msg(BLOGIC_ANNOUNCE_LEVEL, format, ##args)
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun #define blogic_info(format, args...) \
125*4882a593Smuzhiyun blogic_msg(BLOGIC_INFO_LEVEL, format, ##args)
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun #define blogic_notice(format, args...) \
128*4882a593Smuzhiyun blogic_msg(BLOGIC_NOTICE_LEVEL, format, ##args)
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun #define blogic_warn(format, args...) \
131*4882a593Smuzhiyun blogic_msg(BLOGIC_WARN_LEVEL, format, ##args)
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #define blogic_err(format, args...) \
134*4882a593Smuzhiyun blogic_msg(BLOGIC_ERR_LEVEL, format, ##args)
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /*
138*4882a593Smuzhiyun Define the types of BusLogic Host Adapters that are supported and the number
139*4882a593Smuzhiyun of I/O Addresses required by each type.
140*4882a593Smuzhiyun */
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun enum blogic_adapter_type {
143*4882a593Smuzhiyun BLOGIC_MULTIMASTER = 1,
144*4882a593Smuzhiyun BLOGIC_FLASHPOINT = 2
145*4882a593Smuzhiyun } PACKED;
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #define BLOGIC_MULTIMASTER_ADDR_COUNT 4
148*4882a593Smuzhiyun #define BLOGIC_FLASHPOINT_ADDR_COUNT 256
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun static int blogic_adapter_addr_count[3] = { 0, BLOGIC_MULTIMASTER_ADDR_COUNT, BLOGIC_FLASHPOINT_ADDR_COUNT };
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun /*
154*4882a593Smuzhiyun Define macros for testing the Host Adapter Type.
155*4882a593Smuzhiyun */
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun #ifdef CONFIG_SCSI_FLASHPOINT
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun #define blogic_multimaster_type(adapter) \
160*4882a593Smuzhiyun (adapter->adapter_type == BLOGIC_MULTIMASTER)
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun #define blogic_flashpoint_type(adapter) \
163*4882a593Smuzhiyun (adapter->adapter_type == BLOGIC_FLASHPOINT)
164*4882a593Smuzhiyun
165*4882a593Smuzhiyun #else
166*4882a593Smuzhiyun
167*4882a593Smuzhiyun #define blogic_multimaster_type(adapter) (true)
168*4882a593Smuzhiyun #define blogic_flashpoint_type(adapter) (false)
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /*
174*4882a593Smuzhiyun Define the possible Host Adapter Bus Types.
175*4882a593Smuzhiyun */
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun enum blogic_adapter_bus_type {
178*4882a593Smuzhiyun BLOGIC_UNKNOWN_BUS = 0,
179*4882a593Smuzhiyun BLOGIC_ISA_BUS = 1,
180*4882a593Smuzhiyun BLOGIC_EISA_BUS = 2,
181*4882a593Smuzhiyun BLOGIC_PCI_BUS = 3,
182*4882a593Smuzhiyun BLOGIC_VESA_BUS = 4,
183*4882a593Smuzhiyun BLOGIC_MCA_BUS = 5
184*4882a593Smuzhiyun } PACKED;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun static char *blogic_adapter_busnames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun static enum blogic_adapter_bus_type blogic_adater_bus_types[] = {
189*4882a593Smuzhiyun BLOGIC_VESA_BUS, /* BT-4xx */
190*4882a593Smuzhiyun BLOGIC_ISA_BUS, /* BT-5xx */
191*4882a593Smuzhiyun BLOGIC_MCA_BUS, /* BT-6xx */
192*4882a593Smuzhiyun BLOGIC_EISA_BUS, /* BT-7xx */
193*4882a593Smuzhiyun BLOGIC_UNKNOWN_BUS, /* BT-8xx */
194*4882a593Smuzhiyun BLOGIC_PCI_BUS /* BT-9xx */
195*4882a593Smuzhiyun };
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /*
198*4882a593Smuzhiyun Define the possible Host Adapter BIOS Disk Geometry Translations.
199*4882a593Smuzhiyun */
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun enum blogic_bios_diskgeometry {
202*4882a593Smuzhiyun BLOGIC_BIOS_NODISK = 0,
203*4882a593Smuzhiyun BLOGIC_BIOS_DISK64x32 = 1,
204*4882a593Smuzhiyun BLOGIC_BIOS_DISK128x32 = 2,
205*4882a593Smuzhiyun BLOGIC_BIOS_DISK255x63 = 3
206*4882a593Smuzhiyun } PACKED;
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /*
210*4882a593Smuzhiyun Define a 10^18 Statistics Byte Counter data type.
211*4882a593Smuzhiyun */
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun struct blogic_byte_count {
214*4882a593Smuzhiyun unsigned int units;
215*4882a593Smuzhiyun unsigned int billions;
216*4882a593Smuzhiyun };
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /*
220*4882a593Smuzhiyun Define the structure for I/O Address and Bus Probing Information.
221*4882a593Smuzhiyun */
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun struct blogic_probeinfo {
224*4882a593Smuzhiyun enum blogic_adapter_type adapter_type;
225*4882a593Smuzhiyun enum blogic_adapter_bus_type adapter_bus_type;
226*4882a593Smuzhiyun unsigned long io_addr;
227*4882a593Smuzhiyun unsigned long pci_addr;
228*4882a593Smuzhiyun struct pci_dev *pci_device;
229*4882a593Smuzhiyun unsigned char bus;
230*4882a593Smuzhiyun unsigned char dev;
231*4882a593Smuzhiyun unsigned char irq_ch;
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun /*
235*4882a593Smuzhiyun Define the Probe Options.
236*4882a593Smuzhiyun */
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun struct blogic_probe_options {
239*4882a593Smuzhiyun bool noprobe:1; /* Bit 0 */
240*4882a593Smuzhiyun bool noprobe_isa:1; /* Bit 1 */
241*4882a593Smuzhiyun bool noprobe_pci:1; /* Bit 2 */
242*4882a593Smuzhiyun bool nosort_pci:1; /* Bit 3 */
243*4882a593Smuzhiyun bool multimaster_first:1; /* Bit 4 */
244*4882a593Smuzhiyun bool flashpoint_first:1; /* Bit 5 */
245*4882a593Smuzhiyun bool limited_isa:1; /* Bit 6 */
246*4882a593Smuzhiyun bool probe330:1; /* Bit 7 */
247*4882a593Smuzhiyun bool probe334:1; /* Bit 8 */
248*4882a593Smuzhiyun bool probe230:1; /* Bit 9 */
249*4882a593Smuzhiyun bool probe234:1; /* Bit 10 */
250*4882a593Smuzhiyun bool probe130:1; /* Bit 11 */
251*4882a593Smuzhiyun bool probe134:1; /* Bit 12 */
252*4882a593Smuzhiyun };
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun /*
255*4882a593Smuzhiyun Define the Global Options.
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun struct blogic_global_options {
259*4882a593Smuzhiyun bool trace_probe:1; /* Bit 0 */
260*4882a593Smuzhiyun bool trace_hw_reset:1; /* Bit 1 */
261*4882a593Smuzhiyun bool trace_config:1; /* Bit 2 */
262*4882a593Smuzhiyun bool trace_err:1; /* Bit 3 */
263*4882a593Smuzhiyun };
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun /*
266*4882a593Smuzhiyun Define the BusLogic SCSI Host Adapter I/O Register Offsets.
267*4882a593Smuzhiyun */
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun #define BLOGIC_CNTRL_REG 0 /* WO register */
270*4882a593Smuzhiyun #define BLOGIC_STATUS_REG 0 /* RO register */
271*4882a593Smuzhiyun #define BLOGIC_CMD_PARM_REG 1 /* WO register */
272*4882a593Smuzhiyun #define BLOGIC_DATAIN_REG 1 /* RO register */
273*4882a593Smuzhiyun #define BLOGIC_INT_REG 2 /* RO register */
274*4882a593Smuzhiyun #define BLOGIC_GEOMETRY_REG 3 /* RO register */
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun /*
277*4882a593Smuzhiyun Define the structure of the write-only Control Register.
278*4882a593Smuzhiyun */
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun union blogic_cntrl_reg {
281*4882a593Smuzhiyun unsigned char all;
282*4882a593Smuzhiyun struct {
283*4882a593Smuzhiyun unsigned char:4; /* Bits 0-3 */
284*4882a593Smuzhiyun bool bus_reset:1; /* Bit 4 */
285*4882a593Smuzhiyun bool int_reset:1; /* Bit 5 */
286*4882a593Smuzhiyun bool soft_reset:1; /* Bit 6 */
287*4882a593Smuzhiyun bool hard_reset:1; /* Bit 7 */
288*4882a593Smuzhiyun } cr;
289*4882a593Smuzhiyun };
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun /*
292*4882a593Smuzhiyun Define the structure of the read-only Status Register.
293*4882a593Smuzhiyun */
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun union blogic_stat_reg {
296*4882a593Smuzhiyun unsigned char all;
297*4882a593Smuzhiyun struct {
298*4882a593Smuzhiyun bool cmd_invalid:1; /* Bit 0 */
299*4882a593Smuzhiyun bool rsvd:1; /* Bit 1 */
300*4882a593Smuzhiyun bool datain_ready:1; /* Bit 2 */
301*4882a593Smuzhiyun bool cmd_param_busy:1; /* Bit 3 */
302*4882a593Smuzhiyun bool adapter_ready:1; /* Bit 4 */
303*4882a593Smuzhiyun bool init_reqd:1; /* Bit 5 */
304*4882a593Smuzhiyun bool diag_failed:1; /* Bit 6 */
305*4882a593Smuzhiyun bool diag_active:1; /* Bit 7 */
306*4882a593Smuzhiyun } sr;
307*4882a593Smuzhiyun };
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun /*
310*4882a593Smuzhiyun Define the structure of the read-only Interrupt Register.
311*4882a593Smuzhiyun */
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun union blogic_int_reg {
314*4882a593Smuzhiyun unsigned char all;
315*4882a593Smuzhiyun struct {
316*4882a593Smuzhiyun bool mailin_loaded:1; /* Bit 0 */
317*4882a593Smuzhiyun bool mailout_avail:1; /* Bit 1 */
318*4882a593Smuzhiyun bool cmd_complete:1; /* Bit 2 */
319*4882a593Smuzhiyun bool ext_busreset:1; /* Bit 3 */
320*4882a593Smuzhiyun unsigned char rsvd:3; /* Bits 4-6 */
321*4882a593Smuzhiyun bool int_valid:1; /* Bit 7 */
322*4882a593Smuzhiyun } ir;
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /*
326*4882a593Smuzhiyun Define the structure of the read-only Geometry Register.
327*4882a593Smuzhiyun */
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun union blogic_geo_reg {
330*4882a593Smuzhiyun unsigned char all;
331*4882a593Smuzhiyun struct {
332*4882a593Smuzhiyun enum blogic_bios_diskgeometry d0_geo:2; /* Bits 0-1 */
333*4882a593Smuzhiyun enum blogic_bios_diskgeometry d1_geo:2; /* Bits 2-3 */
334*4882a593Smuzhiyun unsigned char:3; /* Bits 4-6 */
335*4882a593Smuzhiyun bool ext_trans_enable:1; /* Bit 7 */
336*4882a593Smuzhiyun } gr;
337*4882a593Smuzhiyun };
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /*
340*4882a593Smuzhiyun Define the BusLogic SCSI Host Adapter Command Register Operation Codes.
341*4882a593Smuzhiyun */
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun enum blogic_opcode {
344*4882a593Smuzhiyun BLOGIC_TEST_CMP_COMPLETE = 0x00,
345*4882a593Smuzhiyun BLOGIC_INIT_MBOX = 0x01,
346*4882a593Smuzhiyun BLOGIC_EXEC_MBOX_CMD = 0x02,
347*4882a593Smuzhiyun BLOGIC_EXEC_BIOS_CMD = 0x03,
348*4882a593Smuzhiyun BLOGIC_GET_BOARD_ID = 0x04,
349*4882a593Smuzhiyun BLOGIC_ENABLE_OUTBOX_AVAIL_INT = 0x05,
350*4882a593Smuzhiyun BLOGIC_SET_SELECT_TIMEOUT = 0x06,
351*4882a593Smuzhiyun BLOGIC_SET_PREEMPT_TIME = 0x07,
352*4882a593Smuzhiyun BLOGIC_SET_TIMEOFF_BUS = 0x08,
353*4882a593Smuzhiyun BLOGIC_SET_TXRATE = 0x09,
354*4882a593Smuzhiyun BLOGIC_INQ_DEV0TO7 = 0x0A,
355*4882a593Smuzhiyun BLOGIC_INQ_CONFIG = 0x0B,
356*4882a593Smuzhiyun BLOGIC_TGT_MODE = 0x0C,
357*4882a593Smuzhiyun BLOGIC_INQ_SETUPINFO = 0x0D,
358*4882a593Smuzhiyun BLOGIC_WRITE_LOCALRAM = 0x1A,
359*4882a593Smuzhiyun BLOGIC_READ_LOCALRAM = 0x1B,
360*4882a593Smuzhiyun BLOGIC_WRITE_BUSMASTER_FIFO = 0x1C,
361*4882a593Smuzhiyun BLOGIC_READ_BUSMASTER_FIFO = 0x1D,
362*4882a593Smuzhiyun BLOGIC_ECHO_CMDDATA = 0x1F,
363*4882a593Smuzhiyun BLOGIC_ADAPTER_DIAG = 0x20,
364*4882a593Smuzhiyun BLOGIC_SET_OPTIONS = 0x21,
365*4882a593Smuzhiyun BLOGIC_INQ_DEV8TO15 = 0x23,
366*4882a593Smuzhiyun BLOGIC_INQ_DEV = 0x24,
367*4882a593Smuzhiyun BLOGIC_DISABLE_INT = 0x25,
368*4882a593Smuzhiyun BLOGIC_INIT_EXT_MBOX = 0x81,
369*4882a593Smuzhiyun BLOGIC_EXEC_SCS_CMD = 0x83,
370*4882a593Smuzhiyun BLOGIC_INQ_FWVER_D3 = 0x84,
371*4882a593Smuzhiyun BLOGIC_INQ_FWVER_LETTER = 0x85,
372*4882a593Smuzhiyun BLOGIC_INQ_PCI_INFO = 0x86,
373*4882a593Smuzhiyun BLOGIC_INQ_MODELNO = 0x8B,
374*4882a593Smuzhiyun BLOGIC_INQ_SYNC_PERIOD = 0x8C,
375*4882a593Smuzhiyun BLOGIC_INQ_EXTSETUP = 0x8D,
376*4882a593Smuzhiyun BLOGIC_STRICT_RR = 0x8F,
377*4882a593Smuzhiyun BLOGIC_STORE_LOCALRAM = 0x90,
378*4882a593Smuzhiyun BLOGIC_FETCH_LOCALRAM = 0x91,
379*4882a593Smuzhiyun BLOGIC_STORE_TO_EEPROM = 0x92,
380*4882a593Smuzhiyun BLOGIC_LOAD_AUTOSCSICODE = 0x94,
381*4882a593Smuzhiyun BLOGIC_MOD_IOADDR = 0x95,
382*4882a593Smuzhiyun BLOGIC_SETCCB_FMT = 0x96,
383*4882a593Smuzhiyun BLOGIC_WRITE_INQBUF = 0x9A,
384*4882a593Smuzhiyun BLOGIC_READ_INQBUF = 0x9B,
385*4882a593Smuzhiyun BLOGIC_FLASH_LOAD = 0xA7,
386*4882a593Smuzhiyun BLOGIC_READ_SCAMDATA = 0xA8,
387*4882a593Smuzhiyun BLOGIC_WRITE_SCAMDATA = 0xA9
388*4882a593Smuzhiyun };
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun /*
391*4882a593Smuzhiyun Define the Inquire Board ID reply structure.
392*4882a593Smuzhiyun */
393*4882a593Smuzhiyun
394*4882a593Smuzhiyun struct blogic_board_id {
395*4882a593Smuzhiyun unsigned char type; /* Byte 0 */
396*4882a593Smuzhiyun unsigned char custom_features; /* Byte 1 */
397*4882a593Smuzhiyun unsigned char fw_ver_digit1; /* Byte 2 */
398*4882a593Smuzhiyun unsigned char fw_ver_digit2; /* Byte 3 */
399*4882a593Smuzhiyun };
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun /*
402*4882a593Smuzhiyun Define the Inquire Configuration reply structure.
403*4882a593Smuzhiyun */
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun struct blogic_config {
406*4882a593Smuzhiyun unsigned char:5; /* Byte 0 Bits 0-4 */
407*4882a593Smuzhiyun bool dma_ch5:1; /* Byte 0 Bit 5 */
408*4882a593Smuzhiyun bool dma_ch6:1; /* Byte 0 Bit 6 */
409*4882a593Smuzhiyun bool dma_ch7:1; /* Byte 0 Bit 7 */
410*4882a593Smuzhiyun bool irq_ch9:1; /* Byte 1 Bit 0 */
411*4882a593Smuzhiyun bool irq_ch10:1; /* Byte 1 Bit 1 */
412*4882a593Smuzhiyun bool irq_ch11:1; /* Byte 1 Bit 2 */
413*4882a593Smuzhiyun bool irq_ch12:1; /* Byte 1 Bit 3 */
414*4882a593Smuzhiyun unsigned char:1; /* Byte 1 Bit 4 */
415*4882a593Smuzhiyun bool irq_ch14:1; /* Byte 1 Bit 5 */
416*4882a593Smuzhiyun bool irq_ch15:1; /* Byte 1 Bit 6 */
417*4882a593Smuzhiyun unsigned char:1; /* Byte 1 Bit 7 */
418*4882a593Smuzhiyun unsigned char id:4; /* Byte 2 Bits 0-3 */
419*4882a593Smuzhiyun unsigned char:4; /* Byte 2 Bits 4-7 */
420*4882a593Smuzhiyun };
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun /*
423*4882a593Smuzhiyun Define the Inquire Setup Information reply structure.
424*4882a593Smuzhiyun */
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun struct blogic_syncval {
427*4882a593Smuzhiyun unsigned char offset:4; /* Bits 0-3 */
428*4882a593Smuzhiyun unsigned char tx_period:3; /* Bits 4-6 */
429*4882a593Smuzhiyun bool sync:1; /* Bit 7 */
430*4882a593Smuzhiyun };
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun struct blogic_setup_info {
433*4882a593Smuzhiyun bool sync:1; /* Byte 0 Bit 0 */
434*4882a593Smuzhiyun bool parity:1; /* Byte 0 Bit 1 */
435*4882a593Smuzhiyun unsigned char:6; /* Byte 0 Bits 2-7 */
436*4882a593Smuzhiyun unsigned char tx_rate; /* Byte 1 */
437*4882a593Smuzhiyun unsigned char preempt_time; /* Byte 2 */
438*4882a593Smuzhiyun unsigned char timeoff_bus; /* Byte 3 */
439*4882a593Smuzhiyun unsigned char mbox_count; /* Byte 4 */
440*4882a593Smuzhiyun unsigned char mbox_addr[3]; /* Bytes 5-7 */
441*4882a593Smuzhiyun struct blogic_syncval sync0to7[8]; /* Bytes 8-15 */
442*4882a593Smuzhiyun unsigned char disconnect_ok0to7; /* Byte 16 */
443*4882a593Smuzhiyun unsigned char sig; /* Byte 17 */
444*4882a593Smuzhiyun unsigned char char_d; /* Byte 18 */
445*4882a593Smuzhiyun unsigned char bus_type; /* Byte 19 */
446*4882a593Smuzhiyun unsigned char wide_tx_ok0to7; /* Byte 20 */
447*4882a593Smuzhiyun unsigned char wide_tx_active0to7; /* Byte 21 */
448*4882a593Smuzhiyun struct blogic_syncval sync8to15[8]; /* Bytes 22-29 */
449*4882a593Smuzhiyun unsigned char disconnect_ok8to15; /* Byte 30 */
450*4882a593Smuzhiyun unsigned char:8; /* Byte 31 */
451*4882a593Smuzhiyun unsigned char wide_tx_ok8to15; /* Byte 32 */
452*4882a593Smuzhiyun unsigned char wide_tx_active8to15; /* Byte 33 */
453*4882a593Smuzhiyun };
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun /*
456*4882a593Smuzhiyun Define the Initialize Extended Mailbox request structure.
457*4882a593Smuzhiyun */
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun struct blogic_extmbox_req {
460*4882a593Smuzhiyun unsigned char mbox_count; /* Byte 0 */
461*4882a593Smuzhiyun u32 base_mbox_addr; /* Bytes 1-4 */
462*4882a593Smuzhiyun } PACKED;
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun /*
466*4882a593Smuzhiyun Define the Inquire PCI Host Adapter Information reply type. The ISA
467*4882a593Smuzhiyun Compatible I/O Port values are defined here and are also used with
468*4882a593Smuzhiyun the Modify I/O Address command.
469*4882a593Smuzhiyun */
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun enum blogic_isa_ioport {
472*4882a593Smuzhiyun BLOGIC_IO_330 = 0,
473*4882a593Smuzhiyun BLOGIC_IO_334 = 1,
474*4882a593Smuzhiyun BLOGIC_IO_230 = 2,
475*4882a593Smuzhiyun BLOGIC_IO_234 = 3,
476*4882a593Smuzhiyun BLOGIC_IO_130 = 4,
477*4882a593Smuzhiyun BLOGIC_IO_134 = 5,
478*4882a593Smuzhiyun BLOGIC_IO_DISABLE = 6,
479*4882a593Smuzhiyun BLOGIC_IO_DISABLE2 = 7
480*4882a593Smuzhiyun } PACKED;
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun struct blogic_adapter_info {
483*4882a593Smuzhiyun enum blogic_isa_ioport isa_port; /* Byte 0 */
484*4882a593Smuzhiyun unsigned char irq_ch; /* Byte 1 */
485*4882a593Smuzhiyun bool low_term:1; /* Byte 2 Bit 0 */
486*4882a593Smuzhiyun bool high_term:1; /* Byte 2 Bit 1 */
487*4882a593Smuzhiyun unsigned char:2; /* Byte 2 Bits 2-3 */
488*4882a593Smuzhiyun bool JP1:1; /* Byte 2 Bit 4 */
489*4882a593Smuzhiyun bool JP2:1; /* Byte 2 Bit 5 */
490*4882a593Smuzhiyun bool JP3:1; /* Byte 2 Bit 6 */
491*4882a593Smuzhiyun bool genericinfo_valid:1; /* Byte 2 Bit 7 */
492*4882a593Smuzhiyun unsigned char:8; /* Byte 3 */
493*4882a593Smuzhiyun };
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun /*
496*4882a593Smuzhiyun Define the Inquire Extended Setup Information reply structure.
497*4882a593Smuzhiyun */
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun struct blogic_ext_setup {
500*4882a593Smuzhiyun unsigned char bus_type; /* Byte 0 */
501*4882a593Smuzhiyun unsigned char bios_addr; /* Byte 1 */
502*4882a593Smuzhiyun unsigned short sg_limit; /* Bytes 2-3 */
503*4882a593Smuzhiyun unsigned char mbox_count; /* Byte 4 */
504*4882a593Smuzhiyun u32 base_mbox_addr; /* Bytes 5-8 */
505*4882a593Smuzhiyun struct {
506*4882a593Smuzhiyun unsigned char:2; /* Byte 9 Bits 0-1 */
507*4882a593Smuzhiyun bool fast_on_eisa:1; /* Byte 9 Bit 2 */
508*4882a593Smuzhiyun unsigned char:3; /* Byte 9 Bits 3-5 */
509*4882a593Smuzhiyun bool level_int:1; /* Byte 9 Bit 6 */
510*4882a593Smuzhiyun unsigned char:1; /* Byte 9 Bit 7 */
511*4882a593Smuzhiyun } misc;
512*4882a593Smuzhiyun unsigned char fw_rev[3]; /* Bytes 10-12 */
513*4882a593Smuzhiyun bool wide:1; /* Byte 13 Bit 0 */
514*4882a593Smuzhiyun bool differential:1; /* Byte 13 Bit 1 */
515*4882a593Smuzhiyun bool scam:1; /* Byte 13 Bit 2 */
516*4882a593Smuzhiyun bool ultra:1; /* Byte 13 Bit 3 */
517*4882a593Smuzhiyun bool smart_term:1; /* Byte 13 Bit 4 */
518*4882a593Smuzhiyun unsigned char:3; /* Byte 13 Bits 5-7 */
519*4882a593Smuzhiyun } PACKED;
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun /*
522*4882a593Smuzhiyun Define the Enable Strict Round Robin Mode request type.
523*4882a593Smuzhiyun */
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun enum blogic_rr_req {
526*4882a593Smuzhiyun BLOGIC_AGGRESSIVE_RR = 0,
527*4882a593Smuzhiyun BLOGIC_STRICT_RR_MODE = 1
528*4882a593Smuzhiyun } PACKED;
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun /*
532*4882a593Smuzhiyun Define the Fetch Host Adapter Local RAM request type.
533*4882a593Smuzhiyun */
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun #define BLOGIC_BIOS_BASE 0
536*4882a593Smuzhiyun #define BLOGIC_AUTOSCSI_BASE 64
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun struct blogic_fetch_localram {
539*4882a593Smuzhiyun unsigned char offset; /* Byte 0 */
540*4882a593Smuzhiyun unsigned char count; /* Byte 1 */
541*4882a593Smuzhiyun };
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun /*
544*4882a593Smuzhiyun Define the Host Adapter Local RAM AutoSCSI structure.
545*4882a593Smuzhiyun */
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun struct blogic_autoscsi {
548*4882a593Smuzhiyun unsigned char factory_sig[2]; /* Bytes 0-1 */
549*4882a593Smuzhiyun unsigned char info_bytes; /* Byte 2 */
550*4882a593Smuzhiyun unsigned char adapter_type[6]; /* Bytes 3-8 */
551*4882a593Smuzhiyun unsigned char:8; /* Byte 9 */
552*4882a593Smuzhiyun bool floppy:1; /* Byte 10 Bit 0 */
553*4882a593Smuzhiyun bool floppy_sec:1; /* Byte 10 Bit 1 */
554*4882a593Smuzhiyun bool level_int:1; /* Byte 10 Bit 2 */
555*4882a593Smuzhiyun unsigned char:2; /* Byte 10 Bits 3-4 */
556*4882a593Smuzhiyun unsigned char systemram_bios:3; /* Byte 10 Bits 5-7 */
557*4882a593Smuzhiyun unsigned char dma_ch:7; /* Byte 11 Bits 0-6 */
558*4882a593Smuzhiyun bool dma_autoconf:1; /* Byte 11 Bit 7 */
559*4882a593Smuzhiyun unsigned char irq_ch:7; /* Byte 12 Bits 0-6 */
560*4882a593Smuzhiyun bool irq_autoconf:1; /* Byte 12 Bit 7 */
561*4882a593Smuzhiyun unsigned char dma_tx_rate; /* Byte 13 */
562*4882a593Smuzhiyun unsigned char scsi_id; /* Byte 14 */
563*4882a593Smuzhiyun bool low_term:1; /* Byte 15 Bit 0 */
564*4882a593Smuzhiyun bool parity:1; /* Byte 15 Bit 1 */
565*4882a593Smuzhiyun bool high_term:1; /* Byte 15 Bit 2 */
566*4882a593Smuzhiyun bool noisy_cable:1; /* Byte 15 Bit 3 */
567*4882a593Smuzhiyun bool fast_sync_neg:1; /* Byte 15 Bit 4 */
568*4882a593Smuzhiyun bool reset_enabled:1; /* Byte 15 Bit 5 */
569*4882a593Smuzhiyun bool:1; /* Byte 15 Bit 6 */
570*4882a593Smuzhiyun bool active_negation:1; /* Byte 15 Bit 7 */
571*4882a593Smuzhiyun unsigned char bus_on_delay; /* Byte 16 */
572*4882a593Smuzhiyun unsigned char bus_off_delay; /* Byte 17 */
573*4882a593Smuzhiyun bool bios_enabled:1; /* Byte 18 Bit 0 */
574*4882a593Smuzhiyun bool int19_redir_enabled:1; /* Byte 18 Bit 1 */
575*4882a593Smuzhiyun bool ext_trans_enable:1; /* Byte 18 Bit 2 */
576*4882a593Smuzhiyun bool removable_as_fixed:1; /* Byte 18 Bit 3 */
577*4882a593Smuzhiyun bool:1; /* Byte 18 Bit 4 */
578*4882a593Smuzhiyun bool morethan2_drives:1; /* Byte 18 Bit 5 */
579*4882a593Smuzhiyun bool bios_int:1; /* Byte 18 Bit 6 */
580*4882a593Smuzhiyun bool floptical:1; /* Byte 19 Bit 7 */
581*4882a593Smuzhiyun unsigned short dev_enabled; /* Bytes 19-20 */
582*4882a593Smuzhiyun unsigned short wide_ok; /* Bytes 21-22 */
583*4882a593Smuzhiyun unsigned short fast_ok; /* Bytes 23-24 */
584*4882a593Smuzhiyun unsigned short sync_ok; /* Bytes 25-26 */
585*4882a593Smuzhiyun unsigned short discon_ok; /* Bytes 27-28 */
586*4882a593Smuzhiyun unsigned short send_start_unit; /* Bytes 29-30 */
587*4882a593Smuzhiyun unsigned short ignore_bios_scan; /* Bytes 31-32 */
588*4882a593Smuzhiyun unsigned char pci_int_pin:2; /* Byte 33 Bits 0-1 */
589*4882a593Smuzhiyun unsigned char adapter_ioport:2; /* Byte 33 Bits 2-3 */
590*4882a593Smuzhiyun bool strict_rr_enabled:1; /* Byte 33 Bit 4 */
591*4882a593Smuzhiyun bool vesabus_33mhzplus:1; /* Byte 33 Bit 5 */
592*4882a593Smuzhiyun bool vesa_burst_write:1; /* Byte 33 Bit 6 */
593*4882a593Smuzhiyun bool vesa_burst_read:1; /* Byte 33 Bit 7 */
594*4882a593Smuzhiyun unsigned short ultra_ok; /* Bytes 34-35 */
595*4882a593Smuzhiyun unsigned int:32; /* Bytes 36-39 */
596*4882a593Smuzhiyun unsigned char:8; /* Byte 40 */
597*4882a593Smuzhiyun unsigned char autoscsi_maxlun; /* Byte 41 */
598*4882a593Smuzhiyun bool:1; /* Byte 42 Bit 0 */
599*4882a593Smuzhiyun bool scam_dominant:1; /* Byte 42 Bit 1 */
600*4882a593Smuzhiyun bool scam_enabled:1; /* Byte 42 Bit 2 */
601*4882a593Smuzhiyun bool scam_lev2:1; /* Byte 42 Bit 3 */
602*4882a593Smuzhiyun unsigned char:4; /* Byte 42 Bits 4-7 */
603*4882a593Smuzhiyun bool int13_exten:1; /* Byte 43 Bit 0 */
604*4882a593Smuzhiyun bool:1; /* Byte 43 Bit 1 */
605*4882a593Smuzhiyun bool cd_boot:1; /* Byte 43 Bit 2 */
606*4882a593Smuzhiyun unsigned char:5; /* Byte 43 Bits 3-7 */
607*4882a593Smuzhiyun unsigned char boot_id:4; /* Byte 44 Bits 0-3 */
608*4882a593Smuzhiyun unsigned char boot_ch:4; /* Byte 44 Bits 4-7 */
609*4882a593Smuzhiyun unsigned char force_scan_order:1; /* Byte 45 Bit 0 */
610*4882a593Smuzhiyun unsigned char:7; /* Byte 45 Bits 1-7 */
611*4882a593Smuzhiyun unsigned short nontagged_to_alt_ok; /* Bytes 46-47 */
612*4882a593Smuzhiyun unsigned short reneg_sync_on_check; /* Bytes 48-49 */
613*4882a593Smuzhiyun unsigned char rsvd[10]; /* Bytes 50-59 */
614*4882a593Smuzhiyun unsigned char manuf_diag[2]; /* Bytes 60-61 */
615*4882a593Smuzhiyun unsigned short cksum; /* Bytes 62-63 */
616*4882a593Smuzhiyun } PACKED;
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun /*
619*4882a593Smuzhiyun Define the Host Adapter Local RAM Auto SCSI Byte 45 structure.
620*4882a593Smuzhiyun */
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun struct blogic_autoscsi_byte45 {
623*4882a593Smuzhiyun unsigned char force_scan_order:1; /* Bit 0 */
624*4882a593Smuzhiyun unsigned char:7; /* Bits 1-7 */
625*4882a593Smuzhiyun };
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun /*
628*4882a593Smuzhiyun Define the Host Adapter Local RAM BIOS Drive Map Byte structure.
629*4882a593Smuzhiyun */
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun #define BLOGIC_BIOS_DRVMAP 17
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun struct blogic_bios_drvmap {
634*4882a593Smuzhiyun unsigned char tgt_idbit3:1; /* Bit 0 */
635*4882a593Smuzhiyun unsigned char:2; /* Bits 1-2 */
636*4882a593Smuzhiyun enum blogic_bios_diskgeometry diskgeom:2; /* Bits 3-4 */
637*4882a593Smuzhiyun unsigned char tgt_id:3; /* Bits 5-7 */
638*4882a593Smuzhiyun };
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /*
641*4882a593Smuzhiyun Define the Set CCB Format request type. Extended LUN Format CCBs are
642*4882a593Smuzhiyun necessary to support more than 8 Logical Units per Target Device.
643*4882a593Smuzhiyun */
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun enum blogic_setccb_fmt {
646*4882a593Smuzhiyun BLOGIC_LEGACY_LUN_CCB = 0,
647*4882a593Smuzhiyun BLOGIC_EXT_LUN_CCB = 1
648*4882a593Smuzhiyun } PACKED;
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun /*
651*4882a593Smuzhiyun Define the Outgoing Mailbox Action Codes.
652*4882a593Smuzhiyun */
653*4882a593Smuzhiyun
654*4882a593Smuzhiyun enum blogic_action {
655*4882a593Smuzhiyun BLOGIC_OUTBOX_FREE = 0x00,
656*4882a593Smuzhiyun BLOGIC_MBOX_START = 0x01,
657*4882a593Smuzhiyun BLOGIC_MBOX_ABORT = 0x02
658*4882a593Smuzhiyun } PACKED;
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun
661*4882a593Smuzhiyun /*
662*4882a593Smuzhiyun Define the Incoming Mailbox Completion Codes. The MultiMaster Firmware
663*4882a593Smuzhiyun only uses codes 0 - 4. The FlashPoint SCCB Manager has no mailboxes, so
664*4882a593Smuzhiyun completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5.
665*4882a593Smuzhiyun */
666*4882a593Smuzhiyun
667*4882a593Smuzhiyun enum blogic_cmplt_code {
668*4882a593Smuzhiyun BLOGIC_INBOX_FREE = 0x00,
669*4882a593Smuzhiyun BLOGIC_CMD_COMPLETE_GOOD = 0x01,
670*4882a593Smuzhiyun BLOGIC_CMD_ABORT_BY_HOST = 0x02,
671*4882a593Smuzhiyun BLOGIC_CMD_NOTFOUND = 0x03,
672*4882a593Smuzhiyun BLOGIC_CMD_COMPLETE_ERROR = 0x04,
673*4882a593Smuzhiyun BLOGIC_INVALID_CCB = 0x05
674*4882a593Smuzhiyun } PACKED;
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun /*
677*4882a593Smuzhiyun Define the Command Control Block (CCB) Opcodes.
678*4882a593Smuzhiyun */
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun enum blogic_ccb_opcode {
681*4882a593Smuzhiyun BLOGIC_INITIATOR_CCB = 0x00,
682*4882a593Smuzhiyun BLOGIC_TGT_CCB = 0x01,
683*4882a593Smuzhiyun BLOGIC_INITIATOR_CCB_SG = 0x02,
684*4882a593Smuzhiyun BLOGIC_INITIATOR_CCBB_RESIDUAL = 0x03,
685*4882a593Smuzhiyun BLOGIC_INITIATOR_CCB_SG_RESIDUAL = 0x04,
686*4882a593Smuzhiyun BLOGIC_BDR = 0x81
687*4882a593Smuzhiyun } PACKED;
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun
690*4882a593Smuzhiyun /*
691*4882a593Smuzhiyun Define the CCB Data Direction Codes.
692*4882a593Smuzhiyun */
693*4882a593Smuzhiyun
694*4882a593Smuzhiyun enum blogic_datadir {
695*4882a593Smuzhiyun BLOGIC_UNCHECKED_TX = 0,
696*4882a593Smuzhiyun BLOGIC_DATAIN_CHECKED = 1,
697*4882a593Smuzhiyun BLOGIC_DATAOUT_CHECKED = 2,
698*4882a593Smuzhiyun BLOGIC_NOTX = 3
699*4882a593Smuzhiyun };
700*4882a593Smuzhiyun
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun /*
703*4882a593Smuzhiyun Define the Host Adapter Status Codes. The MultiMaster Firmware does not
704*4882a593Smuzhiyun return status code 0x0C; it uses 0x12 for both overruns and underruns.
705*4882a593Smuzhiyun */
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun enum blogic_adapter_status {
708*4882a593Smuzhiyun BLOGIC_CMD_CMPLT_NORMAL = 0x00,
709*4882a593Smuzhiyun BLOGIC_LINK_CMD_CMPLT = 0x0A,
710*4882a593Smuzhiyun BLOGIC_LINK_CMD_CMPLT_FLAG = 0x0B,
711*4882a593Smuzhiyun BLOGIC_DATA_UNDERRUN = 0x0C,
712*4882a593Smuzhiyun BLOGIC_SELECT_TIMEOUT = 0x11,
713*4882a593Smuzhiyun BLOGIC_DATA_OVERRUN = 0x12,
714*4882a593Smuzhiyun BLOGIC_NOEXPECT_BUSFREE = 0x13,
715*4882a593Smuzhiyun BLOGIC_INVALID_BUSPHASE = 0x14,
716*4882a593Smuzhiyun BLOGIC_INVALID_OUTBOX_CODE = 0x15,
717*4882a593Smuzhiyun BLOGIC_INVALID_CMD_CODE = 0x16,
718*4882a593Smuzhiyun BLOGIC_LINKCCB_BADLUN = 0x17,
719*4882a593Smuzhiyun BLOGIC_BAD_CMD_PARAM = 0x1A,
720*4882a593Smuzhiyun BLOGIC_AUTOREQSENSE_FAIL = 0x1B,
721*4882a593Smuzhiyun BLOGIC_TAGQUEUE_REJECT = 0x1C,
722*4882a593Smuzhiyun BLOGIC_BAD_MSG_RCVD = 0x1D,
723*4882a593Smuzhiyun BLOGIC_HW_FAIL = 0x20,
724*4882a593Smuzhiyun BLOGIC_NORESPONSE_TO_ATN = 0x21,
725*4882a593Smuzhiyun BLOGIC_HW_RESET = 0x22,
726*4882a593Smuzhiyun BLOGIC_RST_FROM_OTHERDEV = 0x23,
727*4882a593Smuzhiyun BLOGIC_BAD_RECONNECT = 0x24,
728*4882a593Smuzhiyun BLOGIC_HW_BDR = 0x25,
729*4882a593Smuzhiyun BLOGIC_ABRT_QUEUE = 0x26,
730*4882a593Smuzhiyun BLOGIC_ADAPTER_SW_ERROR = 0x27,
731*4882a593Smuzhiyun BLOGIC_HW_TIMEOUT = 0x30,
732*4882a593Smuzhiyun BLOGIC_PARITY_ERR = 0x34
733*4882a593Smuzhiyun } PACKED;
734*4882a593Smuzhiyun
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun /*
737*4882a593Smuzhiyun Define the SCSI Target Device Status Codes.
738*4882a593Smuzhiyun */
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun enum blogic_tgt_status {
741*4882a593Smuzhiyun BLOGIC_OP_GOOD = 0x00,
742*4882a593Smuzhiyun BLOGIC_CHECKCONDITION = 0x02,
743*4882a593Smuzhiyun BLOGIC_DEVBUSY = 0x08
744*4882a593Smuzhiyun } PACKED;
745*4882a593Smuzhiyun
746*4882a593Smuzhiyun /*
747*4882a593Smuzhiyun Define the Queue Tag Codes.
748*4882a593Smuzhiyun */
749*4882a593Smuzhiyun
750*4882a593Smuzhiyun enum blogic_queuetag {
751*4882a593Smuzhiyun BLOGIC_SIMPLETAG = 0,
752*4882a593Smuzhiyun BLOGIC_HEADTAG = 1,
753*4882a593Smuzhiyun BLOGIC_ORDEREDTAG = 2,
754*4882a593Smuzhiyun BLOGIC_RSVDTAG = 3
755*4882a593Smuzhiyun };
756*4882a593Smuzhiyun
757*4882a593Smuzhiyun /*
758*4882a593Smuzhiyun Define the SCSI Command Descriptor Block (CDB).
759*4882a593Smuzhiyun */
760*4882a593Smuzhiyun
761*4882a593Smuzhiyun #define BLOGIC_CDB_MAXLEN 12
762*4882a593Smuzhiyun
763*4882a593Smuzhiyun
764*4882a593Smuzhiyun /*
765*4882a593Smuzhiyun Define the Scatter/Gather Segment structure required by the MultiMaster
766*4882a593Smuzhiyun Firmware Interface and the FlashPoint SCCB Manager.
767*4882a593Smuzhiyun */
768*4882a593Smuzhiyun
769*4882a593Smuzhiyun struct blogic_sg_seg {
770*4882a593Smuzhiyun u32 segbytes; /* Bytes 0-3 */
771*4882a593Smuzhiyun u32 segdata; /* Bytes 4-7 */
772*4882a593Smuzhiyun };
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun /*
775*4882a593Smuzhiyun Define the Driver CCB Status Codes.
776*4882a593Smuzhiyun */
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun enum blogic_ccb_status {
779*4882a593Smuzhiyun BLOGIC_CCB_FREE = 0,
780*4882a593Smuzhiyun BLOGIC_CCB_ACTIVE = 1,
781*4882a593Smuzhiyun BLOGIC_CCB_COMPLETE = 2,
782*4882a593Smuzhiyun BLOGIC_CCB_RESET = 3
783*4882a593Smuzhiyun } PACKED;
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun /*
787*4882a593Smuzhiyun Define the 32 Bit Mode Command Control Block (CCB) structure. The first 40
788*4882a593Smuzhiyun bytes are defined by and common to both the MultiMaster Firmware and the
789*4882a593Smuzhiyun FlashPoint SCCB Manager. The next 60 bytes are defined by the FlashPoint
790*4882a593Smuzhiyun SCCB Manager. The remaining components are defined by the Linux BusLogic
791*4882a593Smuzhiyun Driver. Extended LUN Format CCBs differ from Legacy LUN Format 32 Bit Mode
792*4882a593Smuzhiyun CCBs only in having the TagEnable and QueueTag fields moved from byte 17 to
793*4882a593Smuzhiyun byte 1, and the Logical Unit field in byte 17 expanded to 6 bits. In theory,
794*4882a593Smuzhiyun Extended LUN Format CCBs can support up to 64 Logical Units, but in practice
795*4882a593Smuzhiyun many devices will respond improperly to Logical Units between 32 and 63, and
796*4882a593Smuzhiyun the SCSI-2 specification defines Bit 5 as LUNTAR. Extended LUN Format CCBs
797*4882a593Smuzhiyun are used by recent versions of the MultiMaster Firmware, as well as by the
798*4882a593Smuzhiyun FlashPoint SCCB Manager; the FlashPoint SCCB Manager only supports 32 Logical
799*4882a593Smuzhiyun Units. Since 64 Logical Units are unlikely to be needed in practice, and
800*4882a593Smuzhiyun since they are problematic for the above reasons, and since limiting them to
801*4882a593Smuzhiyun 5 bits simplifies the CCB structure definition, this driver only supports
802*4882a593Smuzhiyun 32 Logical Units per Target Device.
803*4882a593Smuzhiyun */
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun struct blogic_ccb {
806*4882a593Smuzhiyun /*
807*4882a593Smuzhiyun MultiMaster Firmware and FlashPoint SCCB Manager Common Portion.
808*4882a593Smuzhiyun */
809*4882a593Smuzhiyun enum blogic_ccb_opcode opcode; /* Byte 0 */
810*4882a593Smuzhiyun unsigned char:3; /* Byte 1 Bits 0-2 */
811*4882a593Smuzhiyun enum blogic_datadir datadir:2; /* Byte 1 Bits 3-4 */
812*4882a593Smuzhiyun bool tag_enable:1; /* Byte 1 Bit 5 */
813*4882a593Smuzhiyun enum blogic_queuetag queuetag:2; /* Byte 1 Bits 6-7 */
814*4882a593Smuzhiyun unsigned char cdblen; /* Byte 2 */
815*4882a593Smuzhiyun unsigned char sense_datalen; /* Byte 3 */
816*4882a593Smuzhiyun u32 datalen; /* Bytes 4-7 */
817*4882a593Smuzhiyun u32 data; /* Bytes 8-11 */
818*4882a593Smuzhiyun unsigned char:8; /* Byte 12 */
819*4882a593Smuzhiyun unsigned char:8; /* Byte 13 */
820*4882a593Smuzhiyun enum blogic_adapter_status adapter_status; /* Byte 14 */
821*4882a593Smuzhiyun enum blogic_tgt_status tgt_status; /* Byte 15 */
822*4882a593Smuzhiyun unsigned char tgt_id; /* Byte 16 */
823*4882a593Smuzhiyun unsigned char lun:5; /* Byte 17 Bits 0-4 */
824*4882a593Smuzhiyun bool legacytag_enable:1; /* Byte 17 Bit 5 */
825*4882a593Smuzhiyun enum blogic_queuetag legacy_tag:2; /* Byte 17 Bits 6-7 */
826*4882a593Smuzhiyun unsigned char cdb[BLOGIC_CDB_MAXLEN]; /* Bytes 18-29 */
827*4882a593Smuzhiyun unsigned char:8; /* Byte 30 */
828*4882a593Smuzhiyun unsigned char:8; /* Byte 31 */
829*4882a593Smuzhiyun u32 rsvd_int; /* Bytes 32-35 */
830*4882a593Smuzhiyun u32 sensedata; /* Bytes 36-39 */
831*4882a593Smuzhiyun /*
832*4882a593Smuzhiyun FlashPoint SCCB Manager Defined Portion.
833*4882a593Smuzhiyun */
834*4882a593Smuzhiyun void (*callback) (struct blogic_ccb *); /* Bytes 40-43 */
835*4882a593Smuzhiyun u32 base_addr; /* Bytes 44-47 */
836*4882a593Smuzhiyun enum blogic_cmplt_code comp_code; /* Byte 48 */
837*4882a593Smuzhiyun #ifdef CONFIG_SCSI_FLASHPOINT
838*4882a593Smuzhiyun unsigned char:8; /* Byte 49 */
839*4882a593Smuzhiyun u16 os_flags; /* Bytes 50-51 */
840*4882a593Smuzhiyun unsigned char private[24]; /* Bytes 52-99 */
841*4882a593Smuzhiyun void *rsvd1;
842*4882a593Smuzhiyun void *rsvd2;
843*4882a593Smuzhiyun unsigned char private2[16];
844*4882a593Smuzhiyun #endif
845*4882a593Smuzhiyun /*
846*4882a593Smuzhiyun BusLogic Linux Driver Defined Portion.
847*4882a593Smuzhiyun */
848*4882a593Smuzhiyun dma_addr_t allocgrp_head;
849*4882a593Smuzhiyun unsigned int allocgrp_size;
850*4882a593Smuzhiyun u32 dma_handle;
851*4882a593Smuzhiyun enum blogic_ccb_status status;
852*4882a593Smuzhiyun unsigned long serial;
853*4882a593Smuzhiyun struct scsi_cmnd *command;
854*4882a593Smuzhiyun struct blogic_adapter *adapter;
855*4882a593Smuzhiyun struct blogic_ccb *next;
856*4882a593Smuzhiyun struct blogic_ccb *next_all;
857*4882a593Smuzhiyun struct blogic_sg_seg sglist[BLOGIC_SG_LIMIT];
858*4882a593Smuzhiyun };
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun /*
861*4882a593Smuzhiyun Define the 32 Bit Mode Outgoing Mailbox structure.
862*4882a593Smuzhiyun */
863*4882a593Smuzhiyun
864*4882a593Smuzhiyun struct blogic_outbox {
865*4882a593Smuzhiyun u32 ccb; /* Bytes 0-3 */
866*4882a593Smuzhiyun u32:24; /* Bytes 4-6 */
867*4882a593Smuzhiyun enum blogic_action action; /* Byte 7 */
868*4882a593Smuzhiyun };
869*4882a593Smuzhiyun
870*4882a593Smuzhiyun /*
871*4882a593Smuzhiyun Define the 32 Bit Mode Incoming Mailbox structure.
872*4882a593Smuzhiyun */
873*4882a593Smuzhiyun
874*4882a593Smuzhiyun struct blogic_inbox {
875*4882a593Smuzhiyun u32 ccb; /* Bytes 0-3 */
876*4882a593Smuzhiyun enum blogic_adapter_status adapter_status; /* Byte 4 */
877*4882a593Smuzhiyun enum blogic_tgt_status tgt_status; /* Byte 5 */
878*4882a593Smuzhiyun unsigned char:8; /* Byte 6 */
879*4882a593Smuzhiyun enum blogic_cmplt_code comp_code; /* Byte 7 */
880*4882a593Smuzhiyun };
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun
883*4882a593Smuzhiyun /*
884*4882a593Smuzhiyun Define the BusLogic Driver Options structure.
885*4882a593Smuzhiyun */
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun struct blogic_drvr_options {
888*4882a593Smuzhiyun unsigned short tagq_ok;
889*4882a593Smuzhiyun unsigned short tagq_ok_mask;
890*4882a593Smuzhiyun unsigned short bus_settle_time;
891*4882a593Smuzhiyun unsigned short stop_tgt_inquiry;
892*4882a593Smuzhiyun unsigned char common_qdepth;
893*4882a593Smuzhiyun unsigned char qdepth[BLOGIC_MAXDEV];
894*4882a593Smuzhiyun };
895*4882a593Smuzhiyun
896*4882a593Smuzhiyun /*
897*4882a593Smuzhiyun Define the Host Adapter Target Flags structure.
898*4882a593Smuzhiyun */
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun struct blogic_tgt_flags {
901*4882a593Smuzhiyun bool tgt_exists:1;
902*4882a593Smuzhiyun bool tagq_ok:1;
903*4882a593Smuzhiyun bool wide_ok:1;
904*4882a593Smuzhiyun bool tagq_active:1;
905*4882a593Smuzhiyun bool wide_active:1;
906*4882a593Smuzhiyun bool cmd_good:1;
907*4882a593Smuzhiyun bool tgt_info_in:1;
908*4882a593Smuzhiyun };
909*4882a593Smuzhiyun
910*4882a593Smuzhiyun /*
911*4882a593Smuzhiyun Define the Host Adapter Target Statistics structure.
912*4882a593Smuzhiyun */
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun #define BLOGIC_SZ_BUCKETS 10
915*4882a593Smuzhiyun
916*4882a593Smuzhiyun struct blogic_tgt_stats {
917*4882a593Smuzhiyun unsigned int cmds_tried;
918*4882a593Smuzhiyun unsigned int cmds_complete;
919*4882a593Smuzhiyun unsigned int read_cmds;
920*4882a593Smuzhiyun unsigned int write_cmds;
921*4882a593Smuzhiyun struct blogic_byte_count bytesread;
922*4882a593Smuzhiyun struct blogic_byte_count byteswritten;
923*4882a593Smuzhiyun unsigned int read_sz_buckets[BLOGIC_SZ_BUCKETS];
924*4882a593Smuzhiyun unsigned int write_sz_buckets[BLOGIC_SZ_BUCKETS];
925*4882a593Smuzhiyun unsigned short aborts_request;
926*4882a593Smuzhiyun unsigned short aborts_tried;
927*4882a593Smuzhiyun unsigned short aborts_done;
928*4882a593Smuzhiyun unsigned short bdr_request;
929*4882a593Smuzhiyun unsigned short bdr_tried;
930*4882a593Smuzhiyun unsigned short bdr_done;
931*4882a593Smuzhiyun unsigned short adapter_reset_req;
932*4882a593Smuzhiyun unsigned short adapter_reset_attempt;
933*4882a593Smuzhiyun unsigned short adapter_reset_done;
934*4882a593Smuzhiyun };
935*4882a593Smuzhiyun
936*4882a593Smuzhiyun /*
937*4882a593Smuzhiyun Define the FlashPoint Card Handle data type.
938*4882a593Smuzhiyun */
939*4882a593Smuzhiyun
940*4882a593Smuzhiyun #define FPOINT_BADCARD_HANDLE 0xFFFFFFFFL
941*4882a593Smuzhiyun
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun /*
944*4882a593Smuzhiyun Define the FlashPoint Information structure. This structure is defined
945*4882a593Smuzhiyun by the FlashPoint SCCB Manager.
946*4882a593Smuzhiyun */
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun struct fpoint_info {
949*4882a593Smuzhiyun u32 base_addr; /* Bytes 0-3 */
950*4882a593Smuzhiyun bool present; /* Byte 4 */
951*4882a593Smuzhiyun unsigned char irq_ch; /* Byte 5 */
952*4882a593Smuzhiyun unsigned char scsi_id; /* Byte 6 */
953*4882a593Smuzhiyun unsigned char scsi_lun; /* Byte 7 */
954*4882a593Smuzhiyun u16 fw_rev; /* Bytes 8-9 */
955*4882a593Smuzhiyun u16 sync_ok; /* Bytes 10-11 */
956*4882a593Smuzhiyun u16 fast_ok; /* Bytes 12-13 */
957*4882a593Smuzhiyun u16 ultra_ok; /* Bytes 14-15 */
958*4882a593Smuzhiyun u16 discon_ok; /* Bytes 16-17 */
959*4882a593Smuzhiyun u16 wide_ok; /* Bytes 18-19 */
960*4882a593Smuzhiyun bool parity:1; /* Byte 20 Bit 0 */
961*4882a593Smuzhiyun bool wide:1; /* Byte 20 Bit 1 */
962*4882a593Smuzhiyun bool softreset:1; /* Byte 20 Bit 2 */
963*4882a593Smuzhiyun bool ext_trans_enable:1; /* Byte 20 Bit 3 */
964*4882a593Smuzhiyun bool low_term:1; /* Byte 20 Bit 4 */
965*4882a593Smuzhiyun bool high_term:1; /* Byte 20 Bit 5 */
966*4882a593Smuzhiyun bool report_underrun:1; /* Byte 20 Bit 6 */
967*4882a593Smuzhiyun bool scam_enabled:1; /* Byte 20 Bit 7 */
968*4882a593Smuzhiyun bool scam_lev2:1; /* Byte 21 Bit 0 */
969*4882a593Smuzhiyun unsigned char:7; /* Byte 21 Bits 1-7 */
970*4882a593Smuzhiyun unsigned char family; /* Byte 22 */
971*4882a593Smuzhiyun unsigned char bus_type; /* Byte 23 */
972*4882a593Smuzhiyun unsigned char model[3]; /* Bytes 24-26 */
973*4882a593Smuzhiyun unsigned char relative_cardnum; /* Byte 27 */
974*4882a593Smuzhiyun unsigned char rsvd[4]; /* Bytes 28-31 */
975*4882a593Smuzhiyun u32 os_rsvd; /* Bytes 32-35 */
976*4882a593Smuzhiyun unsigned char translation_info[4]; /* Bytes 36-39 */
977*4882a593Smuzhiyun u32 rsvd2[5]; /* Bytes 40-59 */
978*4882a593Smuzhiyun u32 sec_range; /* Bytes 60-63 */
979*4882a593Smuzhiyun };
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun /*
982*4882a593Smuzhiyun Define the BusLogic Driver Host Adapter structure.
983*4882a593Smuzhiyun */
984*4882a593Smuzhiyun
985*4882a593Smuzhiyun struct blogic_adapter {
986*4882a593Smuzhiyun struct Scsi_Host *scsi_host;
987*4882a593Smuzhiyun struct pci_dev *pci_device;
988*4882a593Smuzhiyun enum blogic_adapter_type adapter_type;
989*4882a593Smuzhiyun enum blogic_adapter_bus_type adapter_bus_type;
990*4882a593Smuzhiyun unsigned long io_addr;
991*4882a593Smuzhiyun unsigned long pci_addr;
992*4882a593Smuzhiyun unsigned short addr_count;
993*4882a593Smuzhiyun unsigned char host_no;
994*4882a593Smuzhiyun unsigned char model[9];
995*4882a593Smuzhiyun unsigned char fw_ver[6];
996*4882a593Smuzhiyun unsigned char full_model[18];
997*4882a593Smuzhiyun unsigned char bus;
998*4882a593Smuzhiyun unsigned char dev;
999*4882a593Smuzhiyun unsigned char irq_ch;
1000*4882a593Smuzhiyun unsigned char dma_ch;
1001*4882a593Smuzhiyun unsigned char scsi_id;
1002*4882a593Smuzhiyun bool irq_acquired:1;
1003*4882a593Smuzhiyun bool dma_chan_acquired:1;
1004*4882a593Smuzhiyun bool ext_trans_enable:1;
1005*4882a593Smuzhiyun bool parity:1;
1006*4882a593Smuzhiyun bool reset_enabled:1;
1007*4882a593Smuzhiyun bool level_int:1;
1008*4882a593Smuzhiyun bool wide:1;
1009*4882a593Smuzhiyun bool differential:1;
1010*4882a593Smuzhiyun bool scam:1;
1011*4882a593Smuzhiyun bool ultra:1;
1012*4882a593Smuzhiyun bool ext_lun:1;
1013*4882a593Smuzhiyun bool terminfo_valid:1;
1014*4882a593Smuzhiyun bool low_term:1;
1015*4882a593Smuzhiyun bool high_term:1;
1016*4882a593Smuzhiyun bool need_bouncebuf:1;
1017*4882a593Smuzhiyun bool strict_rr:1;
1018*4882a593Smuzhiyun bool scam_enabled:1;
1019*4882a593Smuzhiyun bool scam_lev2:1;
1020*4882a593Smuzhiyun bool adapter_initd:1;
1021*4882a593Smuzhiyun bool adapter_extreset:1;
1022*4882a593Smuzhiyun bool adapter_intern_err:1;
1023*4882a593Smuzhiyun bool processing_ccbs;
1024*4882a593Smuzhiyun volatile bool adapter_cmd_complete;
1025*4882a593Smuzhiyun unsigned short adapter_sglimit;
1026*4882a593Smuzhiyun unsigned short drvr_sglimit;
1027*4882a593Smuzhiyun unsigned short maxdev;
1028*4882a593Smuzhiyun unsigned short maxlun;
1029*4882a593Smuzhiyun unsigned short mbox_count;
1030*4882a593Smuzhiyun unsigned short initccbs;
1031*4882a593Smuzhiyun unsigned short inc_ccbs;
1032*4882a593Smuzhiyun unsigned short alloc_ccbs;
1033*4882a593Smuzhiyun unsigned short drvr_qdepth;
1034*4882a593Smuzhiyun unsigned short adapter_qdepth;
1035*4882a593Smuzhiyun unsigned short untag_qdepth;
1036*4882a593Smuzhiyun unsigned short common_qdepth;
1037*4882a593Smuzhiyun unsigned short bus_settle_time;
1038*4882a593Smuzhiyun unsigned short sync_ok;
1039*4882a593Smuzhiyun unsigned short fast_ok;
1040*4882a593Smuzhiyun unsigned short ultra_ok;
1041*4882a593Smuzhiyun unsigned short wide_ok;
1042*4882a593Smuzhiyun unsigned short discon_ok;
1043*4882a593Smuzhiyun unsigned short tagq_ok;
1044*4882a593Smuzhiyun unsigned short ext_resets;
1045*4882a593Smuzhiyun unsigned short adapter_intern_errors;
1046*4882a593Smuzhiyun unsigned short tgt_count;
1047*4882a593Smuzhiyun unsigned short msgbuflen;
1048*4882a593Smuzhiyun u32 bios_addr;
1049*4882a593Smuzhiyun struct blogic_drvr_options *drvr_opts;
1050*4882a593Smuzhiyun struct fpoint_info fpinfo;
1051*4882a593Smuzhiyun void *cardhandle;
1052*4882a593Smuzhiyun struct list_head host_list;
1053*4882a593Smuzhiyun struct blogic_ccb *all_ccbs;
1054*4882a593Smuzhiyun struct blogic_ccb *free_ccbs;
1055*4882a593Smuzhiyun struct blogic_ccb *firstccb;
1056*4882a593Smuzhiyun struct blogic_ccb *lastccb;
1057*4882a593Smuzhiyun struct blogic_ccb *bdr_pend[BLOGIC_MAXDEV];
1058*4882a593Smuzhiyun struct blogic_tgt_flags tgt_flags[BLOGIC_MAXDEV];
1059*4882a593Smuzhiyun unsigned char qdepth[BLOGIC_MAXDEV];
1060*4882a593Smuzhiyun unsigned char sync_period[BLOGIC_MAXDEV];
1061*4882a593Smuzhiyun unsigned char sync_offset[BLOGIC_MAXDEV];
1062*4882a593Smuzhiyun unsigned char active_cmds[BLOGIC_MAXDEV];
1063*4882a593Smuzhiyun unsigned int cmds_since_rst[BLOGIC_MAXDEV];
1064*4882a593Smuzhiyun unsigned long last_seqpoint[BLOGIC_MAXDEV];
1065*4882a593Smuzhiyun unsigned long last_resettried[BLOGIC_MAXDEV];
1066*4882a593Smuzhiyun unsigned long last_resetdone[BLOGIC_MAXDEV];
1067*4882a593Smuzhiyun struct blogic_outbox *first_outbox;
1068*4882a593Smuzhiyun struct blogic_outbox *last_outbox;
1069*4882a593Smuzhiyun struct blogic_outbox *next_outbox;
1070*4882a593Smuzhiyun struct blogic_inbox *first_inbox;
1071*4882a593Smuzhiyun struct blogic_inbox *last_inbox;
1072*4882a593Smuzhiyun struct blogic_inbox *next_inbox;
1073*4882a593Smuzhiyun struct blogic_tgt_stats tgt_stats[BLOGIC_MAXDEV];
1074*4882a593Smuzhiyun unsigned char *mbox_space;
1075*4882a593Smuzhiyun dma_addr_t mbox_space_handle;
1076*4882a593Smuzhiyun unsigned int mbox_sz;
1077*4882a593Smuzhiyun unsigned long ccb_offset;
1078*4882a593Smuzhiyun char msgbuf[BLOGIC_MSGBUF_SIZE];
1079*4882a593Smuzhiyun };
1080*4882a593Smuzhiyun
1081*4882a593Smuzhiyun /*
1082*4882a593Smuzhiyun Define a structure for the BIOS Disk Parameters.
1083*4882a593Smuzhiyun */
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun struct bios_diskparam {
1086*4882a593Smuzhiyun int heads;
1087*4882a593Smuzhiyun int sectors;
1088*4882a593Smuzhiyun int cylinders;
1089*4882a593Smuzhiyun };
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun /*
1092*4882a593Smuzhiyun Define a structure for the SCSI Inquiry command results.
1093*4882a593Smuzhiyun */
1094*4882a593Smuzhiyun
1095*4882a593Smuzhiyun struct scsi_inquiry {
1096*4882a593Smuzhiyun unsigned char devtype:5; /* Byte 0 Bits 0-4 */
1097*4882a593Smuzhiyun unsigned char dev_qual:3; /* Byte 0 Bits 5-7 */
1098*4882a593Smuzhiyun unsigned char dev_modifier:7; /* Byte 1 Bits 0-6 */
1099*4882a593Smuzhiyun bool rmb:1; /* Byte 1 Bit 7 */
1100*4882a593Smuzhiyun unsigned char ansi_ver:3; /* Byte 2 Bits 0-2 */
1101*4882a593Smuzhiyun unsigned char ecma_ver:3; /* Byte 2 Bits 3-5 */
1102*4882a593Smuzhiyun unsigned char iso_ver:2; /* Byte 2 Bits 6-7 */
1103*4882a593Smuzhiyun unsigned char resp_fmt:4; /* Byte 3 Bits 0-3 */
1104*4882a593Smuzhiyun unsigned char:2; /* Byte 3 Bits 4-5 */
1105*4882a593Smuzhiyun bool TrmIOP:1; /* Byte 3 Bit 6 */
1106*4882a593Smuzhiyun bool AENC:1; /* Byte 3 Bit 7 */
1107*4882a593Smuzhiyun unsigned char addl_len; /* Byte 4 */
1108*4882a593Smuzhiyun unsigned char:8; /* Byte 5 */
1109*4882a593Smuzhiyun unsigned char:8; /* Byte 6 */
1110*4882a593Smuzhiyun bool SftRe:1; /* Byte 7 Bit 0 */
1111*4882a593Smuzhiyun bool CmdQue:1; /* Byte 7 Bit 1 */
1112*4882a593Smuzhiyun bool:1; /* Byte 7 Bit 2 */
1113*4882a593Smuzhiyun bool linked:1; /* Byte 7 Bit 3 */
1114*4882a593Smuzhiyun bool sync:1; /* Byte 7 Bit 4 */
1115*4882a593Smuzhiyun bool WBus16:1; /* Byte 7 Bit 5 */
1116*4882a593Smuzhiyun bool WBus32:1; /* Byte 7 Bit 6 */
1117*4882a593Smuzhiyun bool RelAdr:1; /* Byte 7 Bit 7 */
1118*4882a593Smuzhiyun unsigned char vendor[8]; /* Bytes 8-15 */
1119*4882a593Smuzhiyun unsigned char product[16]; /* Bytes 16-31 */
1120*4882a593Smuzhiyun unsigned char product_rev[4]; /* Bytes 32-35 */
1121*4882a593Smuzhiyun };
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun /*
1125*4882a593Smuzhiyun Define functions to provide an abstraction for reading and writing the
1126*4882a593Smuzhiyun Host Adapter I/O Registers.
1127*4882a593Smuzhiyun */
1128*4882a593Smuzhiyun
blogic_busreset(struct blogic_adapter * adapter)1129*4882a593Smuzhiyun static inline void blogic_busreset(struct blogic_adapter *adapter)
1130*4882a593Smuzhiyun {
1131*4882a593Smuzhiyun union blogic_cntrl_reg cr;
1132*4882a593Smuzhiyun cr.all = 0;
1133*4882a593Smuzhiyun cr.cr.bus_reset = true;
1134*4882a593Smuzhiyun outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
1135*4882a593Smuzhiyun }
1136*4882a593Smuzhiyun
blogic_intreset(struct blogic_adapter * adapter)1137*4882a593Smuzhiyun static inline void blogic_intreset(struct blogic_adapter *adapter)
1138*4882a593Smuzhiyun {
1139*4882a593Smuzhiyun union blogic_cntrl_reg cr;
1140*4882a593Smuzhiyun cr.all = 0;
1141*4882a593Smuzhiyun cr.cr.int_reset = true;
1142*4882a593Smuzhiyun outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
1143*4882a593Smuzhiyun }
1144*4882a593Smuzhiyun
blogic_softreset(struct blogic_adapter * adapter)1145*4882a593Smuzhiyun static inline void blogic_softreset(struct blogic_adapter *adapter)
1146*4882a593Smuzhiyun {
1147*4882a593Smuzhiyun union blogic_cntrl_reg cr;
1148*4882a593Smuzhiyun cr.all = 0;
1149*4882a593Smuzhiyun cr.cr.soft_reset = true;
1150*4882a593Smuzhiyun outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
1151*4882a593Smuzhiyun }
1152*4882a593Smuzhiyun
blogic_hardreset(struct blogic_adapter * adapter)1153*4882a593Smuzhiyun static inline void blogic_hardreset(struct blogic_adapter *adapter)
1154*4882a593Smuzhiyun {
1155*4882a593Smuzhiyun union blogic_cntrl_reg cr;
1156*4882a593Smuzhiyun cr.all = 0;
1157*4882a593Smuzhiyun cr.cr.hard_reset = true;
1158*4882a593Smuzhiyun outb(cr.all, adapter->io_addr + BLOGIC_CNTRL_REG);
1159*4882a593Smuzhiyun }
1160*4882a593Smuzhiyun
blogic_rdstatus(struct blogic_adapter * adapter)1161*4882a593Smuzhiyun static inline unsigned char blogic_rdstatus(struct blogic_adapter *adapter)
1162*4882a593Smuzhiyun {
1163*4882a593Smuzhiyun return inb(adapter->io_addr + BLOGIC_STATUS_REG);
1164*4882a593Smuzhiyun }
1165*4882a593Smuzhiyun
blogic_setcmdparam(struct blogic_adapter * adapter,unsigned char value)1166*4882a593Smuzhiyun static inline void blogic_setcmdparam(struct blogic_adapter *adapter,
1167*4882a593Smuzhiyun unsigned char value)
1168*4882a593Smuzhiyun {
1169*4882a593Smuzhiyun outb(value, adapter->io_addr + BLOGIC_CMD_PARM_REG);
1170*4882a593Smuzhiyun }
1171*4882a593Smuzhiyun
blogic_rddatain(struct blogic_adapter * adapter)1172*4882a593Smuzhiyun static inline unsigned char blogic_rddatain(struct blogic_adapter *adapter)
1173*4882a593Smuzhiyun {
1174*4882a593Smuzhiyun return inb(adapter->io_addr + BLOGIC_DATAIN_REG);
1175*4882a593Smuzhiyun }
1176*4882a593Smuzhiyun
blogic_rdint(struct blogic_adapter * adapter)1177*4882a593Smuzhiyun static inline unsigned char blogic_rdint(struct blogic_adapter *adapter)
1178*4882a593Smuzhiyun {
1179*4882a593Smuzhiyun return inb(adapter->io_addr + BLOGIC_INT_REG);
1180*4882a593Smuzhiyun }
1181*4882a593Smuzhiyun
blogic_rdgeom(struct blogic_adapter * adapter)1182*4882a593Smuzhiyun static inline unsigned char blogic_rdgeom(struct blogic_adapter *adapter)
1183*4882a593Smuzhiyun {
1184*4882a593Smuzhiyun return inb(adapter->io_addr + BLOGIC_GEOMETRY_REG);
1185*4882a593Smuzhiyun }
1186*4882a593Smuzhiyun
1187*4882a593Smuzhiyun /*
1188*4882a593Smuzhiyun blogic_execmbox issues an Execute Mailbox Command, which
1189*4882a593Smuzhiyun notifies the Host Adapter that an entry has been made in an Outgoing
1190*4882a593Smuzhiyun Mailbox.
1191*4882a593Smuzhiyun */
1192*4882a593Smuzhiyun
blogic_execmbox(struct blogic_adapter * adapter)1193*4882a593Smuzhiyun static inline void blogic_execmbox(struct blogic_adapter *adapter)
1194*4882a593Smuzhiyun {
1195*4882a593Smuzhiyun blogic_setcmdparam(adapter, BLOGIC_EXEC_MBOX_CMD);
1196*4882a593Smuzhiyun }
1197*4882a593Smuzhiyun
1198*4882a593Smuzhiyun /*
1199*4882a593Smuzhiyun blogic_delay waits for Seconds to elapse.
1200*4882a593Smuzhiyun */
1201*4882a593Smuzhiyun
blogic_delay(int seconds)1202*4882a593Smuzhiyun static inline void blogic_delay(int seconds)
1203*4882a593Smuzhiyun {
1204*4882a593Smuzhiyun mdelay(1000 * seconds);
1205*4882a593Smuzhiyun }
1206*4882a593Smuzhiyun
1207*4882a593Smuzhiyun /*
1208*4882a593Smuzhiyun virt_to_32bit_virt maps between Kernel Virtual Addresses and
1209*4882a593Smuzhiyun 32 bit Kernel Virtual Addresses. This avoids compilation warnings
1210*4882a593Smuzhiyun on 64 bit architectures.
1211*4882a593Smuzhiyun */
1212*4882a593Smuzhiyun
virt_to_32bit_virt(void * virt_addr)1213*4882a593Smuzhiyun static inline u32 virt_to_32bit_virt(void *virt_addr)
1214*4882a593Smuzhiyun {
1215*4882a593Smuzhiyun return (u32) (unsigned long) virt_addr;
1216*4882a593Smuzhiyun }
1217*4882a593Smuzhiyun
1218*4882a593Smuzhiyun /*
1219*4882a593Smuzhiyun blogic_inc_count increments counter by 1, stopping at
1220*4882a593Smuzhiyun 65535 rather than wrapping around to 0.
1221*4882a593Smuzhiyun */
1222*4882a593Smuzhiyun
blogic_inc_count(unsigned short * count)1223*4882a593Smuzhiyun static inline void blogic_inc_count(unsigned short *count)
1224*4882a593Smuzhiyun {
1225*4882a593Smuzhiyun if (*count < 65535)
1226*4882a593Smuzhiyun (*count)++;
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun
1229*4882a593Smuzhiyun /*
1230*4882a593Smuzhiyun blogic_addcount increments Byte Counter by Amount.
1231*4882a593Smuzhiyun */
1232*4882a593Smuzhiyun
blogic_addcount(struct blogic_byte_count * bytecount,unsigned int amount)1233*4882a593Smuzhiyun static inline void blogic_addcount(struct blogic_byte_count *bytecount,
1234*4882a593Smuzhiyun unsigned int amount)
1235*4882a593Smuzhiyun {
1236*4882a593Smuzhiyun bytecount->units += amount;
1237*4882a593Smuzhiyun if (bytecount->units > 999999999) {
1238*4882a593Smuzhiyun bytecount->units -= 1000000000;
1239*4882a593Smuzhiyun bytecount->billions++;
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun }
1242*4882a593Smuzhiyun
1243*4882a593Smuzhiyun /*
1244*4882a593Smuzhiyun blogic_incszbucket increments the Bucket for Amount.
1245*4882a593Smuzhiyun */
1246*4882a593Smuzhiyun
blogic_incszbucket(unsigned int * cmdsz_buckets,unsigned int amount)1247*4882a593Smuzhiyun static inline void blogic_incszbucket(unsigned int *cmdsz_buckets,
1248*4882a593Smuzhiyun unsigned int amount)
1249*4882a593Smuzhiyun {
1250*4882a593Smuzhiyun int index = 0;
1251*4882a593Smuzhiyun if (amount < 8 * 1024) {
1252*4882a593Smuzhiyun if (amount < 2 * 1024)
1253*4882a593Smuzhiyun index = (amount < 1 * 1024 ? 0 : 1);
1254*4882a593Smuzhiyun else
1255*4882a593Smuzhiyun index = (amount < 4 * 1024 ? 2 : 3);
1256*4882a593Smuzhiyun } else if (amount < 128 * 1024) {
1257*4882a593Smuzhiyun if (amount < 32 * 1024)
1258*4882a593Smuzhiyun index = (amount < 16 * 1024 ? 4 : 5);
1259*4882a593Smuzhiyun else
1260*4882a593Smuzhiyun index = (amount < 64 * 1024 ? 6 : 7);
1261*4882a593Smuzhiyun } else
1262*4882a593Smuzhiyun index = (amount < 256 * 1024 ? 8 : 9);
1263*4882a593Smuzhiyun cmdsz_buckets[index]++;
1264*4882a593Smuzhiyun }
1265*4882a593Smuzhiyun
1266*4882a593Smuzhiyun /*
1267*4882a593Smuzhiyun Define the version number of the FlashPoint Firmware (SCCB Manager).
1268*4882a593Smuzhiyun */
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun #define FLASHPOINT_FW_VER "5.02"
1271*4882a593Smuzhiyun
1272*4882a593Smuzhiyun /*
1273*4882a593Smuzhiyun Define the possible return values from FlashPoint_HandleInterrupt.
1274*4882a593Smuzhiyun */
1275*4882a593Smuzhiyun
1276*4882a593Smuzhiyun #define FPOINT_NORMAL_INT 0x00
1277*4882a593Smuzhiyun #define FPOINT_INTERN_ERR 0xFE
1278*4882a593Smuzhiyun #define FPOINT_EXT_RESET 0xFF
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun /*
1281*4882a593Smuzhiyun Define prototypes for the forward referenced BusLogic Driver
1282*4882a593Smuzhiyun Internal Functions.
1283*4882a593Smuzhiyun */
1284*4882a593Smuzhiyun
1285*4882a593Smuzhiyun static const char *blogic_drvr_info(struct Scsi_Host *);
1286*4882a593Smuzhiyun static int blogic_qcmd(struct Scsi_Host *h, struct scsi_cmnd *);
1287*4882a593Smuzhiyun static int blogic_diskparam(struct scsi_device *, struct block_device *, sector_t, int *);
1288*4882a593Smuzhiyun static int blogic_slaveconfig(struct scsi_device *);
1289*4882a593Smuzhiyun static void blogic_qcompleted_ccb(struct blogic_ccb *);
1290*4882a593Smuzhiyun static irqreturn_t blogic_inthandler(int, void *);
1291*4882a593Smuzhiyun static int blogic_resetadapter(struct blogic_adapter *, bool hard_reset);
1292*4882a593Smuzhiyun static void blogic_msg(enum blogic_msglevel, char *, struct blogic_adapter *, ...);
1293*4882a593Smuzhiyun static int __init blogic_setup(char *);
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun #endif /* _BUSLOGIC_H */
1296