1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
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 | *----------------------------------------------------------------------------- |
25 | */ |
26 | |
27 | #ifndef SYM_GLUE_H |
28 | #define SYM_GLUE_H |
29 | |
30 | #include <linux/completion.h> |
31 | #include <linux/delay.h> |
32 | #include <linux/interrupt.h> |
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 | |
59 | #undef SYM_OPT_HANDLE_DEVICE_QUEUEING |
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 | |
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 | /* |
164 | * Chip and controller identification. |
165 | */ |
166 | int unit; |
167 | char inst_name[16]; |
168 | char chip_name[8]; |
169 | |
170 | struct Scsi_Host *host; |
171 | |
172 | void __iomem * ioaddr; /* MMIO kernel io address */ |
173 | void __iomem * ramaddr; /* RAM kernel io address */ |
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; |
201 | u_char host_id; |
202 | }; |
203 | |
204 | /* |
205 | * Driver host data structure. |
206 | */ |
207 | struct sym_data { |
208 | struct sym_hcb *ncb; |
209 | struct completion *io_reset; /* PCI error handling */ |
210 | struct pci_dev *pdev; |
211 | }; |
212 | |
213 | static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host) |
214 | { |
215 | return ((struct sym_data *)host->hostdata)->ncb; |
216 | } |
217 | |
218 | #include "sym_fw.h" |
219 | #include "sym_hipd.h" |
220 | |
221 | /* |
222 | * Set the status field of a CAM CCB. |
223 | */ |
224 | static inline void |
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 | */ |
234 | static inline int |
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 | */ |
243 | static inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid) |
244 | { |
245 | scsi_set_resid(cmd, resid); |
246 | cmd->result = (DID_OK << 16) | (cp->ssss_status & 0x7f); |
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); |
253 | int sym_setup_data_and_start (struct sym_hcb *np, struct scsi_cmnd *csio, struct sym_ccb *cp); |
254 | void sym_log_bus_error(struct Scsi_Host *); |
255 | void sym_dump_registers(struct Scsi_Host *); |
256 | |
257 | #endif /* SYM_GLUE_H */ |
258 | |