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