d77ace0cfd3c86440058821c7005507ea4aa3c79
[mirror/scst/.git] / qla_isp / linux / isp_linux.h
1 /* $Id: isp_linux.h,v 1.176 2009/09/06 00:37:07 mjacob Exp $ */
2 /*
3  *  Copyright (c) 1997-2009 by Matthew Jacob
4  *  All rights reserved.
5  *
6  *  Redistribution and use in source and binary forms, with or without
7  *  modification, are permitted provided that the following conditions
8  *  are met:
9  *
10  *  1. Redistributions of source code must retain the above copyright
11  *     notice, this list of conditions and the following disclaimer.
12  *  2. Redistributions in binary form must reproduce the above copyright
13  *     notice, this list of conditions and the following disclaimer in the
14  *     documentation and/or other materials provided with the distribution.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  *  SUCH DAMAGE.
27  *
28  *
29  *  Alternatively, this software may be distributed under the terms of the
30  *  the GNU Public License ("GPL") with platforms where the prevalant license
31  *  is the GNU Public License:
32  *
33  *   This program is free software; you can redistribute it and/or modify
34  *   it under the terms of The Version 2 GNU General Public License as published
35  *   by the Free Software Foundation.
36  *
37  *   This program is distributed in the hope that it will be useful,
38  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
39  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40  *   GNU General Public License for more details.
41  *
42  *   You should have received a copy of the GNU General Public License
43  *   along with this program; if not, write to the Free Software
44  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
45  *
46  *
47  *  Matthew Jacob
48  *  Feral Software
49  *  421 Laurel Avenue
50  *  Menlo Park, CA 94025
51  *  USA
52  *
53  *  gplbsd at feral com
54  */
55 /*
56  * Qlogic ISP SCSI Host Adapter Linux Wrapper Definitions
57  */
58
59 #ifndef _ISP_LINUX_H
60 #define _ISP_LINUX_H
61
62 #ifndef ISP_MODULE
63 #define __NO_VERSION__
64 #endif
65 #ifdef  MODULE
66 #define EXPORT_SYMTAB   1
67 #endif
68
69 #include <linux/version.h>
70 #ifndef KERNEL_VERSION
71 #define KERNEL_VERSION(v,p,s)   (((v)<<16)+(p<<8)+s)
72 #endif
73
74 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) || LINUX_VERSION_CODE >=  KERNEL_VERSION(2,7,0)
75 #error  "Only Linux 2.5/2.6 kernels are supported with this driver"
76 #endif
77
78 #ifndef UNUSED_PARAMETER
79 #define UNUSED_PARAMETER(x) (void) x
80 #endif
81
82 #include <linux/autoconf.h>
83 #ifdef  CONFIG_SMP
84 #define __SMP__ 1
85 #endif
86
87 #include <linux/module.h>
88 #include <linux/autoconf.h>
89 #include <linux/init.h>
90 #include <linux/types.h>
91 #include <linux/blkdev.h>
92 #include <linux/delay.h>
93 #include <linux/ioport.h>
94 #include <linux/mm.h>
95 #include <linux/vmalloc.h>
96 #include <linux/sched.h>
97 #include <linux/kthread.h>
98 #include <linux/stat.h>
99 #include <linux/pci.h>
100 #include <asm/dma.h>
101 #include <asm/io.h>
102 #include <asm/irq.h>
103 #include <linux/smp.h>
104 #include <linux/spinlock.h>
105 #include <asm/system.h>
106 #include <asm/uaccess.h>
107 #include <asm/byteorder.h>
108 #include <linux/interrupt.h>
109 #include <scsi/scsi.h>
110 #include <scsi/scsi_cmnd.h>
111 #include <scsi/scsi_host.h>
112 #include <scsi/scsi_tcq.h>
113 #include <scsi/scsi_device.h>
114
115 #include <linux/cdev.h>
116 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
117 #include <linux/devfs_fs_kernel.h>
118 #define ISP_CLASS           struct class_simple
119 #define CREATE_ISP_CLASS    class_simple_create
120 #define DESTROY_ISP_CLASS   class_simple_destroy
121
122 #define CREATE_ISP_DEV(isp, class)     \
123     class_simple_device_add(class, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit),     \
124     devfs_mk_cdev(MKDEV(MAJOR(isp_dev), isp->isp_unit), S_IFCHR | S_IRUGO | S_IWUGO, "%s%d", ISP_NAME, isp->isp_unit)
125 #define DESTROY_ISP_DEV(isp)    \
126     devfs_remove("%s%d", ISP_NAME, isp->isp_unit), class_simple_device_remove(MKDEV(MAJOR(isp_dev), isp->isp_unit))
127
128 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
129 #define ISP_CLASS               struct class
130 #define CREATE_ISP_CLASS        class_create
131 #define DESTROY_ISP_CLASS       class_destroy
132
133 #define CREATE_ISP_DEV(isp, class)     \
134     class_device_create(class, NULL, MKDEV(MAJOR(isp_dev), isp->isp_unit), NULL, "%s%d", ISP_NAME, isp->isp_unit)
135 #define DESTROY_ISP_DEV(isp)    \
136     class_device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (isp)->isp_unit));
137
138 #elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
139 #define ISP_CLASS               struct class
140 #define CREATE_ISP_CLASS        class_create
141 #define DESTROY_ISP_CLASS       class_destroy
142 #define CREATE_ISP_DEV(i, c)    (void) device_create(c, NULL, MKDEV(MAJOR(isp_dev), (i)->isp_unit), "%s%d", ISP_NAME, (i)->isp_unit);
143 #define DESTROY_ISP_DEV(i)      device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (i)->isp_unit));
144 #else
145 #define ISP_CLASS               struct class
146 #define CREATE_ISP_CLASS        class_create
147 #define DESTROY_ISP_CLASS       class_destroy
148 #define CREATE_ISP_DEV(i, c)    (void) device_create(c, NULL, MKDEV(MAJOR(isp_dev), (i)->isp_unit), NULL, "%s%d", ISP_NAME, (i)->isp_unit);
149 #define DESTROY_ISP_DEV(i)      device_destroy(isp_class, MKDEV(MAJOR(isp_dev), (i)->isp_unit));
150 #endif
151
152 typedef struct scsi_cmnd Scsi_Cmnd;
153 typedef struct scsi_request Scsi_Request;
154 typedef struct scsi_host_template Scsi_Host_Template;
155 #ifdef  CONFIG_PROC_FS
156 #include <linux/proc_fs.h>
157 #endif
158
159 /*
160  * Efficiency- get rid of SBus code && tests unless we need them.
161  */
162 #if defined(__sparcv9__ ) || defined(__sparc__)
163 #define ISP_SBUS_SUPPORTED  1
164 #else
165 #define ISP_SBUS_SUPPORTED  0
166 #endif
167
168 #define ISP_PLATFORM_VERSION_MAJOR  6
169 #define ISP_PLATFORM_VERSION_MINOR  1
170
171 #ifndef ISP_NAME
172 #define ISP_NAME    "isp"
173 #endif
174
175 #ifndef BIG_ENDIAN
176 #define BIG_ENDIAN  4321
177 #endif
178 #ifndef LITTLE_ENDIAN
179 #define LITTLE_ENDIAN   1234
180 #endif
181
182 #ifdef  __BIG_ENDIAN
183 #define BYTE_ORDER  BIG_ENDIAN
184 #endif
185 #ifdef  __LITTLE_ENDIAN
186 #define BYTE_ORDER  LITTLE_ENDIAN
187 #endif
188
189 #ifndef __WORDSIZE
190 #define __WORDSIZE  BITS_PER_LONG
191 #endif
192
193 #define DMA_HTYPE_T     dma_addr_t
194 #define QLA_HANDLE(cmd) (cmd)->SCp.dma_handle
195
196 #ifdef  min
197 #undef  min
198 #endif
199 #ifdef  max
200 #undef  max
201 #endif
202
203 #define ull     unsigned long long
204
205 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
206 #define sg_page(_sg)                ((_sg)->page)
207 #define sg_assign_page(_sg, _pg)    ((_sg)->page = (_pg))
208 #endif
209
210 /*
211  * Normally this should be taken care of by typedefs,
212  * but linux includes are a complete dog's breakfast.
213  */
214
215 #define uint8_t    u8
216 #define uint16_t   u16
217 #define uint32_t   u32
218 #define uint64_t   u64
219 #define int8_t      char
220 #define int16_t     short
221 #define int32_t     int
222
223 #define u_long      unsigned long
224 #define uint       unsigned int
225 #define u_char      unsigned char
226 typedef u_long  vm_offset_t;
227
228 /* bit map using 8 bit arrays */
229 typedef uint8_t isp_bmap_t;
230 #define _ISP_WIX(isp, ix)   (ix >> 3)
231 #define _ISP_BIX(isp, ix)   (1 << (ix & 0x7))
232 #define ISP_NBPIDX(x)       ((x + 7) / 8)  /* index width from bits */
233 #define ISP_BTST(map, ix)   (((map)[_ISP_WIX(isp, ix)] & _ISP_BIX(isp, ix)) != 0)
234 #define ISP_BSET(map, ix)   (map)[_ISP_WIX(isp, ix)] |= _ISP_BIX(isp, ix)
235 #define ISP_BCLR(map, ix)   (map)[_ISP_WIX(isp, ix)] &= ~_ISP_BIX(isp, ix)
236
237 #ifdef  ISP_TARGET_MODE
238
239 #include "isp_tpublic.h"
240
241 #ifndef DEFAULT_DEVICE_TYPE
242 #define DEFAULT_DEVICE_TYPE 0
243 #endif
244 #define NTGT_CMDS           1024
245 #define N_NOTIFIES          256
246 #define DEFAULT_INQSIZE     32
247
248 typedef struct notify notify_t;
249
250 #define cd_action   cd_lreserved[0].shorts[0]
251 #define cd_oxid     cd_lreserved[0].shorts[1]
252 #define cd_lflags   cd_lreserved[0].shorts[2]
253 #define cd_nphdl    cd_lreserved[0].shorts[3]
254 #define cd_nseg     cd_lreserved[1].longs[0]
255 #define cd_portid   cd_lreserved[1].longs[1]
256 #define cd_next     cd_lreserved[2].ptrs[0]
257 #define cd_lastoff  cd_lreserved[3].longs[0]
258 #define cd_lastsize cd_lreserved[3].longs[1]
259
260 #define CDFL_LCL        0x8000
261 #define CDFL_RESRC_FILL 0x4000
262 #define CDFL_ABORTED    0x2000
263 #define CDFL_NEED_CLNUP 0x1000
264 #define CDFL_BUSY       0x0800
265
266 typedef struct enalun tgt_enalun_t;
267 struct enalun {
268     tgt_enalun_t *  next;
269     uint16_t        lun;
270     uint16_t        bus;
271 };
272
273 typedef struct {
274     struct scatterlist sg;
275     tmd_xact_t         xact;
276 } tgt_auxcmd_t;
277 #define N_TGT_AUX       32
278
279 #define ISP_CT_TIMEOUT  120
280 #endif  /* ISP_TARGET_MODE */
281
282 typedef struct isp_thread_action isp_thread_action_t;
283 struct isp_thread_action {
284     isp_thread_action_t *next;
285     enum {
286         ISP_THREAD_NIL=1,
287         ISP_THREAD_FC_RESCAN,
288         ISP_THREAD_REINIT,
289         ISP_THREAD_FW_CRASH_DUMP,
290         ISP_THREAD_LOGOUT,
291         ISP_THREAD_FINDIID,
292         ISP_THREAD_FINDPORTID,
293         ISP_THREAD_TERMINATE,
294         ISP_THREAD_RESTART_AT7,
295         ISP_THREAD_FC_PUTBACK,
296         ISP_THREAD_SCSI_SCAN,
297     }   thread_action;
298     void * arg;
299     wait_queue_head_t thread_waiter;
300     uint32_t
301         waiting :   1,
302         done    :   1,
303         count   :   30;
304 };
305 #define MAX_THREAD_ACTION   128
306 #define MAX_FC_CHAN         128
307
308 #define ISP_HOST2ISP(host)  (ispsoftc_t *) host->hostdata
309
310 struct isposinfo {
311     struct Scsi_Host *  host;
312     unsigned int        device_id;
313     u32                 mcorig;     /* original maxcmds */
314     void                *device;    /* hardware device structure */
315     Scsi_Cmnd           *wqnext, *wqtail;
316     Scsi_Cmnd           *dqnext, *dqtail;
317     void *              storep;
318     size_t              storep_amt;
319     size_t              param_amt;
320     const struct firmware *fwp;
321 #ifdef  CONFIG_PROC_FS
322     struct proc_dir_entry *pdp;
323 #endif
324     char                hbaname[16];
325     long                bins[8];
326     u16                 wqcnt;
327     u16                 wqhiwater;
328     u16                 hiwater;
329     struct timer_list   timer;
330     struct semaphore    mbox_sem;
331     wait_queue_head_t   mboxwq;
332     struct semaphore    mbox_c_sem;
333     spinlock_t          slock;
334     uint32_t
335         dogcnt          : 5,
336         isopen          : 1,
337         is_64bit_dma    : 1,
338         dogactive       : 1,
339         mboxcmd_done    : 1,
340         mbintsok        : 1,
341         intsok          : 1;
342     u16                 scan_timeout;
343     u16                 rescan_timeout;
344     u16                 frame_size;
345     u16                 exec_throttle;
346     struct task_struct *thread_task;
347     wait_queue_head_t   trq;
348     spinlock_t          tlock;
349     isp_thread_action_t t_actions[MAX_THREAD_ACTION];
350     isp_thread_action_t *t_free;
351     isp_thread_action_t *t_busy, *t_busy_t;
352 #ifdef  ISP_TARGET_MODE
353     u32         isget       : 16,
354                 rstatus     : 8,
355                             : 7,
356                 hcb         : 1;
357     struct semaphore    tgt_inisem;
358     struct semaphore *  rsemap;
359     tgt_enalun_t *          luns;       /* enabled { lun, port } tuples */
360     struct tmd_cmd *        pending_t;  /* pending list of commands going upstream */
361     struct tmd_cmd *        waiting_t;  /* pending list of commands waiting to be fleshed out */
362     struct tmd_cmd *        tfreelist;  /* freelist head */
363     struct tmd_cmd *        bfreelist;  /* freelist tail */
364     struct tmd_cmd *        pool;       /* pool itself */
365     notify_t *              pending_n;  /* pending list of notifies going upstream */
366     notify_t *              nfreelist;  /* freelist */
367     notify_t *              npool;      /* pool itself */
368     struct tmd_xact *       pending_x;  /* pending list of xacts going upstream */
369     /*
370      * When we have inquiry commands that we have to xfer data with
371      * locally we have to have some aux info (scatterlist, tmd_xact_t)
372      * to manage those commands.
373      */
374     tgt_auxcmd_t            auxinfo[N_TGT_AUX];
375     isp_bmap_t              auxbmap[ISP_NBPIDX(N_TGT_AUX)];
376     u8                      inqdata[DEFAULT_INQSIZE];
377
378     u64                     cmds_started;
379     u64                     cmds_completed;
380     unsigned long           out_of_tmds;
381 #endif
382 };
383 #define mbtimer         isp_osinfo.mbtimer
384 #define dogactive       isp_osinfo.dogactive
385 #define mbintsok        isp_osinfo.mbintsok
386 #define intsok          isp_osinfo.intsok
387 #define mbox_waiting    isp_osinfo.mbox_waiting
388 #define mboxcmd_done    isp_osinfo.mboxcmd_done
389 #define isp_isopen      isp_osinfo.isopen
390
391 /*
392  * Locking macros...
393  */
394 #define ISP_LOCK_INIT(isp)          spin_lock_init(&isp->isp_osinfo.slock)
395 #define ISP_LOCK_SOFTC(isp)         spin_lock_irqsave(&isp->isp_osinfo.slock, flags)
396 #define ISP_UNLK_SOFTC(isp)         spin_unlock_irqrestore(&isp->isp_osinfo.slock, flags)
397 #define ISP_ILOCK_SOFTC             ISP_LOCK_SOFTC
398 #define ISP_IUNLK_SOFTC             ISP_UNLK_SOFTC
399 #define ISP_IGET_LK_SOFTC(isp)      spin_lock_irq(&isp->isp_osinfo.slock)
400 #define ISP_DROP_LK_SOFTC(isp)      spin_unlock_irq(&isp->isp_osinfo.slock)
401 #define ISP_LOCK_SCSI_DONE(isp)     do { } while(0)
402 #define ISP_UNLK_SCSI_DONE(isp)     do { } while(0)
403 #define ISP_LOCKU_SOFTC             ISP_ILOCK_SOFTC
404 #define ISP_UNLKU_SOFTC             ISP_IUNLK_SOFTC
405 #define ISP_TLOCK_INIT(isp)         spin_lock_init(&isp->isp_osinfo.tlock)
406 #define ISP_DRIVER_ENTRY_LOCK(isp)  spin_unlock_irq(isp->isp_osinfo.host->host_lock)
407 #define ISP_DRIVER_EXIT_LOCK(isp)   spin_lock_irq(isp->isp_osinfo.host->host_lock)
408 #define ISP_DRIVER_CTL_ENTRY_LOCK(isp)  do { } while (0)
409 #define ISP_DRIVER_CTL_EXIT_LOCK(isp)   do { } while (0)
410
411 #define ISP_MUST_POLL(isp)          (in_interrupt() || isp->mbintsok == 0)
412
413 /*
414  * Required Macros/Defines
415  */
416
417 #define ISP_FC_SCRLEN   0x1000
418
419 #define ISP_MEMZERO(b, a)   memset(b, 0, a)
420 #define ISP_MEMCPY          memcpy
421 #define ISP_SNPRINTF        snprintf
422 #define ISP_DELAY           _isp_usec_delay
423 #define ISP_SLEEP(isp, x)                               \
424         ISP_DROP_LK_SOFTC(isp);                         \
425         __set_current_state(TASK_UNINTERRUPTIBLE);      \
426         (void) schedule_timeout(_usec_to_jiffies(x));   \
427         ISP_IGET_LK_SOFTC(isp)
428
429 #define ISP_INLINE          inline
430
431 #define NANOTIME_T      struct timeval
432 /* for prior to 2.2.19, use do_gettimeofday, and, well, it'll be inaccurate */
433 #define GET_NANOTIME(ptr)   (ptr)->tv_sec = 0, (ptr)->tv_usec = 0, do_gettimeofday(ptr)
434 #define GET_NANOSEC(x)      ((uint64_t) ((((uint64_t)(x)->tv_sec) * 1000000 + (x)->tv_usec)))
435 #define NANOTIME_SUB        _isp_microtime_sub
436
437 #define MAXISPREQUEST(isp)  (IS_24XX(isp)? 2048 : ((IS_FC(isp) || IS_ULTRA2(isp))? 1024 : 256))
438
439 #if   defined(__powerpc__)
440 #define MEMORYBARRIER(isp, type, offset, size)  __asm__ __volatile__("eieio" ::: "memory")
441 #else
442 #  ifdef mb
443 #    define MEMORYBARRIER(isp, type, offset, size)  mb()
444 #  else
445 #    define MEMORYBARRIER(isp, type, offset, size)  barrier()
446 #  endif
447 #endif
448
449 #define MBOX_ACQUIRE(isp)   down_trylock(&isp->isp_osinfo.mbox_sem)
450 #define MBOX_WAIT_COMPLETE  mbox_wait_complete
451 #define MBOX_NOTIFY_COMPLETE(isp)       \
452     wake_up(&isp->isp_osinfo.mboxwq);   \
453     isp->mboxcmd_done = 1
454 #define MBOX_RELEASE(isp)   up(&isp->isp_osinfo.mbox_sem)
455
456 #define FC_SCRATCH_ACQUIRE              fc_scratch_acquire
457 #define FC_SCRATCH_RELEASE(isp, chan)   ISP_DATA(isp, chan)->scratch_busy = 0
458
459
460 #ifndef SCSI_GOOD
461 #define SCSI_GOOD   0x0
462 #endif
463 #ifndef SCSI_CHECK
464 #define SCSI_CHECK  0x2
465 #endif
466 #ifndef SCSI_BUSY
467 #define SCSI_BUSY   0x8
468 #endif
469 #ifndef SCSI_QFULL
470 #define SCSI_QFULL  0x28
471 #endif
472
473 #ifndef REPORT_LUNS
474 #define REPORT_LUNS 0xa0
475 #endif
476
477 #define XS_T                Scsi_Cmnd
478 #define XS_DMA_ADDR_T       dma_addr_t
479 #define XS_GET_DMA64_SEG    isp_get_dma64_seg
480 #define XS_GET_DMA_SEG      isp_get_dma_seg
481 #define XS_HOST(Cmnd)       Cmnd->device->host
482 #define XS_CHANNEL(Cmnd)    (Cmnd)->device->channel
483 #define XS_TGT(Cmnd)        (Cmnd)->device->id
484 #define XS_LUN(Cmnd)        (Cmnd)->device->lun
485
486 #define SCSI_DATA_NONE      DMA_NONE
487 #define SCSI_DATA_READ      DMA_FROM_DEVICE
488 #define SCSI_DATA_WRITE     DMA_TO_DEVICE
489 #define scsi_to_pci_dma_dir(x)  x
490
491 #define XS_ISP(Cmnd)        ((ispsoftc_t *)XS_HOST(Cmnd)->hostdata)
492 #define XS_CDBP(Cmnd)       (Cmnd)->cmnd
493 #define XS_CDBLEN(Cmnd)     (Cmnd)->cmd_len
494 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
495 #define XS_GET_RESID(Cmnd)          (Cmnd)->SCp.this_residual
496 #define XS_SET_RESID(Cmnd, resid)   (Cmnd)->SCp.this_residual = resid
497 #define XS_XFRLEN(Cmnd)             (Cmnd)->request_bufflen
498 #else
499 #define XS_GET_RESID        scsi_get_resid
500 #define XS_SET_RESID        scsi_set_resid
501 #define XS_XFRLEN           scsi_bufflen
502 #endif
503 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)
504 #define XS_TIME(Cmnd)       ((((Cmnd)->timeout_per_command) * HZ)*1000)
505 #else
506 #define XS_TIME(Cmnd)       ((((Cmnd)->request->timeout) * HZ)*1000)
507 #endif
508 #define XS_STSP(Cmnd)       (&(Cmnd)->SCp.Status)
509 #define XS_SNSP(Cmnd)       (Cmnd)->sense_buffer
510 #define XS_SNSLEN(Cmnd)     SCSI_SENSE_BUFFERSIZE
511 #define XS_SNSKEY(Cmnd)     (XS_SNSP(Cmnd)[2] & 0xf)
512 #define XS_TAG_P(Cmnd)      (Cmnd->device->tagged_supported != 0)
513 #define XS_TAG_TYPE         isplinux_tagtype
514
515 #define XS_SETERR(xs, v)                \
516     if ((v) == HBA_TGTBSY) {            \
517         (xs)->SCp.Status = SCSI_BUSY;   \
518     } else {                            \
519         (xs)->result &= ~0xff0000;      \
520         (xs)->result |= ((v) << 16);    \
521     }
522
523 #define HBA_NOERROR     DID_OK
524 #define HBA_BOTCH       DID_ERROR
525 #define HBA_CMDTIMEOUT  DID_TIME_OUT
526 #define HBA_SELTIMEOUT  DID_NO_CONNECT
527 #define HBA_TGTBSY      123456 /* special handling */
528 #define HBA_BUSRESET    DID_RESET
529 #define HBA_ABORTED     DID_ABORT
530 #define HBA_DATAOVR     DID_ERROR
531 #define HBA_ARQFAIL     DID_ERROR
532
533 #define XS_ERR(xs)      host_byte((xs)->result)
534
535 #define XS_NOERR(xs)    host_byte((xs)->result) == DID_OK
536
537 #define XS_INITERR(xs)  (xs)->result = 0, (xs)->SCp.Status = 0
538
539 #define XS_SAVE_SENSE(Cmnd, s, l)   memcpy(XS_SNSP(Cmnd), s, min(XS_SNSLEN(Cmnd), l))
540
541 #define XS_SET_STATE_STAT(a, b, c)
542
543 #define GET_DEFAULT_ROLE            isplinux_get_default_role
544 #define SET_DEFAULT_ROLE            isplinux_set_default_role
545 #define DEFAULT_IID                 isplinux_get_default_id
546 #define DEFAULT_LOOPID              isplinux_get_default_id
547 #define DEFAULT_FRAMESIZE(isp)      isp->isp_osinfo.frame_size
548 #define DEFAULT_EXEC_THROTTLE(isp)  isp->isp_osinfo.exec_throttle
549 #define DEFAULT_NODEWWN(isp, chan)  isplinux_default_wwn(isp, chan, 0, 1)
550 #define DEFAULT_PORTWWN(isp, chan)  isplinux_default_wwn(isp, chan, 0, 0)
551 #define ACTIVE_NODEWWN(isp, chan)   isplinux_default_wwn(isp, chan, 1, 1)
552 #define ACTIVE_PORTWWN(isp, chan)   isplinux_default_wwn(isp, chan, 1, 0)
553
554 #define ISP_IOXPUT_8(isp, s, d)     *(d) = s
555 #define ISP_IOXPUT_16(isp, s, d)    *(d) = cpu_to_le16(s)
556 #define ISP_IOXPUT_32(isp, s, d)    *(d) = cpu_to_le32(s)
557 #define ISP_IOXGET_8(isp, s, d)     d = *(s)
558 #define ISP_IOXGET_16(isp, s, d)    d = le16_to_cpu(*((uint16_t *)s))
559 #define ISP_IOXGET_32(isp, s, d)    d = le32_to_cpu(*((uint32_t *)s))
560
561 #if BYTE_ORDER == BIG_ENDIAN
562 #define ISP_IOX_8X2(isp, sptr, dptr, tag1, tag2)    \
563     dptr ## -> ## tag1 = sptr ## -> ## tag2;        \
564     dptr ## -> ## tag2 = sptr ## -> ## tag1
565 #define ISP_IOZ_8X2(isp, sptr, dptr, tag1, tag2)    \
566     dptr ## -> ## tag1 = sptr ## -> ## tag1;        \
567     dptr ## -> ## tag2 = sptr ## -> ## tag2
568 #else
569 #define ISP_IOX_8X2(isp, sptr, dptr, tag1, tag2)    \
570     dptr ## -> ## tag1 = sptr ## -> ## tag1;        \
571     dptr ## -> ## tag2 = sptr ## -> ## tag2
572 #define ISP_IOZ_8X2(isp, sptr, dptr, tag1, tag2)    \
573     dptr ## -> ## tag1 = sptr ## -> ## tag2;        \
574     dptr ## -> ## tag2 = sptr ## -> ## tag1
575 #endif
576
577 #define ISP_IOZPUT_8                ISP_IOXPUT_8
578 #define ISP_IOZPUT_16(isp, s, d)    *(d) = cpu_to_be16(s)
579 #define ISP_IOZPUT_32(isp, s, d)    *(d) = cpu_to_be32(s)
580 #define ISP_IOZGET_8                ISP_IOXGET_8
581 #define ISP_IOZGET_16(isp, s, d)    d = be16_to_cpu(*((uint16_t *)s))
582 #define ISP_IOZGET_32(isp, s, d)    d = be32_to_cpu(*((uint32_t *)s))
583
584 #define ISP_SWIZZLE_NVRAM_WORD(isp, rp) *rp = le16_to_cpu(*rp)
585 #define ISP_SWIZZLE_NVRAM_LONG(isp, rp) *rp = le32_to_cpu(*rp)
586
587 #define ISP_SWAP16(isp, x)  swab16(x)
588 #define ISP_SWAP32(isp, x)  swab32(x)
589
590
591 /*
592  * Includes of common header files
593  */
594 #include "ispreg.h"
595 #include "ispvar.h"
596
597 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
598 void isp_prt(ispsoftc_t *, int level, const char *, ...) __attribute__((__format__(__printf__, 3, 4)));
599 #else
600 void isp_prt(ispsoftc_t *, int level, const char *, ...);
601 #endif
602
603
604 /*
605  * isp_osinfo definitions, extensions and shorthand.
606  */
607
608 /*
609  * Parameter and platform per-channel storage.
610  */
611 typedef struct {
612     uint64_t def_wwnn;
613     uint64_t def_wwpn;
614     uint32_t
615         tgts_tested             :   16,
616                                 :   11,
617         scratch_busy            :   1,
618         blocked                 :   1,
619         deadloop                :   1,
620         role                    :   2;
621     unsigned long downcount, nextscan;
622     unsigned int qfdelay;
623 } isp_data;
624
625 #define ISP_DATA(isp, chan)     (&((isp_data *)((isp)->isp_osinfo.storep))[chan])
626
627 #define isp_name        isp_osinfo.hbaname
628 #define isp_host        isp_osinfo.host
629 #define isp_unit        isp_osinfo.host->unique_id
630
631 /*
632  * Driver prototypes..
633  */
634 void isplinux_timer(unsigned long);
635 void isplinux_mbtimer(unsigned long);
636 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
637 irqreturn_t isplinux_intr(int, void *, struct pt_regs *);
638 #else
639 irqreturn_t isplinux_intr(int, void *);
640 #endif
641 int isplinux_common_init(ispsoftc_t *);
642 #ifdef  CONFIG_PROC_FS
643 void isplinux_init_proc(ispsoftc_t *);
644 void isplinux_undo_proc(ispsoftc_t *);
645 #endif
646 int isplinux_reinit(ispsoftc_t *, int);
647 void isplinux_sqd(struct Scsi_Host *, struct scsi_device *);
648
649 int isp_thread_event(ispsoftc_t *, int, void *, int, const char *, const int line);
650
651 static ISP_INLINE uint64_t _isp_microtime_sub(struct timeval *, struct timeval *);
652 static ISP_INLINE void _isp_usec_delay(unsigned int);
653 static ISP_INLINE unsigned long _usec_to_jiffies(unsigned int);
654 static ISP_INLINE unsigned long _jiffies_to_usec(unsigned long);
655 static ISP_INLINE int isplinux_tagtype(Scsi_Cmnd *);
656 static ISP_INLINE void mbox_wait_complete(ispsoftc_t *, mbreg_t *);
657
658 int isplinux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
659 const char *isplinux_info(struct Scsi_Host *);
660 int isplinux_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
661 int isplinux_biosparam(struct scsi_device *, struct block_device *, sector_t, int[]);
662 int isplinux_get_default_id(ispsoftc_t *, int);
663 int isplinux_get_default_role(ispsoftc_t *, int);
664 void isplinux_set_default_role(ispsoftc_t *, int, int);
665 uint64_t isplinux_default_wwn(ispsoftc_t *, int, int, int);
666
667
668 /*
669  * Driver wide data...
670  */
671 extern int isp_debug;
672 extern int isp_unit_seed;
673 extern int isp_disable;
674 extern int isp_nofwreload;
675 extern int isp_nonvram;
676 extern int isp_fcduplex;
677 extern int isp_maxsectors;
678 extern struct scsi_host_template *isp_template;
679 extern const char *class3_roles[4];
680 extern int isp_vports;
681 extern dev_t isp_dev;
682 extern struct cdev isp_cdev;
683 extern struct file_operations isp_ioctl_operations;
684 extern ISP_CLASS *isp_class;
685
686 /*
687  * This used to be considered bad form, but locking crap made it more attractive.
688  */
689 #define MAX_ISP     32
690 extern ispsoftc_t *isplist[MAX_ISP];
691 extern ispsoftc_t *api_isp;
692 extern int api_channel;
693
694 /*
695  * Platform private flags
696  */
697 #ifndef NULL
698 #define NULL ((void *) 0)
699 #endif
700
701 #define ISP_WATCH_TPS   10
702 #define ISP_WATCH_TIME  (HZ / ISP_WATCH_TPS)
703 #define ISP_SCAN_TIMEOUT    (2 * ISP_WATCH_TPS)
704 #define ISP_RESCAN_TIMEOUT  ISP_WATCH_TPS
705
706 #ifndef min
707 #define min(a,b) (((a)<(b))?(a):(b))
708 #endif
709 #ifndef max
710 #define max(a, b)   (((a) > (b)) ? (a) : (b))
711 #endif
712 #ifndef roundup
713 #define roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
714 #endif
715
716 /*
717  * Platform specific 'inline' or support functions
718  */
719
720 #ifdef  __sparc__
721 #define _SBSWAP(isp, b, c)                      \
722     if (isp->isp_bustype == ISP_BT_SBUS) {      \
723         uint8_t tmp = b;                       \
724         b = c;                                  \
725         c = tmp;                                \
726     }
727 #else
728 #define _SBSWAP(a, b, c)
729 #endif
730
731 static ISP_INLINE uint64_t
732 _isp_microtime_sub(struct timeval *b, struct timeval *a)
733 {
734     uint64_t elapsed;
735     struct timeval x = *b;
736     x.tv_sec -= a->tv_sec;
737     x.tv_usec -= a->tv_usec;
738     if (x.tv_usec < 0) {
739         x.tv_sec--;
740         x.tv_usec += 1000000;
741     }
742     if (x.tv_usec >= 1000000) {
743         x.tv_sec++;
744         x.tv_usec -= 1000000;
745     }
746     elapsed = GET_NANOSEC(&x);
747     if (elapsed == 0)
748         elapsed++;
749     if ((int64_t) elapsed < 0)  /* !!!! */
750         return (1000);
751     return (elapsed * 1000);
752 }
753
754 static ISP_INLINE void
755 _isp_usec_delay(unsigned int usecs)
756 {
757     while (usecs > 1000) {
758         mdelay(1);
759         usecs -= 1000;
760     }
761     if (usecs)
762         udelay(usecs);
763 }
764
765 static ISP_INLINE unsigned long
766 _usec_to_jiffies(unsigned int usecs)
767 {
768     struct timespec lt;
769     if (usecs == 0)
770         usecs++;
771     lt.tv_sec = 0;
772     lt.tv_nsec = usecs * 1000;
773     return (timespec_to_jiffies(&lt));
774 }
775
776 static ISP_INLINE unsigned long
777 _jiffies_to_usec(unsigned long jiffies)
778 {
779     unsigned long usecs;
780     struct timespec lt;
781     jiffies++;
782     jiffies_to_timespec((unsigned long) jiffies, &lt);
783     usecs = (lt.tv_sec * 1000000L);
784     usecs += (lt.tv_nsec * 1000);
785     return (usecs);
786 }
787
788 #ifndef MSG_SIMPLE_TAG
789 #define MSG_SIMPLE_TAG  0x20
790 #endif
791 #ifndef MSG_HEAD_TAG
792 #define MSG_HEAD_TAG    0x21
793 #endif
794 #ifndef MSG_ORDERED_TAG
795 #define MSG_ORDERED_TAG 0x22
796 #endif
797
798 static ISP_INLINE int
799 isplinux_tagtype(Scsi_Cmnd *Cmnd)
800 {
801     switch (Cmnd->tag) {
802     case MSG_ORDERED_TAG:
803         return (REQFLAG_OTAG);
804     case MSG_SIMPLE_TAG:
805         return (REQFLAG_STAG);
806     case MSG_HEAD_TAG:
807         return (REQFLAG_HTAG);
808     default:
809         return (REQFLAG_STAG);
810     }
811 }
812
813 static ISP_INLINE void
814 mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp)
815 {
816     uint32_t lim = mbp->timeout;
817     unsigned long et, tt = jiffies;
818
819     if (lim == 0) {
820         lim = MBCMD_DEFAULT_TIMEOUT;
821     }
822     if (isp->isp_mbxwrk0) {
823         lim *= isp->isp_mbxwrk0;
824     }
825
826     isp->mboxcmd_done = 0;
827     if (ISP_MUST_POLL(isp)) {
828         int j;
829
830         for (j = 0; j < lim; j += 100) {
831             uint32_t isr;
832             uint16_t  sema, mbox;
833             if (isp->mboxcmd_done) {
834                 break;
835             }
836             if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) {
837                 isp_intr(isp, isr, sema, mbox);
838                 if (isp->mboxcmd_done) {
839                     break;
840                 }
841             }
842             ISP_ENABLE_INTS(isp);
843             ISP_DROP_LK_SOFTC(isp);
844             udelay(100);
845             ISP_IGET_LK_SOFTC(isp);
846             if (isp->mboxcmd_done) {
847                 break;
848             }
849         }
850         if (isp->mboxcmd_done == 0) {
851             isp_prt(isp, ISP_LOGWARN, "Polled Mailbox Command (0x%x) Timeout (%lu elapsed usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(jiffies - tt));
852             mbp->param[0] = MBOX_TIMEOUT;
853         }
854     } else {
855         isp_prt(isp, ISP_LOGDEBUG1, "Start Interrupting Mailbox Command (%x)", isp->isp_lastmbxcmd);
856         ISP_ENABLE_INTS(isp);
857         ISP_DROP_LK_SOFTC(isp);
858         et = wait_event_timeout(isp->isp_osinfo.mboxwq, isp->mboxcmd_done, usecs_to_jiffies(lim));
859         ISP_IGET_LK_SOFTC(isp);
860         if (et == 0) {
861             isp_prt(isp, ISP_LOGWARN, "Interrupting Mailbox Command (0x%x) Timeout (elapsed time %lu usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(jiffies - tt));
862             mbp->param[0] = MBOX_TIMEOUT;
863         } else {
864             isp_prt(isp, ISP_LOGDEBUG1, "Interrupting Mailbox Command (0x%x) done (%lu usec)", isp->isp_lastmbxcmd, _jiffies_to_usec(et));
865         }
866     }
867 }
868
869 static ISP_INLINE int
870 fc_scratch_acquire(ispsoftc_t *isp, int chan)
871 {
872     if (ISP_DATA(isp, chan)->scratch_busy) {
873         return (-1);
874     }
875     ISP_DATA(isp, chan)->scratch_busy = 1;
876     return (0);
877 }
878
879 /*
880  * Note that these allocators aren't interrupt safe
881  */
882 static ISP_INLINE void * isp_kalloc(size_t, int);
883 static ISP_INLINE void   isp_kfree(void *, size_t);
884 static ISP_INLINE void * isp_kzalloc(size_t, int);
885
886 static ISP_INLINE void *
887 isp_kalloc(size_t size, int flags)
888 {
889     void *ptr;
890     if (size >= PAGE_SIZE) {
891         ptr = vmalloc(size);
892     } else {
893         ptr = kmalloc(size, flags);
894     }
895     return (ptr);
896 }
897
898 static ISP_INLINE void
899 isp_kfree(void *ptr, size_t size)
900 {
901     if (size >= PAGE_SIZE) {
902         vfree(ptr);
903     } else {
904         kfree(ptr);
905     }
906 }
907
908 static ISP_INLINE void *
909 isp_kzalloc(size_t size, int flags)
910 {
911     void *ptr = isp_kalloc(size, flags);
912     if (ptr != NULL){
913         memset(ptr, 0, size);
914     }
915     return (ptr);
916 }
917
918 #define COPYIN(uarg, karg, amt)     copy_from_user(karg, uarg, amt)
919 #define COPYOUT(karg, uarg, amt)    copy_to_user(uarg, karg, amt)
920
921 static ISP_INLINE void
922 isp_get_dma64_seg(ispds64_t *dsp, struct scatterlist *sg, uint32_t sgidx)
923 {
924     sg += sgidx;
925     dsp->ds_base    = DMA_LO32(sg_dma_address(sg));
926     dsp->ds_basehi  = DMA_HI32(sg_dma_address(sg));
927     dsp->ds_count   = sg_dma_len(sg);
928 }
929
930 static ISP_INLINE void
931 isp_get_dma_seg(ispds_t *dsp, struct scatterlist *sg, uint32_t sgidx)
932 {
933     sg += sgidx;
934     dsp->ds_base = sg_dma_address(sg);
935     dsp->ds_count = sg_dma_len(sg);
936 }
937
938 /*
939  * Common inline functions
940  */
941
942 #include "isp_library.h"
943
944 #ifdef  ISP_TARGET_MODE
945 #include "isp_tpublic.h"
946
947 int isp_init_target(ispsoftc_t *);
948 void isp_attach_target(ispsoftc_t *);
949 void isp_deinit_target(ispsoftc_t *);
950 void isp_detach_target(ispsoftc_t *);
951 int isp_target_async(ispsoftc_t *, int, int);
952 int isp_target_notify(ispsoftc_t *, void *, uint32_t *);
953 int isp_enable_lun(ispsoftc_t *, uint16_t, uint16_t);
954 int isp_disable_lun(ispsoftc_t *,  uint16_t, uint16_t);
955
956 struct notify {
957     isp_notify_t    notify;
958     uint8_t         qentry[QENTRY_LEN]; /* original immediate notify entry */
959     uint8_t         qevalid;
960     uint8_t         tmf_resp;
961 };
962 #endif
963 /*
964  * Config data
965  */
966
967 int isplinux_abort(Scsi_Cmnd *);
968 int isplinux_bdr(Scsi_Cmnd *);
969 int isplinux_sreset(Scsi_Cmnd *);
970 int isplinux_hreset(Scsi_Cmnd *);
971 #endif /* _ISP_LINUX_H */
972 /*
973  * vim:ts=4:sw=4:expandtab
974  */