1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59#ifndef _AIC7XXX_LINUX_H_
60#define _AIC7XXX_LINUX_H_
61
62#include <linux/types.h>
63#include <linux/blk.h>
64#include <linux/blkdev.h>
65#include <linux/delay.h>
66#include <linux/ioport.h>
67#include <linux/pci.h>
68#include <linux/smp_lock.h>
69#include <linux/version.h>
70#include <linux/module.h>
71#include <asm/byteorder.h>
72#include <asm/io.h>
73
74#ifndef KERNEL_VERSION
75#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
76#endif
77
78#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
79#include <linux/interrupt.h>
80#include <linux/config.h>
81#include <linux/slab.h>
82#else
83#include <linux/malloc.h>
84#endif
85
86
87#define AIC_LIB_PREFIX ahc
88#include "scsi.h"
89#include "hosts.h"
90
91
92#ifdef LIST_HEAD
93#undef LIST_HEAD
94#endif
95
96#include "cam.h"
97#include "queue.h"
98#include "scsi_message.h"
99#include "aiclib.h"
100
101
102#ifdef CONFIG_AIC7XXX_DEBUG_ENABLE
103#ifdef CONFIG_AIC7XXX_DEBUG_MASK
104#define AHC_DEBUG 1
105#define AHC_DEBUG_OPTS CONFIG_AIC7XXX_DEBUG_MASK
106#else
107
108
109
110#define AHC_DEBUG 1
111#endif
112
113#endif
114
115
116struct ahc_softc;
117typedef struct pci_dev *ahc_dev_softc_t;
118typedef Scsi_Cmnd *ahc_io_ctx_t;
119
120
121#define ahc_htobe16(x) cpu_to_be16(x)
122#define ahc_htobe32(x) cpu_to_be32(x)
123#define ahc_htobe64(x) cpu_to_be64(x)
124#define ahc_htole16(x) cpu_to_le16(x)
125#define ahc_htole32(x) cpu_to_le32(x)
126#define ahc_htole64(x) cpu_to_le64(x)
127
128#define ahc_be16toh(x) be16_to_cpu(x)
129#define ahc_be32toh(x) be32_to_cpu(x)
130#define ahc_be64toh(x) be64_to_cpu(x)
131#define ahc_le16toh(x) le16_to_cpu(x)
132#define ahc_le32toh(x) le32_to_cpu(x)
133#define ahc_le64toh(x) le64_to_cpu(x)
134
135#ifndef LITTLE_ENDIAN
136#define LITTLE_ENDIAN 1234
137#endif
138
139#ifndef BIG_ENDIAN
140#define BIG_ENDIAN 4321
141#endif
142
143#ifndef BYTE_ORDER
144#if defined(__BIG_ENDIAN)
145#define BYTE_ORDER BIG_ENDIAN
146#endif
147#if defined(__LITTLE_ENDIAN)
148#define BYTE_ORDER LITTLE_ENDIAN
149#endif
150#endif
151
152
153extern u_int aic7xxx_no_probe;
154extern u_int aic7xxx_allow_memio;
155extern int aic7xxx_detect_complete;
156extern Scsi_Host_Template aic7xxx_driver_template;
157
158
159
160#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17)
161typedef dma_addr_t bus_addr_t;
162#else
163typedef uint32_t bus_addr_t;
164#endif
165typedef uint32_t bus_size_t;
166
167typedef enum {
168 BUS_SPACE_MEMIO,
169 BUS_SPACE_PIO
170} bus_space_tag_t;
171
172typedef union {
173 u_long ioport;
174 volatile uint8_t *maddr;
175} bus_space_handle_t;
176
177typedef struct bus_dma_segment
178{
179 bus_addr_t ds_addr;
180 bus_size_t ds_len;
181} bus_dma_segment_t;
182
183struct ahc_linux_dma_tag
184{
185 bus_size_t alignment;
186 bus_size_t boundary;
187 bus_size_t maxsize;
188};
189typedef struct ahc_linux_dma_tag* bus_dma_tag_t;
190
191struct ahc_linux_dmamap
192{
193 bus_addr_t bus_addr;
194};
195typedef struct ahc_linux_dmamap* bus_dmamap_t;
196
197typedef int bus_dma_filter_t(void*, bus_addr_t);
198typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
199
200#define BUS_DMA_WAITOK 0x0
201#define BUS_DMA_NOWAIT 0x1
202#define BUS_DMA_ALLOCNOW 0x2
203#define BUS_DMA_LOAD_SEGS 0x4
204
205
206
207
208#define BUS_SPACE_MAXADDR 0xFFFFFFFF
209#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
210#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
211
212int ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t ,
213 bus_size_t , bus_size_t ,
214 bus_addr_t , bus_addr_t ,
215 bus_dma_filter_t*, void *,
216 bus_size_t , int ,
217 bus_size_t , int ,
218 bus_dma_tag_t *);
219
220void ahc_dma_tag_destroy(struct ahc_softc *, bus_dma_tag_t );
221
222int ahc_dmamem_alloc(struct ahc_softc *, bus_dma_tag_t ,
223 void** , int ,
224 bus_dmamap_t* );
225
226void ahc_dmamem_free(struct ahc_softc *, bus_dma_tag_t ,
227 void* , bus_dmamap_t );
228
229void ahc_dmamap_destroy(struct ahc_softc *, bus_dma_tag_t ,
230 bus_dmamap_t );
231
232int ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t ,
233 bus_dmamap_t , void * ,
234 bus_size_t , bus_dmamap_callback_t *,
235 void *, int );
236
237int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
238
239
240
241
242#define BUS_DMASYNC_PREREAD 0x01
243#define BUS_DMASYNC_POSTREAD 0x02
244#define BUS_DMASYNC_PREWRITE 0x04
245#define BUS_DMASYNC_POSTWRITE 0x08
246
247
248
249
250
251
252
253
254
255#define ahc_dmamap_sync(ahc, dma_tag, dmamap, offset, len, op)
256
257
258typedef struct timer_list ahc_timer_t;
259
260
261#ifdef CONFIG_AIC7XXX_REG_PRETTY_PRINT
262#define AIC_DEBUG_REGISTERS 1
263#else
264#define AIC_DEBUG_REGISTERS 0
265#endif
266#include "aic7xxx.h"
267
268
269#define ahc_timer_init init_timer
270#define ahc_timer_stop del_timer_sync
271typedef void ahc_linux_callback_t (u_long);
272static __inline void ahc_timer_reset(ahc_timer_t *timer, int usec,
273 ahc_callback_t *func, void *arg);
274static __inline void ahc_scb_timer_reset(struct scb *scb, u_int usec);
275
276static __inline void
277ahc_timer_reset(ahc_timer_t *timer, int usec, ahc_callback_t *func, void *arg)
278{
279 struct ahc_softc *ahc;
280
281 ahc = (struct ahc_softc *)arg;
282 del_timer(timer);
283 timer->data = (u_long)arg;
284 timer->expires = jiffies + (usec * HZ)/1000000;
285 timer->function = (ahc_linux_callback_t*)func;
286 add_timer(timer);
287}
288
289static __inline void
290ahc_scb_timer_reset(struct scb *scb, u_int usec)
291{
292 mod_timer(&scb->io_ctx->eh_timeout, jiffies + (usec * HZ)/1000000);
293}
294
295
296#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17)
297#include <linux/spinlock.h>
298#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93)
299#include <linux/smp.h>
300#endif
301
302#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
303#define AHC_SCSI_HAS_HOST_LOCK 1
304#else
305#define AHC_SCSI_HAS_HOST_LOCK 0
306#endif
307
308#define AIC7XXX_DRIVER_VERSION "6.2.36"
309
310
311
312
313
314
315
316
317struct ahc_cmd_internal {
318
319 uint8_t private[offsetof(struct scsi_cmnd, SCp.Status)];
320 union {
321 STAILQ_ENTRY(ahc_cmd) ste;
322 LIST_ENTRY(ahc_cmd) le;
323 TAILQ_ENTRY(ahc_cmd) tqe;
324 } links;
325 uint32_t end;
326};
327
328struct ahc_cmd {
329 union {
330 struct ahc_cmd_internal icmd;
331 struct scsi_cmnd scsi_cmd;
332 } un;
333};
334
335#define acmd_icmd(cmd) ((cmd)->un.icmd)
336#define acmd_scsi_cmd(cmd) ((cmd)->un.scsi_cmd)
337#define acmd_links un.icmd.links
338
339
340
341
342
343
344
345
346
347TAILQ_HEAD(ahc_busyq, ahc_cmd);
348typedef enum {
349 AHC_DEV_UNCONFIGURED = 0x01,
350 AHC_DEV_FREEZE_TIL_EMPTY = 0x02,
351 AHC_DEV_TIMER_ACTIVE = 0x04,
352 AHC_DEV_ON_RUN_LIST = 0x08,
353 AHC_DEV_Q_BASIC = 0x10,
354 AHC_DEV_Q_TAGGED = 0x20,
355 AHC_DEV_PERIODIC_OTAG = 0x40,
356 AHC_DEV_SLAVE_CONFIGURED = 0x80
357} ahc_linux_dev_flags;
358
359struct ahc_linux_target;
360struct ahc_linux_device {
361 TAILQ_ENTRY(ahc_linux_device) links;
362 struct ahc_busyq busyq;
363
364
365
366
367
368 int active;
369
370
371
372
373
374
375
376
377
378 int openings;
379
380
381
382
383
384 u_int qfrozen;
385
386
387
388
389 u_long commands_issued;
390
391
392
393
394
395
396
397 u_int tag_success_count;
398#define AHC_TAG_SUCCESS_INTERVAL 50
399
400 ahc_linux_dev_flags flags;
401
402
403
404
405 struct timer_list timer;
406
407
408
409
410 u_int maxtags;
411
412
413
414
415
416 u_int tags_on_last_queuefull;
417
418
419
420
421
422
423
424 u_int last_queuefull_same_count;
425#define AHC_LOCK_TAGS_COUNT 50
426
427
428
429
430
431
432
433
434
435
436 u_int commands_since_idle_or_otag;
437#define AHC_OTAG_THRESH 500
438
439 int lun;
440 Scsi_Device *scsi_device;
441 struct ahc_linux_target *target;
442};
443
444typedef enum {
445 AHC_DV_REQUIRED = 0x01,
446 AHC_INQ_VALID = 0x02,
447 AHC_BASIC_DV = 0x04,
448 AHC_ENHANCED_DV = 0x08
449} ahc_linux_targ_flags;
450
451
452typedef enum {
453 AHC_DV_STATE_EXIT = 0,
454 AHC_DV_STATE_INQ_SHORT_ASYNC,
455 AHC_DV_STATE_INQ_ASYNC,
456 AHC_DV_STATE_INQ_ASYNC_VERIFY,
457 AHC_DV_STATE_TUR,
458 AHC_DV_STATE_REBD,
459 AHC_DV_STATE_INQ_VERIFY,
460 AHC_DV_STATE_WEB,
461 AHC_DV_STATE_REB,
462 AHC_DV_STATE_SU,
463 AHC_DV_STATE_BUSY
464} ahc_dv_state;
465
466struct ahc_linux_target {
467 struct ahc_linux_device *devices[AHC_NUM_LUNS];
468 int channel;
469 int target;
470 int refcount;
471 struct ahc_transinfo last_tinfo;
472 struct ahc_softc *ahc;
473 ahc_linux_targ_flags flags;
474 struct scsi_inquiry_data *inq_data;
475
476
477
478 uint8_t dv_next_narrow_period;
479 uint8_t dv_next_wide_period;
480 uint8_t dv_max_width;
481 uint8_t dv_max_ppr_options;
482 uint8_t dv_last_ppr_options;
483 u_int dv_echo_size;
484 ahc_dv_state dv_state;
485 u_int dv_state_retry;
486 char *dv_buffer;
487 char *dv_buffer1;
488};
489
490
491
492
493
494
495
496
497#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
498
499
500
501
502
503extern u_int ahc_linux_nseg;
504#define AHC_NSEG ahc_linux_nseg
505#define AHC_LINUX_MIN_NSEG 64
506#else
507#define AHC_NSEG 128
508#endif
509
510
511
512
513typedef enum {
514 AHC_UP_EH_SEMAPHORE = 0x1
515} ahc_linux_scb_flags;
516
517struct scb_platform_data {
518 struct ahc_linux_device *dev;
519 bus_addr_t buf_busaddr;
520 uint32_t xfer_len;
521#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
522 uint32_t resid;
523#endif
524 uint32_t sense_resid;
525 ahc_linux_scb_flags flags;
526};
527
528
529
530
531
532
533
534typedef enum {
535 AHC_DV_WAIT_SIMQ_EMPTY = 0x01,
536 AHC_DV_WAIT_SIMQ_RELEASE = 0x02,
537 AHC_DV_ACTIVE = 0x04,
538 AHC_DV_SHUTDOWN = 0x08,
539 AHC_RUN_CMPLT_Q_TIMER = 0x10
540} ahc_linux_softc_flags;
541
542TAILQ_HEAD(ahc_completeq, ahc_cmd);
543
544struct ahc_platform_data {
545
546
547
548 struct ahc_linux_target *targets[AHC_NUM_TARGETS];
549 TAILQ_HEAD(, ahc_linux_device) device_runq;
550 struct ahc_completeq completeq;
551
552 spinlock_t spin_lock;
553#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
554 struct tasklet_struct runq_tasklet;
555#endif
556 u_int qfrozen;
557 pid_t dv_pid;
558 struct timer_list completeq_timer;
559 struct timer_list reset_timer;
560 struct semaphore eh_sem;
561 struct semaphore dv_sem;
562 struct semaphore dv_cmd_sem;
563
564
565 struct scsi_device *dv_scsi_dev;
566 struct Scsi_Host *host;
567#define AHC_LINUX_NOIRQ ((uint32_t)~0)
568 uint32_t irq;
569 uint32_t bios_address;
570 uint32_t mem_busaddr;
571 bus_addr_t hw_dma_mask;
572 ahc_linux_softc_flags flags;
573};
574
575
576#define printf printk
577#define M_NOWAIT GFP_ATOMIC
578#define M_WAITOK 0
579#define malloc(size, type, flags) kmalloc(size, flags)
580#define free(ptr, type) kfree(ptr)
581
582static __inline void ahc_delay(long);
583static __inline void
584ahc_delay(long usec)
585{
586
587
588
589
590
591 while (usec > 0) {
592 udelay(usec % 1024);
593 usec -= 1024;
594 }
595}
596
597
598
599#if defined(__powerpc__) || defined(__i386__) || defined(__ia64__)
600#define MMAPIO
601#endif
602
603static __inline uint8_t ahc_inb(struct ahc_softc * ahc, long port);
604static __inline void ahc_outb(struct ahc_softc * ahc, long port, uint8_t val);
605static __inline void ahc_outsb(struct ahc_softc * ahc, long port,
606 uint8_t *, int count);
607static __inline void ahc_insb(struct ahc_softc * ahc, long port,
608 uint8_t *, int count);
609
610static __inline uint8_t
611ahc_inb(struct ahc_softc * ahc, long port)
612{
613 uint8_t x;
614#ifdef MMAPIO
615
616 if (ahc->tag == BUS_SPACE_MEMIO) {
617 x = readb(ahc->bsh.maddr + port);
618 } else {
619 x = inb(ahc->bsh.ioport + port);
620 }
621#else
622 x = inb(ahc->bsh.ioport + port);
623#endif
624 mb();
625 return (x);
626}
627
628static __inline void
629ahc_outb(struct ahc_softc * ahc, long port, uint8_t val)
630{
631#ifdef MMAPIO
632 if (ahc->tag == BUS_SPACE_MEMIO) {
633 writeb(val, ahc->bsh.maddr + port);
634 } else {
635 outb(val, ahc->bsh.ioport + port);
636 }
637#else
638 outb(val, ahc->bsh.ioport + port);
639#endif
640 mb();
641}
642
643static __inline void
644ahc_outsb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
645{
646 int i;
647
648
649
650
651
652
653 for (i = 0; i < count; i++)
654 ahc_outb(ahc, port, *array++);
655}
656
657static __inline void
658ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count)
659{
660 int i;
661
662
663
664
665
666
667 for (i = 0; i < count; i++)
668 *array++ = ahc_inb(ahc, port);
669}
670
671
672int ahc_linux_register_host(struct ahc_softc *,
673 Scsi_Host_Template *);
674
675uint64_t ahc_linux_get_memsize(void);
676
677
678struct info_str {
679 char *buffer;
680 int length;
681 off_t offset;
682 int pos;
683};
684
685void ahc_format_transinfo(struct info_str *info,
686 struct ahc_transinfo *tinfo);
687
688
689
690static __inline void ahc_lockinit(struct ahc_softc *);
691static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags);
692static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags);
693
694
695static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *,
696 unsigned long *flags);
697static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *,
698 unsigned long *flags);
699
700
701static __inline void ahc_done_lockinit(struct ahc_softc *);
702static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags);
703static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags);
704
705
706extern spinlock_t ahc_list_spinlock;
707static __inline void ahc_list_lockinit(void);
708static __inline void ahc_list_lock(unsigned long *flags);
709static __inline void ahc_list_unlock(unsigned long *flags);
710
711static __inline void
712ahc_lockinit(struct ahc_softc *ahc)
713{
714 spin_lock_init(&ahc->platform_data->spin_lock);
715}
716
717static __inline void
718ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
719{
720 spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
721}
722
723static __inline void
724ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
725{
726 spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
727}
728
729static __inline void
730ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags)
731{
732
733
734
735
736
737
738
739#if AHC_SCSI_HAS_HOST_LOCK == 0
740 spin_unlock(&io_request_lock);
741 spin_lock(&ahc->platform_data->spin_lock);
742#endif
743}
744
745static __inline void
746ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags)
747{
748#if AHC_SCSI_HAS_HOST_LOCK == 0
749 spin_unlock(&ahc->platform_data->spin_lock);
750 spin_lock(&io_request_lock);
751#endif
752}
753
754static __inline void
755ahc_done_lockinit(struct ahc_softc *ahc)
756{
757
758
759
760
761
762}
763
764static __inline void
765ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags)
766{
767#if AHC_SCSI_HAS_HOST_LOCK == 0
768 spin_lock_irqsave(&io_request_lock, *flags);
769#endif
770}
771
772static __inline void
773ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags)
774{
775#if AHC_SCSI_HAS_HOST_LOCK == 0
776 spin_unlock_irqrestore(&io_request_lock, *flags);
777#endif
778}
779
780static __inline void
781ahc_list_lockinit(void)
782{
783 spin_lock_init(&ahc_list_spinlock);
784}
785
786static __inline void
787ahc_list_lock(unsigned long *flags)
788{
789 spin_lock_irqsave(&ahc_list_spinlock, *flags);
790}
791
792static __inline void
793ahc_list_unlock(unsigned long *flags)
794{
795 spin_unlock_irqrestore(&ahc_list_spinlock, *flags);
796}
797
798
799
800
801
802
803
804
805
806
807
808#define PCIR_DEVVENDOR 0x00
809#define PCIR_VENDOR 0x00
810#define PCIR_DEVICE 0x02
811#define PCIR_COMMAND 0x04
812#define PCIM_CMD_PORTEN 0x0001
813#define PCIM_CMD_MEMEN 0x0002
814#define PCIM_CMD_BUSMASTEREN 0x0004
815#define PCIM_CMD_MWRICEN 0x0010
816#define PCIM_CMD_PERRESPEN 0x0040
817#define PCIM_CMD_SERRESPEN 0x0100
818#define PCIR_STATUS 0x06
819#define PCIR_REVID 0x08
820#define PCIR_PROGIF 0x09
821#define PCIR_SUBCLASS 0x0a
822#define PCIR_CLASS 0x0b
823#define PCIR_CACHELNSZ 0x0c
824#define PCIR_LATTIMER 0x0d
825#define PCIR_HEADERTYPE 0x0e
826#define PCIM_MFDEV 0x80
827#define PCIR_BIST 0x0f
828#define PCIR_CAP_PTR 0x34
829
830
831#define PCIR_MAPS 0x10
832#define PCIR_SUBVEND_0 0x2c
833#define PCIR_SUBDEV_0 0x2e
834
835#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
836extern struct pci_driver aic7xxx_pci_driver;
837#endif
838
839typedef enum
840{
841 AHC_POWER_STATE_D0,
842 AHC_POWER_STATE_D1,
843 AHC_POWER_STATE_D2,
844 AHC_POWER_STATE_D3
845} ahc_power_state;
846
847
848#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \
849 && (defined(__i386__) || defined(__alpha__)) \
850 && (!defined(CONFIG_EISA)))
851#define CONFIG_EISA
852#endif
853
854#ifdef CONFIG_EISA
855extern uint32_t aic7xxx_probe_eisa_vl;
856void ahc_linux_eisa_init(void);
857void ahc_linux_eisa_exit(void);
858int aic7770_map_registers(struct ahc_softc *ahc,
859 u_int port);
860int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
861#endif
862
863
864#ifdef CONFIG_PCI
865void ahc_power_state_change(struct ahc_softc *ahc,
866 ahc_power_state new_state);
867int ahc_linux_pci_init(void);
868void ahc_linux_pci_exit(void);
869int ahc_pci_map_registers(struct ahc_softc *ahc);
870int ahc_pci_map_int(struct ahc_softc *ahc);
871
872static __inline uint32_t ahc_pci_read_config(ahc_dev_softc_t pci,
873 int reg, int width);
874
875static __inline uint32_t
876ahc_pci_read_config(ahc_dev_softc_t pci, int reg, int width)
877{
878 switch (width) {
879 case 1:
880 {
881 uint8_t retval;
882
883 pci_read_config_byte(pci, reg, &retval);
884 return (retval);
885 }
886 case 2:
887 {
888 uint16_t retval;
889 pci_read_config_word(pci, reg, &retval);
890 return (retval);
891 }
892 case 4:
893 {
894 uint32_t retval;
895 pci_read_config_dword(pci, reg, &retval);
896 return (retval);
897 }
898 default:
899 panic("ahc_pci_read_config: Read size too big");
900
901 return (0);
902 }
903}
904
905static __inline void ahc_pci_write_config(ahc_dev_softc_t pci,
906 int reg, uint32_t value,
907 int width);
908
909static __inline void
910ahc_pci_write_config(ahc_dev_softc_t pci, int reg, uint32_t value, int width)
911{
912 switch (width) {
913 case 1:
914 pci_write_config_byte(pci, reg, value);
915 break;
916 case 2:
917 pci_write_config_word(pci, reg, value);
918 break;
919 case 4:
920 pci_write_config_dword(pci, reg, value);
921 break;
922 default:
923 panic("ahc_pci_write_config: Write size too big");
924
925 }
926}
927
928static __inline int ahc_get_pci_function(ahc_dev_softc_t);
929static __inline int
930ahc_get_pci_function(ahc_dev_softc_t pci)
931{
932 return (PCI_FUNC(pci->devfn));
933}
934
935static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
936static __inline int
937ahc_get_pci_slot(ahc_dev_softc_t pci)
938{
939 return (PCI_SLOT(pci->devfn));
940}
941
942static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
943static __inline int
944ahc_get_pci_bus(ahc_dev_softc_t pci)
945{
946 return (pci->bus->number);
947}
948#endif
949
950static __inline void ahc_flush_device_writes(struct ahc_softc *);
951static __inline void
952ahc_flush_device_writes(struct ahc_softc *ahc)
953{
954
955 ahc_inb(ahc, INTSTAT);
956}
957
958#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0)
959#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg)
960#define pci_unmap_sg(pdev, sg_list, nseg, direction)
961#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address))
962#define sg_dma_len(sg) ((sg)->length)
963#define pci_map_single(pdev, buffer, bufflen, direction) \
964 (VIRT_TO_BUS(buffer))
965#define pci_unmap_single(pdev, buffer, buflen, direction)
966#endif
967
968#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
969#define ahc_pci_set_dma_mask pci_set_dma_mask
970#else
971
972
973
974#define ahc_pci_set_dma_mask(dev_softc, mask) \
975 (((dev_softc)->dma_mask = mask) && 0)
976#endif
977
978#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
979int ahc_linux_proc_info(char *, char **, off_t, int, int, int);
980#else
981int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
982 off_t, int, int);
983#endif
984
985
986#define AHC_DV_CMD(cmd) ((cmd)->scsi_done == ahc_linux_dv_complete)
987#define AHC_DV_SIMQ_FROZEN(ahc) \
988 ((((ahc)->platform_data->flags & AHC_DV_ACTIVE) != 0) \
989 && (ahc)->platform_data->qfrozen == 1)
990
991
992static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t);
993static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
994static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t);
995static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
996static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd);
997static __inline uint32_t ahc_get_transaction_status(struct scb *);
998static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd);
999static __inline uint32_t ahc_get_scsi_status(struct scb *);
1000static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
1001static __inline u_long ahc_get_transfer_length(struct scb *);
1002static __inline int ahc_get_transfer_dir(struct scb *);
1003static __inline void ahc_set_residual(struct scb *, u_long);
1004static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
1005static __inline u_long ahc_get_residual(struct scb *);
1006static __inline u_long ahc_get_sense_residual(struct scb *);
1007static __inline int ahc_perform_autosense(struct scb *);
1008static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
1009 struct scb *);
1010static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
1011 struct ahc_devinfo *);
1012static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
1013 struct scb *scb);
1014static __inline void ahc_freeze_scb(struct scb *scb);
1015
1016static __inline
1017void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status)
1018{
1019 cmd->result &= ~(CAM_STATUS_MASK << 16);
1020 cmd->result |= status << 16;
1021}
1022
1023static __inline
1024void ahc_set_transaction_status(struct scb *scb, uint32_t status)
1025{
1026 ahc_cmd_set_transaction_status(scb->io_ctx,status);
1027}
1028
1029static __inline
1030void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status)
1031{
1032 cmd->result &= ~0xFFFF;
1033 cmd->result |= status;
1034}
1035
1036static __inline
1037void ahc_set_scsi_status(struct scb *scb, uint32_t status)
1038{
1039 ahc_cmd_set_scsi_status(scb->io_ctx, status);
1040}
1041
1042static __inline
1043uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd)
1044{
1045 return ((cmd->result >> 16) & CAM_STATUS_MASK);
1046}
1047
1048static __inline
1049uint32_t ahc_get_transaction_status(struct scb *scb)
1050{
1051 return (ahc_cmd_get_transaction_status(scb->io_ctx));
1052}
1053
1054static __inline
1055uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd)
1056{
1057 return (cmd->result & 0xFFFF);
1058}
1059
1060static __inline
1061uint32_t ahc_get_scsi_status(struct scb *scb)
1062{
1063 return (ahc_cmd_get_scsi_status(scb->io_ctx));
1064}
1065
1066static __inline
1067void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
1068{
1069
1070
1071
1072
1073}
1074
1075static __inline
1076u_long ahc_get_transfer_length(struct scb *scb)
1077{
1078 return (scb->platform_data->xfer_len);
1079}
1080
1081static __inline
1082int ahc_get_transfer_dir(struct scb *scb)
1083{
1084#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40)
1085 return (scb->io_ctx->sc_data_direction);
1086#else
1087 if (scb->io_ctx->bufflen == 0)
1088 return (CAM_DIR_NONE);
1089
1090 switch(scb->io_ctx->cmnd[0]) {
1091 case 0x08:
1092 case 0x28:
1093 case 0xA8:
1094 return (CAM_DIR_IN);
1095 case 0x0A:
1096 case 0x2A:
1097 case 0xAA:
1098 return (CAM_DIR_OUT);
1099 default:
1100 return (CAM_DIR_NONE);
1101 }
1102#endif
1103}
1104
1105static __inline
1106void ahc_set_residual(struct scb *scb, u_long resid)
1107{
1108#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
1109 scb->io_ctx->resid = resid;
1110#else
1111 scb->platform_data->resid = resid;
1112#endif
1113}
1114
1115static __inline
1116void ahc_set_sense_residual(struct scb *scb, u_long resid)
1117{
1118 scb->platform_data->sense_resid = resid;
1119}
1120
1121static __inline
1122u_long ahc_get_residual(struct scb *scb)
1123{
1124#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
1125 return (scb->io_ctx->resid);
1126#else
1127 return (scb->platform_data->resid);
1128#endif
1129}
1130
1131static __inline
1132u_long ahc_get_sense_residual(struct scb *scb)
1133{
1134 return (scb->platform_data->sense_resid);
1135}
1136
1137static __inline
1138int ahc_perform_autosense(struct scb *scb)
1139{
1140
1141
1142
1143
1144
1145 return (1);
1146}
1147
1148static __inline uint32_t
1149ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
1150{
1151 return (sizeof(struct scsi_sense_data));
1152}
1153
1154static __inline void
1155ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
1156 struct ahc_devinfo *devinfo)
1157{
1158
1159}
1160
1161static __inline void
1162ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
1163{
1164 ahc->flags &= ~AHC_RESOURCE_SHORTAGE;
1165}
1166
1167int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
1168void ahc_platform_free(struct ahc_softc *ahc);
1169void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
1170
1171static __inline void
1172ahc_freeze_scb(struct scb *scb)
1173{
1174 if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
1175 scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
1176 scb->platform_data->dev->qfrozen++;
1177 }
1178}
1179
1180void ahc_platform_set_tags(struct ahc_softc *ahc,
1181 struct ahc_devinfo *devinfo, ahc_queue_alg);
1182int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target,
1183 char channel, int lun, u_int tag,
1184 role_t role, uint32_t status);
1185irqreturn_t
1186 ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs);
1187void ahc_platform_flushwork(struct ahc_softc *ahc);
1188int ahc_softc_comp(struct ahc_softc *, struct ahc_softc *);
1189void ahc_done(struct ahc_softc*, struct scb*);
1190void ahc_send_async(struct ahc_softc *, char channel,
1191 u_int target, u_int lun, ac_code, void *);
1192void ahc_print_path(struct ahc_softc *, struct scb *);
1193void ahc_platform_dump_card_state(struct ahc_softc *ahc);
1194
1195#ifdef CONFIG_PCI
1196#define AHC_PCI_CONFIG 1
1197#else
1198#define AHC_PCI_CONFIG 0
1199#endif
1200#define bootverbose aic7xxx_verbose
1201extern u_int aic7xxx_verbose;
1202#endif
1203