7f4d4360e0a06fef9370980261c1bfec445c9f21
[dragonfly.git] / sys / dev / raid / asr / asr.c
1 /* $FreeBSD: src/sys/dev/asr/asr.c,v 1.3.2.2 2001/08/23 05:21:29 scottl Exp $ */
2 /* $DragonFly: src/sys/dev/raid/asr/asr.c,v 1.25 2006/09/10 01:26:35 dillon Exp $ */
3 /*
4  * Copyright (c) 1996-2000 Distributed Processing Technology Corporation
5  * Copyright (c) 2000-2001 Adaptec Corporation
6  * All rights reserved.
7  *
8  * TERMS AND CONDITIONS OF USE
9  *
10  * Redistribution and use in source form, with or without modification, are
11  * permitted provided that redistributions of source code must retain the
12  * above copyright notice, this list of conditions and the following disclaimer.
13  *
14  * This software is provided `as is' by Adaptec and any express or implied
15  * warranties, including, but not limited to, the implied warranties of
16  * merchantability and fitness for a particular purpose, are disclaimed. In no
17  * event shall Adaptec be liable for any direct, indirect, incidental, special,
18  * exemplary or consequential damages (including, but not limited to,
19  * procurement of substitute goods or services; loss of use, data, or profits;
20  * or business interruptions) however caused and on any theory of liability,
21  * whether in contract, strict liability, or tort (including negligence or
22  * otherwise) arising in any way out of the use of this driver software, even
23  * if advised of the possibility of such damage.
24  *
25  * SCSI I2O host adapter driver
26  *
27  *      V1.08 2001/08/21 Mark_Salyzyn@adaptec.com
28  *              - The 2000S and 2005S do not initialize on some machines,
29  *                increased timeout to 255ms from 50ms for the StatusGet
30  *                command.
31  *      V1.07 2001/05/22 Mark_Salyzyn@adaptec.com
32  *              - I knew this one was too good to be true. The error return
33  *                on ioctl commands needs to be compared to CAM_REQ_CMP, not
34  *                to the bit masked status.
35  *      V1.06 2001/05/08 Mark_Salyzyn@adaptec.com
36  *              - The 2005S that was supported is affectionately called the
37  *                Conjoined BAR Firmware. In order to support RAID-5 in a
38  *                16MB low-cost configuration, Firmware was forced to go
39  *                to a Split BAR Firmware. This requires a separate IOP and
40  *                Messaging base address.
41  *      V1.05 2001/04/25 Mark_Salyzyn@adaptec.com
42  *              - Handle support for 2005S Zero Channel RAID solution.
43  *              - System locked up if the Adapter locked up. Do not try
44  *                to send other commands if the resetIOP command fails. The
45  *                fail outstanding command discovery loop was flawed as the
46  *                removal of the command from the list prevented discovering
47  *                all the commands.
48  *              - Comment changes to clarify driver.
49  *              - SysInfo searched for an EATA SmartROM, not an I2O SmartROM.
50  *              - We do not use the AC_FOUND_DEV event because of I2O.
51  *                Removed asr_async.
52  *      V1.04 2000/09/22 Mark_Salyzyn@adaptec.com, msmith@freebsd.org,
53  *                       lampa@fee.vutbr.cz and Scott_Long@adaptec.com.
54  *              - Removed support for PM1554, PM2554 and PM2654 in Mode-0
55  *                mode as this is confused with competitor adapters in run
56  *                mode.
57  *              - critical locking needed in ASR_ccbAdd and ASR_ccbRemove
58  *                to prevent operating system panic.
59  *              - moved default major number to 154 from 97.
60  *      V1.03 2000/07/12 Mark_Salyzyn@adaptec.com
61  *              - The controller is not actually an ASR (Adaptec SCSI RAID)
62  *                series that is visible, it's more of an internal code name.
63  *                remove any visible references within reason for now.
64  *              - bus_ptr->LUN was not correctly zeroed when initially
65  *                allocated causing a possible panic of the operating system
66  *                during boot.
67  *      V1.02 2000/06/26 Mark_Salyzyn@adaptec.com
68  *              - Code always fails for ASR_getTid affecting performance.
69  *              - initiated a set of changes that resulted from a formal
70  *                code inspection by Mark_Salyzyn@adaptec.com,
71  *                George_Dake@adaptec.com, Jeff_Zeak@adaptec.com,
72  *                Martin_Wilson@adaptec.com and Vincent_Trandoan@adaptec.com.
73  *                Their findings were focussed on the LCT & TID handler, and
74  *                all resulting changes were to improve code readability,
75  *                consistency or have a positive effect on performance.
76  *      V1.01 2000/06/14 Mark_Salyzyn@adaptec.com
77  *              - Passthrough returned an incorrect error.
78  *              - Passthrough did not migrate the intrinsic scsi layer wakeup
79  *                on command completion.
80  *              - generate control device nodes using make_dev and delete_dev.
81  *              - Performance affected by TID caching reallocing.
82  *              - Made suggested changes by Justin_Gibbs@adaptec.com
83  *                      - use splcam instead of splbio.
84  *                      - use u_int8_t instead of u_char.
85  *                      - use u_int16_t instead of u_short.
86  *                      - use u_int32_t instead of u_long where appropriate.
87  *                      - use 64 bit context handler instead of 32 bit.
88  *                      - create_ccb should only allocate the worst case
89  *                        requirements for the driver since CAM may evolve
90  *                        making union ccb much larger than needed here.
91  *                        renamed create_ccb to asr_alloc_ccb.
92  *                      - go nutz justifying all debug prints as macros
93  *                        defined at the top and remove unsightly ifdefs.
94  *                      - INLINE STATIC viewed as confusing. Historically
95  *                        utilized to affect code performance and debug
96  *                        issues in OS, Compiler or OEM specific situations.
97  *      V1.00 2000/05/31 Mark_Salyzyn@adaptec.com
98  *              - Ported from FreeBSD 2.2.X DPT I2O driver.
99  *                      changed struct scsi_xfer to union ccb/struct ccb_hdr
100  *                      changed variable name xs to ccb
101  *                      changed struct scsi_link to struct cam_path
102  *                      changed struct scsibus_data to struct cam_sim
103  *                      stopped using fordriver for holding on to the TID
104  *                      use proprietary packet creation instead of scsi_inquire
105  *                      CAM layer sends synchronize commands.
106  */
107
108 #define ASR_VERSION     1
109 #define ASR_REVISION    '0'
110 #define ASR_SUBREVISION '8'
111 #define ASR_MONTH       8
112 #define ASR_DAY         21
113 #define ASR_YEAR        2001 - 1980
114
115 /*
116  *      Debug macros to reduce the unsightly ifdefs
117  */
118 #if (defined(DEBUG_ASR) || defined(DEBUG_ASR_USR_CMD) || defined(DEBUG_ASR_CMD))
119 # define debug_asr_message(message)                                            \
120         {                                                                      \
121                 u_int32_t * pointer = (u_int32_t *)message;                    \
122                 u_int32_t   length = I2O_MESSAGE_FRAME_getMessageSize(message);\
123                 u_int32_t   counter = 0;                                       \
124                                                                                \
125                 while (length--) {                                             \
126                         printf ("%08lx%c", (u_long)*(pointer++),               \
127                           (((++counter & 7) == 0) || (length == 0))            \
128                             ? '\n'                                             \
129                             : ' ');                                            \
130                 }                                                              \
131         }
132 #endif /* DEBUG_ASR || DEBUG_ASR_USR_CMD || DEBUG_ASR_CMD */
133
134 #if (defined(DEBUG_ASR))
135   /* Breaks on none STDC based compilers :-( */
136 # define debug_asr_printf(fmt,args...)   printf(fmt, ##args)
137 # define debug_asr_dump_message(message) debug_asr_message(message)
138 # define debug_asr_print_path(ccb)       xpt_print_path(ccb->ccb_h.path);
139   /* None fatal version of the ASSERT macro */
140 # if (defined(__STDC__))
141 #  define ASSERT(phrase) if(!(phrase))printf(#phrase " at line %d file %s\n",__LINE__,__FILE__)
142 # else
143 #  define ASSERT(phrase) if(!(phrase))printf("phrase" " at line %d file %s\n",__LINE__,__FILE__)
144 # endif
145 #else /* DEBUG_ASR */
146 # define debug_asr_printf(fmt,args...)
147 # define debug_asr_dump_message(message)
148 # define debug_asr_print_path(ccb)
149 # define ASSERT(x)
150 #endif /* DEBUG_ASR */
151
152 /*
153  *      If DEBUG_ASR_CMD is defined:
154  *              0 - Display incoming SCSI commands
155  *              1 - add in a quick character before queueing.
156  *              2 - add in outgoing message frames.
157  */
158 #if (defined(DEBUG_ASR_CMD))
159 # define debug_asr_cmd_printf(fmt,args...)     printf(fmt,##args)
160 # define debug_asr_dump_ccb(ccb)                                      \
161         {                                                             \
162                 u_int8_t * cp = (unsigned char *)&(ccb->csio.cdb_io); \
163                 int        len = ccb->csio.cdb_len;                   \
164                                                                       \
165                 while (len) {                                         \
166                         debug_asr_cmd_printf (" %02x", *(cp++));      \
167                         --len;                                        \
168                 }                                                     \
169         }
170 # if (DEBUG_ASR_CMD > 0)
171 #  define debug_asr_cmd1_printf                debug_asr_cmd_printf
172 # else
173 #  define debug_asr_cmd1_printf(fmt,args...)
174 # endif
175 # if (DEBUG_ASR_CMD > 1)
176 #  define debug_asr_cmd2_printf                debug_asr_cmd_printf
177 #  define debug_asr_cmd2_dump_message(message) debug_asr_message(message)
178 # else
179 #  define debug_asr_cmd2_printf(fmt,args...)
180 #  define debug_asr_cmd2_dump_message(message)
181 # endif
182 #else /* DEBUG_ASR_CMD */
183 # define debug_asr_cmd_printf(fmt,args...)
184 # define debug_asr_cmd_dump_ccb(ccb)
185 # define debug_asr_cmd1_printf(fmt,args...)
186 # define debug_asr_cmd2_printf(fmt,args...)
187 # define debug_asr_cmd2_dump_message(message)
188 #endif /* DEBUG_ASR_CMD */
189
190 #if (defined(DEBUG_ASR_USR_CMD))
191 # define debug_usr_cmd_printf(fmt,args...)   printf(fmt,##args)
192 # define debug_usr_cmd_dump_message(message) debug_usr_message(message)
193 #else /* DEBUG_ASR_USR_CMD */
194 # define debug_usr_cmd_printf(fmt,args...)
195 # define debug_usr_cmd_dump_message(message)
196 #endif /* DEBUG_ASR_USR_CMD */
197
198 #define dsDescription_size 46   /* Snug as a bug in a rug */
199 #include "dptsig.h"
200
201 static dpt_sig_S ASR_sig = {
202         { 'd', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION, PROC_INTEL,
203         PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM, FT_HBADRVR, 0,
204         OEM_DPT, OS_FREE_BSD, CAP_ABOVE16MB, DEV_ALL,
205         ADF_ALL_SC5,
206         0, 0, ASR_VERSION, ASR_REVISION, ASR_SUBREVISION,
207         ASR_MONTH, ASR_DAY, ASR_YEAR,
208 /*       01234567890123456789012345678901234567890123456789     < 50 chars */
209         "Adaptec FreeBSD 4.0.0 Unix SCSI I2O HBA Driver"
210         /*               ^^^^^ asr_attach alters these to match OS */
211 };
212
213 #include <sys/param.h>  /* TRUE=1 and FALSE=0 defined here */
214 #include <sys/kernel.h>
215 #include <sys/systm.h>
216 #include <sys/malloc.h>
217 #include <sys/proc.h>
218 #include <sys/conf.h>
219 #include <sys/disklabel.h>
220 #include <sys/bus.h>
221 #include <machine/resource.h>
222 #include <machine/bus.h>
223 #include <sys/rman.h>
224 #include <sys/stat.h>
225 #include <sys/device.h>
226 #include <sys/thread2.h>
227
228 #include <bus/cam/cam.h>
229 #include <bus/cam/cam_ccb.h>
230 #include <bus/cam/cam_sim.h>
231 #include <bus/cam/cam_xpt_sim.h>
232 #include <bus/cam/cam_xpt_periph.h>
233
234 #include <bus/cam/scsi/scsi_all.h>
235 #include <bus/cam/scsi/scsi_message.h>
236
237 #include <vm/vm.h>
238 #include <vm/pmap.h>
239 #include <machine/cputypes.h>
240 #include <machine/clock.h>
241 #include <i386/include/vmparam.h>
242
243 #include <bus/pci/pcivar.h>
244 #include <bus/pci/pcireg.h>
245
246 #define STATIC static
247 #define INLINE
248
249 #if (defined(DEBUG_ASR) && (DEBUG_ASR > 0))
250 # undef STATIC
251 # define STATIC
252 # undef INLINE
253 # define INLINE
254 #endif
255 #define IN
256 #define OUT
257 #define INOUT
258
259 #define osdSwap4(x) ((u_long)ntohl((u_long)(x)))
260 #define KVTOPHYS(x) vtophys(x)
261 #include        "dptalign.h"
262 #include        "i2oexec.h"
263 #include        "i2obscsi.h"
264 #include        "i2odpt.h"
265 #include        "i2oadptr.h"
266 #include        "sys_info.h"
267
268 /* Configuration Definitions */
269
270 #define SG_SIZE          58     /* Scatter Gather list Size              */
271 #define MAX_TARGET_ID    126    /* Maximum Target ID supported           */
272 #define MAX_LUN          255    /* Maximum LUN Supported                 */
273 #define MAX_CHANNEL      7      /* Maximum Channel # Supported by driver */
274 #define MAX_INBOUND      2000   /* Max CCBs, Also Max Queue Size         */
275 #define MAX_OUTBOUND     256    /* Maximum outbound frames/adapter       */
276 #define MAX_INBOUND_SIZE 512    /* Maximum inbound frame size            */
277 #define MAX_MAP          4194304L /* Maximum mapping size of IOP         */
278                                 /* Also serves as the minimum map for    */
279                                 /* the 2005S zero channel RAID product   */
280
281 /**************************************************************************
282 ** ASR Host Adapter structure - One Structure For Each Host Adapter That **
283 **  Is Configured Into The System.  The Structure Supplies Configuration **
284 **  Information, Status Info, Queue Info And An Active CCB List Pointer. **
285 ***************************************************************************/
286
287 /* I2O register set */
288 typedef struct {
289         U8           Address[0x30];
290         volatile U32 Status;
291         volatile U32 Mask;
292 #               define Mask_InterruptsDisabled 0x08
293         U32          x[2];
294         volatile U32 ToFIFO;    /* In Bound FIFO  */
295         volatile U32 FromFIFO;  /* Out Bound FIFO */
296 } i2oRegs_t;
297
298 /*
299  * A MIX of performance and space considerations for TID lookups
300  */
301 typedef u_int16_t tid_t;
302
303 typedef struct {
304         u_int32_t size;         /* up to MAX_LUN    */
305         tid_t     TID[1];
306 } lun2tid_t;
307
308 typedef struct {
309         u_int32_t   size;       /* up to MAX_TARGET */
310         lun2tid_t * LUN[1];
311 } target2lun_t;
312
313 /*
314  *      To ensure that we only allocate and use the worst case ccb here, lets
315  *      make our own local ccb union. If asr_alloc_ccb is utilized for another
316  *      ccb type, ensure that you add the additional structures into our local
317  *      ccb union. To ensure strict type checking, we will utilize the local
318  *      ccb definition wherever possible.
319  */
320 union asr_ccb {
321         struct ccb_hdr      ccb_h;  /* For convenience */
322         struct ccb_scsiio   csio;
323         struct ccb_setasync csa;
324 };
325
326 typedef struct Asr_softc {
327         u_int16_t               ha_irq;
328         void                  * ha_Base;       /* base port for each board */
329         u_int8_t     * volatile ha_blinkLED;
330         i2oRegs_t             * ha_Virt;       /* Base address of IOP      */
331         U8                    * ha_Fvirt;      /* Base address of Frames   */
332         I2O_IOP_ENTRY           ha_SystemTable;
333         LIST_HEAD(,ccb_hdr)     ha_ccb;        /* ccbs in use              */
334         struct cam_path       * ha_path[MAX_CHANNEL+1];
335         struct cam_sim        * ha_sim[MAX_CHANNEL+1];
336         struct resource       * ha_mem_res;
337         struct resource       * ha_mes_res;
338         struct resource       * ha_irq_res;
339         void                  * ha_intr;
340         PI2O_LCT                ha_LCT;        /* Complete list of devices */
341 #                define le_type   IdentityTag[0]
342 #                        define I2O_BSA     0x20
343 #                        define I2O_FCA     0x40
344 #                        define I2O_SCSI    0x00
345 #                        define I2O_PORT    0x80
346 #                        define I2O_UNKNOWN 0x7F
347 #                define le_bus    IdentityTag[1]
348 #                define le_target IdentityTag[2]
349 #                define le_lun    IdentityTag[3]
350         target2lun_t          * ha_targets[MAX_CHANNEL+1];
351         PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME ha_Msgs;
352         u_long                  ha_Msgs_Phys;
353
354         u_int8_t                ha_in_reset;
355 #               define HA_OPERATIONAL       0
356 #               define HA_IN_RESET          1
357 #               define HA_OFF_LINE          2
358 #               define HA_OFF_LINE_RECOVERY 3
359         /* Configuration information */
360         /* The target id maximums we take     */
361         u_int8_t                ha_MaxBus;     /* Maximum bus              */
362         u_int8_t                ha_MaxId;      /* Maximum target ID        */
363         u_int8_t                ha_MaxLun;     /* Maximum target LUN            */
364         u_int8_t                ha_SgSize;     /* Max SG elements          */
365         u_int8_t                ha_pciBusNum;
366         u_int8_t                ha_pciDeviceNum;
367         u_int8_t                ha_adapter_target[MAX_CHANNEL+1];
368         u_int16_t               ha_QueueSize;  /* Max outstanding commands */
369         u_int16_t               ha_Msgs_Count;
370
371         /* Links into other parents and HBAs */
372         struct Asr_softc      * ha_next;       /* HBA list                 */
373 } Asr_softc_t;
374
375 STATIC Asr_softc_t * Asr_softc;
376
377 /*
378  *      Prototypes of the routines we have in this object.
379  */
380
381 /* Externally callable routines */
382 #define PROBE_ARGS  IN device_t tag
383 #define PROBE_RET   int
384 #define PROBE_SET() u_long id = (pci_get_device(tag)<<16)|pci_get_vendor(tag)
385 #define PROBE_RETURN(retval) if(retval){device_set_desc(tag,retval);return(0);}else{return(ENXIO);}
386 #define ATTACH_ARGS IN device_t tag
387 #define ATTACH_RET  int
388 #define ATTACH_SET() int unit = device_get_unit(tag)
389 #define ATTACH_RETURN(retval) return(retval)
390 /* I2O HDM interface */
391 STATIC PROBE_RET      asr_probe (PROBE_ARGS);
392 STATIC ATTACH_RET     asr_attach (ATTACH_ARGS);
393 /* DOMINO placeholder */
394 STATIC PROBE_RET      domino_probe (PROBE_ARGS);
395 STATIC ATTACH_RET     domino_attach (ATTACH_ARGS);
396 /* MODE0 adapter placeholder */
397 STATIC PROBE_RET      mode0_probe (PROBE_ARGS);
398 STATIC ATTACH_RET     mode0_attach (ATTACH_ARGS);
399
400 STATIC Asr_softc_t  * ASR_get_sc (cdev_t dev);
401 STATIC d_ioctl_t asr_ioctl;
402 STATIC d_open_t asr_open;
403 STATIC d_close_t asr_close;
404 STATIC int            asr_intr (IN Asr_softc_t *sc);
405 STATIC void           asr_timeout (INOUT void *arg);
406 STATIC int            ASR_init (IN Asr_softc_t *sc);
407 STATIC INLINE int     ASR_acquireLct (INOUT Asr_softc_t *sc);
408 STATIC INLINE int     ASR_acquireHrt (INOUT Asr_softc_t *sc);
409 STATIC void           asr_action (IN struct cam_sim *sim,
410                                   IN union ccb *ccb);
411 STATIC void           asr_poll (IN struct cam_sim * sim);
412
413 /*
414  *      Here is the auto-probe structure used to nest our tests appropriately
415  *      during the startup phase of the operating system.
416  */
417 STATIC device_method_t asr_methods[] = {
418         DEVMETHOD(device_probe,  asr_probe),
419         DEVMETHOD(device_attach, asr_attach),
420         { 0, 0 }
421 };
422
423 STATIC driver_t asr_driver = {
424         "asr",
425         asr_methods,
426         sizeof(Asr_softc_t)
427 };
428
429 STATIC devclass_t asr_devclass;
430
431 DECLARE_DUMMY_MODULE(asr);
432 DRIVER_MODULE(asr, pci, asr_driver, asr_devclass, 0, 0);
433
434 STATIC device_method_t domino_methods[] = {
435         DEVMETHOD(device_probe,  domino_probe),
436         DEVMETHOD(device_attach, domino_attach),
437         { 0, 0 }
438 };
439
440 STATIC driver_t domino_driver = {
441         "domino",
442         domino_methods,
443         0
444 };
445
446 STATIC devclass_t domino_devclass;
447
448 DRIVER_MODULE(domino, pci, domino_driver, domino_devclass, 0, 0);
449
450 STATIC device_method_t mode0_methods[] = {
451         DEVMETHOD(device_probe,  mode0_probe),
452         DEVMETHOD(device_attach, mode0_attach),
453         { 0, 0 }
454 };
455
456 STATIC driver_t mode0_driver = {
457         "mode0",
458         mode0_methods,
459         0
460 };
461
462 STATIC devclass_t mode0_devclass;
463
464 DRIVER_MODULE(mode0, pci, mode0_driver, mode0_devclass, 0, 0);
465
466 /*
467  * devsw for asr hba driver
468  *
469  * only ioctl is used. the sd driver provides all other access.
470  */
471 #define CDEV_MAJOR 154   /* prefered default character major */
472 STATIC struct dev_ops asr_ops = {
473         { "asr", CDEV_MAJOR, 0 },
474         .d_open =       asr_open,
475         .d_close =      asr_close, 
476         .d_ioctl =      asr_ioctl,
477 };
478
479 /*
480  * Initialize the dynamic dev_ops hooks.
481  */
482 STATIC void
483 asr_drvinit (void * unused)
484 {
485         static int asr_devsw_installed = 0;
486
487         if (asr_devsw_installed) {
488                 return;
489         }
490         asr_devsw_installed++;
491         /*
492          * Find a free spot (the report during driver load used by
493          * osd layer in engine to generate the controlling nodes).
494          *
495          * XXX this is garbage code, store a unit number in asr_ops
496          * and iterate through that instead?
497          */
498         while (asr_ops.head.maj < NUMCDEVSW &&
499                 dev_ops_get(asr_ops.head.maj, -1) != NULL
500         ) {
501                 ++asr_ops.head.maj;
502         }
503         if (asr_ops.head.maj >= NUMCDEVSW) {
504                 asr_ops.head.maj = 0;
505                 while (asr_ops.head.maj < CDEV_MAJOR &&
506                         dev_ops_get(asr_ops.head.maj, -1) != NULL
507                 ) {
508                         ++asr_ops.head.maj;
509                 }
510         }
511
512         /*
513          *      Come to papa
514          */
515         dev_ops_add(&asr_ops, 0, 0);
516 } /* asr_drvinit */
517
518 /* Must initialize before CAM layer picks up our HBA driver */
519 SYSINIT(asrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,asr_drvinit,NULL)
520
521 /* I2O support routines */
522 #define defAlignLong(STRUCT,NAME) char NAME[sizeof(STRUCT)]
523 #define getAlignLong(STRUCT,NAME) ((STRUCT *)(NAME))
524
525 /*
526  *      Fill message with default.
527  */
528 STATIC PI2O_MESSAGE_FRAME
529 ASR_fillMessage (
530         IN char              * Message,
531         IN u_int16_t           size)
532 {
533         OUT PI2O_MESSAGE_FRAME Message_Ptr;
534
535         Message_Ptr = getAlignLong(I2O_MESSAGE_FRAME, Message);
536         bzero ((void *)Message_Ptr, size);
537         I2O_MESSAGE_FRAME_setVersionOffset(Message_Ptr, I2O_VERSION_11);
538         I2O_MESSAGE_FRAME_setMessageSize(Message_Ptr,
539           (size + sizeof(U32) - 1) >> 2);
540         I2O_MESSAGE_FRAME_setInitiatorAddress (Message_Ptr, 1);
541         return (Message_Ptr);
542 } /* ASR_fillMessage */
543
544 #define EMPTY_QUEUE ((U32)-1L)
545
546 STATIC INLINE U32
547 ASR_getMessage(
548         IN i2oRegs_t * virt)
549 {
550         OUT U32        MessageOffset;
551
552         if ((MessageOffset = virt->ToFIFO) == EMPTY_QUEUE) {
553                 MessageOffset = virt->ToFIFO;
554         }
555         return (MessageOffset);
556 } /* ASR_getMessage */
557
558 /* Issue a polled command */
559 STATIC U32
560 ASR_initiateCp (
561         INOUT i2oRegs_t     * virt,
562         INOUT U8            * fvirt,
563         IN PI2O_MESSAGE_FRAME Message)
564 {
565         OUT U32               Mask = -1L;
566         U32                   MessageOffset;
567         u_int                 Delay = 1500;
568
569         /*
570          * ASR_initiateCp is only used for synchronous commands and will
571          * be made more resiliant to adapter delays since commands like
572          * resetIOP can cause the adapter to be deaf for a little time.
573          */
574         while (((MessageOffset = ASR_getMessage(virt)) == EMPTY_QUEUE)
575          && (--Delay != 0)) {
576                 DELAY (10000);
577         }
578         if (MessageOffset != EMPTY_QUEUE) {
579                 bcopy (Message, fvirt + MessageOffset,
580                   I2O_MESSAGE_FRAME_getMessageSize(Message) << 2);
581                 /*
582                  *      Disable the Interrupts
583                  */
584                 virt->Mask = (Mask = virt->Mask) | Mask_InterruptsDisabled;
585                 virt->ToFIFO = MessageOffset;
586         }
587         return (Mask);
588 } /* ASR_initiateCp */
589
590 /*
591  *      Reset the adapter.
592  */
593 STATIC U32
594 ASR_resetIOP (
595         INOUT i2oRegs_t                * virt,
596         INOUT U8                       * fvirt)
597 {
598         struct resetMessage {
599                 I2O_EXEC_IOP_RESET_MESSAGE M;
600                 U32                        R;
601         };
602         defAlignLong(struct resetMessage,Message);
603         PI2O_EXEC_IOP_RESET_MESSAGE      Message_Ptr;
604         OUT U32               * volatile Reply_Ptr;
605         U32                              Old;
606
607         /*
608          *  Build up our copy of the Message.
609          */
610         Message_Ptr = (PI2O_EXEC_IOP_RESET_MESSAGE)ASR_fillMessage(Message,
611           sizeof(I2O_EXEC_IOP_RESET_MESSAGE));
612         I2O_EXEC_IOP_RESET_MESSAGE_setFunction(Message_Ptr, I2O_EXEC_IOP_RESET);
613         /*
614          *  Reset the Reply Status
615          */
616         *(Reply_Ptr = (U32 *)((char *)Message_Ptr
617           + sizeof(I2O_EXEC_IOP_RESET_MESSAGE))) = 0;
618         I2O_EXEC_IOP_RESET_MESSAGE_setStatusWordLowAddress(Message_Ptr,
619           KVTOPHYS((void *)Reply_Ptr));
620         /*
621          *      Send the Message out
622          */
623         if ((Old = ASR_initiateCp (virt, fvirt, (PI2O_MESSAGE_FRAME)Message_Ptr)) != (U32)-1L) {
624                 /*
625                  *      Wait for a response (Poll), timeouts are dangerous if
626                  * the card is truly responsive. We assume response in 2s.
627                  */
628                 u_int8_t Delay = 200;
629
630                 while ((*Reply_Ptr == 0) && (--Delay != 0)) {
631                         DELAY (10000);
632                 }
633                 /*
634                  *      Re-enable the interrupts.
635                  */
636                 virt->Mask = Old;
637                 ASSERT (*Reply_Ptr);
638                 return (*Reply_Ptr);
639         }
640         ASSERT (Old != (U32)-1L);
641         return (0);
642 } /* ASR_resetIOP */
643
644 /*
645  *      Get the curent state of the adapter
646  */
647 STATIC INLINE PI2O_EXEC_STATUS_GET_REPLY
648 ASR_getStatus (
649         INOUT i2oRegs_t *                        virt,
650         INOUT U8 *                               fvirt,
651         OUT PI2O_EXEC_STATUS_GET_REPLY           buffer)
652 {
653         defAlignLong(I2O_EXEC_STATUS_GET_MESSAGE,Message);
654         PI2O_EXEC_STATUS_GET_MESSAGE             Message_Ptr;
655         U32                                      Old;
656
657         /*
658          *  Build up our copy of the Message.
659          */
660         Message_Ptr = (PI2O_EXEC_STATUS_GET_MESSAGE)ASR_fillMessage(Message,
661           sizeof(I2O_EXEC_STATUS_GET_MESSAGE));
662         I2O_EXEC_STATUS_GET_MESSAGE_setFunction(Message_Ptr,
663           I2O_EXEC_STATUS_GET);
664         I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferAddressLow(Message_Ptr,
665           KVTOPHYS((void *)buffer));
666         /* This one is a Byte Count */
667         I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength(Message_Ptr,
668           sizeof(I2O_EXEC_STATUS_GET_REPLY));
669         /*
670          *  Reset the Reply Status
671          */
672         bzero ((void *)buffer, sizeof(I2O_EXEC_STATUS_GET_REPLY));
673         /*
674          *      Send the Message out
675          */
676         if ((Old = ASR_initiateCp (virt, fvirt, (PI2O_MESSAGE_FRAME)Message_Ptr)) != (U32)-1L) {
677                 /*
678                  *      Wait for a response (Poll), timeouts are dangerous if
679                  * the card is truly responsive. We assume response in 50ms.
680                  */
681                 u_int8_t Delay = 255;
682
683                 while (*((U8 * volatile)&(buffer->SyncByte)) == 0) {
684                         if (--Delay == 0) {
685                                 buffer = (PI2O_EXEC_STATUS_GET_REPLY)NULL;
686                                 break;
687                         }
688                         DELAY (1000);
689                 }
690                 /*
691                  *      Re-enable the interrupts.
692                  */
693                 virt->Mask = Old;
694                 return (buffer);
695         }
696         return ((PI2O_EXEC_STATUS_GET_REPLY)NULL);
697 } /* ASR_getStatus */
698
699 /*
700  *      Check if the device is a SCSI I2O HBA, and add it to the list.
701  */
702
703 /*
704  * Probe for ASR controller.  If we find it, we will use it.
705  * virtual adapters.
706  */
707 STATIC PROBE_RET
708 asr_probe(PROBE_ARGS)
709 {
710         PROBE_SET();
711         if ((id == 0xA5011044) || (id == 0xA5111044)) {
712                 PROBE_RETURN ("Adaptec Caching SCSI RAID");
713         }
714         PROBE_RETURN (NULL);
715 } /* asr_probe */
716
717 /*
718  * Probe/Attach for DOMINO chipset.
719  */
720 STATIC PROBE_RET
721 domino_probe(PROBE_ARGS)
722 {
723         PROBE_SET();
724         if (id == 0x10121044) {
725                 PROBE_RETURN ("Adaptec Caching Memory Controller");
726         }
727         PROBE_RETURN (NULL);
728 } /* domino_probe */
729
730 STATIC ATTACH_RET
731 domino_attach (ATTACH_ARGS)
732 {
733         ATTACH_RETURN (0);
734 } /* domino_attach */
735
736 /*
737  * Probe/Attach for MODE0 adapters.
738  */
739 STATIC PROBE_RET
740 mode0_probe(PROBE_ARGS)
741 {
742         PROBE_SET();
743
744         /*
745          *      If/When we can get a business case to commit to a
746          * Mode0 driver here, we can make all these tests more
747          * specific and robust. Mode0 adapters have their processors
748          * turned off, this the chips are in a raw state.
749          */
750
751         /* This is a PLX9054 */
752         if (id == 0x905410B5) {
753                 PROBE_RETURN ("Adaptec Mode0 PM3757");
754         }
755         /* This is a PLX9080 */
756         if (id == 0x908010B5) {
757                 PROBE_RETURN ("Adaptec Mode0 PM3754/PM3755");
758         }
759         /* This is a ZION 80303 */
760         if (id == 0x53098086) {
761                 PROBE_RETURN ("Adaptec Mode0 3010S");
762         }
763         /* This is an i960RS */
764         if (id == 0x39628086) {
765                 PROBE_RETURN ("Adaptec Mode0 2100S");
766         }
767         /* This is an i960RN */
768         if (id == 0x19648086) {
769                 PROBE_RETURN ("Adaptec Mode0 PM2865/2400A/3200S/3400S");
770         }
771 #if 0   /* this would match any generic i960 -- mjs */
772         /* This is an i960RP (typically also on Motherboards) */
773         if (id == 0x19608086) {
774                 PROBE_RETURN ("Adaptec Mode0 PM2554/PM1554/PM2654");
775         }
776 #endif
777         PROBE_RETURN (NULL);
778 } /* mode0_probe */
779
780 STATIC ATTACH_RET
781 mode0_attach (ATTACH_ARGS)
782 {
783         ATTACH_RETURN (0);
784 } /* mode0_attach */
785
786 STATIC INLINE union asr_ccb *
787 asr_alloc_ccb (
788         IN Asr_softc_t    * sc)
789 {
790         OUT union asr_ccb * new_ccb;
791
792         if ((new_ccb = (union asr_ccb *)kmalloc(sizeof(*new_ccb),
793           M_DEVBUF, M_WAITOK)) != (union asr_ccb *)NULL) {
794                 bzero (new_ccb, sizeof(*new_ccb));
795                 new_ccb->ccb_h.pinfo.priority = 1;
796                 new_ccb->ccb_h.pinfo.index = CAM_UNQUEUED_INDEX;
797                 new_ccb->ccb_h.spriv_ptr0 = sc;
798         }
799         return (new_ccb);
800 } /* asr_alloc_ccb */
801
802 STATIC INLINE void
803 asr_free_ccb (
804         IN union asr_ccb * free_ccb)
805 {
806         kfree(free_ccb, M_DEVBUF);
807 } /* asr_free_ccb */
808
809 /*
810  *      Print inquiry data `carefully'
811  */
812 STATIC void
813 ASR_prstring (
814         u_int8_t * s,
815         int        len)
816 {
817         while ((--len >= 0) && (*s) && (*s != ' ') && (*s != '-')) {
818                 printf ("%c", *(s++));
819         }
820 } /* ASR_prstring */
821
822 /*
823  * Prototypes
824  */
825 STATIC INLINE int ASR_queue (
826         IN Asr_softc_t             * sc,
827         IN PI2O_MESSAGE_FRAME Message);
828 /*
829  *      Send a message synchronously and without Interrupt to a ccb.
830  */
831 STATIC int
832 ASR_queue_s (
833         INOUT union asr_ccb * ccb,
834         IN PI2O_MESSAGE_FRAME Message)
835 {
836         U32                   Mask;
837         Asr_softc_t         * sc = (Asr_softc_t *)(ccb->ccb_h.spriv_ptr0);
838
839         /*
840          * We do not need any (optional byteswapping) method access to
841          * the Initiator context field.
842          */
843         I2O_MESSAGE_FRAME_setInitiatorContext64(Message, (long)ccb);
844
845         /* Prevent interrupt service */
846         crit_enter();
847         sc->ha_Virt->Mask = (Mask = sc->ha_Virt->Mask)
848           | Mask_InterruptsDisabled;
849
850         if (ASR_queue (sc, Message) == EMPTY_QUEUE) {
851                 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
852                 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
853         }
854
855         /*
856          * Wait for this board to report a finished instruction.
857          */
858         while ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
859                 (void)asr_intr (sc);
860         }
861
862         /* Re-enable Interrupts */
863         sc->ha_Virt->Mask = Mask;
864         crit_exit();
865
866         return (ccb->ccb_h.status);
867 } /* ASR_queue_s */
868
869 /*
870  *      Send a message synchronously to a Asr_softc_t
871  */
872 STATIC int
873 ASR_queue_c (
874         IN Asr_softc_t      * sc,
875         IN PI2O_MESSAGE_FRAME Message)
876 {
877         union asr_ccb       * ccb;
878         OUT int               status;
879
880         if ((ccb = asr_alloc_ccb (sc)) == (union asr_ccb *)NULL) {
881                 return (CAM_REQUEUE_REQ);
882         }
883
884         status = ASR_queue_s (ccb, Message);
885
886         asr_free_ccb(ccb);
887
888         return (status);
889 } /* ASR_queue_c */
890
891 /*
892  *      Add the specified ccb to the active queue
893  */
894 STATIC INLINE void
895 ASR_ccbAdd (
896         IN Asr_softc_t      * sc,
897         INOUT union asr_ccb * ccb)
898 {
899         crit_enter();
900         LIST_INSERT_HEAD(&(sc->ha_ccb), &(ccb->ccb_h), sim_links.le);
901         if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) {
902                 if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) {
903                         /*
904                          * RAID systems can take considerable time to
905                          * complete some commands given the large cache
906                          * flashes switching from write back to write thru.
907                          */
908                         ccb->ccb_h.timeout = 6 * 60 * 1000;
909                 }
910                 callout_reset(&ccb->ccb_h.timeout_ch,
911                     (ccb->ccb_h.timeout * hz) / 1000, asr_timeout, ccb);
912         }
913         crit_exit();
914 } /* ASR_ccbAdd */
915
916 /*
917  *      Remove the specified ccb from the active queue.
918  */
919 STATIC INLINE void
920 ASR_ccbRemove (
921         IN Asr_softc_t      * sc,
922         INOUT union asr_ccb * ccb)
923 {
924         crit_enter();
925         callout_stop(&ccb->ccb_h.timeout_ch);
926         LIST_REMOVE(&(ccb->ccb_h), sim_links.le);
927         crit_exit();
928 } /* ASR_ccbRemove */
929
930 /*
931  *      Fail all the active commands, so they get re-issued by the operating
932  *      system.
933  */
934 STATIC INLINE void
935 ASR_failActiveCommands (
936         IN Asr_softc_t                         * sc)
937 {
938         struct ccb_hdr                         * ccb;
939
940 #if 0 /* Currently handled by callers, unnecessary paranoia currently */
941       /* Left in for historical perspective. */
942         defAlignLong(I2O_EXEC_LCT_NOTIFY_MESSAGE,Message);
943         PI2O_EXEC_LCT_NOTIFY_MESSAGE             Message_Ptr;
944
945         /* Send a blind LCT command to wait for the enableSys to complete */
946         Message_Ptr = (PI2O_EXEC_LCT_NOTIFY_MESSAGE)ASR_fillMessage(Message,
947           sizeof(I2O_EXEC_LCT_NOTIFY_MESSAGE) - sizeof(I2O_SG_ELEMENT));
948         I2O_MESSAGE_FRAME_setFunction(&(Message_Ptr->StdMessageFrame),
949           I2O_EXEC_LCT_NOTIFY);
950         I2O_EXEC_LCT_NOTIFY_MESSAGE_setClassIdentifier(Message_Ptr,
951           I2O_CLASS_MATCH_ANYCLASS);
952         (void)ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
953 #endif
954
955         crit_enter();
956         /*
957          *      We do not need to inform the CAM layer that we had a bus
958          * reset since we manage it on our own, this also prevents the
959          * SCSI_DELAY settling that would be required on other systems.
960          * The `SCSI_DELAY' has already been handled by the card via the
961          * acquisition of the LCT table while we are at CAM priority level.
962          *  for (int bus = 0; bus <= sc->ha_MaxBus; ++bus) {
963          *      xpt_async (AC_BUS_RESET, sc->ha_path[bus], NULL);
964          *  }
965          */
966         while ((ccb = LIST_FIRST(&(sc->ha_ccb))) != (struct ccb_hdr *)NULL) {
967                 ASR_ccbRemove (sc, (union asr_ccb *)ccb);
968
969                 ccb->status &= ~CAM_STATUS_MASK;
970                 ccb->status |= CAM_REQUEUE_REQ;
971                 /* Nothing Transfered */
972                 ((struct ccb_scsiio *)ccb)->resid
973                   = ((struct ccb_scsiio *)ccb)->dxfer_len;
974
975                 if (ccb->path) {
976                         xpt_done ((union ccb *)ccb);
977                 } else {
978                         wakeup ((caddr_t)ccb);
979                 }
980         }
981         crit_exit();
982 } /* ASR_failActiveCommands */
983
984 /*
985  *      The following command causes the HBA to reset the specific bus
986  */
987 STATIC INLINE void
988 ASR_resetBus(
989         IN Asr_softc_t                       * sc,
990         IN int                                 bus)
991 {
992         defAlignLong(I2O_HBA_BUS_RESET_MESSAGE,Message);
993         I2O_HBA_BUS_RESET_MESSAGE            * Message_Ptr;
994         PI2O_LCT_ENTRY                         Device;
995
996         Message_Ptr = (I2O_HBA_BUS_RESET_MESSAGE *)ASR_fillMessage(Message,
997           sizeof(I2O_HBA_BUS_RESET_MESSAGE));
998         I2O_MESSAGE_FRAME_setFunction(&Message_Ptr->StdMessageFrame,
999           I2O_HBA_BUS_RESET);
1000         for (Device = sc->ha_LCT->LCTEntry; Device < (PI2O_LCT_ENTRY)
1001           (((U32 *)sc->ha_LCT)+I2O_LCT_getTableSize(sc->ha_LCT));
1002           ++Device) {
1003                 if (((Device->le_type & I2O_PORT) != 0)
1004                  && (Device->le_bus == bus)) {
1005                         I2O_MESSAGE_FRAME_setTargetAddress(
1006                           &Message_Ptr->StdMessageFrame,
1007                           I2O_LCT_ENTRY_getLocalTID(Device));
1008                         /* Asynchronous command, with no expectations */
1009                         (void)ASR_queue(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
1010                         break;
1011                 }
1012         }
1013 } /* ASR_resetBus */
1014
1015 STATIC INLINE int
1016 ASR_getBlinkLedCode (
1017         IN Asr_softc_t * sc)
1018 {
1019         if ((sc != (Asr_softc_t *)NULL)
1020          && (sc->ha_blinkLED != (u_int8_t *)NULL)
1021          && (sc->ha_blinkLED[1] == 0xBC)) {
1022                 return (sc->ha_blinkLED[0]);
1023         }
1024         return (0);
1025 } /* ASR_getBlinkCode */
1026
1027 /*
1028  *      Determine the address of an TID lookup. Must be done at high priority
1029  *      since the address can be changed by other threads of execution.
1030  *
1031  *      Returns NULL pointer if not indexible (but will attempt to generate
1032  *      an index if `new_entry' flag is set to TRUE).
1033  *
1034  *      All addressible entries are to be guaranteed zero if never initialized.
1035  */
1036 STATIC INLINE tid_t *
1037 ASR_getTidAddress(
1038         INOUT Asr_softc_t * sc,
1039         IN int              bus,
1040         IN int              target,
1041         IN int              lun,
1042         IN int              new_entry)
1043 {
1044         target2lun_t      * bus_ptr;
1045         lun2tid_t         * target_ptr;
1046         unsigned            new_size;
1047
1048         /*
1049          *      Validity checking of incoming parameters. More of a bound
1050          * expansion limit than an issue with the code dealing with the
1051          * values.
1052          *
1053          *      sc must be valid before it gets here, so that check could be
1054          * dropped if speed a critical issue.
1055          */
1056         if ((sc == (Asr_softc_t *)NULL)
1057          || (bus > MAX_CHANNEL)
1058          || (target > sc->ha_MaxId)
1059          || (lun > sc->ha_MaxLun)) {
1060                 debug_asr_printf("(%lx,%d,%d,%d) target out of range\n",
1061                   (u_long)sc, bus, target, lun);
1062                 return ((tid_t *)NULL);
1063         }
1064         /*
1065          *      See if there is an associated bus list.
1066          *
1067          *      for performance, allocate in size of BUS_CHUNK chunks.
1068          *      BUS_CHUNK must be a power of two. This is to reduce
1069          *      fragmentation effects on the allocations.
1070          */
1071 #       define BUS_CHUNK 8
1072         new_size = ((target + BUS_CHUNK - 1) & ~(BUS_CHUNK - 1));
1073         if ((bus_ptr = sc->ha_targets[bus]) == (target2lun_t *)NULL) {
1074                 /*
1075                  *      Allocate a new structure?
1076                  *              Since one element in structure, the +1
1077                  *              needed for size has been abstracted.
1078                  */
1079                 if ((new_entry == FALSE)
1080                  || ((sc->ha_targets[bus] = bus_ptr = (target2lun_t *)kmalloc (
1081                     sizeof(*bus_ptr) + (sizeof(bus_ptr->LUN) * new_size),
1082                     M_TEMP, M_WAITOK))
1083                    == (target2lun_t *)NULL)) {
1084                         debug_asr_printf("failed to allocate bus list\n");
1085                         return ((tid_t *)NULL);
1086                 }
1087                 bzero (bus_ptr, sizeof(*bus_ptr)
1088                   + (sizeof(bus_ptr->LUN) * new_size));
1089                 bus_ptr->size = new_size + 1;
1090         } else if (bus_ptr->size <= new_size) {
1091                 target2lun_t * new_bus_ptr;
1092
1093                 /*
1094                  *      Reallocate a new structure?
1095                  *              Since one element in structure, the +1
1096                  *              needed for size has been abstracted.
1097                  */
1098                 if ((new_entry == FALSE)
1099                  || ((new_bus_ptr = (target2lun_t *)kmalloc (
1100                     sizeof(*bus_ptr) + (sizeof(bus_ptr->LUN) * new_size),
1101                     M_TEMP, M_WAITOK))
1102                    == (target2lun_t *)NULL)) {
1103                         debug_asr_printf("failed to reallocate bus list\n");
1104                         return ((tid_t *)NULL);
1105                 }
1106                 /*
1107                  *      Zero and copy the whole thing, safer, simpler coding
1108                  * and not really performance critical at this point.
1109                  */
1110                 bzero (new_bus_ptr, sizeof(*bus_ptr)
1111                   + (sizeof(bus_ptr->LUN) * new_size));
1112                 bcopy (bus_ptr, new_bus_ptr, sizeof(*bus_ptr)
1113                   + (sizeof(bus_ptr->LUN) * (bus_ptr->size - 1)));
1114                 sc->ha_targets[bus] = new_bus_ptr;
1115                 kfree (bus_ptr, M_TEMP);
1116                 bus_ptr = new_bus_ptr;
1117                 bus_ptr->size = new_size + 1;
1118         }
1119         /*
1120          *      We now have the bus list, lets get to the target list.
1121          *      Since most systems have only *one* lun, we do not allocate
1122          *      in chunks as above, here we allow one, then in chunk sizes.
1123          *      TARGET_CHUNK must be a power of two. This is to reduce
1124          *      fragmentation effects on the allocations.
1125          */
1126 #       define TARGET_CHUNK 8
1127         if ((new_size = lun) != 0) {
1128                 new_size = ((lun + TARGET_CHUNK - 1) & ~(TARGET_CHUNK - 1));
1129         }
1130         if ((target_ptr = bus_ptr->LUN[target]) == (lun2tid_t *)NULL) {
1131                 /*
1132                  *      Allocate a new structure?
1133                  *              Since one element in structure, the +1
1134                  *              needed for size has been abstracted.
1135                  */
1136                 if ((new_entry == FALSE)
1137                  || ((bus_ptr->LUN[target] = target_ptr = (lun2tid_t *)kmalloc (
1138                     sizeof(*target_ptr) + (sizeof(target_ptr->TID) * new_size),
1139                     M_TEMP, M_WAITOK))
1140                    == (lun2tid_t *)NULL)) {
1141                         debug_asr_printf("failed to allocate target list\n");
1142                         return ((tid_t *)NULL);
1143                 }
1144                 bzero (target_ptr, sizeof(*target_ptr)
1145                   + (sizeof(target_ptr->TID) * new_size));
1146                 target_ptr->size = new_size + 1;
1147         } else if (target_ptr->size <= new_size) {
1148                 lun2tid_t * new_target_ptr;
1149
1150                 /*
1151                  *      Reallocate a new structure?
1152                  *              Since one element in structure, the +1
1153                  *              needed for size has been abstracted.
1154                  */
1155                 if ((new_entry == FALSE)
1156                  || ((new_target_ptr = (lun2tid_t *)kmalloc (
1157                     sizeof(*target_ptr) + (sizeof(target_ptr->TID) * new_size),
1158                     M_TEMP, M_WAITOK))
1159                    == (lun2tid_t *)NULL)) {
1160                         debug_asr_printf("failed to reallocate target list\n");
1161                         return ((tid_t *)NULL);
1162                 }
1163                 /*
1164                  *      Zero and copy the whole thing, safer, simpler coding
1165                  * and not really performance critical at this point.
1166                  */
1167                 bzero (new_target_ptr, sizeof(*target_ptr)
1168                   + (sizeof(target_ptr->TID) * new_size));
1169                 bcopy (target_ptr, new_target_ptr,
1170                   sizeof(*target_ptr)
1171                   + (sizeof(target_ptr->TID) * (target_ptr->size - 1)));
1172                 bus_ptr->LUN[target] = new_target_ptr;
1173                 kfree (target_ptr, M_TEMP);
1174                 target_ptr = new_target_ptr;
1175                 target_ptr->size = new_size + 1;
1176         }
1177         /*
1178          *      Now, acquire the TID address from the LUN indexed list.
1179          */
1180         return (&(target_ptr->TID[lun]));
1181 } /* ASR_getTidAddress */
1182
1183 /*
1184  *      Get a pre-existing TID relationship.
1185  *
1186  *      If the TID was never set, return (tid_t)-1.
1187  *
1188  *      should use mutex rather than spl.
1189  */
1190 STATIC INLINE tid_t
1191 ASR_getTid (
1192         IN Asr_softc_t * sc,
1193         IN int           bus,
1194         IN int           target,
1195         IN int           lun)
1196 {
1197         tid_t          * tid_ptr;
1198         OUT tid_t        retval;
1199
1200         crit_enter();
1201         if (((tid_ptr = ASR_getTidAddress (sc, bus, target, lun, FALSE))
1202           == (tid_t *)NULL)
1203         /* (tid_t)0 or (tid_t)-1 indicate no TID */
1204          || (*tid_ptr == (tid_t)0)) {
1205                 crit_exit();
1206                 return ((tid_t)-1);
1207         }
1208         retval = *tid_ptr;
1209         crit_exit();
1210         return (retval);
1211 } /* ASR_getTid */
1212
1213 /*
1214  *      Set a TID relationship.
1215  *
1216  *      If the TID was not set, return (tid_t)-1.
1217  *
1218  *      should use mutex rather than spl.
1219  */
1220 STATIC INLINE tid_t
1221 ASR_setTid (
1222         INOUT Asr_softc_t * sc,
1223         IN int              bus,
1224         IN int              target,
1225         IN int              lun,
1226         INOUT tid_t         TID)
1227 {
1228         tid_t             * tid_ptr;
1229
1230         if (TID != (tid_t)-1) {
1231                 if (TID == 0) {
1232                         return ((tid_t)-1);
1233                 }
1234                 crit_enter();
1235                 if ((tid_ptr = ASR_getTidAddress (sc, bus, target, lun, TRUE))
1236                  == (tid_t *)NULL) {
1237                         crit_exit();
1238                         return ((tid_t)-1);
1239                 }
1240                 *tid_ptr = TID;
1241                 crit_exit();
1242         }
1243         return (TID);
1244 } /* ASR_setTid */
1245
1246 /*-------------------------------------------------------------------------*/
1247 /*                    Function ASR_rescan                                  */
1248 /*-------------------------------------------------------------------------*/
1249 /* The Parameters Passed To This Function Are :                            */
1250 /*     Asr_softc_t *     : HBA miniport driver's adapter data storage.     */
1251 /*                                                                         */
1252 /* This Function Will rescan the adapter and resynchronize any data        */
1253 /*                                                                         */
1254 /* Return : 0 For OK, Error Code Otherwise                                 */
1255 /*-------------------------------------------------------------------------*/
1256
1257 STATIC INLINE int
1258 ASR_rescan(
1259         IN Asr_softc_t * sc)
1260 {
1261         int              bus;
1262         OUT int          error;
1263
1264         /*
1265          * Re-acquire the LCT table and synchronize us to the adapter.
1266          */
1267         if ((error = ASR_acquireLct(sc)) == 0) {
1268                 error = ASR_acquireHrt(sc);
1269         }
1270
1271         if (error != 0) {
1272                 return error;
1273         }
1274
1275         bus = sc->ha_MaxBus;
1276         /* Reset all existing cached TID lookups */
1277         do {
1278                 int target, event = 0;
1279
1280                 /*
1281                  *      Scan for all targets on this bus to see if they
1282                  * got affected by the rescan.
1283                  */
1284                 for (target = 0; target <= sc->ha_MaxId; ++target) {
1285                         int lun;
1286
1287                         /* Stay away from the controller ID */
1288                         if (target == sc->ha_adapter_target[bus]) {
1289                                 continue;
1290                         }
1291                         for (lun = 0; lun <= sc->ha_MaxLun; ++lun) {
1292                                 PI2O_LCT_ENTRY Device;
1293                                 tid_t          TID = (tid_t)-1;
1294                                 tid_t          LastTID;
1295
1296                                 /*
1297                                  * See if the cached TID changed. Search for
1298                                  * the device in our new LCT.
1299                                  */
1300                                 for (Device = sc->ha_LCT->LCTEntry;
1301                                   Device < (PI2O_LCT_ENTRY)(((U32 *)sc->ha_LCT)
1302                                    + I2O_LCT_getTableSize(sc->ha_LCT));
1303                                   ++Device) {
1304                                         if ((Device->le_type != I2O_UNKNOWN)
1305                                          && (Device->le_bus == bus)
1306                                          && (Device->le_target == target)
1307                                          && (Device->le_lun == lun)
1308                                          && (I2O_LCT_ENTRY_getUserTID(Device)
1309                                           == 0xFFF)) {
1310                                                 TID = I2O_LCT_ENTRY_getLocalTID(
1311                                                   Device);
1312                                                 break;
1313                                         }
1314                                 }
1315                                 /*
1316                                  * Indicate to the OS that the label needs
1317                                  * to be recalculated, or that the specific
1318                                  * open device is no longer valid (Merde)
1319                                  * because the cached TID changed.
1320                                  */
1321                                 LastTID = ASR_getTid (sc, bus, target, lun);
1322                                 if (LastTID != TID) {
1323                                         struct cam_path * path;
1324
1325                                         if (xpt_create_path(&path,
1326                                           /*periph*/NULL,
1327                                           cam_sim_path(sc->ha_sim[bus]),
1328                                           target, lun) != CAM_REQ_CMP) {
1329                                                 if (TID == (tid_t)-1) {
1330                                                         event |= AC_LOST_DEVICE;
1331                                                 } else {
1332                                                         event |= AC_INQ_CHANGED
1333                                                                | AC_GETDEV_CHANGED;
1334                                                 }
1335                                         } else {
1336                                                 if (TID == (tid_t)-1) {
1337                                                         xpt_async(
1338                                                           AC_LOST_DEVICE,
1339                                                           path, NULL);
1340                                                 } else if (LastTID == (tid_t)-1) {
1341                                                         struct ccb_getdev ccb;
1342
1343                                                         xpt_setup_ccb(
1344                                                           &(ccb.ccb_h),
1345                                                           path, /*priority*/5);
1346                                                         xpt_async(
1347                                                           AC_FOUND_DEVICE,
1348                                                           path,
1349                                                           &ccb);
1350                                                 } else {
1351                                                         xpt_async(
1352                                                           AC_INQ_CHANGED,
1353                                                           path, NULL);
1354                                                         xpt_async(
1355                                                           AC_GETDEV_CHANGED,
1356                                                           path, NULL);
1357                                                 }
1358                                         }
1359                                 }
1360                                 /*
1361                                  *      We have the option of clearing the
1362                                  * cached TID for it to be rescanned, or to
1363                                  * set it now even if the device never got
1364                                  * accessed. We chose the later since we
1365                                  * currently do not use the condition that
1366                                  * the TID ever got cached.
1367                                  */
1368                                 ASR_setTid (sc, bus, target, lun, TID);
1369                         }
1370                 }
1371                 /*
1372                  *      The xpt layer can not handle multiple events at the
1373                  * same call.
1374                  */
1375                 if (event & AC_LOST_DEVICE) {
1376                         xpt_async(AC_LOST_DEVICE, sc->ha_path[bus], NULL);
1377                 }
1378                 if (event & AC_INQ_CHANGED) {
1379                         xpt_async(AC_INQ_CHANGED, sc->ha_path[bus], NULL);
1380                 }
1381                 if (event & AC_GETDEV_CHANGED) {
1382                         xpt_async(AC_GETDEV_CHANGED, sc->ha_path[bus], NULL);
1383                 }
1384         } while (--bus >= 0);
1385         return (error);
1386 } /* ASR_rescan */
1387
1388 /*-------------------------------------------------------------------------*/
1389 /*                    Function ASR_reset                                   */
1390 /*-------------------------------------------------------------------------*/
1391 /* The Parameters Passed To This Function Are :                            */
1392 /*     Asr_softc_t *      : HBA miniport driver's adapter data storage.    */
1393 /*                                                                         */
1394 /* This Function Will reset the adapter and resynchronize any data         */
1395 /*                                                                         */
1396 /* Return : None                                                           */
1397 /*-------------------------------------------------------------------------*/
1398
1399 STATIC INLINE int
1400 ASR_reset(
1401         IN Asr_softc_t * sc)
1402 {
1403         int              retVal;
1404
1405         crit_enter();
1406         if ((sc->ha_in_reset == HA_IN_RESET)
1407          || (sc->ha_in_reset == HA_OFF_LINE_RECOVERY)) {
1408                 crit_exit();
1409                 return (EBUSY);
1410         }
1411         /*
1412          *      Promotes HA_OPERATIONAL to HA_IN_RESET,
1413          * or HA_OFF_LINE to HA_OFF_LINE_RECOVERY.
1414          */
1415         ++(sc->ha_in_reset);
1416         if (ASR_resetIOP (sc->ha_Virt, sc->ha_Fvirt) == 0) {
1417                 debug_asr_printf ("ASR_resetIOP failed\n");
1418                 /*
1419                  *      We really need to take this card off-line, easier said
1420                  * than make sense. Better to keep retrying for now since if a
1421                  * UART cable is connected the blinkLEDs the adapter is now in
1422                  * a hard state requiring action from the monitor commands to
1423                  * the HBA to continue. For debugging waiting forever is a
1424                  * good thing. In a production system, however, one may wish
1425                  * to instead take the card off-line ...
1426                  */
1427 #               if 0 && (defined(HA_OFF_LINE))
1428                         /*
1429                          * Take adapter off-line.
1430                          */
1431                         printf ("asr%d: Taking adapter off-line\n",
1432                           sc->ha_path[0]
1433                             ? cam_sim_unit(xpt_path_sim(sc->ha_path[0]))
1434                             : 0);
1435                         sc->ha_in_reset = HA_OFF_LINE;
1436                         crit_exit();
1437                         return (ENXIO);
1438 #               else
1439                         /* Wait Forever */
1440                         while (ASR_resetIOP (sc->ha_Virt, sc->ha_Fvirt) == 0);
1441 #               endif
1442         }
1443         retVal = ASR_init (sc);
1444         crit_exit();
1445         if (retVal != 0) {
1446                 debug_asr_printf ("ASR_init failed\n");
1447                 sc->ha_in_reset = HA_OFF_LINE;
1448                 return (ENXIO);
1449         }
1450         if (ASR_rescan (sc) != 0) {
1451                 debug_asr_printf ("ASR_rescan failed\n");
1452         }
1453         ASR_failActiveCommands (sc);
1454         if (sc->ha_in_reset == HA_OFF_LINE_RECOVERY) {
1455                 printf ("asr%d: Brining adapter back on-line\n",
1456                   sc->ha_path[0]
1457                     ? cam_sim_unit(xpt_path_sim(sc->ha_path[0]))
1458                     : 0);
1459         }
1460         sc->ha_in_reset = HA_OPERATIONAL;
1461         return (0);
1462 } /* ASR_reset */
1463
1464 /*
1465  *      Device timeout handler.
1466  */
1467 STATIC void
1468 asr_timeout(
1469         INOUT void  * arg)
1470 {
1471         union asr_ccb * ccb = (union asr_ccb *)arg;
1472         Asr_softc_t   * sc = (Asr_softc_t *)(ccb->ccb_h.spriv_ptr0);
1473         int             s;
1474
1475         debug_asr_print_path(ccb);
1476         debug_asr_printf("timed out");
1477
1478         /*
1479          *      Check if the adapter has locked up?
1480          */
1481         if ((s = ASR_getBlinkLedCode(sc)) != 0) {
1482                 /* Reset Adapter */
1483                 printf ("asr%d: Blink LED 0x%x resetting adapter\n",
1484                   cam_sim_unit(xpt_path_sim(ccb->ccb_h.path)), s);
1485                 if (ASR_reset (sc) == ENXIO) {
1486                         /* Try again later */
1487                         callout_reset(&ccb->ccb_h.timeout_ch,
1488                             (ccb->ccb_h.timeout * hz) / 1000, asr_timeout, ccb);
1489                 }
1490                 return;
1491         }
1492         /*
1493          *      Abort does not function on the ASR card!!! Walking away from
1494          * the SCSI command is also *very* dangerous. A SCSI BUS reset is
1495          * our best bet, followed by a complete adapter reset if that fails.
1496          */
1497         crit_enter();
1498         /* Check if we already timed out once to raise the issue */
1499         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_CMD_TIMEOUT) {
1500                 debug_asr_printf (" AGAIN\nreinitializing adapter\n");
1501                 if (ASR_reset (sc) == ENXIO) {
1502                         callout_reset(&ccb->ccb_h.timeout_ch,
1503                             (ccb->ccb_h.timeout * hz) / 1000, asr_timeout, ccb);
1504                 }
1505                 crit_exit();
1506                 return;
1507         }
1508         debug_asr_printf ("\nresetting bus\n");
1509         /* If the BUS reset does not take, then an adapter reset is next! */
1510         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
1511         ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
1512         callout_reset(&ccb->ccb_h.timeout_ch, (ccb->ccb_h.timeout * hz) / 1000,
1513                       asr_timeout, ccb);
1514         ASR_resetBus (sc, cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)));
1515         xpt_async (AC_BUS_RESET, ccb->ccb_h.path, NULL);
1516         crit_exit();
1517 } /* asr_timeout */
1518
1519 /*
1520  * send a message asynchronously
1521  */
1522 STATIC INLINE int
1523 ASR_queue(
1524         IN Asr_softc_t      * sc,
1525         IN PI2O_MESSAGE_FRAME Message)
1526 {
1527         OUT U32               MessageOffset;
1528         union asr_ccb       * ccb;
1529
1530         debug_asr_printf ("Host Command Dump:\n");
1531         debug_asr_dump_message (Message);
1532
1533         ccb = (union asr_ccb *)(long)
1534           I2O_MESSAGE_FRAME_getInitiatorContext64(Message);
1535
1536         if ((MessageOffset = ASR_getMessage(sc->ha_Virt)) != EMPTY_QUEUE) {
1537                 bcopy (Message, sc->ha_Fvirt + MessageOffset,
1538                   I2O_MESSAGE_FRAME_getMessageSize(Message) << 2);
1539                 if (ccb) {
1540                         ASR_ccbAdd (sc, ccb);
1541                 }
1542                 /* Post the command */
1543                 sc->ha_Virt->ToFIFO = MessageOffset;
1544         } else {
1545                 if (ASR_getBlinkLedCode(sc)) {
1546                         /*
1547                          *      Unlikely we can do anything if we can't grab a
1548                          * message frame :-(, but lets give it a try.
1549                          */
1550                         (void)ASR_reset (sc);
1551                 }
1552         }
1553         return (MessageOffset);
1554 } /* ASR_queue */
1555
1556
1557 /* Simple Scatter Gather elements */
1558 #define SG(SGL,Index,Flags,Buffer,Size)                            \
1559         I2O_FLAGS_COUNT_setCount(                                  \
1560           &(((PI2O_SG_ELEMENT)(SGL))->u.Simple[Index].FlagsCount), \
1561           Size);                                                   \
1562         I2O_FLAGS_COUNT_setFlags(                                  \
1563           &(((PI2O_SG_ELEMENT)(SGL))->u.Simple[Index].FlagsCount), \
1564           I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | (Flags));         \
1565         I2O_SGE_SIMPLE_ELEMENT_setPhysicalAddress(                 \
1566           &(((PI2O_SG_ELEMENT)(SGL))->u.Simple[Index]),            \
1567           (Buffer == NULL) ? NULL : KVTOPHYS(Buffer))
1568
1569 /*
1570  *      Retrieve Parameter Group.
1571  *              Buffer must be allocated using defAlignLong macro.
1572  */
1573 STATIC void *
1574 ASR_getParams(
1575         IN Asr_softc_t                     * sc,
1576         IN tid_t                             TID,
1577         IN int                               Group,
1578         OUT void                           * Buffer,
1579         IN unsigned                          BufferSize)
1580 {
1581         struct paramGetMessage {
1582                 I2O_UTIL_PARAMS_GET_MESSAGE M;
1583                 char                         F[
1584                   sizeof(I2O_SGE_SIMPLE_ELEMENT)*2 - sizeof(I2O_SG_ELEMENT)];
1585                 struct Operations {
1586                         I2O_PARAM_OPERATIONS_LIST_HEADER Header;
1587                         I2O_PARAM_OPERATION_ALL_TEMPLATE Template[1];
1588                 }                            O;
1589         };
1590         defAlignLong(struct paramGetMessage, Message);
1591         struct Operations                  * Operations_Ptr;
1592         I2O_UTIL_PARAMS_GET_MESSAGE        * Message_Ptr;
1593         struct ParamBuffer {
1594                 I2O_PARAM_RESULTS_LIST_HEADER       Header;
1595                 I2O_PARAM_READ_OPERATION_RESULT     Read;
1596                 char                                Info[1];
1597         }                                  * Buffer_Ptr;
1598
1599         Message_Ptr = (I2O_UTIL_PARAMS_GET_MESSAGE *)ASR_fillMessage(Message,
1600           sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)
1601             + sizeof(I2O_SGE_SIMPLE_ELEMENT)*2 - sizeof(I2O_SG_ELEMENT));
1602         Operations_Ptr = (struct Operations *)((char *)Message_Ptr
1603           + sizeof(I2O_UTIL_PARAMS_GET_MESSAGE)
1604           + sizeof(I2O_SGE_SIMPLE_ELEMENT)*2 - sizeof(I2O_SG_ELEMENT));
1605         bzero ((void *)Operations_Ptr, sizeof(struct Operations));
1606         I2O_PARAM_OPERATIONS_LIST_HEADER_setOperationCount(
1607           &(Operations_Ptr->Header), 1);
1608         I2O_PARAM_OPERATION_ALL_TEMPLATE_setOperation(
1609           &(Operations_Ptr->Template[0]), I2O_PARAMS_OPERATION_FIELD_GET);
1610         I2O_PARAM_OPERATION_ALL_TEMPLATE_setFieldCount(
1611           &(Operations_Ptr->Template[0]), 0xFFFF);
1612         I2O_PARAM_OPERATION_ALL_TEMPLATE_setGroupNumber(
1613           &(Operations_Ptr->Template[0]), Group);
1614         bzero ((void *)(Buffer_Ptr = getAlignLong(struct ParamBuffer, Buffer)),
1615           BufferSize);
1616
1617         I2O_MESSAGE_FRAME_setVersionOffset(&(Message_Ptr->StdMessageFrame),
1618           I2O_VERSION_11
1619           + (((sizeof(I2O_UTIL_PARAMS_GET_MESSAGE) - sizeof(I2O_SG_ELEMENT))
1620             / sizeof(U32)) << 4));
1621         I2O_MESSAGE_FRAME_setTargetAddress (&(Message_Ptr->StdMessageFrame),
1622           TID);
1623         I2O_MESSAGE_FRAME_setFunction (&(Message_Ptr->StdMessageFrame),
1624           I2O_UTIL_PARAMS_GET);
1625         /*
1626          *  Set up the buffers as scatter gather elements.
1627          */
1628         SG(&(Message_Ptr->SGL), 0,
1629           I2O_SGL_FLAGS_DIR | I2O_SGL_FLAGS_END_OF_BUFFER,
1630           Operations_Ptr, sizeof(struct Operations));
1631         SG(&(Message_Ptr->SGL), 1,
1632           I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER,
1633           Buffer_Ptr, BufferSize);
1634
1635         if ((ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr) == CAM_REQ_CMP)
1636          && (Buffer_Ptr->Header.ResultCount)) {
1637                 return ((void *)(Buffer_Ptr->Info));
1638         }
1639         return ((void *)NULL);
1640 } /* ASR_getParams */
1641
1642 /*
1643  *      Acquire the LCT information.
1644  */
1645 STATIC INLINE int
1646 ASR_acquireLct (
1647         INOUT Asr_softc_t          * sc)
1648 {
1649         PI2O_EXEC_LCT_NOTIFY_MESSAGE Message_Ptr;
1650         PI2O_SGE_SIMPLE_ELEMENT      sg;
1651         int                          MessageSizeInBytes;
1652         caddr_t                      v;
1653         int                          len;
1654         I2O_LCT                      Table;
1655         PI2O_LCT_ENTRY               Entry;
1656
1657         /*
1658          *      sc value assumed valid
1659          */
1660         MessageSizeInBytes = sizeof(I2O_EXEC_LCT_NOTIFY_MESSAGE)
1661           - sizeof(I2O_SG_ELEMENT) + sizeof(I2O_SGE_SIMPLE_ELEMENT);
1662         if ((Message_Ptr = (PI2O_EXEC_LCT_NOTIFY_MESSAGE)kmalloc (
1663           MessageSizeInBytes, M_TEMP, M_WAITOK))
1664           == (PI2O_EXEC_LCT_NOTIFY_MESSAGE)NULL) {
1665                 return (ENOMEM);
1666         }
1667         (void)ASR_fillMessage((char *)Message_Ptr, MessageSizeInBytes);
1668         I2O_MESSAGE_FRAME_setVersionOffset(&(Message_Ptr->StdMessageFrame),
1669           (I2O_VERSION_11 +
1670           (((sizeof(I2O_EXEC_LCT_NOTIFY_MESSAGE) - sizeof(I2O_SG_ELEMENT))
1671                         / sizeof(U32)) << 4)));
1672         I2O_MESSAGE_FRAME_setFunction(&(Message_Ptr->StdMessageFrame),
1673           I2O_EXEC_LCT_NOTIFY);
1674         I2O_EXEC_LCT_NOTIFY_MESSAGE_setClassIdentifier(Message_Ptr,
1675           I2O_CLASS_MATCH_ANYCLASS);
1676         /*
1677          *      Call the LCT table to determine the number of device entries
1678          * to reserve space for.
1679          */
1680         SG(&(Message_Ptr->SGL), 0,
1681           I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER, &Table,
1682           sizeof(I2O_LCT));
1683         /*
1684          *      since this code is reused in several systems, code efficiency
1685          * is greater by using a shift operation rather than a divide by
1686          * sizeof(u_int32_t).
1687          */
1688         I2O_LCT_setTableSize(&Table,
1689           (sizeof(I2O_LCT) - sizeof(I2O_LCT_ENTRY)) >> 2);
1690         (void)ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
1691         /*
1692          *      Determine the size of the LCT table.
1693          */
1694         if (sc->ha_LCT) {
1695                 kfree (sc->ha_LCT, M_TEMP);
1696         }
1697         /*
1698          *      kmalloc only generates contiguous memory when less than a
1699          * page is expected. We must break the request up into an SG list ...
1700          */
1701         if (((len = (I2O_LCT_getTableSize(&Table) << 2)) <=
1702           (sizeof(I2O_LCT) - sizeof(I2O_LCT_ENTRY)))
1703          || (len > (128 * 1024))) {     /* Arbitrary */
1704                 kfree (Message_Ptr, M_TEMP);
1705                 return (EINVAL);
1706         }
1707         if ((sc->ha_LCT = (PI2O_LCT)kmalloc (len, M_TEMP, M_WAITOK))
1708           == (PI2O_LCT)NULL) {
1709                 kfree (Message_Ptr, M_TEMP);
1710                 return (ENOMEM);
1711         }
1712         /*
1713          *      since this code is reused in several systems, code efficiency
1714          * is greater by using a shift operation rather than a divide by
1715          * sizeof(u_int32_t).
1716          */
1717         I2O_LCT_setTableSize(sc->ha_LCT,
1718           (sizeof(I2O_LCT) - sizeof(I2O_LCT_ENTRY)) >> 2);
1719         /*
1720          *      Convert the access to the LCT table into a SG list.
1721          */
1722         sg = Message_Ptr->SGL.u.Simple;
1723         v = (caddr_t)(sc->ha_LCT);
1724         for (;;) {
1725                 int next, base, span;
1726
1727                 span = 0;
1728                 next = base = KVTOPHYS(v);
1729                 I2O_SGE_SIMPLE_ELEMENT_setPhysicalAddress(sg, base);
1730
1731                 /* How far can we go contiguously */
1732                 while ((len > 0) && (base == next)) {
1733                         int size;
1734
1735                         next = trunc_page(base) + PAGE_SIZE;
1736                         size = next - base;
1737                         if (size > len) {
1738                                 size = len;
1739                         }
1740                         span += size;
1741                         v += size;
1742                         len -= size;
1743                         base = KVTOPHYS(v);
1744                 }
1745
1746                 /* Construct the Flags */
1747                 I2O_FLAGS_COUNT_setCount(&(sg->FlagsCount), span);
1748                 {
1749                         int rw = I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT;
1750                         if (len <= 0) {
1751                                 rw = (I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT
1752                                     | I2O_SGL_FLAGS_LAST_ELEMENT
1753                                     | I2O_SGL_FLAGS_END_OF_BUFFER);
1754                         }
1755                         I2O_FLAGS_COUNT_setFlags(&(sg->FlagsCount), rw);
1756                 }
1757
1758                 if (len <= 0) {
1759                         break;
1760                 }
1761
1762                 /*
1763                  * Incrementing requires resizing of the packet.
1764                  */
1765                 ++sg;
1766                 MessageSizeInBytes += sizeof(*sg);
1767                 I2O_MESSAGE_FRAME_setMessageSize(
1768                   &(Message_Ptr->StdMessageFrame),
1769                   I2O_MESSAGE_FRAME_getMessageSize(
1770                     &(Message_Ptr->StdMessageFrame))
1771                   + (sizeof(*sg) / sizeof(U32)));
1772                 {
1773                         PI2O_EXEC_LCT_NOTIFY_MESSAGE NewMessage_Ptr;
1774
1775                         if ((NewMessage_Ptr = (PI2O_EXEC_LCT_NOTIFY_MESSAGE)
1776                             kmalloc (MessageSizeInBytes, M_TEMP, M_WAITOK))
1777                             == (PI2O_EXEC_LCT_NOTIFY_MESSAGE)NULL) {
1778                                 kfree (sc->ha_LCT, M_TEMP);
1779                                 sc->ha_LCT = (PI2O_LCT)NULL;
1780                                 kfree (Message_Ptr, M_TEMP);
1781                                 return (ENOMEM);
1782                         }
1783                         span = ((caddr_t)sg) - (caddr_t)Message_Ptr;
1784                         bcopy ((caddr_t)Message_Ptr,
1785                           (caddr_t)NewMessage_Ptr, span);
1786                         kfree (Message_Ptr, M_TEMP);
1787                         sg = (PI2O_SGE_SIMPLE_ELEMENT)
1788                           (((caddr_t)NewMessage_Ptr) + span);
1789                         Message_Ptr = NewMessage_Ptr;
1790                 }
1791         }
1792         {       int retval;
1793
1794                 retval = ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
1795                 kfree (Message_Ptr, M_TEMP);
1796                 if (retval != CAM_REQ_CMP) {
1797                         return (ENODEV);
1798                 }
1799         }
1800         /* If the LCT table grew, lets truncate accesses */
1801         if (I2O_LCT_getTableSize(&Table) < I2O_LCT_getTableSize(sc->ha_LCT)) {
1802                 I2O_LCT_setTableSize(sc->ha_LCT, I2O_LCT_getTableSize(&Table));
1803         }
1804         for (Entry = sc->ha_LCT->LCTEntry; Entry < (PI2O_LCT_ENTRY)
1805           (((U32 *)sc->ha_LCT)+I2O_LCT_getTableSize(sc->ha_LCT));
1806           ++Entry) {
1807                 Entry->le_type = I2O_UNKNOWN;
1808                 switch (I2O_CLASS_ID_getClass(&(Entry->ClassID))) {
1809
1810                 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
1811                         Entry->le_type = I2O_BSA;
1812                         break;
1813
1814                 case I2O_CLASS_SCSI_PERIPHERAL:
1815                         Entry->le_type = I2O_SCSI;
1816                         break;
1817
1818                 case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
1819                         Entry->le_type = I2O_FCA;
1820                         break;
1821
1822                 case I2O_CLASS_BUS_ADAPTER_PORT:
1823                         Entry->le_type = I2O_PORT | I2O_SCSI;
1824                         /* FALLTHRU */
1825                 case I2O_CLASS_FIBRE_CHANNEL_PORT:
1826                         if (I2O_CLASS_ID_getClass(&(Entry->ClassID)) ==
1827                           I2O_CLASS_FIBRE_CHANNEL_PORT) {
1828                                 Entry->le_type = I2O_PORT | I2O_FCA;
1829                         }
1830                 {       struct ControllerInfo {
1831                                 I2O_PARAM_RESULTS_LIST_HEADER       Header;
1832                                 I2O_PARAM_READ_OPERATION_RESULT     Read;
1833                                 I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR Info;
1834                         };
1835                         defAlignLong(struct ControllerInfo, Buffer);
1836                         PI2O_HBA_SCSI_CONTROLLER_INFO_SCALAR Info;
1837
1838                         Entry->le_bus = 0xff;
1839                         Entry->le_target = 0xff;
1840                         Entry->le_lun = 0xff;
1841
1842                         if ((Info = (PI2O_HBA_SCSI_CONTROLLER_INFO_SCALAR)
1843                           ASR_getParams(sc,
1844                             I2O_LCT_ENTRY_getLocalTID(Entry),
1845                             I2O_HBA_SCSI_CONTROLLER_INFO_GROUP_NO,
1846                             Buffer, sizeof(struct ControllerInfo)))
1847                         == (PI2O_HBA_SCSI_CONTROLLER_INFO_SCALAR)NULL) {
1848                                 continue;
1849                         }
1850                         Entry->le_target
1851                           = I2O_HBA_SCSI_CONTROLLER_INFO_SCALAR_getInitiatorID(
1852                             Info);
1853                         Entry->le_lun = 0;
1854                 }       /* FALLTHRU */
1855                 default:
1856                         continue;
1857                 }
1858                 {       struct DeviceInfo {
1859                                 I2O_PARAM_RESULTS_LIST_HEADER   Header;
1860                                 I2O_PARAM_READ_OPERATION_RESULT Read;
1861                                 I2O_DPT_DEVICE_INFO_SCALAR      Info;
1862                         };
1863                         defAlignLong (struct DeviceInfo, Buffer);
1864                         PI2O_DPT_DEVICE_INFO_SCALAR      Info;
1865
1866                         Entry->le_bus = 0xff;
1867                         Entry->le_target = 0xff;
1868                         Entry->le_lun = 0xff;
1869
1870                         if ((Info = (PI2O_DPT_DEVICE_INFO_SCALAR)
1871                           ASR_getParams(sc,
1872                             I2O_LCT_ENTRY_getLocalTID(Entry),
1873                             I2O_DPT_DEVICE_INFO_GROUP_NO,
1874                             Buffer, sizeof(struct DeviceInfo)))
1875                         == (PI2O_DPT_DEVICE_INFO_SCALAR)NULL) {
1876                                 continue;
1877                         }
1878                         Entry->le_type
1879                           |= I2O_DPT_DEVICE_INFO_SCALAR_getDeviceType(Info);
1880                         Entry->le_bus
1881                           = I2O_DPT_DEVICE_INFO_SCALAR_getBus(Info);
1882                         if ((Entry->le_bus > sc->ha_MaxBus)
1883                          && (Entry->le_bus <= MAX_CHANNEL)) {
1884                                 sc->ha_MaxBus = Entry->le_bus;
1885                         }
1886                         Entry->le_target
1887                           = I2O_DPT_DEVICE_INFO_SCALAR_getIdentifier(Info);
1888                         Entry->le_lun
1889                           = I2O_DPT_DEVICE_INFO_SCALAR_getLunInfo(Info);
1890                 }
1891         }
1892         /*
1893          *      A zero return value indicates success.
1894          */
1895         return (0);
1896 } /* ASR_acquireLct */
1897
1898 /*
1899  * Initialize a message frame.
1900  * We assume that the CDB has already been set up, so all we do here is
1901  * generate the Scatter Gather list.
1902  */
1903 STATIC INLINE PI2O_MESSAGE_FRAME
1904 ASR_init_message(
1905         IN union asr_ccb      * ccb,
1906         OUT PI2O_MESSAGE_FRAME  Message)
1907 {
1908         int                     next, span, base, rw;
1909         OUT PI2O_MESSAGE_FRAME  Message_Ptr;
1910         Asr_softc_t           * sc = (Asr_softc_t *)(ccb->ccb_h.spriv_ptr0);
1911         PI2O_SGE_SIMPLE_ELEMENT sg;
1912         caddr_t                 v;
1913         vm_size_t               size, len;
1914         U32                     MessageSize;
1915
1916         /* We only need to zero out the PRIVATE_SCSI_SCB_EXECUTE_MESSAGE */
1917         bzero (Message_Ptr = getAlignLong(I2O_MESSAGE_FRAME, Message),
1918           (sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE) - sizeof(I2O_SG_ELEMENT)));
1919
1920         {
1921                 int   target = ccb->ccb_h.target_id;
1922                 int   lun = ccb->ccb_h.target_lun;
1923                 int   bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path));
1924                 tid_t TID;
1925
1926                 if ((TID = ASR_getTid (sc, bus, target, lun)) == (tid_t)-1) {
1927                         PI2O_LCT_ENTRY Device;
1928
1929                         TID = (tid_t)0;
1930                         for (Device = sc->ha_LCT->LCTEntry; Device < (PI2O_LCT_ENTRY)
1931                           (((U32 *)sc->ha_LCT)+I2O_LCT_getTableSize(sc->ha_LCT));
1932                           ++Device) {
1933                                 if ((Device->le_type != I2O_UNKNOWN)
1934                                  && (Device->le_bus == bus)
1935                                  && (Device->le_target == target)
1936                                  && (Device->le_lun == lun)
1937                                  && (I2O_LCT_ENTRY_getUserTID(Device) == 0xFFF)) {
1938                                         TID = I2O_LCT_ENTRY_getLocalTID(Device);
1939                                         ASR_setTid (sc, Device->le_bus,
1940                                           Device->le_target, Device->le_lun,
1941                                           TID);
1942                                         break;
1943                                 }
1944                         }
1945                 }
1946                 if (TID == (tid_t)0) {
1947                         return ((PI2O_MESSAGE_FRAME)NULL);
1948                 }
1949                 I2O_MESSAGE_FRAME_setTargetAddress(Message_Ptr, TID);
1950                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setTID(
1951                   (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr, TID);
1952         }
1953         I2O_MESSAGE_FRAME_setVersionOffset(Message_Ptr, I2O_VERSION_11 |
1954           (((sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE) - sizeof(I2O_SG_ELEMENT))
1955                 / sizeof(U32)) << 4));
1956         I2O_MESSAGE_FRAME_setMessageSize(Message_Ptr,
1957           (sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
1958           - sizeof(I2O_SG_ELEMENT)) / sizeof(U32));
1959         I2O_MESSAGE_FRAME_setInitiatorAddress (Message_Ptr, 1);
1960         I2O_MESSAGE_FRAME_setFunction(Message_Ptr, I2O_PRIVATE_MESSAGE);
1961         I2O_PRIVATE_MESSAGE_FRAME_setXFunctionCode (
1962           (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr, I2O_SCSI_SCB_EXEC);
1963         PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (
1964           (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr,
1965             I2O_SCB_FLAG_ENABLE_DISCONNECT
1966           | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
1967           | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER);
1968         /*
1969          * We do not need any (optional byteswapping) method access to
1970          * the Initiator & Transaction context field.
1971          */
1972         I2O_MESSAGE_FRAME_setInitiatorContext64(Message, (long)ccb);
1973
1974         I2O_PRIVATE_MESSAGE_FRAME_setOrganizationID(
1975           (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr, DPT_ORGANIZATION_ID);
1976         /*
1977          * copy the cdb over
1978          */
1979         PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setCDBLength(
1980           (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr, ccb->csio.cdb_len);
1981         bcopy (&(ccb->csio.cdb_io),
1982           ((PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr)->CDB, ccb->csio.cdb_len);
1983
1984         /*
1985          * Given a buffer describing a transfer, set up a scatter/gather map
1986          * in a ccb to map that SCSI transfer.
1987          */
1988
1989         rw = (ccb->ccb_h.flags & CAM_DIR_IN) ? 0 : I2O_SGL_FLAGS_DIR;
1990
1991         PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (
1992           (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr,
1993           (ccb->csio.dxfer_len)
1994             ? ((rw) ? (I2O_SCB_FLAG_XFER_TO_DEVICE
1995                      | I2O_SCB_FLAG_ENABLE_DISCONNECT
1996                      | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
1997                      | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER)
1998                     : (I2O_SCB_FLAG_XFER_FROM_DEVICE
1999                      | I2O_SCB_FLAG_ENABLE_DISCONNECT
2000                      | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2001                      | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER))
2002             :         (I2O_SCB_FLAG_ENABLE_DISCONNECT
2003                      | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2004                      | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER));
2005
2006         /*
2007          * Given a transfer described by a `data', fill in the SG list.
2008          */
2009         sg = &((PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr)->SGL.u.Simple[0];
2010
2011         len = ccb->csio.dxfer_len;
2012         v = ccb->csio.data_ptr;
2013         ASSERT (ccb->csio.dxfer_len >= 0);
2014         MessageSize = I2O_MESSAGE_FRAME_getMessageSize(Message_Ptr);
2015         PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setByteCount(
2016           (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr, len);
2017         while ((len > 0) && (sg < &((PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2018           Message_Ptr)->SGL.u.Simple[SG_SIZE])) {
2019                 span = 0;
2020                 next = base = KVTOPHYS(v);
2021                 I2O_SGE_SIMPLE_ELEMENT_setPhysicalAddress(sg, base);
2022
2023                 /* How far can we go contiguously */
2024                 while ((len > 0) && (base == next)) {
2025                         next = trunc_page(base) + PAGE_SIZE;
2026                         size = next - base;
2027                         if (size > len) {
2028                                 size = len;
2029                         }
2030                         span += size;
2031                         v += size;
2032                         len -= size;
2033                         base = KVTOPHYS(v);
2034                 }
2035
2036                 I2O_FLAGS_COUNT_setCount(&(sg->FlagsCount), span);
2037                 if (len == 0) {
2038                         rw |= I2O_SGL_FLAGS_LAST_ELEMENT;
2039                 }
2040                 I2O_FLAGS_COUNT_setFlags(&(sg->FlagsCount),
2041                   I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT | rw);
2042                 ++sg;
2043                 MessageSize += sizeof(*sg) / sizeof(U32);
2044         }
2045         /* We always do the request sense ... */
2046         if ((span = ccb->csio.sense_len) == 0) {
2047                 span = sizeof(ccb->csio.sense_data);
2048         }
2049         SG(sg, 0, I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER,
2050           &(ccb->csio.sense_data), span);
2051         I2O_MESSAGE_FRAME_setMessageSize(Message_Ptr,
2052           MessageSize + (sizeof(*sg) / sizeof(U32)));
2053         return (Message_Ptr);
2054 } /* ASR_init_message */
2055
2056 /*
2057  *      Reset the adapter.
2058  */
2059 STATIC INLINE U32
2060 ASR_initOutBound (
2061         INOUT Asr_softc_t                     * sc)
2062 {
2063         struct initOutBoundMessage {
2064                 I2O_EXEC_OUTBOUND_INIT_MESSAGE M;
2065                 U32                            R;
2066         };
2067         defAlignLong(struct initOutBoundMessage,Message);
2068         PI2O_EXEC_OUTBOUND_INIT_MESSAGE         Message_Ptr;
2069         OUT U32                      * volatile Reply_Ptr;
2070         U32                                     Old;
2071
2072         /*
2073          *  Build up our copy of the Message.
2074          */
2075         Message_Ptr = (PI2O_EXEC_OUTBOUND_INIT_MESSAGE)ASR_fillMessage(Message,
2076           sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE));
2077         I2O_MESSAGE_FRAME_setFunction(&(Message_Ptr->StdMessageFrame),
2078           I2O_EXEC_OUTBOUND_INIT);
2079         I2O_EXEC_OUTBOUND_INIT_MESSAGE_setHostPageFrameSize(Message_Ptr, PAGE_SIZE);
2080         I2O_EXEC_OUTBOUND_INIT_MESSAGE_setOutboundMFrameSize(Message_Ptr,
2081           sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME));
2082         /*
2083          *  Reset the Reply Status
2084          */
2085         *(Reply_Ptr = (U32 *)((char *)Message_Ptr
2086           + sizeof(I2O_EXEC_OUTBOUND_INIT_MESSAGE))) = 0;
2087         SG (&(Message_Ptr->SGL), 0, I2O_SGL_FLAGS_LAST_ELEMENT, Reply_Ptr,
2088           sizeof(U32));
2089         /*
2090          *      Send the Message out
2091          */
2092         if ((Old = ASR_initiateCp (sc->ha_Virt, sc->ha_Fvirt, (PI2O_MESSAGE_FRAME)Message_Ptr)) != (U32)-1L) {
2093                 u_long size, addr;
2094
2095                 /*
2096                  *      Wait for a response (Poll).
2097                  */
2098                 while (*Reply_Ptr < I2O_EXEC_OUTBOUND_INIT_REJECTED);
2099                 /*
2100                  *      Re-enable the interrupts.
2101                  */
2102                 sc->ha_Virt->Mask = Old;
2103                 /*
2104                  *      Populate the outbound table.
2105                  */
2106                 if (sc->ha_Msgs == (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)NULL) {
2107
2108                         /* Allocate the reply frames */
2109                         size = sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)
2110                           * sc->ha_Msgs_Count;
2111
2112                         /*
2113                          *      contigmalloc only works reliably at
2114                          * initialization time.
2115                          */
2116                         if ((sc->ha_Msgs = (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)
2117                           contigmalloc (size, M_DEVBUF, M_WAITOK, 0ul,
2118                             0xFFFFFFFFul, (u_long)sizeof(U32), 0ul))
2119                           != (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)NULL) {
2120                                 (void)bzero ((char *)sc->ha_Msgs, size);
2121                                 sc->ha_Msgs_Phys = KVTOPHYS(sc->ha_Msgs);
2122                         }
2123                 }
2124
2125                 /* Initialize the outbound FIFO */
2126                 if (sc->ha_Msgs != (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)NULL)
2127                 for (size = sc->ha_Msgs_Count, addr = sc->ha_Msgs_Phys;
2128                   size; --size) {
2129                         sc->ha_Virt->FromFIFO = addr;
2130                         addr += sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME);
2131                 }
2132                 return (*Reply_Ptr);
2133         }
2134         return (0);
2135 } /* ASR_initOutBound */
2136
2137 /*
2138  *      Set the system table
2139  */
2140 STATIC INLINE int
2141 ASR_setSysTab(
2142         IN Asr_softc_t              * sc)
2143 {
2144         PI2O_EXEC_SYS_TAB_SET_MESSAGE Message_Ptr;
2145         PI2O_SET_SYSTAB_HEADER        SystemTable;
2146         Asr_softc_t                 * ha;
2147         PI2O_SGE_SIMPLE_ELEMENT       sg;
2148         int                           retVal;
2149
2150         if ((SystemTable = (PI2O_SET_SYSTAB_HEADER)kmalloc (
2151           sizeof(I2O_SET_SYSTAB_HEADER), M_TEMP, M_WAITOK))
2152           == (PI2O_SET_SYSTAB_HEADER)NULL) {
2153                 return (ENOMEM);
2154         }
2155         bzero (SystemTable, sizeof(I2O_SET_SYSTAB_HEADER));
2156         for (ha = Asr_softc; ha; ha = ha->ha_next) {
2157                 ++SystemTable->NumberEntries;
2158         }
2159         if ((Message_Ptr = (PI2O_EXEC_SYS_TAB_SET_MESSAGE)kmalloc (
2160           sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE) - sizeof(I2O_SG_ELEMENT)
2161            + ((3+SystemTable->NumberEntries) * sizeof(I2O_SGE_SIMPLE_ELEMENT)),
2162           M_TEMP, M_WAITOK)) == (PI2O_EXEC_SYS_TAB_SET_MESSAGE)NULL) {
2163                 kfree (SystemTable, M_TEMP);
2164                 return (ENOMEM);
2165         }
2166         (void)ASR_fillMessage((char *)Message_Ptr,
2167           sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE) - sizeof(I2O_SG_ELEMENT)
2168            + ((3+SystemTable->NumberEntries) * sizeof(I2O_SGE_SIMPLE_ELEMENT)));
2169         I2O_MESSAGE_FRAME_setVersionOffset(&(Message_Ptr->StdMessageFrame),
2170           (I2O_VERSION_11 +
2171           (((sizeof(I2O_EXEC_SYS_TAB_SET_MESSAGE) - sizeof(I2O_SG_ELEMENT))
2172                         / sizeof(U32)) << 4)));
2173         I2O_MESSAGE_FRAME_setFunction(&(Message_Ptr->StdMessageFrame),
2174           I2O_EXEC_SYS_TAB_SET);
2175         /*
2176          *      Call the LCT table to determine the number of device entries
2177          * to reserve space for.
2178          *      since this code is reused in several systems, code efficiency
2179          * is greater by using a shift operation rather than a divide by
2180          * sizeof(u_int32_t).
2181          */
2182         sg = (PI2O_SGE_SIMPLE_ELEMENT)((char *)Message_Ptr
2183           + ((I2O_MESSAGE_FRAME_getVersionOffset(
2184               &(Message_Ptr->StdMessageFrame)) & 0xF0) >> 2));
2185         SG(sg, 0, I2O_SGL_FLAGS_DIR, SystemTable, sizeof(I2O_SET_SYSTAB_HEADER));
2186         ++sg;
2187         for (ha = Asr_softc; ha; ha = ha->ha_next) {
2188                 SG(sg, 0,
2189                   ((ha->ha_next)
2190                     ? (I2O_SGL_FLAGS_DIR)
2191                     : (I2O_SGL_FLAGS_DIR | I2O_SGL_FLAGS_END_OF_BUFFER)),
2192                   &(ha->ha_SystemTable), sizeof(ha->ha_SystemTable));
2193                 ++sg;
2194         }
2195         SG(sg, 0, I2O_SGL_FLAGS_DIR | I2O_SGL_FLAGS_END_OF_BUFFER, NULL, 0);
2196         SG(sg, 1, I2O_SGL_FLAGS_DIR | I2O_SGL_FLAGS_LAST_ELEMENT
2197             | I2O_SGL_FLAGS_END_OF_BUFFER, NULL, 0);
2198         retVal = ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
2199         kfree (Message_Ptr, M_TEMP);
2200         kfree (SystemTable, M_TEMP);
2201         return (retVal);
2202 } /* ASR_setSysTab */
2203
2204 STATIC INLINE int
2205 ASR_acquireHrt (
2206         INOUT Asr_softc_t                   * sc)
2207 {
2208         defAlignLong(I2O_EXEC_HRT_GET_MESSAGE,Message);
2209         I2O_EXEC_HRT_GET_MESSAGE *            Message_Ptr;
2210         struct {
2211                 I2O_HRT       Header;
2212                 I2O_HRT_ENTRY Entry[MAX_CHANNEL];
2213         }                                     Hrt;
2214         u_int8_t                              NumberOfEntries;
2215         PI2O_HRT_ENTRY                        Entry;
2216
2217         bzero ((void *)&Hrt, sizeof (Hrt));
2218         Message_Ptr = (I2O_EXEC_HRT_GET_MESSAGE *)ASR_fillMessage(Message,
2219           sizeof(I2O_EXEC_HRT_GET_MESSAGE) - sizeof(I2O_SG_ELEMENT)
2220           + sizeof(I2O_SGE_SIMPLE_ELEMENT));
2221         I2O_MESSAGE_FRAME_setVersionOffset(&(Message_Ptr->StdMessageFrame),
2222           (I2O_VERSION_11
2223           + (((sizeof(I2O_EXEC_HRT_GET_MESSAGE) - sizeof(I2O_SG_ELEMENT))
2224                    / sizeof(U32)) << 4)));
2225         I2O_MESSAGE_FRAME_setFunction (&(Message_Ptr->StdMessageFrame),
2226           I2O_EXEC_HRT_GET);
2227
2228         /*
2229          *  Set up the buffers as scatter gather elements.
2230          */
2231         SG(&(Message_Ptr->SGL), 0,
2232           I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER,
2233           &Hrt, sizeof(Hrt));
2234         if (ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr) != CAM_REQ_CMP) {
2235                 return (ENODEV);
2236         }
2237         if ((NumberOfEntries = I2O_HRT_getNumberEntries(&Hrt.Header))
2238           > (MAX_CHANNEL + 1)) {
2239                 NumberOfEntries = MAX_CHANNEL + 1;
2240         }
2241         for (Entry = Hrt.Header.HRTEntry;
2242           NumberOfEntries != 0;
2243           ++Entry, --NumberOfEntries) {
2244                 PI2O_LCT_ENTRY Device;
2245
2246                 for (Device = sc->ha_LCT->LCTEntry; Device < (PI2O_LCT_ENTRY)
2247                   (((U32 *)sc->ha_LCT)+I2O_LCT_getTableSize(sc->ha_LCT));
2248                   ++Device) {
2249                         if (I2O_LCT_ENTRY_getLocalTID(Device)
2250                           == (I2O_HRT_ENTRY_getAdapterID(Entry) & 0xFFF)) {
2251                                 Device->le_bus = I2O_HRT_ENTRY_getAdapterID(
2252                                   Entry) >> 16;
2253                                 if ((Device->le_bus > sc->ha_MaxBus)
2254                                  && (Device->le_bus <= MAX_CHANNEL)) {
2255                                         sc->ha_MaxBus = Device->le_bus;
2256                                 }
2257                         }
2258                 }
2259         }
2260         return (0);
2261 } /* ASR_acquireHrt */
2262
2263 /*
2264  *      Enable the adapter.
2265  */
2266 STATIC INLINE int
2267 ASR_enableSys (
2268         IN Asr_softc_t                         * sc)
2269 {
2270         defAlignLong(I2O_EXEC_SYS_ENABLE_MESSAGE,Message);
2271         PI2O_EXEC_SYS_ENABLE_MESSAGE             Message_Ptr;
2272
2273         Message_Ptr = (PI2O_EXEC_SYS_ENABLE_MESSAGE)ASR_fillMessage(Message,
2274           sizeof(I2O_EXEC_SYS_ENABLE_MESSAGE));
2275         I2O_MESSAGE_FRAME_setFunction(&(Message_Ptr->StdMessageFrame),
2276           I2O_EXEC_SYS_ENABLE);
2277         return (ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr) != 0);
2278 } /* ASR_enableSys */
2279
2280 /*
2281  *      Perform the stages necessary to initialize the adapter
2282  */
2283 STATIC int
2284 ASR_init(
2285         IN Asr_softc_t * sc)
2286 {
2287         return ((ASR_initOutBound(sc) == 0)
2288          || (ASR_setSysTab(sc) != CAM_REQ_CMP)
2289          || (ASR_enableSys(sc) != CAM_REQ_CMP));
2290 } /* ASR_init */
2291
2292 /*
2293  *      Send a Synchronize Cache command to the target device.
2294  */
2295 STATIC INLINE void
2296 ASR_sync (
2297         IN Asr_softc_t * sc,
2298         IN int           bus,
2299         IN int           target,
2300         IN int           lun)
2301 {
2302         tid_t            TID;
2303
2304         /*
2305          * We will not synchronize the device when there are outstanding
2306          * commands issued by the OS (this is due to a locked up device,
2307          * as the OS normally would flush all outstanding commands before
2308          * issuing a shutdown or an adapter reset).
2309          */
2310         if ((sc != (Asr_softc_t *)NULL)
2311          && (LIST_FIRST(&(sc->ha_ccb)) != (struct ccb_hdr *)NULL)
2312          && ((TID = ASR_getTid (sc, bus, target, lun)) != (tid_t)-1)
2313          && (TID != (tid_t)0)) {
2314                 defAlignLong(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE,Message);
2315                 PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE             Message_Ptr;
2316
2317                 bzero (Message_Ptr
2318                   = getAlignLong(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE, Message),
2319                   sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2320                   - sizeof(I2O_SG_ELEMENT) + sizeof(I2O_SGE_SIMPLE_ELEMENT));
2321
2322                 I2O_MESSAGE_FRAME_setVersionOffset(
2323                   (PI2O_MESSAGE_FRAME)Message_Ptr,
2324                   I2O_VERSION_11
2325                     | (((sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2326                     - sizeof(I2O_SG_ELEMENT))
2327                         / sizeof(U32)) << 4));
2328                 I2O_MESSAGE_FRAME_setMessageSize(
2329                   (PI2O_MESSAGE_FRAME)Message_Ptr,
2330                   (sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2331                   - sizeof(I2O_SG_ELEMENT))
2332                         / sizeof(U32));
2333                 I2O_MESSAGE_FRAME_setInitiatorAddress (
2334                   (PI2O_MESSAGE_FRAME)Message_Ptr, 1);
2335                 I2O_MESSAGE_FRAME_setFunction(
2336                   (PI2O_MESSAGE_FRAME)Message_Ptr, I2O_PRIVATE_MESSAGE);
2337                 I2O_MESSAGE_FRAME_setTargetAddress(
2338                   (PI2O_MESSAGE_FRAME)Message_Ptr, TID);
2339                 I2O_PRIVATE_MESSAGE_FRAME_setXFunctionCode (
2340                   (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr,
2341                   I2O_SCSI_SCB_EXEC);
2342                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setTID(Message_Ptr, TID);
2343                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (Message_Ptr,
2344                     I2O_SCB_FLAG_ENABLE_DISCONNECT
2345                   | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2346                   | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER);
2347                 I2O_PRIVATE_MESSAGE_FRAME_setOrganizationID(
2348                   (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr,
2349                   DPT_ORGANIZATION_ID);
2350                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setCDBLength(Message_Ptr, 6);
2351                 Message_Ptr->CDB[0] = SYNCHRONIZE_CACHE;
2352                 Message_Ptr->CDB[1] = (lun << 5);
2353
2354                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (Message_Ptr,
2355                   (I2O_SCB_FLAG_XFER_FROM_DEVICE
2356                     | I2O_SCB_FLAG_ENABLE_DISCONNECT
2357                     | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2358                     | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER));
2359
2360                 (void)ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
2361
2362         }
2363 }
2364
2365 STATIC INLINE void
2366 ASR_synchronize (
2367         IN Asr_softc_t * sc)
2368 {
2369         int              bus, target, lun;
2370
2371         for (bus = 0; bus <= sc->ha_MaxBus; ++bus) {
2372                 for (target = 0; target <= sc->ha_MaxId; ++target) {
2373                         for (lun = 0; lun <= sc->ha_MaxLun; ++lun) {
2374                                 ASR_sync(sc,bus,target,lun);
2375                         }
2376                 }
2377         }
2378 }
2379
2380 /*
2381  *      Reset the HBA, targets and BUS.
2382  *              Currently this resets *all* the SCSI busses.
2383  */
2384 STATIC INLINE void
2385 asr_hbareset(
2386         IN Asr_softc_t * sc)
2387 {
2388         ASR_synchronize (sc);
2389         (void)ASR_reset (sc);
2390 } /* asr_hbareset */
2391
2392 /*
2393  *      A reduced copy of the real pci_map_mem, incorporating the MAX_MAP
2394  * limit and a reduction in error checking (in the pre 4.0 case).
2395  */
2396 STATIC int
2397 asr_pci_map_mem (
2398         IN device_t      tag,
2399         IN Asr_softc_t * sc)
2400 {
2401         int              rid;
2402         u_int32_t        p, l, s;
2403
2404         /*
2405          * I2O specification says we must find first *memory* mapped BAR
2406          */
2407         for (rid = PCIR_MAPS;
2408           rid < (PCIR_MAPS + 4 * sizeof(u_int32_t));
2409           rid += sizeof(u_int32_t)) {
2410                 p = pci_read_config(tag, rid, sizeof(p));
2411                 if ((p & 1) == 0) {
2412                         break;
2413                 }
2414         }
2415         /*
2416          *      Give up?
2417          */
2418         if (rid >= (PCIR_MAPS + 4 * sizeof(u_int32_t))) {
2419                 rid = PCIR_MAPS;
2420         }
2421         p = pci_read_config(tag, rid, sizeof(p));
2422         pci_write_config(tag, rid, -1, sizeof(p));
2423         l = 0 - (pci_read_config(tag, rid, sizeof(l)) & ~15);
2424         pci_write_config(tag, rid, p, sizeof(p));
2425         if (l > MAX_MAP) {
2426                 l = MAX_MAP;
2427         }
2428         /*
2429          * The 2005S Zero Channel RAID solution is not a perfect PCI
2430          * citizen. It asks for 4MB on BAR0, and 0MB on BAR1, once
2431          * enabled it rewrites the size of BAR0 to 2MB, sets BAR1 to
2432          * BAR0+2MB and sets it's size to 2MB. The IOP registers are
2433          * accessible via BAR0, the messaging registers are accessible
2434          * via BAR1. If the subdevice code is 50 to 59 decimal.
2435          */
2436         s = pci_read_config(tag, PCIR_DEVVENDOR, sizeof(s));
2437         if (s != 0xA5111044) {
2438                 s = pci_read_config(tag, PCIR_SUBVEND_0, sizeof(s));
2439                 if ((((ADPTDOMINATOR_SUB_ID_START ^ s) & 0xF000FFFF) == 0)
2440                  && (ADPTDOMINATOR_SUB_ID_START <= s)
2441                  && (s <= ADPTDOMINATOR_SUB_ID_END)) {
2442                         l = MAX_MAP; /* Conjoined BAR Raptor Daptor */
2443                 }
2444         }
2445         p &= ~15;
2446         sc->ha_mem_res = bus_alloc_resource(tag, SYS_RES_MEMORY, &rid,
2447           p, p + l, l, RF_ACTIVE);
2448         if (sc->ha_mem_res == (struct resource *)NULL) {
2449                 return (0);
2450         }
2451         sc->ha_Base = (void *)rman_get_start(sc->ha_mem_res);
2452         if (sc->ha_Base == (void *)NULL) {
2453                 return (0);
2454         }
2455         sc->ha_Virt = (i2oRegs_t *) rman_get_virtual(sc->ha_mem_res);
2456         if (s == 0xA5111044) { /* Split BAR Raptor Daptor */
2457                 if ((rid += sizeof(u_int32_t))
2458                   >= (PCIR_MAPS + 4 * sizeof(u_int32_t))) {
2459                         return (0);
2460                 }
2461                 p = pci_read_config(tag, rid, sizeof(p));
2462                 pci_write_config(tag, rid, -1, sizeof(p));
2463                 l = 0 - (pci_read_config(tag, rid, sizeof(l)) & ~15);
2464                 pci_write_config(tag, rid, p, sizeof(p));
2465                 if (l > MAX_MAP) {
2466                         l = MAX_MAP;
2467                 }
2468                 p &= ~15;
2469                 sc->ha_mes_res = bus_alloc_resource(tag, SYS_RES_MEMORY, &rid,
2470                   p, p + l, l, RF_ACTIVE);
2471                 if (sc->ha_mes_res == (struct resource *)NULL) {
2472                         return (0);
2473                 }
2474                 if ((void *)rman_get_start(sc->ha_mes_res) == (void *)NULL) {
2475                         return (0);
2476                 }
2477                 sc->ha_Fvirt = (U8 *) rman_get_virtual(sc->ha_mes_res);
2478         } else {
2479                 sc->ha_Fvirt = (U8 *)(sc->ha_Virt);
2480         }
2481         return (1);
2482 } /* asr_pci_map_mem */
2483
2484 /*
2485  *      A simplified copy of the real pci_map_int with additional
2486  * registration requirements.
2487  */
2488 STATIC int
2489 asr_pci_map_int (
2490         IN device_t      tag,
2491         IN Asr_softc_t * sc)
2492 {
2493         int rid = 0;
2494         int error;
2495
2496         sc->ha_irq_res = bus_alloc_resource(tag, SYS_RES_IRQ, &rid,
2497           0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
2498         if (sc->ha_irq_res == (struct resource *)NULL) {
2499                 return (0);
2500         }
2501         error = bus_setup_intr(tag, sc->ha_irq_res, 0,
2502                               (driver_intr_t *)asr_intr, (void *)sc, 
2503                               &(sc->ha_intr), NULL);
2504         if (error) {
2505                 return (0);
2506         }
2507         sc->ha_irq = pci_read_config(tag, PCIR_INTLINE, sizeof(char));
2508         return (1);
2509 } /* asr_pci_map_int */
2510
2511 /*
2512  *      Attach the devices, and virtual devices to the driver list.
2513  */
2514 STATIC ATTACH_RET
2515 asr_attach (ATTACH_ARGS)
2516 {
2517         Asr_softc_t              * sc;
2518         struct scsi_inquiry_data * iq;
2519         ATTACH_SET();
2520
2521         sc = kmalloc(sizeof(*sc), M_DEVBUF, M_INTWAIT);
2522         if (Asr_softc == (Asr_softc_t *)NULL) {
2523                 /*
2524                  *      Fixup the OS revision as saved in the dptsig for the
2525                  *      engine (dptioctl.h) to pick up.
2526                  */
2527                 bcopy (osrelease, &ASR_sig.dsDescription[16], 5);
2528                 printf ("asr%d: major=%d\n", unit, asr_ops.head.maj);
2529         }
2530         /*
2531          *      Initialize the software structure
2532          */
2533         bzero (sc, sizeof(*sc));
2534         LIST_INIT(&(sc->ha_ccb));
2535         /* Link us into the HA list */
2536         {
2537                 Asr_softc_t **ha;
2538
2539                 for (ha = &Asr_softc; *ha; ha = &((*ha)->ha_next));
2540                 *(ha) = sc;
2541         }
2542         {
2543                 PI2O_EXEC_STATUS_GET_REPLY status;
2544                 int size;
2545
2546                 /*
2547                  *      This is the real McCoy!
2548                  */
2549                 if (!asr_pci_map_mem(tag, sc)) {
2550                         printf ("asr%d: could not map memory\n", unit);
2551                         ATTACH_RETURN(ENXIO);
2552                 }
2553                 /* Enable if not formerly enabled */
2554                 pci_write_config (tag, PCIR_COMMAND,
2555                   pci_read_config (tag, PCIR_COMMAND, sizeof(char))
2556                   | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN, sizeof(char));
2557                 /* Knowledge is power, responsibility is direct */
2558                 {
2559                         struct pci_devinfo {
2560                                 STAILQ_ENTRY(pci_devinfo) pci_links;
2561                                 struct resource_list      resources;
2562                                 pcicfgregs                cfg;
2563                         } * dinfo = device_get_ivars(tag);
2564                         sc->ha_pciBusNum = dinfo->cfg.bus;
2565                         sc->ha_pciDeviceNum = (dinfo->cfg.slot << 3)
2566                                             | dinfo->cfg.func;
2567                 }
2568                 /* Check if the device is there? */
2569                 if ((ASR_resetIOP(sc->ha_Virt, sc->ha_Fvirt) == 0)
2570                  || ((status = (PI2O_EXEC_STATUS_GET_REPLY)kmalloc (
2571                   sizeof(I2O_EXEC_STATUS_GET_REPLY), M_TEMP, M_WAITOK))
2572                   == (PI2O_EXEC_STATUS_GET_REPLY)NULL)
2573                  || (ASR_getStatus(sc->ha_Virt, sc->ha_Fvirt, status) == NULL)) {
2574                         printf ("asr%d: could not initialize hardware\n", unit);
2575                         ATTACH_RETURN(ENODEV);  /* Get next, maybe better luck */
2576                 }
2577                 sc->ha_SystemTable.OrganizationID = status->OrganizationID;
2578                 sc->ha_SystemTable.IOP_ID = status->IOP_ID;
2579                 sc->ha_SystemTable.I2oVersion = status->I2oVersion;
2580                 sc->ha_SystemTable.IopState = status->IopState;
2581                 sc->ha_SystemTable.MessengerType = status->MessengerType;
2582                 sc->ha_SystemTable.InboundMessageFrameSize
2583                   = status->InboundMFrameSize;
2584                 sc->ha_SystemTable.MessengerInfo.InboundMessagePortAddressLow
2585                   = (U32)(sc->ha_Base) + (U32)(&(((i2oRegs_t *)NULL)->ToFIFO));
2586
2587                 if (!asr_pci_map_int(tag, (void *)sc)) {
2588                         printf ("asr%d: could not map interrupt\n", unit);
2589                         ATTACH_RETURN(ENXIO);
2590                 }
2591
2592                 /* Adjust the maximim inbound count */
2593                 if (((sc->ha_QueueSize
2594                   = I2O_EXEC_STATUS_GET_REPLY_getMaxInboundMFrames(status))
2595                      > MAX_INBOUND)
2596                  || (sc->ha_QueueSize == 0)) {
2597                         sc->ha_QueueSize = MAX_INBOUND;
2598                 }
2599
2600                 /* Adjust the maximum outbound count */
2601                 if (((sc->ha_Msgs_Count
2602                   = I2O_EXEC_STATUS_GET_REPLY_getMaxOutboundMFrames(status))
2603                      > MAX_OUTBOUND)
2604                  || (sc->ha_Msgs_Count == 0)) {
2605                         sc->ha_Msgs_Count = MAX_OUTBOUND;
2606                 }
2607                 if (sc->ha_Msgs_Count > sc->ha_QueueSize) {
2608                         sc->ha_Msgs_Count = sc->ha_QueueSize;
2609                 }
2610
2611                 /* Adjust the maximum SG size to adapter */
2612                 if ((size = (I2O_EXEC_STATUS_GET_REPLY_getInboundMFrameSize(
2613                   status) << 2)) > MAX_INBOUND_SIZE) {
2614                         size = MAX_INBOUND_SIZE;
2615                 }
2616                 kfree (status, M_TEMP);
2617                 sc->ha_SgSize = (size - sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2618                   + sizeof(I2O_SG_ELEMENT)) / sizeof(I2O_SGE_SIMPLE_ELEMENT);
2619         }
2620
2621         /*
2622          *      Only do a bus/HBA reset on the first time through. On this
2623          * first time through, we do not send a flush to the devices.
2624          */
2625         if (ASR_init(sc) == 0) {
2626                 struct BufferInfo {
2627                         I2O_PARAM_RESULTS_LIST_HEADER       Header;
2628                         I2O_PARAM_READ_OPERATION_RESULT     Read;
2629                         I2O_DPT_EXEC_IOP_BUFFERS_SCALAR     Info;
2630                 };
2631                 defAlignLong (struct BufferInfo, Buffer);
2632                 PI2O_DPT_EXEC_IOP_BUFFERS_SCALAR Info;
2633 #                       define FW_DEBUG_BLED_OFFSET 8
2634
2635                 if ((Info = (PI2O_DPT_EXEC_IOP_BUFFERS_SCALAR)
2636                   ASR_getParams(sc, 0,
2637                     I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO,
2638                     Buffer, sizeof(struct BufferInfo)))
2639                 != (PI2O_DPT_EXEC_IOP_BUFFERS_SCALAR)NULL) {
2640                         sc->ha_blinkLED = sc->ha_Fvirt
2641                           + I2O_DPT_EXEC_IOP_BUFFERS_SCALAR_getSerialOutputOffset(Info)
2642                           + FW_DEBUG_BLED_OFFSET;
2643                 }
2644                 if (ASR_acquireLct(sc) == 0) {
2645                         (void)ASR_acquireHrt(sc);
2646                 }
2647         } else {
2648                 printf ("asr%d: failed to initialize\n", unit);
2649                 ATTACH_RETURN(ENXIO);
2650         }
2651         /*
2652          *      Add in additional probe responses for more channels. We
2653          * are reusing the variable `target' for a channel loop counter.
2654          * Done here because of we need both the acquireLct and
2655          * acquireHrt data.
2656          */
2657         {       PI2O_LCT_ENTRY Device;
2658
2659                 for (Device = sc->ha_LCT->LCTEntry; Device < (PI2O_LCT_ENTRY)
2660                   (((U32 *)sc->ha_LCT)+I2O_LCT_getTableSize(sc->ha_LCT));
2661                   ++Device) {
2662                         if (Device->le_type == I2O_UNKNOWN) {
2663                                 continue;
2664                         }
2665                         if (I2O_LCT_ENTRY_getUserTID(Device) == 0xFFF) {
2666                                 if (Device->le_target > sc->ha_MaxId) {
2667                                         sc->ha_MaxId = Device->le_target;
2668                                 }
2669                                 if (Device->le_lun > sc->ha_MaxLun) {
2670                                         sc->ha_MaxLun = Device->le_lun;
2671                                 }
2672                         }
2673                         if (((Device->le_type & I2O_PORT) != 0)
2674                          && (Device->le_bus <= MAX_CHANNEL)) {
2675                                 /* Do not increase MaxId for efficiency */
2676                                 sc->ha_adapter_target[Device->le_bus]
2677                                         = Device->le_target;
2678                         }
2679                 }
2680         }
2681
2682
2683         /*
2684          *      Print the HBA model number as inquired from the card.
2685          */
2686
2687         printf ("asr%d:", unit);
2688
2689         if ((iq = (struct scsi_inquiry_data *)kmalloc (
2690             sizeof(struct scsi_inquiry_data), M_TEMP, M_WAITOK))
2691           != (struct scsi_inquiry_data *)NULL) {
2692                 defAlignLong(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE,Message);
2693                 PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE             Message_Ptr;
2694                 int                                           posted = 0;
2695
2696                 bzero (iq, sizeof(struct scsi_inquiry_data));
2697                 bzero (Message_Ptr
2698                   = getAlignLong(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE, Message),
2699                   sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2700                   - sizeof(I2O_SG_ELEMENT) + sizeof(I2O_SGE_SIMPLE_ELEMENT));
2701
2702                 I2O_MESSAGE_FRAME_setVersionOffset(
2703                   (PI2O_MESSAGE_FRAME)Message_Ptr,
2704                   I2O_VERSION_11
2705                     | (((sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2706                     - sizeof(I2O_SG_ELEMENT))
2707                         / sizeof(U32)) << 4));
2708                 I2O_MESSAGE_FRAME_setMessageSize(
2709                   (PI2O_MESSAGE_FRAME)Message_Ptr,
2710                   (sizeof(PRIVATE_SCSI_SCB_EXECUTE_MESSAGE)
2711                   - sizeof(I2O_SG_ELEMENT) + sizeof(I2O_SGE_SIMPLE_ELEMENT))
2712                         / sizeof(U32));
2713                 I2O_MESSAGE_FRAME_setInitiatorAddress (
2714                   (PI2O_MESSAGE_FRAME)Message_Ptr, 1);
2715                 I2O_MESSAGE_FRAME_setFunction(
2716                   (PI2O_MESSAGE_FRAME)Message_Ptr, I2O_PRIVATE_MESSAGE);
2717                 I2O_PRIVATE_MESSAGE_FRAME_setXFunctionCode (
2718                   (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr,
2719                   I2O_SCSI_SCB_EXEC);
2720                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (Message_Ptr,
2721                     I2O_SCB_FLAG_ENABLE_DISCONNECT
2722                   | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2723                   | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER);
2724                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setInterpret(Message_Ptr, 1);
2725                 I2O_PRIVATE_MESSAGE_FRAME_setOrganizationID(
2726                   (PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr,
2727                   DPT_ORGANIZATION_ID);
2728                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setCDBLength(Message_Ptr, 6);
2729                 Message_Ptr->CDB[0] = INQUIRY;
2730                 Message_Ptr->CDB[4] = (unsigned char)sizeof(struct scsi_inquiry_data);
2731                 if (Message_Ptr->CDB[4] == 0) {
2732                         Message_Ptr->CDB[4] = 255;
2733                 }
2734
2735                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setSCBFlags (Message_Ptr,
2736                   (I2O_SCB_FLAG_XFER_FROM_DEVICE
2737                     | I2O_SCB_FLAG_ENABLE_DISCONNECT
2738                     | I2O_SCB_FLAG_SIMPLE_QUEUE_TAG
2739                     | I2O_SCB_FLAG_SENSE_DATA_IN_BUFFER));
2740
2741                 PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_setByteCount(
2742                   (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr,
2743                   sizeof(struct scsi_inquiry_data));
2744                 SG(&(Message_Ptr->SGL), 0,
2745                   I2O_SGL_FLAGS_LAST_ELEMENT | I2O_SGL_FLAGS_END_OF_BUFFER,
2746                   iq, sizeof(struct scsi_inquiry_data));
2747                 (void)ASR_queue_c(sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
2748
2749                 if (iq->vendor[0] && (iq->vendor[0] != ' ')) {
2750                         printf (" ");
2751                         ASR_prstring (iq->vendor, 8);
2752                         ++posted;
2753                 }
2754                 if (iq->product[0] && (iq->product[0] != ' ')) {
2755                         printf (" ");
2756                         ASR_prstring (iq->product, 16);
2757                         ++posted;
2758                 }
2759                 if (iq->revision[0] && (iq->revision[0] != ' ')) {
2760                         printf (" FW Rev. ");
2761                         ASR_prstring (iq->revision, 4);
2762                         ++posted;
2763                 }
2764                 kfree ((caddr_t)iq, M_TEMP);
2765                 if (posted) {
2766                         printf (",");
2767                 }
2768         }
2769         printf (" %d channel, %d CCBs, Protocol I2O\n", sc->ha_MaxBus + 1,
2770           (sc->ha_QueueSize > MAX_INBOUND) ? MAX_INBOUND : sc->ha_QueueSize);
2771
2772         /*
2773          * fill in the prototype cam_path.
2774          */
2775         {
2776                 int             bus;
2777                 union asr_ccb * ccb;
2778
2779                 if ((ccb = asr_alloc_ccb (sc)) == (union asr_ccb *)NULL) {
2780                         printf ("asr%d: CAM could not be notified of asynchronous callback parameters\n", unit);
2781                         ATTACH_RETURN(ENOMEM);
2782                 }
2783                 for (bus = 0; bus <= sc->ha_MaxBus; ++bus) {
2784                         int                 QueueSize = sc->ha_QueueSize;
2785
2786                         if (QueueSize > MAX_INBOUND) {
2787                                 QueueSize = MAX_INBOUND;
2788                         }
2789
2790                         /*
2791                          *      Construct our first channel SIM entry
2792                          */
2793                         sc->ha_sim[bus] = cam_sim_alloc(
2794                           asr_action, asr_poll, "asr", sc,
2795                           unit, 1, QueueSize, NULL);
2796                         if (sc->ha_sim[bus] == NULL)
2797                                 continue;
2798
2799                         if (xpt_bus_register(sc->ha_sim[bus], bus)
2800                           != CAM_SUCCESS) {
2801                                 cam_sim_free(sc->ha_sim[bus]);
2802                                 sc->ha_sim[bus] = NULL;
2803                                 continue;
2804                         }
2805
2806                         if (xpt_create_path(&(sc->ha_path[bus]), /*periph*/NULL,
2807                           cam_sim_path(sc->ha_sim[bus]), CAM_TARGET_WILDCARD,
2808                           CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
2809                                 xpt_bus_deregister(
2810                                   cam_sim_path(sc->ha_sim[bus]));
2811                                 cam_sim_free(sc->ha_sim[bus]);
2812                                 sc->ha_sim[bus] = NULL;
2813                                 continue;
2814                         }
2815                 }
2816                 asr_free_ccb (ccb);
2817         }
2818         /*
2819          *      Generate the device node information
2820          */
2821         make_dev(&asr_ops, unit, 0, 0, S_IRWXU, "rasr%d", unit);
2822         ATTACH_RETURN(0);
2823 } /* asr_attach */
2824
2825 STATIC void
2826 asr_poll(
2827         IN struct cam_sim *sim)
2828 {
2829         asr_intr(cam_sim_softc(sim));
2830 } /* asr_poll */
2831
2832 STATIC void
2833 asr_action(
2834         IN struct cam_sim * sim,
2835         IN union ccb      * ccb)
2836 {
2837         struct Asr_softc  * sc;
2838
2839         debug_asr_printf ("asr_action(%lx,%lx{%x})\n",
2840           (u_long)sim, (u_long)ccb, ccb->ccb_h.func_code);
2841
2842         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("asr_action\n"));
2843
2844         ccb->ccb_h.spriv_ptr0 = sc = (struct Asr_softc *)cam_sim_softc(sim);
2845
2846         switch (ccb->ccb_h.func_code) {
2847
2848         /* Common cases first */
2849         case XPT_SCSI_IO:       /* Execute the requested I/O operation */
2850         {
2851                 struct Message {
2852                         char M[MAX_INBOUND_SIZE];
2853                 };
2854                 defAlignLong(struct Message,Message);
2855                 PI2O_MESSAGE_FRAME   Message_Ptr;
2856
2857                 /* Reject incoming commands while we are resetting the card */
2858                 if (sc->ha_in_reset != HA_OPERATIONAL) {
2859                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2860                         if (sc->ha_in_reset >= HA_OFF_LINE) {
2861                                 /* HBA is now off-line */
2862                                 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR;
2863                         } else {
2864                                 /* HBA currently resetting, try again later. */
2865                                 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2866                         }
2867                         debug_asr_cmd_printf (" e\n");
2868                         xpt_done(ccb);
2869                         debug_asr_cmd_printf (" q\n");
2870                         break;
2871                 }
2872                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) {
2873                         printf(
2874                           "asr%d WARNING: scsi_cmd(%x) already done on b%dt%du%d\n",
2875                           cam_sim_unit(xpt_path_sim(ccb->ccb_h.path)),
2876                           ccb->csio.cdb_io.cdb_bytes[0],
2877                           cam_sim_bus(sim),
2878                           ccb->ccb_h.target_id,
2879                           ccb->ccb_h.target_lun);
2880                 }
2881                 debug_asr_cmd_printf ("(%d,%d,%d,%d)",
2882                   cam_sim_unit(sim),
2883                   cam_sim_bus(sim),
2884                   ccb->ccb_h.target_id,
2885                   ccb->ccb_h.target_lun);
2886                 debug_asr_cmd_dump_ccb(ccb);
2887
2888                 if ((Message_Ptr = ASR_init_message ((union asr_ccb *)ccb,
2889                   (PI2O_MESSAGE_FRAME)Message)) != (PI2O_MESSAGE_FRAME)NULL) {
2890                         debug_asr_cmd2_printf ("TID=%x:\n",
2891                           PRIVATE_SCSI_SCB_EXECUTE_MESSAGE_getTID(
2892                             (PPRIVATE_SCSI_SCB_EXECUTE_MESSAGE)Message_Ptr));
2893                         debug_asr_cmd2_dump_message(Message_Ptr);
2894                         debug_asr_cmd1_printf (" q");
2895
2896                         if (ASR_queue (sc, Message_Ptr) == EMPTY_QUEUE) {
2897                                 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2898                                 ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2899                                 debug_asr_cmd_printf (" E\n");
2900                                 xpt_done(ccb);
2901                         }
2902                         debug_asr_cmd_printf (" Q\n");
2903                         break;
2904                 }
2905                 /*
2906                  *      We will get here if there is no valid TID for the device
2907                  * referenced in the scsi command packet.
2908                  */
2909                 ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2910                 ccb->ccb_h.status |= CAM_SEL_TIMEOUT;
2911                 debug_asr_cmd_printf (" B\n");
2912                 xpt_done(ccb);
2913                 break;
2914         }
2915
2916         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
2917                 /* Rese HBA device ... */
2918                 asr_hbareset (sc);
2919                 ccb->ccb_h.status = CAM_REQ_CMP;
2920                 xpt_done(ccb);
2921                 break;
2922
2923 #       if (defined(REPORT_LUNS))
2924         case REPORT_LUNS:
2925 #       endif
2926         case XPT_ABORT:                 /* Abort the specified CCB */
2927                 /* XXX Implement */
2928                 ccb->ccb_h.status = CAM_REQ_INVALID;
2929                 xpt_done(ccb);
2930                 break;
2931
2932         case XPT_SET_TRAN_SETTINGS:
2933                 /* XXX Implement */
2934                 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2935                 xpt_done(ccb);
2936                 break;
2937
2938         case XPT_GET_TRAN_SETTINGS:
2939         /* Get default/user set transfer settings for the target */
2940         {
2941                 struct  ccb_trans_settings *cts;
2942                 u_int   target_mask;
2943
2944                 cts = &(ccb->cts);
2945                 target_mask = 0x01 << ccb->ccb_h.target_id;
2946                 if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) {
2947                         cts->flags = CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB;
2948                         cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
2949                         cts->sync_period = 6; /* 40MHz */
2950                         cts->sync_offset = 15;
2951
2952                         cts->valid = CCB_TRANS_SYNC_RATE_VALID
2953                                    | CCB_TRANS_SYNC_OFFSET_VALID
2954                                    | CCB_TRANS_BUS_WIDTH_VALID
2955                                    | CCB_TRANS_DISC_VALID
2956                                    | CCB_TRANS_TQ_VALID;
2957                         ccb->ccb_h.status = CAM_REQ_CMP;
2958                 } else {
2959                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
2960                 }
2961                 xpt_done(ccb);
2962                 break;
2963         }
2964
2965         case XPT_CALC_GEOMETRY:
2966         {
2967                 struct    ccb_calc_geometry *ccg;
2968                 u_int32_t size_mb;
2969                 u_int32_t secs_per_cylinder;
2970
2971                 ccg = &(ccb->ccg);
2972                 size_mb = ccg->volume_size
2973                         / ((1024L * 1024L) / ccg->block_size);
2974
2975                 if (size_mb > 4096) {
2976                         ccg->heads = 255;
2977                         ccg->secs_per_track = 63;
2978                 } else if (size_mb > 2048) {
2979                         ccg->heads = 128;
2980                         ccg->secs_per_track = 63;
2981                 } else if (size_mb > 1024) {
2982                         ccg->heads = 65;
2983                         ccg->secs_per_track = 63;
2984                 } else {
2985                         ccg->heads = 64;
2986                         ccg->secs_per_track = 32;
2987                 }
2988                 secs_per_cylinder = ccg->heads * ccg->secs_per_track;
2989                 ccg->cylinders = ccg->volume_size / secs_per_cylinder;
2990                 ccb->ccb_h.status = CAM_REQ_CMP;
2991                 xpt_done(ccb);
2992                 break;
2993         }
2994
2995         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
2996                 ASR_resetBus (sc, cam_sim_bus(sim));
2997                 ccb->ccb_h.status = CAM_REQ_CMP;
2998                 xpt_done(ccb);
2999                 break;
3000
3001         case XPT_TERM_IO:               /* Terminate the I/O process */
3002                 /* XXX Implement */
3003                 ccb->ccb_h.status = CAM_REQ_INVALID;
3004                 xpt_done(ccb);
3005                 break;
3006
3007         case XPT_PATH_INQ:              /* Path routing inquiry */
3008         {
3009                 struct ccb_pathinq *cpi = &(ccb->cpi);
3010
3011                 cpi->version_num = 1; /* XXX??? */
3012                 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
3013                 cpi->target_sprt = 0;
3014                 /* Not necessary to reset bus, done by HDM initialization */
3015                 cpi->hba_misc = PIM_NOBUSRESET;
3016                 cpi->hba_eng_cnt = 0;
3017                 cpi->max_target = sc->ha_MaxId;
3018                 cpi->max_lun = sc->ha_MaxLun;
3019                 cpi->initiator_id = sc->ha_adapter_target[cam_sim_bus(sim)];
3020                 cpi->bus_id = cam_sim_bus(sim);
3021                 cpi->base_transfer_speed = 3300;
3022                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
3023                 strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
3024                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
3025                 cpi->unit_number = cam_sim_unit(sim);
3026                 cpi->ccb_h.status = CAM_REQ_CMP;
3027                 xpt_done(ccb);
3028                 break;
3029         }
3030         default:
3031                 ccb->ccb_h.status = CAM_REQ_INVALID;
3032                 xpt_done(ccb);
3033                 break;
3034         }
3035 } /* asr_action */
3036
3037
3038 /*
3039  * Handle processing of current CCB as pointed to by the Status.
3040  */
3041 STATIC int
3042 asr_intr (
3043         IN Asr_softc_t * sc)
3044 {
3045         OUT int          processed;
3046
3047         for (processed = 0;
3048           sc->ha_Virt->Status & Mask_InterruptsDisabled;
3049           processed = 1) {
3050                 union asr_ccb                     * ccb;
3051                 U32                                 ReplyOffset;
3052                 PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME Reply;
3053
3054                 if (((ReplyOffset = sc->ha_Virt->FromFIFO) == EMPTY_QUEUE)
3055                  && ((ReplyOffset = sc->ha_Virt->FromFIFO) == EMPTY_QUEUE)) {
3056                         break;
3057                 }
3058                 Reply = (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)(ReplyOffset
3059                   - sc->ha_Msgs_Phys + (char *)(sc->ha_Msgs));
3060                 /*
3061                  * We do not need any (optional byteswapping) method access to
3062                  * the Initiator context field.
3063                  */
3064                 ccb = (union asr_ccb *)(long)
3065                   I2O_MESSAGE_FRAME_getInitiatorContext64(
3066                     &(Reply->StdReplyFrame.StdMessageFrame));
3067                 if (I2O_MESSAGE_FRAME_getMsgFlags(
3068                   &(Reply->StdReplyFrame.StdMessageFrame))
3069                   & I2O_MESSAGE_FLAGS_FAIL) {
3070                         defAlignLong(I2O_UTIL_NOP_MESSAGE,Message);
3071                         PI2O_UTIL_NOP_MESSAGE             Message_Ptr;
3072                         U32                               MessageOffset;
3073
3074                         MessageOffset = (u_long)
3075                           I2O_FAILURE_REPLY_MESSAGE_FRAME_getPreservedMFA(
3076                             (PI2O_FAILURE_REPLY_MESSAGE_FRAME)Reply);
3077                         /*
3078                          *  Get the Original Message Frame's address, and get
3079                          * it's Transaction Context into our space. (Currently
3080                          * unused at original authorship, but better to be
3081                          * safe than sorry). Straight copy means that we
3082                          * need not concern ourselves with the (optional
3083                          * byteswapping) method access.
3084                          */
3085                         Reply->StdReplyFrame.TransactionContext
3086                           = ((PI2O_SINGLE_REPLY_MESSAGE_FRAME)
3087                             (sc->ha_Fvirt + MessageOffset))->TransactionContext;
3088                         /*
3089                          *      For 64 bit machines, we need to reconstruct the
3090                          * 64 bit context.
3091                          */
3092                         ccb = (union asr_ccb *)(long)
3093                           I2O_MESSAGE_FRAME_getInitiatorContext64(
3094                             &(Reply->StdReplyFrame.StdMessageFrame));
3095                         /*
3096                          * Unique error code for command failure.
3097                          */
3098                         I2O_SINGLE_REPLY_MESSAGE_FRAME_setDetailedStatusCode(
3099                           &(Reply->StdReplyFrame), (u_int16_t)-2);
3100                         /*
3101                          *  Modify the message frame to contain a NOP and
3102                          * re-issue it to the controller.
3103                          */
3104                         Message_Ptr = (PI2O_UTIL_NOP_MESSAGE)ASR_fillMessage(
3105                           Message, sizeof(I2O_UTIL_NOP_MESSAGE));
3106 #                       if (I2O_UTIL_NOP != 0)
3107                                 I2O_MESSAGE_FRAME_setFunction (
3108                                   &(Message_Ptr->StdMessageFrame),
3109                                   I2O_UTIL_NOP);
3110 #                       endif
3111                         /*
3112                          *  Copy the packet out to the Original Message
3113                          */
3114                         bcopy ((caddr_t)Message_Ptr,
3115                           sc->ha_Fvirt + MessageOffset,
3116                           sizeof(I2O_UTIL_NOP_MESSAGE));
3117                         /*
3118                          *  Issue the NOP
3119                          */
3120                         sc->ha_Virt->ToFIFO = MessageOffset;
3121                 }
3122
3123                 /*
3124                  *      Asynchronous command with no return requirements,
3125                  * and a generic handler for immunity against odd error
3126                  * returns from the adapter.
3127                  */
3128                 if (ccb == (union asr_ccb *)NULL) {
3129                         /*
3130                          * Return Reply so that it can be used for the
3131                          * next command
3132                          */
3133                         sc->ha_Virt->FromFIFO = ReplyOffset;
3134                         continue;
3135                 }
3136
3137                 /* Welease Wadjah! (and stop timeouts) */
3138                 ASR_ccbRemove (sc, ccb);
3139
3140                 switch (
3141                   I2O_SINGLE_REPLY_MESSAGE_FRAME_getDetailedStatusCode(
3142                     &(Reply->StdReplyFrame))) {
3143
3144                 case I2O_SCSI_DSC_SUCCESS:
3145                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3146                         ccb->ccb_h.status |= CAM_REQ_CMP;
3147                         break;
3148
3149                 case I2O_SCSI_DSC_CHECK_CONDITION:
3150                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3151                         ccb->ccb_h.status |= CAM_REQ_CMP|CAM_AUTOSNS_VALID;
3152                         break;
3153
3154                 case I2O_SCSI_DSC_BUSY:
3155                         /* FALLTHRU */
3156                 case I2O_SCSI_HBA_DSC_ADAPTER_BUSY:
3157                         /* FALLTHRU */
3158                 case I2O_SCSI_HBA_DSC_SCSI_BUS_RESET:
3159                         /* FALLTHRU */
3160                 case I2O_SCSI_HBA_DSC_BUS_BUSY:
3161                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3162                         ccb->ccb_h.status |= CAM_SCSI_BUSY;
3163                         break;
3164
3165                 case I2O_SCSI_HBA_DSC_SELECTION_TIMEOUT:
3166                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3167                         ccb->ccb_h.status |= CAM_SEL_TIMEOUT;
3168                         break;
3169
3170                 case I2O_SCSI_HBA_DSC_COMMAND_TIMEOUT:
3171                         /* FALLTHRU */
3172                 case I2O_SCSI_HBA_DSC_DEVICE_NOT_PRESENT:
3173                         /* FALLTHRU */
3174                 case I2O_SCSI_HBA_DSC_LUN_INVALID:
3175                         /* FALLTHRU */
3176                 case I2O_SCSI_HBA_DSC_SCSI_TID_INVALID:
3177                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3178                         ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
3179                         break;
3180
3181                 case I2O_SCSI_HBA_DSC_DATA_OVERRUN:
3182                         /* FALLTHRU */
3183                 case I2O_SCSI_HBA_DSC_REQUEST_LENGTH_ERROR:
3184                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3185                         ccb->ccb_h.status |= CAM_DATA_RUN_ERR;
3186                         break;
3187
3188                 default:
3189                         ccb->ccb_h.status &= ~CAM_STATUS_MASK;
3190                         ccb->ccb_h.status |= CAM_REQUEUE_REQ;
3191                         break;
3192                 }
3193                 if ((ccb->csio.resid = ccb->csio.dxfer_len) != 0) {
3194                         ccb->csio.resid -=
3195                           I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_getTransferCount(
3196                             Reply);
3197                 }
3198
3199                 /* Sense data in reply packet */
3200                 if (ccb->ccb_h.status & CAM_AUTOSNS_VALID) {
3201                         u_int16_t size = I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_getAutoSenseTransferCount(Reply);
3202
3203                         if (size) {
3204                                 if (size > sizeof(ccb->csio.sense_data)) {
3205                                         size = sizeof(ccb->csio.sense_data);
3206                                 }
3207                                 if (size > I2O_SCSI_SENSE_DATA_SZ) {
3208                                         size = I2O_SCSI_SENSE_DATA_SZ;
3209                                 }
3210                                 if ((ccb->csio.sense_len)
3211                                  && (size > ccb->csio.sense_len)) {
3212                                         size = ccb->csio.sense_len;
3213                                 }
3214                                 bcopy ((caddr_t)Reply->SenseData,
3215                                   (caddr_t)&(ccb->csio.sense_data), size);
3216                         }
3217                 }
3218
3219                 /*
3220                  * Return Reply so that it can be used for the next command
3221                  * since we have no more need for it now
3222                  */
3223                 sc->ha_Virt->FromFIFO = ReplyOffset;
3224
3225                 if (ccb->ccb_h.path) {
3226                         xpt_done ((union ccb *)ccb);
3227                 } else {
3228                         wakeup ((caddr_t)ccb);
3229                 }
3230         }
3231         return (processed);
3232 } /* asr_intr */
3233
3234 #undef QueueSize        /* Grrrr */
3235 #undef SG_Size          /* Grrrr */
3236
3237 /*
3238  *      Meant to be included at the bottom of asr.c !!!
3239  */
3240
3241 /*
3242  *      Included here as hard coded. Done because other necessary include
3243  *      files utilize C++ comment structures which make them a nuisance to
3244  *      included here just to pick up these three typedefs.
3245  */
3246 typedef U32   DPT_TAG_T;
3247 typedef U32   DPT_MSG_T;
3248 typedef U32   DPT_RTN_T;
3249
3250 #undef SCSI_RESET       /* Conflicts with "scsi/scsiconf.h" defintion */
3251 #include        "osd_unix.h"
3252
3253 #define asr_unit(dev)     minor(dev)
3254
3255 STATIC INLINE Asr_softc_t *
3256 ASR_get_sc (
3257         IN cdev_t          dev)
3258 {
3259         int               unit = asr_unit(dev);
3260         OUT Asr_softc_t * sc = Asr_softc;
3261
3262         while (sc && sc->ha_sim[0] && (cam_sim_unit(sc->ha_sim[0]) != unit)) {
3263                 sc = sc->ha_next;
3264         }
3265         return (sc);
3266 } /* ASR_get_sc */
3267
3268 STATIC u_int8_t ASR_ctlr_held;
3269 #if (!defined(UNREFERENCED_PARAMETER))
3270 # define UNREFERENCED_PARAMETER(x) (void)(x)
3271 #endif
3272
3273 STATIC int
3274 asr_open(struct dev_open_args *ap)
3275 {
3276         cdev_t dev = ap->a_head.a_dev;
3277         OUT int error;
3278
3279         if (ASR_get_sc (dev) == (Asr_softc_t *)NULL) {
3280                 return (ENODEV);
3281         }
3282         crit_enter();
3283         if (ASR_ctlr_held) {
3284                 error = EBUSY;
3285         } else if ((error = suser_cred(ap->a_cred, 0)) == 0) {
3286                 ++ASR_ctlr_held;
3287         }
3288         crit_exit();
3289         return (error);
3290 } /* asr_open */
3291
3292 STATIC int
3293 asr_close(struct dev_close_args *ap)
3294 {
3295         ASR_ctlr_held = 0;
3296         return (0);
3297 } /* asr_close */
3298
3299
3300 /*-------------------------------------------------------------------------*/
3301 /*                    Function ASR_queue_i                                 */
3302 /*-------------------------------------------------------------------------*/
3303 /* The Parameters Passed To This Function Are :                            */
3304 /*     Asr_softc_t *      : HBA miniport driver's adapter data storage.    */
3305 /*     PI2O_MESSAGE_FRAME : Msg Structure Pointer For This Command         */
3306 /*      I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME following the Msg Structure     */
3307 /*                                                                         */
3308 /* This Function Will Take The User Request Packet And Convert It To An    */
3309 /* I2O MSG And Send It Off To The Adapter.                                 */
3310 /*                                                                         */
3311 /* Return : 0 For OK, Error Code Otherwise                                 */
3312 /*-------------------------------------------------------------------------*/
3313 STATIC INLINE int
3314 ASR_queue_i(
3315         IN Asr_softc_t                             * sc,
3316         INOUT PI2O_MESSAGE_FRAME                     Packet)
3317 {
3318         union asr_ccb                              * ccb;
3319         PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME          Reply;
3320         PI2O_MESSAGE_FRAME                           Message_Ptr;
3321         PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME          Reply_Ptr;
3322         int                                          MessageSizeInBytes;
3323         int                                          ReplySizeInBytes;
3324         int                                          error;
3325         int                                          s;
3326         /* Scatter Gather buffer list */
3327         struct ioctlSgList_S {
3328                 SLIST_ENTRY(ioctlSgList_S) link;
3329                 caddr_t                    UserSpace;
3330                 I2O_FLAGS_COUNT            FlagsCount;
3331                 char                       KernelSpace[sizeof(long)];
3332         }                                          * elm;
3333         /* Generates a `first' entry */
3334         SLIST_HEAD(ioctlSgListHead_S, ioctlSgList_S) sgList;
3335
3336         if (ASR_getBlinkLedCode(sc)) {
3337                 debug_usr_cmd_printf ("Adapter currently in BlinkLed %x\n",
3338                   ASR_getBlinkLedCode(sc));
3339                 return (EIO);
3340         }
3341         /* Copy in the message into a local allocation */
3342         if ((Message_Ptr = (PI2O_MESSAGE_FRAME)kmalloc (
3343           sizeof(I2O_MESSAGE_FRAME), M_TEMP, M_WAITOK))
3344          == (PI2O_MESSAGE_FRAME)NULL) {
3345                 debug_usr_cmd_printf (
3346                   "Failed to acquire I2O_MESSAGE_FRAME memory\n");
3347                 return (ENOMEM);
3348         }
3349         if ((error = copyin ((caddr_t)Packet, (caddr_t)Message_Ptr,
3350           sizeof(I2O_MESSAGE_FRAME))) != 0) {
3351                 kfree (Message_Ptr, M_TEMP);
3352                 debug_usr_cmd_printf ("Can't copy in packet errno=%d\n", error);
3353                 return (error);
3354         }
3355         /* Acquire information to determine type of packet */
3356         MessageSizeInBytes = (I2O_MESSAGE_FRAME_getMessageSize(Message_Ptr)<<2);
3357         /* The offset of the reply information within the user packet */
3358         Reply = (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)((char *)Packet
3359           + MessageSizeInBytes);
3360
3361         /* Check if the message is a synchronous initialization command */
3362         s = I2O_MESSAGE_FRAME_getFunction(Message_Ptr);
3363         kfree (Message_Ptr, M_TEMP);
3364         switch (s) {
3365
3366         case I2O_EXEC_IOP_RESET:
3367         {       U32 status;
3368
3369                 status = ASR_resetIOP(sc->ha_Virt, sc->ha_Fvirt);
3370                 ReplySizeInBytes = sizeof(status);
3371                 debug_usr_cmd_printf ("resetIOP done\n");
3372                 return (copyout ((caddr_t)&status, (caddr_t)Reply,
3373                   ReplySizeInBytes));
3374         }
3375
3376         case I2O_EXEC_STATUS_GET:
3377         {       I2O_EXEC_STATUS_GET_REPLY status;
3378
3379                 if (ASR_getStatus (sc->ha_Virt, sc->ha_Fvirt, &status)
3380                   == (PI2O_EXEC_STATUS_GET_REPLY)NULL) {
3381                         debug_usr_cmd_printf ("getStatus failed\n");
3382                         return (ENXIO);
3383                 }
3384                 ReplySizeInBytes = sizeof(status);
3385                 debug_usr_cmd_printf ("getStatus done\n");
3386                 return (copyout ((caddr_t)&status, (caddr_t)Reply,
3387                   ReplySizeInBytes));
3388         }
3389
3390         case I2O_EXEC_OUTBOUND_INIT:
3391         {       U32 status;
3392
3393                 status = ASR_initOutBound(sc);
3394                 ReplySizeInBytes = sizeof(status);
3395                 debug_usr_cmd_printf ("intOutBound done\n");
3396                 return (copyout ((caddr_t)&status, (caddr_t)Reply,
3397                   ReplySizeInBytes));
3398         }
3399         }
3400
3401         /* Determine if the message size is valid */
3402         if ((MessageSizeInBytes < sizeof(I2O_MESSAGE_FRAME))
3403          || (MAX_INBOUND_SIZE < MessageSizeInBytes)) {
3404                 debug_usr_cmd_printf ("Packet size %d incorrect\n",
3405                   MessageSizeInBytes);
3406                 return (EINVAL);
3407         }
3408
3409         if ((Message_Ptr = (PI2O_MESSAGE_FRAME)kmalloc (MessageSizeInBytes,
3410           M_TEMP, M_WAITOK)) == (PI2O_MESSAGE_FRAME)NULL) {
3411                 debug_usr_cmd_printf ("Failed to acquire frame[%d] memory\n",
3412                   MessageSizeInBytes);
3413                 return (ENOMEM);
3414         }
3415         if ((error = copyin ((caddr_t)Packet, (caddr_t)Message_Ptr,
3416           MessageSizeInBytes)) != 0) {
3417                 kfree (Message_Ptr, M_TEMP);
3418                 debug_usr_cmd_printf ("Can't copy in packet[%d] errno=%d\n",
3419                   MessageSizeInBytes, error);
3420                 return (error);
3421         }
3422
3423         /* Check the size of the reply frame, and start constructing */
3424
3425         if ((Reply_Ptr = (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)kmalloc (
3426           sizeof(I2O_MESSAGE_FRAME), M_TEMP, M_WAITOK))
3427           == (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)NULL) {
3428                 kfree (Message_Ptr, M_TEMP);
3429                 debug_usr_cmd_printf (
3430                   "Failed to acquire I2O_MESSAGE_FRAME memory\n");
3431                 return (ENOMEM);
3432         }
3433         if ((error = copyin ((caddr_t)Reply, (caddr_t)Reply_Ptr,
3434           sizeof(I2O_MESSAGE_FRAME))) != 0) {
3435                 kfree (Reply_Ptr, M_TEMP);
3436                 kfree (Message_Ptr, M_TEMP);
3437                 debug_usr_cmd_printf (
3438                   "Failed to copy in reply frame, errno=%d\n",
3439                   error);
3440                 return (error);
3441         }
3442         ReplySizeInBytes = (I2O_MESSAGE_FRAME_getMessageSize(
3443           &(Reply_Ptr->StdReplyFrame.StdMessageFrame)) << 2);
3444         kfree (Reply_Ptr, M_TEMP);
3445         if (ReplySizeInBytes < sizeof(I2O_SINGLE_REPLY_MESSAGE_FRAME)) {
3446                 kfree (Message_Ptr, M_TEMP);
3447                 debug_usr_cmd_printf (
3448                   "Failed to copy in reply frame[%d], errno=%d\n",
3449                   ReplySizeInBytes, error);
3450                 return (EINVAL);
3451         }
3452
3453         if ((Reply_Ptr = (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)kmalloc (
3454           ((ReplySizeInBytes > sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME))
3455             ? ReplySizeInBytes
3456             : sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)),
3457           M_TEMP, M_WAITOK)) == (PI2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)NULL) {
3458                 kfree (Message_Ptr, M_TEMP);
3459                 debug_usr_cmd_printf ("Failed to acquire frame[%d] memory\n",
3460                   ReplySizeInBytes);
3461                 return (ENOMEM);
3462         }
3463         (void)ASR_fillMessage ((char *)Reply_Ptr, ReplySizeInBytes);
3464         Reply_Ptr->StdReplyFrame.StdMessageFrame.InitiatorContext
3465           = Message_Ptr->InitiatorContext;
3466         Reply_Ptr->StdReplyFrame.TransactionContext
3467           = ((PI2O_PRIVATE_MESSAGE_FRAME)Message_Ptr)->TransactionContext;
3468         I2O_MESSAGE_FRAME_setMsgFlags(
3469           &(Reply_Ptr->StdReplyFrame.StdMessageFrame),
3470           I2O_MESSAGE_FRAME_getMsgFlags(
3471             &(Reply_Ptr->StdReplyFrame.StdMessageFrame))
3472               | I2O_MESSAGE_FLAGS_REPLY);
3473
3474         /* Check if the message is a special case command */
3475         switch (I2O_MESSAGE_FRAME_getFunction(Message_Ptr)) {
3476         case I2O_EXEC_SYS_TAB_SET: /* Special Case of empty Scatter Gather */
3477                 if (MessageSizeInBytes == ((I2O_MESSAGE_FRAME_getVersionOffset(
3478                   Message_Ptr) & 0xF0) >> 2)) {
3479                         kfree (Message_Ptr, M_TEMP);
3480                         I2O_SINGLE_REPLY_MESSAGE_FRAME_setDetailedStatusCode(
3481                           &(Reply_Ptr->StdReplyFrame),
3482                           (ASR_setSysTab(sc) != CAM_REQ_CMP));
3483                         I2O_MESSAGE_FRAME_setMessageSize(
3484                           &(Reply_Ptr->StdReplyFrame.StdMessageFrame),
3485                           sizeof(I2O_SINGLE_REPLY_MESSAGE_FRAME));
3486                         error = copyout ((caddr_t)Reply_Ptr, (caddr_t)Reply,
3487                           ReplySizeInBytes);
3488                         kfree (Reply_Ptr, M_TEMP);
3489                         return (error);
3490                 }
3491         }
3492
3493         /* Deal in the general case */
3494         /* First allocate and optionally copy in each scatter gather element */
3495         SLIST_INIT(&sgList);
3496         if ((I2O_MESSAGE_FRAME_getVersionOffset(Message_Ptr) & 0xF0) != 0) {
3497                 PI2O_SGE_SIMPLE_ELEMENT sg;
3498
3499                 /*
3500                  *      since this code is reused in several systems, code
3501                  * efficiency is greater by using a shift operation rather
3502                  * than a divide by sizeof(u_int32_t).
3503                  */
3504                 sg = (PI2O_SGE_SIMPLE_ELEMENT)((char *)Message_Ptr
3505                   + ((I2O_MESSAGE_FRAME_getVersionOffset(Message_Ptr) & 0xF0)
3506                     >> 2));
3507                 while (sg < (PI2O_SGE_SIMPLE_ELEMENT)(((caddr_t)Message_Ptr)
3508                   + MessageSizeInBytes)) {
3509                         caddr_t v;
3510                         int     len;
3511
3512                         if ((I2O_FLAGS_COUNT_getFlags(&(sg->FlagsCount))
3513                          & I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT) == 0) {
3514                                 error = EINVAL;
3515                                 break;
3516                         }
3517                         len = I2O_FLAGS_COUNT_getCount(&(sg->FlagsCount));
3518                         debug_usr_cmd_printf ("SG[%d] = %x[%d]\n",
3519                           sg - (PI2O_SGE_SIMPLE_ELEMENT)((char *)Message_Ptr
3520                           + ((I2O_MESSAGE_FRAME_getVersionOffset(
3521                                 Message_Ptr) & 0xF0) >> 2)),
3522                           I2O_SGE_SIMPLE_ELEMENT_getPhysicalAddress(sg), len);
3523
3524                         if ((elm = (struct ioctlSgList_S *)kmalloc (
3525                           sizeof(*elm) - sizeof(elm->KernelSpace) + len,
3526                           M_TEMP, M_WAITOK))
3527                           == (struct ioctlSgList_S *)NULL) {
3528                                 debug_usr_cmd_printf (
3529                                   "Failed to allocate SG[%d]\n", len);
3530                                 error = ENOMEM;
3531                                 break;
3532                         }
3533                         SLIST_INSERT_HEAD(&sgList, elm, link);
3534                         elm->FlagsCount = sg->FlagsCount;
3535                         elm->UserSpace = (caddr_t)
3536                           (I2O_SGE_SIMPLE_ELEMENT_getPhysicalAddress(sg));
3537                         v = elm->KernelSpace;
3538                         /* Copy in outgoing data (DIR bit could be invalid) */
3539                         if ((error = copyin (elm->UserSpace, (caddr_t)v, len))
3540                           != 0) {
3541                                 break;
3542                         }
3543                         /*
3544                          *      If the buffer is not contiguous, lets
3545                          * break up the scatter/gather entries.
3546                          */
3547                         while ((len > 0)
3548                          && (sg < (PI2O_SGE_SIMPLE_ELEMENT)
3549                           (((caddr_t)Message_Ptr) + MAX_INBOUND_SIZE))) {
3550                                 int next, base, span;
3551
3552                                 span = 0;
3553                                 next = base = KVTOPHYS(v);
3554                                 I2O_SGE_SIMPLE_ELEMENT_setPhysicalAddress(sg,
3555                                   base);
3556
3557                                 /* How far can we go physically contiguously */
3558                                 while ((len > 0) && (base == next)) {
3559                                         int size;
3560
3561                                         next = trunc_page(base) + PAGE_SIZE;
3562                                         size = next - base;
3563                                         if (size > len) {
3564                                                 size = len;
3565                                         }
3566                                         span += size;
3567                                         v += size;
3568                                         len -= size;
3569                                         base = KVTOPHYS(v);
3570                                 }
3571
3572                                 /* Construct the Flags */
3573                                 I2O_FLAGS_COUNT_setCount(&(sg->FlagsCount),
3574                                   span);
3575                                 {
3576                                         int flags = I2O_FLAGS_COUNT_getFlags(
3577                                           &(elm->FlagsCount));
3578                                         /* Any remaining length? */
3579                                         if (len > 0) {
3580                                             flags &=
3581                                                 ~(I2O_SGL_FLAGS_END_OF_BUFFER
3582                                                  | I2O_SGL_FLAGS_LAST_ELEMENT);
3583                                         }
3584                                         I2O_FLAGS_COUNT_setFlags(
3585                                           &(sg->FlagsCount), flags);
3586                                 }
3587
3588                                 debug_usr_cmd_printf ("sg[%d] = %x[%d]\n",
3589                                   sg - (PI2O_SGE_SIMPLE_ELEMENT)
3590                                     ((char *)Message_Ptr
3591                                   + ((I2O_MESSAGE_FRAME_getVersionOffset(
3592                                         Message_Ptr) & 0xF0) >> 2)),
3593                                   I2O_SGE_SIMPLE_ELEMENT_getPhysicalAddress(sg),
3594                                   span);
3595                                 if (len <= 0) {
3596                                         break;
3597                                 }
3598
3599                                 /*
3600                                  * Incrementing requires resizing of the
3601                                  * packet, and moving up the existing SG
3602                                  * elements.
3603                                  */
3604                                 ++sg;
3605                                 MessageSizeInBytes += sizeof(*sg);
3606                                 I2O_MESSAGE_FRAME_setMessageSize(Message_Ptr,
3607                                   I2O_MESSAGE_FRAME_getMessageSize(Message_Ptr)
3608                                   + (sizeof(*sg) / sizeof(U32)));
3609                                 {
3610                                         PI2O_MESSAGE_FRAME NewMessage_Ptr;
3611
3612                                         if ((NewMessage_Ptr
3613                                           = (PI2O_MESSAGE_FRAME)
3614                                             kmalloc (MessageSizeInBytes,
3615                                              M_TEMP, M_WAITOK))
3616                                             == (PI2O_MESSAGE_FRAME)NULL) {
3617                                                 debug_usr_cmd_printf (
3618                                                   "Failed to acquire frame[%d] memory\n",
3619                                                   MessageSizeInBytes);
3620                                                 error = ENOMEM;
3621                                                 break;
3622                                         }
3623                                         span = ((caddr_t)sg)
3624                                              - (caddr_t)Message_Ptr;
3625                                         bcopy ((caddr_t)Message_Ptr,
3626                                           (caddr_t)NewMessage_Ptr, span);
3627                                         bcopy ((caddr_t)(sg-1),
3628                                           ((caddr_t)NewMessage_Ptr) + span,
3629                                           MessageSizeInBytes - span);
3630                                         kfree (Message_Ptr, M_TEMP);
3631                                         sg = (PI2O_SGE_SIMPLE_ELEMENT)
3632                                           (((caddr_t)NewMessage_Ptr) + span);
3633                                         Message_Ptr = NewMessage_Ptr;
3634                                 }
3635                         }
3636                         if ((error)
3637                          || ((I2O_FLAGS_COUNT_getFlags(&(sg->FlagsCount))
3638                           & I2O_SGL_FLAGS_LAST_ELEMENT) != 0)) {
3639                                 break;
3640                         }
3641                         ++sg;
3642                 }
3643                 if (error) {
3644                         while ((elm = SLIST_FIRST(&sgList))
3645                           != (struct ioctlSgList_S *)NULL) {
3646                                 SLIST_REMOVE_HEAD(&sgList, link);
3647                                 kfree (elm, M_TEMP);
3648                         }
3649                         kfree (Reply_Ptr, M_TEMP);
3650                         kfree (Message_Ptr, M_TEMP);
3651                         return (error);
3652                 }
3653         }
3654
3655         debug_usr_cmd_printf ("Inbound: ");
3656         debug_usr_cmd_dump_message(Message_Ptr);
3657
3658         /* Send the command */
3659         if ((ccb = asr_alloc_ccb (sc)) == (union asr_ccb *)NULL) {
3660                 /* Free up in-kernel buffers */
3661                 while ((elm = SLIST_FIRST(&sgList))
3662                   != (struct ioctlSgList_S *)NULL) {
3663                         SLIST_REMOVE_HEAD(&sgList, link);
3664                         kfree (elm, M_TEMP);
3665                 }
3666                 kfree (Reply_Ptr, M_TEMP);
3667                 kfree (Message_Ptr, M_TEMP);
3668                 return (ENOMEM);
3669         }
3670
3671         /*
3672          * We do not need any (optional byteswapping) method access to
3673          * the Initiator context field.
3674          */
3675         I2O_MESSAGE_FRAME_setInitiatorContext64(
3676           (PI2O_MESSAGE_FRAME)Message_Ptr, (long)ccb);
3677
3678         (void)ASR_queue (sc, (PI2O_MESSAGE_FRAME)Message_Ptr);
3679
3680         kfree (Message_Ptr, M_TEMP);
3681
3682         /*
3683          * Wait for the board to report a finished instruction.
3684          */
3685         crit_enter();
3686         while ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) {
3687                 if (ASR_getBlinkLedCode(sc)) {
3688                         /* Reset Adapter */
3689                         printf ("asr%d: Blink LED 0x%x resetting adapter\n",
3690                           cam_sim_unit(xpt_path_sim(ccb->ccb_h.path)),
3691                           ASR_getBlinkLedCode(sc));
3692                         if (ASR_reset (sc) == ENXIO) {
3693                                 /* Command Cleanup */
3694                                 ASR_ccbRemove(sc, ccb);
3695                         }
3696                         crit_exit();
3697                         /* Free up in-kernel buffers */
3698                         while ((elm = SLIST_FIRST(&sgList))
3699                           != (struct ioctlSgList_S *)NULL) {
3700                                 SLIST_REMOVE_HEAD(&sgList, link);
3701                                 kfree (elm, M_TEMP);
3702                         }
3703                         kfree (Reply_Ptr, M_TEMP);
3704                         asr_free_ccb(ccb);
3705                         return (EIO);
3706                 }
3707                 /* Check every second for BlinkLed */
3708                 tsleep((caddr_t)ccb, 0, "asr", hz);
3709         }
3710         crit_exit();
3711
3712         debug_usr_cmd_printf ("Outbound: ");
3713         debug_usr_cmd_dump_message(Reply_Ptr);
3714
3715         I2O_SINGLE_REPLY_MESSAGE_FRAME_setDetailedStatusCode(
3716           &(Reply_Ptr->StdReplyFrame),
3717           (ccb->ccb_h.status != CAM_REQ_CMP));
3718
3719         if (ReplySizeInBytes >= (sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)
3720           - I2O_SCSI_SENSE_DATA_SZ - sizeof(U32))) {
3721                 I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_setTransferCount(Reply_Ptr,
3722                   ccb->csio.dxfer_len - ccb->csio.resid);
3723         }
3724         if ((ccb->ccb_h.status & CAM_AUTOSNS_VALID) && (ReplySizeInBytes
3725          > (sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)
3726          - I2O_SCSI_SENSE_DATA_SZ))) {
3727                 int size = ReplySizeInBytes
3728                   - sizeof(I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME)
3729                   - I2O_SCSI_SENSE_DATA_SZ;
3730
3731                 if (size > sizeof(ccb->csio.sense_data)) {
3732                         size = sizeof(ccb->csio.sense_data);
3733                 }
3734                 bcopy ((caddr_t)&(ccb->csio.sense_data), (caddr_t)Reply_Ptr->SenseData,
3735                   size);
3736                 I2O_SCSI_ERROR_REPLY_MESSAGE_FRAME_setAutoSenseTransferCount(
3737                   Reply_Ptr, size);
3738         }
3739
3740         /* Free up in-kernel buffers */
3741         while ((elm = SLIST_FIRST(&sgList)) != (struct ioctlSgList_S *)NULL) {
3742                 /* Copy out as necessary */
3743                 if ((error == 0)
3744                 /* DIR bit considered `valid', error due to ignorance works */
3745                  && ((I2O_FLAGS_COUNT_getFlags(&(elm->FlagsCount))
3746                   & I2O_SGL_FLAGS_DIR) == 0)) {
3747                         error = copyout ((caddr_t)(elm->KernelSpace),
3748                           elm->UserSpace,
3749                           I2O_FLAGS_COUNT_getCount(&(elm->FlagsCount)));
3750                 }
3751                 SLIST_REMOVE_HEAD(&sgList, link);
3752                 kfree (elm, M_TEMP);
3753         }
3754         if (error == 0) {
3755         /* Copy reply frame to user space */
3756                 error = copyout ((caddr_t)Reply_Ptr, (caddr_t)Reply,
3757                   ReplySizeInBytes);
3758         }
3759         kfree (Reply_Ptr, M_TEMP);
3760         asr_free_ccb(ccb);
3761
3762         return (error);
3763 } /* ASR_queue_i */
3764
3765 /*----------------------------------------------------------------------*/
3766 /*                          Function asr_ioctl                         */
3767 /*----------------------------------------------------------------------*/
3768 /* The parameters passed to this function are :                         */
3769 /*     dev  : Device number.                                            */
3770 /*     cmd  : Ioctl Command                                             */
3771 /*     data : User Argument Passed In.                                  */
3772 /*     flag : Mode Parameter                                            */
3773 /*     proc : Process Parameter                                         */
3774 /*                                                                      */
3775 /* This function is the user interface into this adapter driver         */
3776 /*                                                                      */
3777 /* Return : zero if OK, error code if not                               */
3778 /*----------------------------------------------------------------------*/
3779
3780 STATIC int
3781 asr_ioctl(struct dev_ioctl_args *ap)
3782 {
3783         cdev_t dev = ap->a_head.a_dev;
3784         caddr_t data = ap->a_data;
3785         int           i, j;
3786         OUT int       error = 0;
3787         Asr_softc_t * sc = ASR_get_sc (dev);
3788
3789         if (sc != (Asr_softc_t *)NULL)
3790         switch(ap->a_cmd) {
3791
3792         case DPT_SIGNATURE:
3793 #       if (dsDescription_size != 50)
3794             case DPT_SIGNATURE + ((50 - dsDescription_size) << 16):
3795 #       endif
3796                 if (ap->a_cmd & 0xFFFF0000) {
3797                         (void)bcopy ((caddr_t)(&ASR_sig), data,
3798                             sizeof(dpt_sig_S));
3799                         return (0);
3800                 }
3801         /* Traditional version of the ioctl interface */
3802         case DPT_SIGNATURE & 0x0000FFFF:
3803                 return (copyout ((caddr_t)(&ASR_sig), *((caddr_t *)data),
3804                     sizeof(dpt_sig_S)));
3805
3806         /* Traditional version of the ioctl interface */
3807         case DPT_CTRLINFO & 0x0000FFFF:
3808         case DPT_CTRLINFO: {
3809                 struct {
3810                         u_int16_t length;
3811                         u_int16_t drvrHBAnum;
3812                         u_int32_t baseAddr;
3813                         u_int16_t blinkState;
3814                         u_int8_t  pciBusNum;
3815                         u_int8_t  pciDeviceNum;
3816                         u_int16_t hbaFlags;
3817                         u_int16_t Interrupt;
3818                         u_int32_t reserved1;
3819                         u_int32_t reserved2;
3820                         u_int32_t reserved3;
3821                 } CtlrInfo;
3822
3823                 bzero (&CtlrInfo, sizeof(CtlrInfo));
3824                 CtlrInfo.length = sizeof(CtlrInfo) - sizeof(u_int16_t);
3825                 CtlrInfo.drvrHBAnum = asr_unit(dev);
3826                 CtlrInfo.baseAddr = (u_long)sc->ha_Base;
3827                 i = ASR_getBlinkLedCode (sc);
3828                 if (i == -1) {
3829                         i = 0;
3830                 }
3831                 CtlrInfo.blinkState = i;
3832                 CtlrInfo.pciBusNum = sc->ha_pciBusNum;
3833                 CtlrInfo.pciDeviceNum = sc->ha_pciDeviceNum;
3834 #define FLG_OSD_PCI_VALID 0x0001
3835 #define FLG_OSD_DMA       0x0002
3836 #define FLG_OSD_I2O       0x0004
3837                 CtlrInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
3838                 CtlrInfo.Interrupt = sc->ha_irq;
3839                 if (ap->a_cmd & 0xFFFF0000) {
3840                         bcopy (&CtlrInfo, data, sizeof(CtlrInfo));
3841                 } else {
3842                         error = copyout (&CtlrInfo, *(caddr_t *)data, sizeof(CtlrInfo));
3843                 }
3844         }       return (error);
3845
3846         /* Traditional version of the ioctl interface */
3847         case DPT_SYSINFO & 0x0000FFFF:
3848         case DPT_SYSINFO: {
3849                 sysInfo_S       Info;
3850                 char          * cp;
3851                 /* Kernel Specific ptok `hack' */
3852 #               define          ptok(a) ((char *)(a) + KERNBASE)
3853
3854                 bzero (&Info, sizeof(Info));
3855
3856                 /* Appears I am the only person in the Kernel doing this */
3857                 outb (0x70, 0x12);
3858                 i = inb(0x71);
3859                 j = i >> 4;
3860                 if (i == 0x0f) {
3861                         outb (0x70, 0x19);
3862                         j = inb (0x71);
3863                 }
3864                 Info.drive0CMOS = j;
3865
3866                 j = i & 0x0f;
3867                 if (i == 0x0f) {
3868                         outb (0x70, 0x1a);
3869                         j = inb (0x71);
3870                 }
3871                 Info.drive1CMOS = j;
3872
3873                 Info.numDrives = *((char *)ptok(0x475));
3874
3875                 Info.processorFamily = ASR_sig.dsProcessorFamily;
3876                 switch (cpu) {
3877                 case CPU_386SX: case CPU_386:
3878                         Info.processorType = PROC_386; break;
3879                 case CPU_486SX: case CPU_486:
3880                         Info.processorType = PROC_486; break;
3881                 case CPU_586:
3882                         Info.processorType = PROC_PENTIUM; break;
3883                 case CPU_686:
3884                         Info.processorType = PROC_SEXIUM; break;
3885                 }
3886                 Info.osType = OS_BSDI_UNIX;
3887                 Info.osMajorVersion = osrelease[0] - '0';
3888                 Info.osMinorVersion = osrelease[2] - '0';
3889                 /* Info.osRevision = 0; */
3890                 /* Info.osSubRevision = 0; */
3891                 Info.busType = SI_PCI_BUS;
3892                 Info.flags = SI_CMOS_Valid | SI_NumDrivesValid
3893                        | SI_OSversionValid | SI_BusTypeValid | SI_NO_SmartROM;
3894
3895                 /* Go Out And Look For I2O SmartROM */
3896                 for(j = 0xC8000; j < 0xE0000; j += 2048) {
3897                         int k;
3898
3899                         cp = ptok(j);
3900                         if (*((unsigned short *)cp) != 0xAA55) {
3901                                 continue;
3902                         }
3903                         j += (cp[2] * 512) - 2048;
3904                         if ((*((u_long *)(cp + 6))
3905                           != ('S' + (' ' * 256) + (' ' * 65536L)))
3906                          || (*((u_long *)(cp + 10))
3907                           != ('I' + ('2' * 256) + ('0' * 65536L)))) {
3908                                 continue;
3909                         }
3910                         cp += 0x24;
3911                         for (k = 0; k < 64; ++k) {
3912                                 if (*((unsigned short *)cp)
3913                                  == (' ' + ('v' * 256))) {
3914                                         break;
3915                                 }
3916                         }
3917                         if (k < 64) {
3918                                 Info.smartROMMajorVersion
3919                                     = *((unsigned char *)(cp += 4)) - '0';
3920                                 Info.smartROMMinorVersion
3921                                     = *((unsigned char *)(cp += 2));
3922                                 Info.smartROMRevision
3923                                     = *((unsigned char *)(++cp));
3924                                 Info.flags |= SI_SmartROMverValid;
3925                                 Info.flags &= ~SI_NO_SmartROM;
3926                                 break;
3927                         }
3928                 }
3929                 /* Get The Conventional Memory Size From CMOS */
3930                 outb (0x70, 0x16);
3931                 j = inb (0x71);
3932                 j <<= 8;
3933                 outb (0x70, 0x15);
3934                 j |= inb(0x71);
3935                 Info.conventionalMemSize = j;
3936
3937                 /* Get The Extended Memory Found At Power On From CMOS */
3938                 outb (0x70, 0x31);
3939                 j = inb (0x71);
3940                 j <<= 8;
3941                 outb (0x70, 0x30);
3942                 j |= inb(0x71);
3943                 Info.extendedMemSize = j;
3944                 Info.flags |= SI_MemorySizeValid;
3945
3946 #               if (defined(THIS_IS_BROKEN))
3947                 /* If There Is 1 or 2 Drives Found, Set Up Drive Parameters */
3948                 if (Info.numDrives > 0) {
3949                         /*
3950                          *      Get The Pointer From Int 41 For The First
3951                          *      Drive Parameters
3952                          */
3953                         j = ((unsigned)(*((unsigned short *)ptok(0x104+2))) << 4)
3954                            + (unsigned)(*((unsigned short *)ptok(0x104+0)));
3955                         /*
3956                          * It appears that SmartROM's Int41/Int46 pointers
3957                          * use memory that gets stepped on by the kernel
3958                          * loading. We no longer have access to this
3959                          * geometry information but try anyways (!?)
3960                          */
3961                         Info.drives[0].cylinders = *((unsigned char *)ptok(j));
3962                         ++j;
3963                         Info.drives[0].cylinders += ((int)*((unsigned char *)
3964                             ptok(j))) << 8;
3965                         ++j;
3966                         Info.drives[0].heads = *((unsigned char *)ptok(j));
3967                         j += 12;
3968                         Info.drives[0].sectors = *((unsigned char *)ptok(j));
3969                         Info.flags |= SI_DriveParamsValid;
3970                         if ((Info.drives[0].cylinders == 0)
3971                          || (Info.drives[0].heads == 0)
3972                          || (Info.drives[0].sectors == 0)) {
3973                                 Info.flags &= ~SI_DriveParamsValid;
3974                         }
3975                         if (Info.numDrives > 1) {
3976                                 /*
3977                                  *      Get The Pointer From Int 46 For The
3978                                  *      Second Drive Parameters
3979                                  */
3980                                 j = ((unsigned)(*((unsigned short *)ptok(0x118+2))) << 4)
3981                                    + (unsigned)(*((unsigned short *)ptok(0x118+0)));
3982                                 Info.drives[1].cylinders = *((unsigned char *)
3983                                     ptok(j));
3984                                 ++j;
3985                                 Info.drives[1].cylinders += ((int)
3986                                     *((unsigned char *)ptok(j))) << 8;
3987                                 ++j;
3988                                 Info.drives[1].heads = *((unsigned char *)
3989                                     ptok(j));
3990                                 j += 12;
3991                                 Info.drives[1].sectors = *((unsigned char *)
3992                                     ptok(j));
3993                                 if ((Info.drives[1].cylinders == 0)
3994                                  || (Info.drives[1].heads == 0)
3995                                  || (Info.drives[1].sectors == 0)) {
3996                                         Info.flags &= ~SI_DriveParamsValid;
3997                                 }
3998                         }
3999                 }
4000 #               endif
4001                 /* Copy Out The Info Structure To The User */
4002                 if (ap->a_cmd & 0xFFFF0000) {
4003                         bcopy (&Info, data, sizeof(Info));
4004                 } else {
4005                         error = copyout (&Info, *(caddr_t *)data, sizeof(Info));
4006                 }
4007                 return (error); }
4008
4009                 /* Get The BlinkLED State */
4010         case DPT_BLINKLED:
4011                 i = ASR_getBlinkLedCode (sc);
4012                 if (i == -1) {
4013                         i = 0;
4014                 }
4015                 if (ap->a_cmd & 0xFFFF0000) {
4016                         bcopy ((caddr_t)(&i), data, sizeof(i));
4017                 } else {
4018                         error = copyout (&i, *(caddr_t *)data, sizeof(i));
4019                 }
4020                 break;
4021
4022                 /* Send an I2O command */
4023         case I2OUSRCMD:
4024                 return (ASR_queue_i (sc, *((PI2O_MESSAGE_FRAME *)data)));
4025
4026                 /* Reset and re-initialize the adapter */
4027         case I2ORESETCMD:
4028                 return (ASR_reset (sc));
4029
4030                 /* Rescan the LCT table and resynchronize the information */
4031         case I2ORESCANCMD:
4032                 return (ASR_rescan (sc));
4033         }
4034         return (EINVAL);
4035 } /* asr_ioctl */