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