Commit | Line | Data |
---|---|---|
1a59d1b8 | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
1da177e4 LT |
2 | /* |
3 | * Device driver for the SYMBIOS/LSILOGIC 53C8XX and 53C1010 family | |
4 | * of PCI-SCSI IO processors. | |
5 | * | |
6 | * Copyright (C) 1999-2001 Gerard Roudier <groudier@free.fr> | |
7 | * | |
8 | * This driver is derived from the Linux sym53c8xx driver. | |
9 | * Copyright (C) 1998-2000 Gerard Roudier | |
10 | * | |
11 | * The sym53c8xx driver is derived from the ncr53c8xx driver that had been | |
12 | * a port of the FreeBSD ncr driver to Linux-1.2.13. | |
13 | * | |
14 | * The original ncr driver has been written for 386bsd and FreeBSD by | |
15 | * Wolfgang Stanglmeier <wolf@cologne.de> | |
16 | * Stefan Esser <se@mi.Uni-Koeln.de> | |
17 | * Copyright (C) 1994 Wolfgang Stanglmeier | |
18 | * | |
19 | * Other major contributions: | |
20 | * | |
21 | * NVRAM detection and reading. | |
22 | * Copyright (C) 1997 Richard Waltham <dormouse@farsrobt.demon.co.uk> | |
23 | * | |
24 | *----------------------------------------------------------------------------- | |
1da177e4 LT |
25 | */ |
26 | ||
27 | #ifndef SYM_GLUE_H | |
28 | #define SYM_GLUE_H | |
29 | ||
d68cd759 | 30 | #include <linux/completion.h> |
1da177e4 | 31 | #include <linux/delay.h> |
99c9e0a1 | 32 | #include <linux/interrupt.h> |
1da177e4 LT |
33 | #include <linux/ioport.h> |
34 | #include <linux/pci.h> | |
35 | #include <linux/string.h> | |
36 | #include <linux/timer.h> | |
37 | #include <linux/types.h> | |
38 | ||
39 | #include <asm/io.h> | |
40 | #ifdef __sparc__ | |
41 | # include <asm/irq.h> | |
42 | #endif | |
43 | ||
44 | #include <scsi/scsi.h> | |
45 | #include <scsi/scsi_cmnd.h> | |
46 | #include <scsi/scsi_device.h> | |
47 | #include <scsi/scsi_transport_spi.h> | |
48 | #include <scsi/scsi_host.h> | |
49 | ||
50 | #include "sym53c8xx.h" | |
51 | #include "sym_defs.h" | |
52 | #include "sym_misc.h" | |
53 | ||
54 | /* | |
55 | * Configuration addendum for Linux. | |
56 | */ | |
57 | #define SYM_CONF_TIMER_INTERVAL ((HZ+1)/2) | |
58 | ||
3bea15a7 | 59 | #undef SYM_OPT_HANDLE_DEVICE_QUEUEING |
1da177e4 LT |
60 | #define SYM_OPT_LIMIT_COMMAND_REORDERING |
61 | ||
62 | /* | |
63 | * Print a message with severity. | |
64 | */ | |
65 | #define printf_emerg(args...) printk(KERN_EMERG args) | |
66 | #define printf_alert(args...) printk(KERN_ALERT args) | |
67 | #define printf_crit(args...) printk(KERN_CRIT args) | |
68 | #define printf_err(args...) printk(KERN_ERR args) | |
69 | #define printf_warning(args...) printk(KERN_WARNING args) | |
70 | #define printf_notice(args...) printk(KERN_NOTICE args) | |
71 | #define printf_info(args...) printk(KERN_INFO args) | |
72 | #define printf_debug(args...) printk(KERN_DEBUG args) | |
73 | #define printf(args...) printk(args) | |
74 | ||
75 | /* | |
76 | * A 'read barrier' flushes any data that have been prefetched | |
77 | * by the processor due to out of order execution. Such a barrier | |
78 | * must notably be inserted prior to looking at data that have | |
79 | * been DMAed, assuming that program does memory READs in proper | |
80 | * order and that the device ensured proper ordering of WRITEs. | |
81 | * | |
82 | * A 'write barrier' prevents any previous WRITEs to pass further | |
83 | * WRITEs. Such barriers must be inserted each time another agent | |
84 | * relies on ordering of WRITEs. | |
85 | * | |
86 | * Note that, due to posting of PCI memory writes, we also must | |
87 | * insert dummy PCI read transactions when some ordering involving | |
88 | * both directions over the PCI does matter. PCI transactions are | |
89 | * fully ordered in each direction. | |
90 | */ | |
91 | ||
92 | #define MEMORY_READ_BARRIER() rmb() | |
93 | #define MEMORY_WRITE_BARRIER() wmb() | |
94 | ||
95 | /* | |
96 | * IO functions definition for big/little endian CPU support. | |
97 | * For now, PCI chips are only supported in little endian addressing mode, | |
98 | */ | |
99 | ||
100 | #ifdef __BIG_ENDIAN | |
101 | ||
102 | #define readw_l2b readw | |
103 | #define readl_l2b readl | |
104 | #define writew_b2l writew | |
105 | #define writel_b2l writel | |
106 | ||
107 | #else /* little endian */ | |
108 | ||
109 | #define readw_raw readw | |
110 | #define readl_raw readl | |
111 | #define writew_raw writew | |
112 | #define writel_raw writel | |
113 | ||
114 | #endif /* endian */ | |
115 | ||
116 | #ifdef SYM_CONF_CHIP_BIG_ENDIAN | |
117 | #error "Chips in BIG ENDIAN addressing mode are not (yet) supported" | |
118 | #endif | |
119 | ||
120 | /* | |
121 | * If the CPU and the chip use same endian-ness addressing, | |
122 | * no byte reordering is needed for script patching. | |
123 | * Macro cpu_to_scr() is to be used for script patching. | |
124 | * Macro scr_to_cpu() is to be used for getting a DWORD | |
125 | * from the script. | |
126 | */ | |
127 | ||
128 | #define cpu_to_scr(dw) cpu_to_le32(dw) | |
129 | #define scr_to_cpu(dw) le32_to_cpu(dw) | |
130 | ||
1da177e4 LT |
131 | /* |
132 | * These ones are used as return code from | |
133 | * error recovery handlers under Linux. | |
134 | */ | |
135 | #define SCSI_SUCCESS SUCCESS | |
136 | #define SCSI_FAILED FAILED | |
137 | ||
138 | /* | |
139 | * System specific target data structure. | |
140 | * None for now, under Linux. | |
141 | */ | |
142 | /* #define SYM_HAVE_STCB */ | |
143 | ||
144 | /* | |
145 | * System specific lun data structure. | |
146 | */ | |
147 | #define SYM_HAVE_SLCB | |
148 | struct sym_slcb { | |
149 | u_short reqtags; /* Number of tags requested by user */ | |
150 | u_short scdev_depth; /* Queue depth set in select_queue_depth() */ | |
151 | }; | |
152 | ||
153 | /* | |
154 | * System specific command data structure. | |
155 | * Not needed under Linux. | |
156 | */ | |
157 | /* struct sym_sccb */ | |
158 | ||
159 | /* | |
160 | * System specific host data structure. | |
161 | */ | |
162 | struct sym_shcb { | |
163 | /* | |
3f79410c | 164 | * Chip and controller identification. |
1da177e4 LT |
165 | */ |
166 | int unit; | |
167 | char inst_name[16]; | |
168 | char chip_name[8]; | |
1da177e4 LT |
169 | |
170 | struct Scsi_Host *host; | |
171 | ||
172 | void __iomem * ioaddr; /* MMIO kernel io address */ | |
173 | void __iomem * ramaddr; /* RAM kernel io address */ | |
1da177e4 LT |
174 | |
175 | struct timer_list timer; /* Timer handler link header */ | |
176 | u_long lasttime; | |
177 | u_long settle_time; /* Resetting the SCSI BUS */ | |
178 | u_char settle_time_valid; | |
179 | }; | |
180 | ||
181 | /* | |
182 | * Return the name of the controller. | |
183 | */ | |
184 | #define sym_name(np) (np)->s.inst_name | |
185 | ||
186 | struct sym_nvram; | |
187 | ||
188 | /* | |
189 | * The IO macros require a struct called 's' and are abused in sym_nvram.c | |
190 | */ | |
191 | struct sym_device { | |
192 | struct pci_dev *pdev; | |
193 | unsigned long mmio_base; | |
194 | unsigned long ram_base; | |
195 | struct { | |
196 | void __iomem *ioaddr; | |
197 | void __iomem *ramaddr; | |
198 | } s; | |
199 | struct sym_chip chip; | |
200 | struct sym_nvram *nvram; | |
1da177e4 LT |
201 | u_char host_id; |
202 | }; | |
203 | ||
204 | /* | |
205 | * Driver host data structure. | |
206 | */ | |
99c9e0a1 | 207 | struct sym_data { |
1da177e4 | 208 | struct sym_hcb *ncb; |
d68cd759 | 209 | struct completion *io_reset; /* PCI error handling */ |
99c9e0a1 | 210 | struct pci_dev *pdev; |
1da177e4 LT |
211 | }; |
212 | ||
213 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) | |
214 | { | |
99c9e0a1 | 215 | return ((struct sym_data *)host->hostdata)->ncb; |
1da177e4 LT |
216 | } |
217 | ||
218 | #include "sym_fw.h" | |
219 | #include "sym_hipd.h" | |
220 | ||
221 | /* | |
222 | * Set the status field of a CAM CCB. | |
223 | */ | |
1beb6fa8 | 224 | static inline void |
1da177e4 LT |
225 | sym_set_cam_status(struct scsi_cmnd *cmd, int status) |
226 | { | |
227 | cmd->result &= ~(0xff << 16); | |
228 | cmd->result |= (status << 16); | |
229 | } | |
230 | ||
231 | /* | |
232 | * Get the status field of a CAM CCB. | |
233 | */ | |
1beb6fa8 | 234 | static inline int |
1da177e4 LT |
235 | sym_get_cam_status(struct scsi_cmnd *cmd) |
236 | { | |
237 | return host_byte(cmd->result); | |
238 | } | |
239 | ||
240 | /* | |
241 | * Build CAM result for a successful IO and for a failed IO. | |
242 | */ | |
1beb6fa8 | 243 | static inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid) |
1da177e4 | 244 | { |
938febd6 | 245 | scsi_set_resid(cmd, resid); |
6bec4c38 | 246 | cmd->result = (DID_OK << 16) | (cp->ssss_status & 0x7f); |
1da177e4 LT |
247 | } |
248 | void sym_set_cam_result_error(struct sym_hcb *np, struct sym_ccb *cp, int resid); | |
249 | ||
250 | void sym_xpt_done(struct sym_hcb *np, struct scsi_cmnd *ccb); | |
251 | #define sym_print_addr(cmd, arg...) dev_info(&cmd->device->sdev_gendev , ## arg) | |
252 | void sym_xpt_async_bus_reset(struct sym_hcb *np); | |
1da177e4 | 253 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); |
5111eefa MW |
254 | void sym_log_bus_error(struct Scsi_Host *); |
255 | void sym_dump_registers(struct Scsi_Host *); | |
1da177e4 LT |
256 | |
257 | #endif /* SYM_GLUE_H */ |