OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [drivers/] [scsi/] [aic7xxx/] [aic79xx_osm.h] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * Adaptec AIC79xx device driver for Linux.
3
 *
4
 * Copyright (c) 2000-2001 Adaptec Inc.
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions, and the following disclaimer,
12
 *    without modification.
13
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
14
 *    substantially similar to the "NO WARRANTY" disclaimer below
15
 *    ("Disclaimer") and any redistribution must be conditioned upon
16
 *    including a substantially similar Disclaimer requirement for further
17
 *    binary redistribution.
18
 * 3. Neither the names of the above-listed copyright holders nor the names
19
 *    of any contributors may be used to endorse or promote products derived
20
 *    from this software without specific prior written permission.
21
 *
22
 * Alternatively, this software may be distributed under the terms of the
23
 * GNU General Public License ("GPL") version 2 as published by the Free
24
 * Software Foundation.
25
 *
26
 * NO WARRANTY
27
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
30
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
35
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
 * POSSIBILITY OF SUCH DAMAGES.
38
 *
39
 * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#166 $
40
 *
41
 */
42
#ifndef _AIC79XX_LINUX_H_
43
#define _AIC79XX_LINUX_H_
44
 
45
#include <linux/types.h>
46
#include <linux/blkdev.h>
47
#include <linux/delay.h>
48
#include <linux/ioport.h>
49
#include <linux/pci.h>
50
#include <linux/interrupt.h>
51
#include <linux/module.h>
52
#include <linux/slab.h>
53
#include <asm/byteorder.h>
54
#include <asm/io.h>
55
 
56
#include <scsi/scsi.h>
57
#include <scsi/scsi_cmnd.h>
58
#include <scsi/scsi_eh.h>
59
#include <scsi/scsi_device.h>
60
#include <scsi/scsi_host.h>
61
#include <scsi/scsi_tcq.h>
62
#include <scsi/scsi_transport.h>
63
#include <scsi/scsi_transport_spi.h>
64
 
65
/* Core SCSI definitions */
66
#define AIC_LIB_PREFIX ahd
67
 
68
/* Name space conflict with BSD queue macros */
69
#ifdef LIST_HEAD
70
#undef LIST_HEAD
71
#endif
72
 
73
#include "cam.h"
74
#include "queue.h"
75
#include "scsi_message.h"
76
#include "scsi_iu.h"
77
#include "aiclib.h"
78
 
79
/*********************************** Debugging ********************************/
80
#ifdef CONFIG_AIC79XX_DEBUG_ENABLE
81
#ifdef CONFIG_AIC79XX_DEBUG_MASK
82
#define AHD_DEBUG 1
83
#define AHD_DEBUG_OPTS CONFIG_AIC79XX_DEBUG_MASK
84
#else
85
/*
86
 * Compile in debugging code, but do not enable any printfs.
87
 */
88
#define AHD_DEBUG 1
89
#define AHD_DEBUG_OPTS 0
90
#endif
91
/* No debugging code. */
92
#endif
93
 
94
/********************************** Misc Macros *******************************/
95
#define powerof2(x)     ((((x)-1)&(x))==0)
96
 
97
/************************* Forward Declarations *******************************/
98
struct ahd_softc;
99
typedef struct pci_dev *ahd_dev_softc_t;
100
typedef struct scsi_cmnd      *ahd_io_ctx_t;
101
 
102
/******************************* Byte Order ***********************************/
103
#define ahd_htobe16(x)  cpu_to_be16(x)
104
#define ahd_htobe32(x)  cpu_to_be32(x)
105
#define ahd_htobe64(x)  cpu_to_be64(x)
106
#define ahd_htole16(x)  cpu_to_le16(x)
107
#define ahd_htole32(x)  cpu_to_le32(x)
108
#define ahd_htole64(x)  cpu_to_le64(x)
109
 
110
#define ahd_be16toh(x)  be16_to_cpu(x)
111
#define ahd_be32toh(x)  be32_to_cpu(x)
112
#define ahd_be64toh(x)  be64_to_cpu(x)
113
#define ahd_le16toh(x)  le16_to_cpu(x)
114
#define ahd_le32toh(x)  le32_to_cpu(x)
115
#define ahd_le64toh(x)  le64_to_cpu(x)
116
 
117
/************************* Configuration Data *********************************/
118
extern uint32_t aic79xx_allow_memio;
119
extern struct scsi_host_template aic79xx_driver_template;
120
 
121
/***************************** Bus Space/DMA **********************************/
122
 
123
typedef uint32_t bus_size_t;
124
 
125
typedef enum {
126
        BUS_SPACE_MEMIO,
127
        BUS_SPACE_PIO
128
} bus_space_tag_t;
129
 
130
typedef union {
131
        u_long            ioport;
132
        volatile uint8_t __iomem *maddr;
133
} bus_space_handle_t;
134
 
135
typedef struct bus_dma_segment
136
{
137
        dma_addr_t      ds_addr;
138
        bus_size_t      ds_len;
139
} bus_dma_segment_t;
140
 
141
struct ahd_linux_dma_tag
142
{
143
        bus_size_t      alignment;
144
        bus_size_t      boundary;
145
        bus_size_t      maxsize;
146
};
147
typedef struct ahd_linux_dma_tag* bus_dma_tag_t;
148
 
149
typedef dma_addr_t bus_dmamap_t;
150
 
151
typedef int bus_dma_filter_t(void*, dma_addr_t);
152
typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
153
 
154
#define BUS_DMA_WAITOK          0x0
155
#define BUS_DMA_NOWAIT          0x1
156
#define BUS_DMA_ALLOCNOW        0x2
157
#define BUS_DMA_LOAD_SEGS       0x4     /*
158
                                         * Argument is an S/G list not
159
                                         * a single buffer.
160
                                         */
161
 
162
#define BUS_SPACE_MAXADDR       0xFFFFFFFF
163
#define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
164
#define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
165
 
166
int     ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/,
167
                           bus_size_t /*alignment*/, bus_size_t /*boundary*/,
168
                           dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/,
169
                           bus_dma_filter_t*/*filter*/, void */*filterarg*/,
170
                           bus_size_t /*maxsize*/, int /*nsegments*/,
171
                           bus_size_t /*maxsegsz*/, int /*flags*/,
172
                           bus_dma_tag_t */*dma_tagp*/);
173
 
174
void    ahd_dma_tag_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/);
175
 
176
int     ahd_dmamem_alloc(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
177
                         void** /*vaddr*/, int /*flags*/,
178
                         bus_dmamap_t* /*mapp*/);
179
 
180
void    ahd_dmamem_free(struct ahd_softc *, bus_dma_tag_t /*dmat*/,
181
                        void* /*vaddr*/, bus_dmamap_t /*map*/);
182
 
183
void    ahd_dmamap_destroy(struct ahd_softc *, bus_dma_tag_t /*tag*/,
184
                           bus_dmamap_t /*map*/);
185
 
186
int     ahd_dmamap_load(struct ahd_softc *ahd, bus_dma_tag_t /*dmat*/,
187
                        bus_dmamap_t /*map*/, void * /*buf*/,
188
                        bus_size_t /*buflen*/, bus_dmamap_callback_t *,
189
                        void */*callback_arg*/, int /*flags*/);
190
 
191
int     ahd_dmamap_unload(struct ahd_softc *, bus_dma_tag_t, bus_dmamap_t);
192
 
193
/*
194
 * Operations performed by ahd_dmamap_sync().
195
 */
196
#define BUS_DMASYNC_PREREAD     0x01    /* pre-read synchronization */
197
#define BUS_DMASYNC_POSTREAD    0x02    /* post-read synchronization */
198
#define BUS_DMASYNC_PREWRITE    0x04    /* pre-write synchronization */
199
#define BUS_DMASYNC_POSTWRITE   0x08    /* post-write synchronization */
200
 
201
/*
202
 * XXX
203
 * ahd_dmamap_sync is only used on buffers allocated with
204
 * the pci_alloc_consistent() API.  Although I'm not sure how
205
 * this works on architectures with a write buffer, Linux does
206
 * not have an API to sync "coherent" memory.  Perhaps we need
207
 * to do an mb()?
208
 */
209
#define ahd_dmamap_sync(ahd, dma_tag, dmamap, offset, len, op)
210
 
211
/************************** Timer DataStructures ******************************/
212
typedef struct timer_list ahd_timer_t;
213
 
214
/********************************** Includes **********************************/
215
#ifdef CONFIG_AIC79XX_REG_PRETTY_PRINT
216
#define AIC_DEBUG_REGISTERS 1
217
#else
218
#define AIC_DEBUG_REGISTERS 0
219
#endif
220
#include "aic79xx.h"
221
 
222
/***************************** Timer Facilities *******************************/
223
#define ahd_timer_init init_timer
224
#define ahd_timer_stop del_timer_sync
225
typedef void ahd_linux_callback_t (u_long);
226
static __inline void ahd_timer_reset(ahd_timer_t *timer, int usec,
227
                                     ahd_callback_t *func, void *arg);
228
 
229
static __inline void
230
ahd_timer_reset(ahd_timer_t *timer, int usec, ahd_callback_t *func, void *arg)
231
{
232
        struct ahd_softc *ahd;
233
 
234
        ahd = (struct ahd_softc *)arg;
235
        del_timer(timer);
236
        timer->data = (u_long)arg;
237
        timer->expires = jiffies + (usec * HZ)/1000000;
238
        timer->function = (ahd_linux_callback_t*)func;
239
        add_timer(timer);
240
}
241
 
242
/***************************** SMP support ************************************/
243
#include <linux/spinlock.h>
244
 
245
#define AIC79XX_DRIVER_VERSION "3.0"
246
 
247
/*************************** Device Data Structures ***************************/
248
/*
249
 * A per probed device structure used to deal with some error recovery
250
 * scenarios that the Linux mid-layer code just doesn't know how to
251
 * handle.  The structure allocated for a device only becomes persistent
252
 * after a successfully completed inquiry command to the target when
253
 * that inquiry data indicates a lun is present.
254
 */
255
 
256
typedef enum {
257
        AHD_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */
258
        AHD_DEV_Q_BASIC          = 0x10, /* Allow basic device queuing */
259
        AHD_DEV_Q_TAGGED         = 0x20, /* Allow full SCSI2 command queueing */
260
        AHD_DEV_PERIODIC_OTAG    = 0x40, /* Send OTAG to prevent starvation */
261
} ahd_linux_dev_flags;
262
 
263
struct ahd_linux_device {
264
        TAILQ_ENTRY(ahd_linux_device) links;
265
 
266
        /*
267
         * The number of transactions currently
268
         * queued to the device.
269
         */
270
        int                     active;
271
 
272
        /*
273
         * The currently allowed number of
274
         * transactions that can be queued to
275
         * the device.  Must be signed for
276
         * conversion from tagged to untagged
277
         * mode where the device may have more
278
         * than one outstanding active transaction.
279
         */
280
        int                     openings;
281
 
282
        /*
283
         * A positive count indicates that this
284
         * device's queue is halted.
285
         */
286
        u_int                   qfrozen;
287
 
288
        /*
289
         * Cumulative command counter.
290
         */
291
        u_long                  commands_issued;
292
 
293
        /*
294
         * The number of tagged transactions when
295
         * running at our current opening level
296
         * that have been successfully received by
297
         * this device since the last QUEUE FULL.
298
         */
299
        u_int                   tag_success_count;
300
#define AHD_TAG_SUCCESS_INTERVAL 50
301
 
302
        ahd_linux_dev_flags     flags;
303
 
304
        /*
305
         * Per device timer.
306
         */
307
        struct timer_list       timer;
308
 
309
        /*
310
         * The high limit for the tags variable.
311
         */
312
        u_int                   maxtags;
313
 
314
        /*
315
         * The computed number of tags outstanding
316
         * at the time of the last QUEUE FULL event.
317
         */
318
        u_int                   tags_on_last_queuefull;
319
 
320
        /*
321
         * How many times we have seen a queue full
322
         * with the same number of tags.  This is used
323
         * to stop our adaptive queue depth algorithm
324
         * on devices with a fixed number of tags.
325
         */
326
        u_int                   last_queuefull_same_count;
327
#define AHD_LOCK_TAGS_COUNT 50
328
 
329
        /*
330
         * How many transactions have been queued
331
         * without the device going idle.  We use
332
         * this statistic to determine when to issue
333
         * an ordered tag to prevent transaction
334
         * starvation.  This statistic is only updated
335
         * if the AHD_DEV_PERIODIC_OTAG flag is set
336
         * on this device.
337
         */
338
        u_int                   commands_since_idle_or_otag;
339
#define AHD_OTAG_THRESH 500
340
};
341
 
342
/********************* Definitions Required by the Core ***********************/
343
/*
344
 * Number of SG segments we require.  So long as the S/G segments for
345
 * a particular transaction are allocated in a physically contiguous
346
 * manner and are allocated below 4GB, the number of S/G segments is
347
 * unrestricted.
348
 */
349
#define AHD_NSEG 128
350
 
351
/*
352
 * Per-SCB OSM storage.
353
 */
354
struct scb_platform_data {
355
        struct ahd_linux_device *dev;
356
        dma_addr_t               buf_busaddr;
357
        uint32_t                 xfer_len;
358
        uint32_t                 sense_resid;   /* Auto-Sense residual */
359
};
360
 
361
/*
362
 * Define a structure used for each host adapter.  All members are
363
 * aligned on a boundary >= the size of the member to honor the
364
 * alignment restrictions of the various platforms supported by
365
 * this driver.
366
 */
367
struct ahd_platform_data {
368
        /*
369
         * Fields accessed from interrupt context.
370
         */
371
        struct scsi_target *starget[AHD_NUM_TARGETS];
372
 
373
        spinlock_t               spin_lock;
374
        struct completion       *eh_done;
375
        struct Scsi_Host        *host;          /* pointer to scsi host */
376
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
377
        uint32_t                 irq;           /* IRQ for this adapter */
378
        uint32_t                 bios_address;
379
        uint32_t                 mem_busaddr;   /* Mem Base Addr */
380
};
381
 
382
/************************** OS Utility Wrappers *******************************/
383
#define printf printk
384
#define M_NOWAIT GFP_ATOMIC
385
#define M_WAITOK 0
386
#define malloc(size, type, flags) kmalloc(size, flags)
387
#define free(ptr, type) kfree(ptr)
388
 
389
static __inline void ahd_delay(long);
390
static __inline void
391
ahd_delay(long usec)
392
{
393
        /*
394
         * udelay on Linux can have problems for
395
         * multi-millisecond waits.  Wait at most
396
         * 1024us per call.
397
         */
398
        while (usec > 0) {
399
                udelay(usec % 1024);
400
                usec -= 1024;
401
        }
402
}
403
 
404
 
405
/***************************** Low Level I/O **********************************/
406
static __inline uint8_t ahd_inb(struct ahd_softc * ahd, long port);
407
static __inline uint16_t ahd_inw_atomic(struct ahd_softc * ahd, long port);
408
static __inline void ahd_outb(struct ahd_softc * ahd, long port, uint8_t val);
409
static __inline void ahd_outw_atomic(struct ahd_softc * ahd,
410
                                     long port, uint16_t val);
411
static __inline void ahd_outsb(struct ahd_softc * ahd, long port,
412
                               uint8_t *, int count);
413
static __inline void ahd_insb(struct ahd_softc * ahd, long port,
414
                               uint8_t *, int count);
415
 
416
static __inline uint8_t
417
ahd_inb(struct ahd_softc * ahd, long port)
418
{
419
        uint8_t x;
420
 
421
        if (ahd->tags[0] == BUS_SPACE_MEMIO) {
422
                x = readb(ahd->bshs[0].maddr + port);
423
        } else {
424
                x = inb(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
425
        }
426
        mb();
427
        return (x);
428
}
429
 
430
static __inline uint16_t
431
ahd_inw_atomic(struct ahd_softc * ahd, long port)
432
{
433
        uint8_t x;
434
 
435
        if (ahd->tags[0] == BUS_SPACE_MEMIO) {
436
                x = readw(ahd->bshs[0].maddr + port);
437
        } else {
438
                x = inw(ahd->bshs[(port) >> 8].ioport + ((port) & 0xFF));
439
        }
440
        mb();
441
        return (x);
442
}
443
 
444
static __inline void
445
ahd_outb(struct ahd_softc * ahd, long port, uint8_t val)
446
{
447
        if (ahd->tags[0] == BUS_SPACE_MEMIO) {
448
                writeb(val, ahd->bshs[0].maddr + port);
449
        } else {
450
                outb(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
451
        }
452
        mb();
453
}
454
 
455
static __inline void
456
ahd_outw_atomic(struct ahd_softc * ahd, long port, uint16_t val)
457
{
458
        if (ahd->tags[0] == BUS_SPACE_MEMIO) {
459
                writew(val, ahd->bshs[0].maddr + port);
460
        } else {
461
                outw(val, ahd->bshs[(port) >> 8].ioport + (port & 0xFF));
462
        }
463
        mb();
464
}
465
 
466
static __inline void
467
ahd_outsb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
468
{
469
        int i;
470
 
471
        /*
472
         * There is probably a more efficient way to do this on Linux
473
         * but we don't use this for anything speed critical and this
474
         * should work.
475
         */
476
        for (i = 0; i < count; i++)
477
                ahd_outb(ahd, port, *array++);
478
}
479
 
480
static __inline void
481
ahd_insb(struct ahd_softc * ahd, long port, uint8_t *array, int count)
482
{
483
        int i;
484
 
485
        /*
486
         * There is probably a more efficient way to do this on Linux
487
         * but we don't use this for anything speed critical and this
488
         * should work.
489
         */
490
        for (i = 0; i < count; i++)
491
                *array++ = ahd_inb(ahd, port);
492
}
493
 
494
/**************************** Initialization **********************************/
495
int             ahd_linux_register_host(struct ahd_softc *,
496
                                        struct scsi_host_template *);
497
 
498
/*************************** Pretty Printing **********************************/
499
struct info_str {
500
        char *buffer;
501
        int length;
502
        off_t offset;
503
        int pos;
504
};
505
 
506
/******************************** Locking *************************************/
507
static __inline void
508
ahd_lockinit(struct ahd_softc *ahd)
509
{
510
        spin_lock_init(&ahd->platform_data->spin_lock);
511
}
512
 
513
static __inline void
514
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
515
{
516
        spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
517
}
518
 
519
static __inline void
520
ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
521
{
522
        spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
523
}
524
 
525
/******************************* PCI Definitions ******************************/
526
/*
527
 * PCIM_xxx: mask to locate subfield in register
528
 * PCIR_xxx: config register offset
529
 * PCIC_xxx: device class
530
 * PCIS_xxx: device subclass
531
 * PCIP_xxx: device programming interface
532
 * PCIV_xxx: PCI vendor ID (only required to fixup ancient devices)
533
 * PCID_xxx: device ID
534
 */
535
#define PCIR_DEVVENDOR          0x00
536
#define PCIR_VENDOR             0x00
537
#define PCIR_DEVICE             0x02
538
#define PCIR_COMMAND            0x04
539
#define PCIM_CMD_PORTEN         0x0001
540
#define PCIM_CMD_MEMEN          0x0002
541
#define PCIM_CMD_BUSMASTEREN    0x0004
542
#define PCIM_CMD_MWRICEN        0x0010
543
#define PCIM_CMD_PERRESPEN      0x0040
544
#define PCIM_CMD_SERRESPEN      0x0100
545
#define PCIR_STATUS             0x06
546
#define PCIR_REVID              0x08
547
#define PCIR_PROGIF             0x09
548
#define PCIR_SUBCLASS           0x0a
549
#define PCIR_CLASS              0x0b
550
#define PCIR_CACHELNSZ          0x0c
551
#define PCIR_LATTIMER           0x0d
552
#define PCIR_HEADERTYPE         0x0e
553
#define PCIM_MFDEV              0x80
554
#define PCIR_BIST               0x0f
555
#define PCIR_CAP_PTR            0x34
556
 
557
/* config registers for header type 0 devices */
558
#define PCIR_MAPS       0x10
559
#define PCIR_SUBVEND_0  0x2c
560
#define PCIR_SUBDEV_0   0x2e
561
 
562
/****************************** PCI-X definitions *****************************/
563
#define PCIXR_COMMAND   0x96
564
#define PCIXR_DEVADDR   0x98
565
#define PCIXM_DEVADDR_FNUM      0x0003  /* Function Number */
566
#define PCIXM_DEVADDR_DNUM      0x00F8  /* Device Number */
567
#define PCIXM_DEVADDR_BNUM      0xFF00  /* Bus Number */
568
#define PCIXR_STATUS    0x9A
569
#define PCIXM_STATUS_64BIT      0x0001  /* Active 64bit connection to device. */
570
#define PCIXM_STATUS_133CAP     0x0002  /* Device is 133MHz capable */
571
#define PCIXM_STATUS_SCDISC     0x0004  /* Split Completion Discarded */
572
#define PCIXM_STATUS_UNEXPSC    0x0008  /* Unexpected Split Completion */
573
#define PCIXM_STATUS_CMPLEXDEV  0x0010  /* Device Complexity (set == bridge) */
574
#define PCIXM_STATUS_MAXMRDBC   0x0060  /* Maximum Burst Read Count */
575
#define PCIXM_STATUS_MAXSPLITS  0x0380  /* Maximum Split Transactions */
576
#define PCIXM_STATUS_MAXCRDS    0x1C00  /* Maximum Cumulative Read Size */
577
#define PCIXM_STATUS_RCVDSCEM   0x2000  /* Received a Split Comp w/Error msg */
578
 
579
typedef enum
580
{
581
        AHD_POWER_STATE_D0,
582
        AHD_POWER_STATE_D1,
583
        AHD_POWER_STATE_D2,
584
        AHD_POWER_STATE_D3
585
} ahd_power_state;
586
 
587
void ahd_power_state_change(struct ahd_softc *ahd,
588
                            ahd_power_state new_state);
589
 
590
/******************************* PCI Routines *********************************/
591
int                      ahd_linux_pci_init(void);
592
void                     ahd_linux_pci_exit(void);
593
int                      ahd_pci_map_registers(struct ahd_softc *ahd);
594
int                      ahd_pci_map_int(struct ahd_softc *ahd);
595
 
596
static __inline uint32_t ahd_pci_read_config(ahd_dev_softc_t pci,
597
                                             int reg, int width);
598
 
599
static __inline uint32_t
600
ahd_pci_read_config(ahd_dev_softc_t pci, int reg, int width)
601
{
602
        switch (width) {
603
        case 1:
604
        {
605
                uint8_t retval;
606
 
607
                pci_read_config_byte(pci, reg, &retval);
608
                return (retval);
609
        }
610
        case 2:
611
        {
612
                uint16_t retval;
613
                pci_read_config_word(pci, reg, &retval);
614
                return (retval);
615
        }
616
        case 4:
617
        {
618
                uint32_t retval;
619
                pci_read_config_dword(pci, reg, &retval);
620
                return (retval);
621
        }
622
        default:
623
                panic("ahd_pci_read_config: Read size too big");
624
                /* NOTREACHED */
625
                return (0);
626
        }
627
}
628
 
629
static __inline void ahd_pci_write_config(ahd_dev_softc_t pci,
630
                                          int reg, uint32_t value,
631
                                          int width);
632
 
633
static __inline void
634
ahd_pci_write_config(ahd_dev_softc_t pci, int reg, uint32_t value, int width)
635
{
636
        switch (width) {
637
        case 1:
638
                pci_write_config_byte(pci, reg, value);
639
                break;
640
        case 2:
641
                pci_write_config_word(pci, reg, value);
642
                break;
643
        case 4:
644
                pci_write_config_dword(pci, reg, value);
645
                break;
646
        default:
647
                panic("ahd_pci_write_config: Write size too big");
648
                /* NOTREACHED */
649
        }
650
}
651
 
652
static __inline int ahd_get_pci_function(ahd_dev_softc_t);
653
static __inline int
654
ahd_get_pci_function(ahd_dev_softc_t pci)
655
{
656
        return (PCI_FUNC(pci->devfn));
657
}
658
 
659
static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
660
static __inline int
661
ahd_get_pci_slot(ahd_dev_softc_t pci)
662
{
663
        return (PCI_SLOT(pci->devfn));
664
}
665
 
666
static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
667
static __inline int
668
ahd_get_pci_bus(ahd_dev_softc_t pci)
669
{
670
        return (pci->bus->number);
671
}
672
 
673
static __inline void ahd_flush_device_writes(struct ahd_softc *);
674
static __inline void
675
ahd_flush_device_writes(struct ahd_softc *ahd)
676
{
677
        /* XXX Is this sufficient for all architectures??? */
678
        ahd_inb(ahd, INTSTAT);
679
}
680
 
681
/**************************** Proc FS Support *********************************/
682
int     ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
683
                            off_t, int, int);
684
 
685
/*********************** Transaction Access Wrappers **************************/
686
static __inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
687
static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
688
static __inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
689
static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
690
static __inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
691
static __inline uint32_t ahd_get_transaction_status(struct scb *);
692
static __inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
693
static __inline uint32_t ahd_get_scsi_status(struct scb *);
694
static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
695
static __inline u_long ahd_get_transfer_length(struct scb *);
696
static __inline int ahd_get_transfer_dir(struct scb *);
697
static __inline void ahd_set_residual(struct scb *, u_long);
698
static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
699
static __inline u_long ahd_get_residual(struct scb *);
700
static __inline u_long ahd_get_sense_residual(struct scb *);
701
static __inline int ahd_perform_autosense(struct scb *);
702
static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
703
                                               struct scb *);
704
static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
705
                                                     struct ahd_devinfo *);
706
static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
707
                                           struct scb *scb);
708
static __inline void ahd_freeze_scb(struct scb *scb);
709
 
710
static __inline
711
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
712
{
713
        cmd->result &= ~(CAM_STATUS_MASK << 16);
714
        cmd->result |= status << 16;
715
}
716
 
717
static __inline
718
void ahd_set_transaction_status(struct scb *scb, uint32_t status)
719
{
720
        ahd_cmd_set_transaction_status(scb->io_ctx,status);
721
}
722
 
723
static __inline
724
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
725
{
726
        cmd->result &= ~0xFFFF;
727
        cmd->result |= status;
728
}
729
 
730
static __inline
731
void ahd_set_scsi_status(struct scb *scb, uint32_t status)
732
{
733
        ahd_cmd_set_scsi_status(scb->io_ctx, status);
734
}
735
 
736
static __inline
737
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
738
{
739
        return ((cmd->result >> 16) & CAM_STATUS_MASK);
740
}
741
 
742
static __inline
743
uint32_t ahd_get_transaction_status(struct scb *scb)
744
{
745
        return (ahd_cmd_get_transaction_status(scb->io_ctx));
746
}
747
 
748
static __inline
749
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
750
{
751
        return (cmd->result & 0xFFFF);
752
}
753
 
754
static __inline
755
uint32_t ahd_get_scsi_status(struct scb *scb)
756
{
757
        return (ahd_cmd_get_scsi_status(scb->io_ctx));
758
}
759
 
760
static __inline
761
void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
762
{
763
        /*
764
         * Nothing to do for linux as the incoming transaction
765
         * has no concept of tag/non tagged, etc.
766
         */
767
}
768
 
769
static __inline
770
u_long ahd_get_transfer_length(struct scb *scb)
771
{
772
        return (scb->platform_data->xfer_len);
773
}
774
 
775
static __inline
776
int ahd_get_transfer_dir(struct scb *scb)
777
{
778
        return (scb->io_ctx->sc_data_direction);
779
}
780
 
781
static __inline
782
void ahd_set_residual(struct scb *scb, u_long resid)
783
{
784
        scsi_set_resid(scb->io_ctx, resid);
785
}
786
 
787
static __inline
788
void ahd_set_sense_residual(struct scb *scb, u_long resid)
789
{
790
        scb->platform_data->sense_resid = resid;
791
}
792
 
793
static __inline
794
u_long ahd_get_residual(struct scb *scb)
795
{
796
        return scsi_get_resid(scb->io_ctx);
797
}
798
 
799
static __inline
800
u_long ahd_get_sense_residual(struct scb *scb)
801
{
802
        return (scb->platform_data->sense_resid);
803
}
804
 
805
static __inline
806
int ahd_perform_autosense(struct scb *scb)
807
{
808
        /*
809
         * We always perform autosense in Linux.
810
         * On other platforms this is set on a
811
         * per-transaction basis.
812
         */
813
        return (1);
814
}
815
 
816
static __inline uint32_t
817
ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
818
{
819
        return (sizeof(struct scsi_sense_data));
820
}
821
 
822
static __inline void
823
ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
824
                                struct ahd_devinfo *devinfo)
825
{
826
        /* Nothing to do here for linux */
827
}
828
 
829
static __inline void
830
ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
831
{
832
        ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
833
}
834
 
835
int     ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg);
836
void    ahd_platform_free(struct ahd_softc *ahd);
837
void    ahd_platform_init(struct ahd_softc *ahd);
838
void    ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
839
 
840
static __inline void
841
ahd_freeze_scb(struct scb *scb)
842
{
843
        if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
844
                scb->io_ctx->result |= CAM_DEV_QFRZN << 16;
845
                scb->platform_data->dev->qfrozen++;
846
        }
847
}
848
 
849
void    ahd_platform_set_tags(struct ahd_softc *ahd, struct scsi_device *sdev,
850
                              struct ahd_devinfo *devinfo, ahd_queue_alg);
851
int     ahd_platform_abort_scbs(struct ahd_softc *ahd, int target,
852
                                char channel, int lun, u_int tag,
853
                                role_t role, uint32_t status);
854
irqreturn_t
855
        ahd_linux_isr(int irq, void *dev_id);
856
void    ahd_done(struct ahd_softc*, struct scb*);
857
void    ahd_send_async(struct ahd_softc *, char channel,
858
                       u_int target, u_int lun, ac_code);
859
void    ahd_print_path(struct ahd_softc *, struct scb *);
860
 
861
#ifdef CONFIG_PCI
862
#define AHD_PCI_CONFIG 1
863
#else
864
#define AHD_PCI_CONFIG 0
865
#endif
866
#define bootverbose aic79xx_verbose
867
extern uint32_t aic79xx_verbose;
868
 
869
#endif /* _AIC79XX_LINUX_H_ */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.