1 | /* |
2 | * Adaptec AIC7xxx device driver for Linux. |
3 | * |
4 | * Copyright (c) 1994 John Aycock |
5 | * The University of Calgary Department of Computer Science. |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2, or (at your option) |
10 | * any later version. |
11 | * |
12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; see the file COPYING. If not, write to |
19 | * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
20 | * |
21 | * Copyright (c) 2000-2003 Adaptec Inc. |
22 | * All rights reserved. |
23 | * |
24 | * Redistribution and use in source and binary forms, with or without |
25 | * modification, are permitted provided that the following conditions |
26 | * are met: |
27 | * 1. Redistributions of source code must retain the above copyright |
28 | * notice, this list of conditions, and the following disclaimer, |
29 | * without modification. |
30 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer |
31 | * substantially similar to the "NO WARRANTY" disclaimer below |
32 | * ("Disclaimer") and any redistribution must be conditioned upon |
33 | * including a substantially similar Disclaimer requirement for further |
34 | * binary redistribution. |
35 | * 3. Neither the names of the above-listed copyright holders nor the names |
36 | * of any contributors may be used to endorse or promote products derived |
37 | * from this software without specific prior written permission. |
38 | * |
39 | * Alternatively, this software may be distributed under the terms of the |
40 | * GNU General Public License ("GPL") version 2 as published by the Free |
41 | * Software Foundation. |
42 | * |
43 | * NO WARRANTY |
44 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
45 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
46 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR |
47 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
48 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
52 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
53 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
54 | * POSSIBILITY OF SUCH DAMAGES. |
55 | * |
56 | * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#151 $ |
57 | * |
58 | */ |
59 | #ifndef _AIC7XXX_LINUX_H_ |
60 | #define _AIC7XXX_LINUX_H_ |
61 | |
62 | #include <linux/types.h> |
63 | #include <linux/blkdev.h> |
64 | #include <linux/delay.h> |
65 | #include <linux/ioport.h> |
66 | #include <linux/pci.h> |
67 | #include <linux/interrupt.h> |
68 | #include <linux/module.h> |
69 | #include <linux/slab.h> |
70 | #include <asm/byteorder.h> |
71 | #include <asm/io.h> |
72 | |
73 | #include <scsi/scsi.h> |
74 | #include <scsi/scsi_cmnd.h> |
75 | #include <scsi/scsi_eh.h> |
76 | #include <scsi/scsi_device.h> |
77 | #include <scsi/scsi_host.h> |
78 | #include <scsi/scsi_tcq.h> |
79 | #include <scsi/scsi_transport.h> |
80 | #include <scsi/scsi_transport_spi.h> |
81 | |
82 | /* Core SCSI definitions */ |
83 | #define AIC_LIB_PREFIX ahc |
84 | |
85 | #include "cam.h" |
86 | #include "queue.h" |
87 | #include "scsi_message.h" |
88 | #include "aiclib.h" |
89 | |
90 | /*********************************** Debugging ********************************/ |
91 | #ifdef CONFIG_AIC7XXX_DEBUG_ENABLE |
92 | #ifdef CONFIG_AIC7XXX_DEBUG_MASK |
93 | #define AHC_DEBUG 1 |
94 | #define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK |
95 | #else |
96 | /* |
97 | * Compile in debugging code, but do not enable any printfs. |
98 | */ |
99 | #define AHC_DEBUG 1 |
100 | #endif |
101 | /* No debugging code. */ |
102 | #endif |
103 | |
104 | /************************* Forward Declarations *******************************/ |
105 | struct ahc_softc; |
106 | typedef struct pci_dev *ahc_dev_softc_t; |
107 | typedef struct scsi_cmnd *ahc_io_ctx_t; |
108 | |
109 | /******************************* Byte Order ***********************************/ |
110 | #define ahc_htobe16(x) cpu_to_be16(x) |
111 | #define ahc_htobe32(x) cpu_to_be32(x) |
112 | #define ahc_htobe64(x) cpu_to_be64(x) |
113 | #define ahc_htole16(x) cpu_to_le16(x) |
114 | #define ahc_htole32(x) cpu_to_le32(x) |
115 | #define ahc_htole64(x) cpu_to_le64(x) |
116 | |
117 | #define ahc_be16toh(x) be16_to_cpu(x) |
118 | #define ahc_be32toh(x) be32_to_cpu(x) |
119 | #define ahc_be64toh(x) be64_to_cpu(x) |
120 | #define ahc_le16toh(x) le16_to_cpu(x) |
121 | #define ahc_le32toh(x) le32_to_cpu(x) |
122 | #define ahc_le64toh(x) le64_to_cpu(x) |
123 | |
124 | /************************* Configuration Data *********************************/ |
125 | extern u_int aic7xxx_no_probe; |
126 | extern u_int aic7xxx_allow_memio; |
127 | extern struct scsi_host_template aic7xxx_driver_template; |
128 | |
129 | /***************************** Bus Space/DMA **********************************/ |
130 | |
131 | typedef uint32_t bus_size_t; |
132 | |
133 | typedef enum { |
134 | BUS_SPACE_MEMIO, |
135 | BUS_SPACE_PIO |
136 | } bus_space_tag_t; |
137 | |
138 | typedef union { |
139 | u_long ioport; |
140 | volatile uint8_t __iomem *maddr; |
141 | } bus_space_handle_t; |
142 | |
143 | typedef struct bus_dma_segment |
144 | { |
145 | dma_addr_t ds_addr; |
146 | bus_size_t ds_len; |
147 | } bus_dma_segment_t; |
148 | |
149 | struct ahc_linux_dma_tag |
150 | { |
151 | bus_size_t alignment; |
152 | bus_size_t boundary; |
153 | bus_size_t maxsize; |
154 | }; |
155 | typedef struct ahc_linux_dma_tag* bus_dma_tag_t; |
156 | |
157 | typedef dma_addr_t bus_dmamap_t; |
158 | |
159 | typedef int bus_dma_filter_t(void*, dma_addr_t); |
160 | typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); |
161 | |
162 | #define BUS_DMA_WAITOK 0x0 |
163 | #define BUS_DMA_NOWAIT 0x1 |
164 | #define BUS_DMA_ALLOCNOW 0x2 |
165 | #define BUS_DMA_LOAD_SEGS 0x4 /* |
166 | * Argument is an S/G list not |
167 | * a single buffer. |
168 | */ |
169 | |
170 | #define BUS_SPACE_MAXADDR 0xFFFFFFFF |
171 | #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF |
172 | #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF |
173 | |
174 | int ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t /*parent*/, |
175 | bus_size_t /*alignment*/, bus_size_t /*boundary*/, |
176 | dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/, |
177 | bus_dma_filter_t*/*filter*/, void */*filterarg*/, |
178 | bus_size_t /*maxsize*/, int /*nsegments*/, |
179 | bus_size_t /*maxsegsz*/, int /*flags*/, |
180 | bus_dma_tag_t */*dma_tagp*/); |
181 | |
182 | void ahc_dma_tag_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/); |
183 | |
184 | int ahc_dmamem_alloc(struct ahc_softc *, bus_dma_tag_t /*dmat*/, |
185 | void** /*vaddr*/, int /*flags*/, |
186 | bus_dmamap_t* /*mapp*/); |
187 | |
188 | void ahc_dmamem_free(struct ahc_softc *, bus_dma_tag_t /*dmat*/, |
189 | void* /*vaddr*/, bus_dmamap_t /*map*/); |
190 | |
191 | void ahc_dmamap_destroy(struct ahc_softc *, bus_dma_tag_t /*tag*/, |
192 | bus_dmamap_t /*map*/); |
193 | |
194 | int ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t /*dmat*/, |
195 | bus_dmamap_t /*map*/, void * /*buf*/, |
196 | bus_size_t /*buflen*/, bus_dmamap_callback_t *, |
197 | void */*callback_arg*/, int /*flags*/); |
198 | |
199 | int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t); |
200 | |
201 | /* |
202 | * Operations performed by ahc_dmamap_sync(). |
203 | */ |
204 | #define BUS_DMASYNC_PREREAD 0x01 /* pre-read synchronization */ |
205 | #define BUS_DMASYNC_POSTREAD 0x02 /* post-read synchronization */ |
206 | #define BUS_DMASYNC_PREWRITE 0x04 /* pre-write synchronization */ |
207 | #define BUS_DMASYNC_POSTWRITE 0x08 /* post-write synchronization */ |
208 | |
209 | /* |
210 | * XXX |
211 | * ahc_dmamap_sync is only used on buffers allocated with |
212 | * the dma_alloc_coherent() API. Although I'm not sure how |
213 | * this works on architectures with a write buffer, Linux does |
214 | * not have an API to sync "coherent" memory. Perhaps we need |
215 | * to do an mb()? |
216 | */ |
217 | #define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op) |
218 | |
219 | /********************************** Includes **********************************/ |
220 | #ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT |
221 | #define AIC_DEBUG_REGISTERS 1 |
222 | #else |
223 | #define AIC_DEBUG_REGISTERS 0 |
224 | #endif |
225 | #include "aic7xxx.h" |
226 | |
227 | /***************************** Timer Facilities *******************************/ |
228 | static inline void |
229 | ahc_scb_timer_reset(struct scb *scb, u_int usec) |
230 | { |
231 | } |
232 | |
233 | /***************************** SMP support ************************************/ |
234 | #include <linux/spinlock.h> |
235 | |
236 | #define AIC7XXX_DRIVER_VERSION "7.0" |
237 | |
238 | /*************************** Device Data Structures ***************************/ |
239 | /* |
240 | * A per probed device structure used to deal with some error recovery |
241 | * scenarios that the Linux mid-layer code just doesn't know how to |
242 | * handle. The structure allocated for a device only becomes persistent |
243 | * after a successfully completed inquiry command to the target when |
244 | * that inquiry data indicates a lun is present. |
245 | */ |
246 | typedef enum { |
247 | AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ |
248 | AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ |
249 | AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ |
250 | AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
251 | } ahc_linux_dev_flags; |
252 | |
253 | struct ahc_linux_device { |
254 | /* |
255 | * The number of transactions currently |
256 | * queued to the device. |
257 | */ |
258 | int active; |
259 | |
260 | /* |
261 | * The currently allowed number of |
262 | * transactions that can be queued to |
263 | * the device. Must be signed for |
264 | * conversion from tagged to untagged |
265 | * mode where the device may have more |
266 | * than one outstanding active transaction. |
267 | */ |
268 | int openings; |
269 | |
270 | /* |
271 | * A positive count indicates that this |
272 | * device's queue is halted. |
273 | */ |
274 | u_int qfrozen; |
275 | |
276 | /* |
277 | * Cumulative command counter. |
278 | */ |
279 | u_long commands_issued; |
280 | |
281 | /* |
282 | * The number of tagged transactions when |
283 | * running at our current opening level |
284 | * that have been successfully received by |
285 | * this device since the last QUEUE FULL. |
286 | */ |
287 | u_int tag_success_count; |
288 | #define AHC_TAG_SUCCESS_INTERVAL 50 |
289 | |
290 | ahc_linux_dev_flags flags; |
291 | |
292 | /* |
293 | * The high limit for the tags variable. |
294 | */ |
295 | u_int maxtags; |
296 | |
297 | /* |
298 | * The computed number of tags outstanding |
299 | * at the time of the last QUEUE FULL event. |
300 | */ |
301 | u_int tags_on_last_queuefull; |
302 | |
303 | /* |
304 | * How many times we have seen a queue full |
305 | * with the same number of tags. This is used |
306 | * to stop our adaptive queue depth algorithm |
307 | * on devices with a fixed number of tags. |
308 | */ |
309 | u_int last_queuefull_same_count; |
310 | #define AHC_LOCK_TAGS_COUNT 50 |
311 | |
312 | /* |
313 | * How many transactions have been queued |
314 | * without the device going idle. We use |
315 | * this statistic to determine when to issue |
316 | * an ordered tag to prevent transaction |
317 | * starvation. This statistic is only updated |
318 | * if the AHC_DEV_PERIODIC_OTAG flag is set |
319 | * on this device. |
320 | */ |
321 | u_int commands_since_idle_or_otag; |
322 | #define AHC_OTAG_THRESH 500 |
323 | }; |
324 | |
325 | /********************* Definitions Required by the Core ***********************/ |
326 | /* |
327 | * Number of SG segments we require. So long as the S/G segments for |
328 | * a particular transaction are allocated in a physically contiguous |
329 | * manner and are allocated below 4GB, the number of S/G segments is |
330 | * unrestricted. |
331 | */ |
332 | #define AHC_NSEG 128 |
333 | |
334 | /* |
335 | * Per-SCB OSM storage. |
336 | */ |
337 | struct scb_platform_data { |
338 | struct ahc_linux_device *dev; |
339 | dma_addr_t buf_busaddr; |
340 | uint32_t xfer_len; |
341 | uint32_t sense_resid; /* Auto-Sense residual */ |
342 | }; |
343 | |
344 | /* |
345 | * Define a structure used for each host adapter. All members are |
346 | * aligned on a boundary >= the size of the member to honor the |
347 | * alignment restrictions of the various platforms supported by |
348 | * this driver. |
349 | */ |
350 | struct ahc_platform_data { |
351 | /* |
352 | * Fields accessed from interrupt context. |
353 | */ |
354 | struct scsi_target *starget[AHC_NUM_TARGETS]; |
355 | |
356 | spinlock_t spin_lock; |
357 | u_int qfrozen; |
358 | struct completion *eh_done; |
359 | struct Scsi_Host *host; /* pointer to scsi host */ |
360 | #define AHC_LINUX_NOIRQ ((uint32_t)~0) |
361 | uint32_t irq; /* IRQ for this adapter */ |
362 | uint32_t bios_address; |
363 | resource_size_t mem_busaddr; /* Mem Base Addr */ |
364 | }; |
365 | |
366 | void ahc_delay(long); |
367 | |
368 | |
369 | /***************************** Low Level I/O **********************************/ |
370 | uint8_t ahc_inb(struct ahc_softc * ahc, long port); |
371 | void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val); |
372 | void ahc_outsb(struct ahc_softc * ahc, long port, |
373 | uint8_t *, int count); |
374 | void ahc_insb(struct ahc_softc * ahc, long port, |
375 | uint8_t *, int count); |
376 | |
377 | /**************************** Initialization **********************************/ |
378 | int ahc_linux_register_host(struct ahc_softc *, |
379 | struct scsi_host_template *); |
380 | |
381 | /******************************** Locking *************************************/ |
382 | /* Lock protecting internal data structures */ |
383 | |
384 | static inline void |
385 | ahc_lockinit(struct ahc_softc *ahc) |
386 | { |
387 | spin_lock_init(&ahc->platform_data->spin_lock); |
388 | } |
389 | |
390 | static inline void |
391 | ahc_lock(struct ahc_softc *ahc, unsigned long *flags) |
392 | { |
393 | spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags); |
394 | } |
395 | |
396 | static inline void |
397 | ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) |
398 | { |
399 | spin_unlock_irqrestore(lock: &ahc->platform_data->spin_lock, flags: *flags); |
400 | } |
401 | |
402 | /******************************* PCI Definitions ******************************/ |
403 | /* |
404 | * PCIM_xxx: mask to locate subfield in register |
405 | * PCIR_xxx: config register offset |
406 | * PCIC_xxx: device class |
407 | * PCIS_xxx: device subclass |
408 | * PCIP_xxx: device programming interface |
409 | * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices) |
410 | * PCID_xxx: device ID |
411 | */ |
412 | #define PCIR_DEVVENDOR 0x00 |
413 | #define PCIR_VENDOR 0x00 |
414 | #define PCIR_DEVICE 0x02 |
415 | #define PCIR_COMMAND 0x04 |
416 | #define PCIM_CMD_PORTEN 0x0001 |
417 | #define PCIM_CMD_MEMEN 0x0002 |
418 | #define PCIM_CMD_BUSMASTEREN 0x0004 |
419 | #define PCIM_CMD_MWRICEN 0x0010 |
420 | #define PCIM_CMD_PERRESPEN 0x0040 |
421 | #define PCIM_CMD_SERRESPEN 0x0100 |
422 | #define PCIR_STATUS 0x06 |
423 | #define PCIR_REVID 0x08 |
424 | #define PCIR_PROGIF 0x09 |
425 | #define PCIR_SUBCLASS 0x0a |
426 | #define PCIR_CLASS 0x0b |
427 | #define PCIR_CACHELNSZ 0x0c |
428 | #define PCIR_LATTIMER 0x0d |
429 | #define 0x0e |
430 | #define PCIM_MFDEV 0x80 |
431 | #define PCIR_BIST 0x0f |
432 | #define PCIR_CAP_PTR 0x34 |
433 | |
434 | /* config registers for header type 0 devices */ |
435 | #define PCIR_MAPS 0x10 |
436 | |
437 | typedef enum |
438 | { |
439 | AHC_POWER_STATE_D0, |
440 | AHC_POWER_STATE_D1, |
441 | AHC_POWER_STATE_D2, |
442 | AHC_POWER_STATE_D3 |
443 | } ahc_power_state; |
444 | |
445 | /**************************** VL/EISA Routines ********************************/ |
446 | #ifdef CONFIG_EISA |
447 | int ahc_linux_eisa_init(void); |
448 | void ahc_linux_eisa_exit(void); |
449 | int aic7770_map_registers(struct ahc_softc *ahc, |
450 | u_int port); |
451 | int aic7770_map_int(struct ahc_softc *ahc, u_int irq); |
452 | #else |
453 | static inline int ahc_linux_eisa_init(void) { |
454 | return -ENODEV; |
455 | } |
456 | static inline void ahc_linux_eisa_exit(void) { |
457 | } |
458 | #endif |
459 | |
460 | /******************************* PCI Routines *********************************/ |
461 | #ifdef CONFIG_PCI |
462 | int ahc_linux_pci_init(void); |
463 | void ahc_linux_pci_exit(void); |
464 | int ahc_pci_map_registers(struct ahc_softc *ahc); |
465 | int ahc_pci_map_int(struct ahc_softc *ahc); |
466 | |
467 | uint32_t ahc_pci_read_config(ahc_dev_softc_t pci, |
468 | int reg, int width); |
469 | |
470 | void ahc_pci_write_config(ahc_dev_softc_t pci, |
471 | int reg, uint32_t value, |
472 | int width); |
473 | |
474 | static inline int ahc_get_pci_function(ahc_dev_softc_t); |
475 | static inline int |
476 | ahc_get_pci_function(ahc_dev_softc_t pci) |
477 | { |
478 | return (PCI_FUNC(pci->devfn)); |
479 | } |
480 | |
481 | static inline int ahc_get_pci_slot(ahc_dev_softc_t); |
482 | static inline int |
483 | ahc_get_pci_slot(ahc_dev_softc_t pci) |
484 | { |
485 | return (PCI_SLOT(pci->devfn)); |
486 | } |
487 | |
488 | static inline int ahc_get_pci_bus(ahc_dev_softc_t); |
489 | static inline int |
490 | ahc_get_pci_bus(ahc_dev_softc_t pci) |
491 | { |
492 | return (pci->bus->number); |
493 | } |
494 | #else |
495 | static inline int ahc_linux_pci_init(void) { |
496 | return 0; |
497 | } |
498 | static inline void ahc_linux_pci_exit(void) { |
499 | } |
500 | #endif |
501 | |
502 | static inline void ahc_flush_device_writes(struct ahc_softc *); |
503 | static inline void |
504 | ahc_flush_device_writes(struct ahc_softc *ahc) |
505 | { |
506 | /* XXX Is this sufficient for all architectures??? */ |
507 | ahc_inb(ahc, port: INTSTAT); |
508 | } |
509 | |
510 | /**************************** Proc FS Support *********************************/ |
511 | int ahc_proc_write_seeprom(struct Scsi_Host *, char *, int); |
512 | int ahc_linux_show_info(struct seq_file *, struct Scsi_Host *); |
513 | |
514 | /*************************** Domain Validation ********************************/ |
515 | /*********************** Transaction Access Wrappers *************************/ |
516 | |
517 | static inline |
518 | void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status) |
519 | { |
520 | cmd->result &= ~(CAM_STATUS_MASK << 16); |
521 | cmd->result |= status << 16; |
522 | } |
523 | |
524 | static inline |
525 | void ahc_set_transaction_status(struct scb *scb, uint32_t status) |
526 | { |
527 | ahc_cmd_set_transaction_status(cmd: scb->io_ctx,status); |
528 | } |
529 | |
530 | static inline |
531 | void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status) |
532 | { |
533 | cmd->result &= ~0xFFFF; |
534 | cmd->result |= status; |
535 | } |
536 | |
537 | static inline |
538 | void ahc_set_scsi_status(struct scb *scb, uint32_t status) |
539 | { |
540 | ahc_cmd_set_scsi_status(cmd: scb->io_ctx, status); |
541 | } |
542 | |
543 | static inline |
544 | uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd) |
545 | { |
546 | return ((cmd->result >> 16) & CAM_STATUS_MASK); |
547 | } |
548 | |
549 | static inline |
550 | uint32_t ahc_get_transaction_status(struct scb *scb) |
551 | { |
552 | return (ahc_cmd_get_transaction_status(cmd: scb->io_ctx)); |
553 | } |
554 | |
555 | static inline |
556 | uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd) |
557 | { |
558 | return (cmd->result & 0xFFFF); |
559 | } |
560 | |
561 | static inline |
562 | uint32_t ahc_get_scsi_status(struct scb *scb) |
563 | { |
564 | return (ahc_cmd_get_scsi_status(cmd: scb->io_ctx)); |
565 | } |
566 | |
567 | static inline |
568 | void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type) |
569 | { |
570 | /* |
571 | * Nothing to do for linux as the incoming transaction |
572 | * has no concept of tag/non tagged, etc. |
573 | */ |
574 | } |
575 | |
576 | static inline |
577 | u_long ahc_get_transfer_length(struct scb *scb) |
578 | { |
579 | return (scb->platform_data->xfer_len); |
580 | } |
581 | |
582 | static inline |
583 | int ahc_get_transfer_dir(struct scb *scb) |
584 | { |
585 | return (scb->io_ctx->sc_data_direction); |
586 | } |
587 | |
588 | static inline |
589 | void ahc_set_residual(struct scb *scb, u_long resid) |
590 | { |
591 | scsi_set_resid(cmd: scb->io_ctx, resid); |
592 | } |
593 | |
594 | static inline |
595 | void ahc_set_sense_residual(struct scb *scb, u_long resid) |
596 | { |
597 | scb->platform_data->sense_resid = resid; |
598 | } |
599 | |
600 | static inline |
601 | u_long ahc_get_residual(struct scb *scb) |
602 | { |
603 | return scsi_get_resid(cmd: scb->io_ctx); |
604 | } |
605 | |
606 | static inline |
607 | u_long ahc_get_sense_residual(struct scb *scb) |
608 | { |
609 | return (scb->platform_data->sense_resid); |
610 | } |
611 | |
612 | static inline |
613 | int ahc_perform_autosense(struct scb *scb) |
614 | { |
615 | /* |
616 | * We always perform autosense in Linux. |
617 | * On other platforms this is set on a |
618 | * per-transaction basis. |
619 | */ |
620 | return (1); |
621 | } |
622 | |
623 | static inline uint32_t |
624 | ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb) |
625 | { |
626 | return (sizeof(struct scsi_sense_data)); |
627 | } |
628 | |
629 | static inline void |
630 | ahc_notify_xfer_settings_change(struct ahc_softc *ahc, |
631 | struct ahc_devinfo *devinfo) |
632 | { |
633 | /* Nothing to do here for linux */ |
634 | } |
635 | |
636 | static inline void |
637 | ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb) |
638 | { |
639 | } |
640 | |
641 | int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg); |
642 | void ahc_platform_free(struct ahc_softc *ahc); |
643 | void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb); |
644 | |
645 | static inline void |
646 | ahc_freeze_scb(struct scb *scb) |
647 | { |
648 | if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) { |
649 | scb->io_ctx->result |= CAM_DEV_QFRZN << 16; |
650 | scb->platform_data->dev->qfrozen++; |
651 | } |
652 | } |
653 | |
654 | void ahc_platform_set_tags(struct ahc_softc *ahc, struct scsi_device *sdev, |
655 | struct ahc_devinfo *devinfo, ahc_queue_alg); |
656 | int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, |
657 | char channel, int lun, u_int tag, |
658 | role_t role, uint32_t status); |
659 | irqreturn_t |
660 | ahc_linux_isr(int irq, void *dev_id); |
661 | void ahc_platform_flushwork(struct ahc_softc *ahc); |
662 | void ahc_done(struct ahc_softc*, struct scb*); |
663 | void ahc_send_async(struct ahc_softc *, char channel, |
664 | u_int target, u_int lun, ac_code); |
665 | void ahc_print_path(struct ahc_softc *, struct scb *); |
666 | |
667 | #ifdef CONFIG_PCI |
668 | #define AHC_PCI_CONFIG 1 |
669 | #else |
670 | #define AHC_PCI_CONFIG 0 |
671 | #endif |
672 | #define bootverbose aic7xxx_verbose |
673 | extern u_int aic7xxx_verbose; |
674 | #endif /* _AIC7XXX_LINUX_H_ */ |
675 | |