|
|
1.1 ! root 1: /* ! 2: * Ported for use with the UltraStor 14f by Gary Close ([email protected]) ! 3: * Thanks to Julian Elischer for advice and help with this port. ! 4: * ! 5: * Written by Julian Elischer ([email protected]) ! 6: * for TRW Financial Systems for use under the MACH(2.5) operating system. ! 7: * ! 8: * TRW Financial Systems, in accordance with their agreement with Carnegie ! 9: * Mellon University, makes this software available to CMU to distribute ! 10: * or use in any manner that they see fit as long as this message is kept with ! 11: * the software. For this reason TFS also grants any other persons or ! 12: * organisations permission to use or modify this software. ! 13: * ! 14: * TFS supplies this software to be publicly redistributed ! 15: * on the understanding that TFS is not responsible for the correct ! 16: * functioning of this software in any circumstances. ! 17: * ! 18: * ! 19: * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE ! 20: * -------------------- ----- ---------------------- ! 21: * CURRENT PATCH LEVEL: 1 00098 ! 22: * -------------------- ----- ---------------------- ! 23: * ! 24: * 16 Feb 93 Julian Elischer ADDED for SCSI system ! 25: * commenced: Sun Sep 27 18:14:01 PDT 1992 ! 26: */ ! 27: ! 28: #include <sys/types.h> ! 29: #include <uha.h> ! 30: ! 31: #include <sys/param.h> ! 32: #include <sys/systm.h> ! 33: #include <sys/errno.h> ! 34: #include <sys/ioctl.h> ! 35: #include <sys/buf.h> ! 36: #include <sys/proc.h> ! 37: #include <sys/user.h> ! 38: ! 39: #ifdef MACH /* EITHER CMU OR OSF */ ! 40: #include <i386/ipl.h> ! 41: #include <i386at/scsi.h> ! 42: #include <i386at/scsiconf.h> ! 43: ! 44: #ifdef OSF /* OSF ONLY */ ! 45: #include <sys/table.h> ! 46: #include <i386/handler.h> ! 47: #include <i386/dispatcher.h> ! 48: #include <i386/AT386/atbus.h> ! 49: ! 50: #else OSF /* CMU ONLY */ ! 51: #include <i386at/atbus.h> ! 52: #include <i386/pio.h> ! 53: #endif OSF ! 54: #endif MACH /* end of MACH specific */ ! 55: ! 56: #ifdef __386BSD__ /* 386BSD specific */ ! 57: #define isa_dev isa_device ! 58: #define dev_unit id_unit ! 59: #define dev_addr id_iobase ! 60: ! 61: #include <i386/include/pio.h> ! 62: #include <i386/isa/isa_device.h> ! 63: #include <scsi/scsi_all.h> ! 64: #include <scsi/scsiconf.h> ! 65: #endif __386BSD__ ! 66: ! 67: /**/ ! 68: ! 69: #ifdef __386BSD__ ! 70: #ifdef DDB ! 71: int Debugger(); ! 72: #else ! 73: #define Debugger() panic("should call debugger here") ! 74: #endif /*!DDB*/ ! 75: #endif __386BSD__ ! 76: ! 77: #ifdef MACH ! 78: int Debugger(); ! 79: #endif MACH ! 80: ! 81: typedef struct {unsigned char addr[4]; } physaddr; ! 82: typedef struct {unsigned char len[4]; } physlen; ! 83: ! 84: ! 85: #ifdef MACH ! 86: extern physaddr kvtophys(); ! 87: #define PHYSTOKV(x) phystokv(x) ! 88: #define KVTOPHYS(x) kvtophys(x) ! 89: #endif MACH ! 90: ! 91: #ifdef __386BSD__ ! 92: #define PHYSTOKV(x) (x | 0xFE000000) ! 93: #define KVTOPHYS(x) vtophys(x) ! 94: #endif __386BSD__ ! 95: ! 96: extern int delaycount; /* from clock setup code */ ! 97: #define NUM_CONCURRENT 16 /* number of concurrent ops per board */ ! 98: #define UHA_NSEG 33 /* number of dma segments supported */ ! 99: #define FUDGE(X) (X>>1) /* our loops are slower than spinwait() */ ! 100: /**/ ! 101: /************************** board definitions *******************************/ ! 102: /* ! 103: * I/O Port Interface ! 104: */ ! 105: #define UHA_LMASK (0x000) /* local doorbell mask reg */ ! 106: #define UHA_LINT (0x001) /* local doorbell int/stat reg */ ! 107: #define UHA_SMASK (0x002) /* system doorbell mask reg */ ! 108: #define UHA_SINT (0x003) /* system doorbell int/stat reg */ ! 109: #define UHA_ID0 (0x004) /* product id reg 0 */ ! 110: #define UHA_ID1 (0x005) /* product id reg 1 */ ! 111: #define UHA_CONF1 (0x006) /* config reg 1 */ ! 112: #define UHA_CONF2 (0x007) /* config reg 2 */ ! 113: #define UHA_OGM0 (0x008) /* outgoing mail ptr 0 least sig */ ! 114: #define UHA_OGM1 (0x009) /* outgoing mail ptr 1 least mid */ ! 115: #define UHA_OGM2 (0x00a) /* outgoing mail ptr 2 most mid */ ! 116: #define UHA_OGM3 (0x00b) /* outgoing mail ptr 3 most sig */ ! 117: #define UHA_ICM0 (0x00c) /* incoming mail ptr 0 */ ! 118: #define UHA_ICM1 (0x00d) /* incoming mail ptr 1 */ ! 119: #define UHA_ICM2 (0x00e) /* incoming mail ptr 2 */ ! 120: #define UHA_ICM3 (0x00f) /* incoming mail ptr 3 */ ! 121: ! 122: /* ! 123: * UHA_LMASK bits (read only) ! 124: */ ! 125: ! 126: #define UHA_LDIE 0x80 /* local doorbell int enabled */ ! 127: #define UHA_SRSTE 0x40 /* soft reset enabled */ ! 128: #define UHA_ABORTEN 0x10 /* abort MSCP enabled */ ! 129: #define UHA_OGMINTEN 0x01 /* outgoing mail interrupt enabled */ ! 130: ! 131: /* ! 132: * UHA_LINT bits (read) ! 133: */ ! 134: ! 135: #define UHA_LDIP 0x80 /* local doorbell int pending */ ! 136: ! 137: /* ! 138: * UHA_LINT bits (write) ! 139: */ ! 140: ! 141: #define UHA_ADRST 0x40 /* adapter soft reset */ ! 142: #define UHA_SBRST 0x20 /* scsi bus reset */ ! 143: #define UHA_ASRST 0x60 /* adapter and scsi reset */ ! 144: #define UHA_ABORT 0x10 /* abort MSCP */ ! 145: #define UHA_OGMINT 0x01 /* tell adapter to get mail */ ! 146: ! 147: /* ! 148: * UHA_SMASK bits (read) ! 149: */ ! 150: ! 151: #define UHA_SINTEN 0x80 /* system doorbell interupt Enabled */ ! 152: #define UHA_ABORT_COMPLETE_EN 0x10 /* abort MSCP command complete int Enabled */ ! 153: #define UHA_ICM_ENABLED 0x01 /* ICM interrupt enabled ! 154: ! 155: /* ! 156: * UHA_SMASK bits (write) ! 157: */ ! 158: ! 159: #define UHA_ENSINT 0x80 /* enable system doorbell interrupt */ ! 160: #define UHA_EN_ABORT_COMPLETE 0x10 /* enable abort MSCP complete int */ ! 161: #define UHA_ENICM 0x01 /* enable ICM interrupt */ ! 162: ! 163: /* ! 164: * UHA_SINT bits (read) ! 165: */ ! 166: ! 167: #define UHA_SINTP 0x80 /* system doorbell int pending */ ! 168: #define UHA_ABORT_SUCC 0x10 /* abort MSCP successful */ ! 169: #define UHA_ABORT_FAIL 0x18 /* abort MSCP failed */ ! 170: ! 171: /* ! 172: * UHA_SINT bits (write) ! 173: */ ! 174: ! 175: #define UHA_ABORT_ACK 0x18 /* acknowledge status and clear */ ! 176: #define UHA_ICM_ACK 0x01 /* acknowledge ICM and clear */ ! 177: ! 178: /* ! 179: * UHA_CONF1 bits (read only) ! 180: */ ! 181: ! 182: #define UHA_DMA_CH5 0x00 /* DMA channel 5 */ ! 183: #define UHA_DMA_CH6 0x40 /* 6 */ ! 184: #define UHA_DMA_CH7 0x80 /* 7 */ ! 185: #define UHA_IRQ15 0x00 /* IRQ 15 */ ! 186: #define UHA_IRQ14 0x10 /* 14 */ ! 187: #define UHA_IRQ11 0x20 /* 11 */ ! 188: #define UHA_IRQ10 0x30 /* 10 */ ! 189: ! 190: /*********************************** ! 191: * ha_status error codes ! 192: \***********************************/ ! 193: ! 194: #define UHA_NO_ERR 0x00 /* No error supposedly */ ! 195: #define UHA_SBUS_ABORT_ERR 0x84 /* scsi bus abort error */ ! 196: #define UHA_SBUS_TIMEOUT 0x91 /* scsi bus selection timeout */ ! 197: #define UHA_SBUS_OVER_UNDER 0x92 /* scsi bus over/underrun */ ! 198: #define UHA_BAD_SCSI_CMD 0x96 /* illegal scsi command */ ! 199: #define UHA_AUTO_SENSE_ERR 0x9b /* auto request sense err */ ! 200: #define UHA_SBUS_RES_ERR 0xa3 /* scsi bus reset error */ ! 201: #define UHA_BAD_SG_LIST 0xff /* invalid scatter gath list */ ! 202: ! 203: /**/ ! 204: ! 205: struct uha_dma_seg ! 206: { ! 207: physaddr addr; ! 208: physlen len; ! 209: }; ! 210: /**/ ! 211: ! 212: struct mscp ! 213: { ! 214: unsigned char opcode:3; ! 215: #define U14_HAC 0x01 /*host adapter command*/ ! 216: #define U14_TSP 0x02 /*target scsi pass through command*/ ! 217: #define U14_SDR 0x04 /*scsi device reset*/ ! 218: unsigned char xdir:2; /*xfer direction*/ ! 219: #define U14_SDET 0x00 /*determined by scsi command*/ ! 220: #define U14_SDIN 0x01 /*scsi data in*/ ! 221: #define U14_SDOUT 0x02 /*scsi data out*/ ! 222: #define U14_NODATA 0x03 /*no data xfer*/ ! 223: unsigned char dcn:1; /*disable disconnect for this command*/ ! 224: unsigned char ca:1; /*Cache control*/ ! 225: unsigned char sgth:1; /*scatter gather flag*/ ! 226: unsigned char target:3; ! 227: unsigned char chan:2; /*scsi channel (always 0 for 14f)*/ ! 228: unsigned char lun:3; ! 229: physaddr data; ! 230: physlen datalen; ! 231: physaddr link; ! 232: unsigned char link_id; ! 233: unsigned char sg_num; /*number of scat gath segs */ ! 234: /*in s-g list if sg flag is*/ ! 235: /*set. starts at 1, 8bytes per*/ ! 236: unsigned char senselen; ! 237: unsigned char cdblen; ! 238: unsigned char cdb[12]; ! 239: unsigned char ha_status; ! 240: unsigned char targ_status; ! 241: physaddr sense; /* if 0 no auto sense */ ! 242: /*-----------------end of hardware supported fields----------------*/ ! 243: struct mscp *next; /* in free list */ ! 244: struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ ! 245: long int delta; /* difference from previous*/ ! 246: struct mscp *later,*sooner; ! 247: int flags; ! 248: #define MSCP_FREE 0 ! 249: #define MSCP_ACTIVE 1 ! 250: #define MSCP_ABORTED 2 ! 251: struct uha_dma_seg uha_dma[UHA_NSEG]; ! 252: struct scsi_sense_data mscp_sense; ! 253: }; ! 254: ! 255: struct mscp *uha_soonest = (struct mscp *)0; ! 256: struct mscp *uha_latest = (struct mscp *)0; ! 257: long int uha_furtherest = 0; /* longest time in the timeout queue */ ! 258: /**/ ! 259: ! 260: struct uha_data ! 261: { ! 262: int flags; ! 263: #define UHA_INIT 0x01; ! 264: int baseport; ! 265: struct mscp mscps[NUM_CONCURRENT]; ! 266: struct mscp *free_mscp; ! 267: int our_id; /* our scsi id */ ! 268: int vect; ! 269: int dma; ! 270: } uha_data[NUHA]; ! 271: ! 272: int uhaprobe(); ! 273: int uha_attach(); ! 274: int uhaintr(); ! 275: int uha_scsi_cmd(); ! 276: int uha_timeout(); ! 277: int uha_abort(); ! 278: struct mscp *cheat; ! 279: void uhaminphys(); ! 280: long int uha_adapter_info(); ! 281: ! 282: unsigned long int scratch; ! 283: ! 284: #ifdef MACH ! 285: struct isa_driver uhadriver = { uhaprobe, 0, uha_attach, "uha", 0, 0, 0}; ! 286: int (*uhaintrs[])() = {uhaintr, 0}; ! 287: #endif MACH ! 288: ! 289: #ifdef __386BSD__ ! 290: struct isa_driver uhadriver = { uhaprobe, uha_attach, "uha"}; ! 291: #endif __386BSD__ ! 292: ! 293: static uha_unit = 0; ! 294: int uha_debug = 0; ! 295: #define UHA_SHOWMSCPS 0x01 ! 296: #define UHA_SHOWINTS 0x02 ! 297: #define UHA_SHOWCMDS 0x04 ! 298: #define UHA_SHOWMISC 0x08 ! 299: #define FAIL 1 ! 300: #define SUCCESS 0 ! 301: #define PAGESIZ 4096 ! 302: ! 303: struct scsi_switch uha_switch = ! 304: { ! 305: uha_scsi_cmd, ! 306: uhaminphys, ! 307: 0, ! 308: 0, ! 309: uha_adapter_info, ! 310: 0,0,0 ! 311: }; ! 312: ! 313: /**/ ! 314: /***********************************************************************\ ! 315: * Function to send a command out through a mailbox * ! 316: \***********************************************************************/ ! 317: uha_send_mbox( int unit ! 318: ,struct mscp *mscp) ! 319: { ! 320: int port = uha_data[unit].baseport; ! 321: int spincount = FUDGE(delaycount) * 1; /* 1ms should be enough */ ! 322: int s = splbio(); ! 323: ! 324: while( ((inb(port + UHA_LINT) & (UHA_LDIP)) ! 325: != (0)) ! 326: && (spincount--)); ! 327: if(spincount == -1) ! 328: { ! 329: printf("uha%d: board not responding\n",unit); ! 330: Debugger(); ! 331: } ! 332: ! 333: outl(port + UHA_OGM0,KVTOPHYS(mscp)); ! 334: outb(port + UHA_LINT, (UHA_OGMINT)); ! 335: splx(s); ! 336: } ! 337: ! 338: /***********************************************************************\ ! 339: * Function to send abort to 14f * ! 340: \***********************************************************************/ ! 341: ! 342: uha_abort( int unit ! 343: ,struct mscp *mscp) ! 344: { ! 345: int port = uha_data[unit].baseport; ! 346: int spincount = FUDGE(delaycount) * 1; ! 347: int abortcount = FUDGE(delaycount) * 2000; ! 348: int s = splbio(); ! 349: ! 350: while(((inb(port + UHA_LINT) & (UHA_LDIP)) ! 351: != (0)) ! 352: && (spincount--)); ! 353: if(spincount == -1); ! 354: { ! 355: printf("uha%d: board not responding\n",unit); ! 356: Debugger(); ! 357: } ! 358: ! 359: outl(port + UHA_OGM0,KVTOPHYS(mscp)); ! 360: outb(port + UHA_LINT,UHA_ABORT); ! 361: ! 362: while((abortcount--) && (!(inb(port + UHA_SINT) & UHA_ABORT_FAIL))); ! 363: if(abortcount == -1) ! 364: { ! 365: printf("uha%d: board not responding\n",unit); ! 366: Debugger(); ! 367: } ! 368: if((inb(port + UHA_SINT) & 0x10) != 0) ! 369: { ! 370: outb(port + UHA_SINT,UHA_ABORT_ACK); ! 371: return(1); ! 372: } ! 373: else ! 374: { ! 375: outb(port + UHA_SINT,UHA_ABORT_ACK); ! 376: return(0); ! 377: } ! 378: } ! 379: ! 380: /***********************************************************************\ ! 381: * Function to poll for command completion when in poll mode * ! 382: \***********************************************************************/ ! 383: uha_poll(int unit ,int wait) /* in msec */ ! 384: { ! 385: int port = uha_data[unit].baseport; ! 386: int spincount = FUDGE(delaycount) * wait; /* in msec */ ! 387: int stport = port + UHA_SINT; ! 388: int start = spincount; ! 389: ! 390: retry: ! 391: while( (spincount--) && (!(inb(stport) & UHA_SINTP))); ! 392: if(spincount == -1) ! 393: { ! 394: printf("uha%d: board not responding\n",unit); ! 395: return(EIO); ! 396: } ! 397: if ((int)cheat != PHYSTOKV(inl(port + UHA_ICM0))) ! 398: { ! 399: printf("discarding %x ",inl(port + UHA_ICM0)); ! 400: outb(port + UHA_SINT, UHA_ICM_ACK); ! 401: spinwait(50); ! 402: goto retry; ! 403: }/* don't know this will work */ ! 404: uhaintr(unit); ! 405: return(0); ! 406: } ! 407: ! 408: /*******************************************************\ ! 409: * Check if the device can be found at the port given * ! 410: * and if so, set it up ready for further work * ! 411: * as an argument, takes the isa_dev structure from * ! 412: * autoconf.c * ! 413: \*******************************************************/ ! 414: uhaprobe(dev) ! 415: struct isa_dev *dev; ! 416: { ! 417: int unit = uha_unit; ! 418: dev->dev_unit = unit; ! 419: uha_data[unit].baseport = dev->dev_addr; ! 420: if(unit >= NUHA) ! 421: { ! 422: printf("uha: unit number (%d) too high\n",unit); ! 423: return(0); ! 424: } ! 425: ! 426: /*try and initialize unit at this location*/ ! 427: if (uha_init(unit) != 0) ! 428: { ! 429: return(0); ! 430: } ! 431: ! 432: /* if its there put in it's interrupt and DRQ vectors */ ! 433: ! 434: dev->id_irq = (1 << uha_data[unit].vect); ! 435: dev->id_drq = uha_data[unit].dma; ! 436: ! 437: ! 438: uha_unit ++; ! 439: return(1); ! 440: } ! 441: ! 442: /***********************************************\ ! 443: * Attach all the sub-devices we can find * ! 444: \***********************************************/ ! 445: uha_attach(dev) ! 446: struct isa_dev *dev; ! 447: { ! 448: int unit = dev->dev_unit; ! 449: ! 450: ! 451: #ifdef __386BSD__ ! 452: printf("uha%d: probing for scsi devices..", unit); ! 453: #endif __386BSD__ ! 454: ! 455: /***********************************************\ ! 456: * ask the adapter what subunits are present * ! 457: \***********************************************/ ! 458: scsi_attachdevs( unit, uha_data[unit].our_id, &uha_switch); ! 459: ! 460: #if defined(OSF) ! 461: uha_attached[unit]=1; ! 462: #endif /* defined(OSF) */ ! 463: if(!unit) /* only one for all boards */ ! 464: { ! 465: uha_timeout(0); ! 466: } ! 467: return; ! 468: } ! 469: ! 470: /***********************************************\ ! 471: * Return some information to the caller about * ! 472: * the adapter and it's capabilities * ! 473: \***********************************************/ ! 474: long int uha_adapter_info(unit) ! 475: int unit; ! 476: { ! 477: return(2); /* 2 outstanding requests at a time per device */ ! 478: } ! 479: ! 480: /***********************************************\ ! 481: * Catch an interrupt from the adaptor * ! 482: \***********************************************/ ! 483: uhaintr(unit) ! 484: { ! 485: struct mscp *mscp; ! 486: u_char uhastat; ! 487: unsigned long int mboxval; ! 488: ! 489: int port = uha_data[unit].baseport; ! 490: ! 491: ! 492: if(scsi_debug & PRINTROUTINES) ! 493: printf("uhaintr "); ! 494: ! 495: #if defined(OSF) ! 496: if (!uha_attached[unit]) ! 497: { ! 498: return(1); ! 499: } ! 500: #endif /* defined(OSF) */ ! 501: while(inb(port + UHA_SINT) & UHA_SINTP) ! 502: { ! 503: /***********************************************\ ! 504: * First get all the information and then * ! 505: * acknowlege the interrupt * ! 506: \***********************************************/ ! 507: uhastat = inb(port + UHA_SINT); ! 508: mboxval = inl(port + UHA_ICM0); ! 509: outb(port + UHA_SINT,UHA_ICM_ACK); ! 510: ! 511: if(scsi_debug & TRACEINTERRUPTS) ! 512: printf("status = 0x%x ",uhastat); ! 513: /***********************************************\ ! 514: * Process the completed operation * ! 515: \***********************************************/ ! 516: ! 517: mscp = (struct mscp *)(PHYSTOKV(mboxval)); ! 518: ! 519: if(uha_debug & UHA_SHOWCMDS ) ! 520: { ! 521: uha_show_scsi_cmd(mscp->xs); ! 522: } ! 523: if((uha_debug & UHA_SHOWMSCPS) && mscp) ! 524: printf("<int mscp(%x)>",mscp); ! 525: uha_remove_timeout(mscp); ! 526: ! 527: uha_done(unit,mscp); ! 528: } ! 529: return(1); ! 530: } ! 531: ! 532: /***********************************************\ ! 533: * We have a mscp which has been processed by the * ! 534: * adaptor, now we look to see how the operation * ! 535: * went. * ! 536: \***********************************************/ ! 537: ! 538: uha_done(unit,mscp) ! 539: int unit; ! 540: struct mscp *mscp; ! 541: { ! 542: struct scsi_sense_data *s1,*s2; ! 543: struct scsi_xfer *xs = mscp->xs; ! 544: ! 545: if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS)) ! 546: printf("uha_done "); ! 547: /***********************************************\ ! 548: * Otherwise, put the results of the operation * ! 549: * into the xfer and call whoever started it * ! 550: \***********************************************/ ! 551: if ( (mscp->ha_status == UHA_NO_ERR) || (xs->flags & SCSI_ERR_OK)) ! 552: { /* All went correctly OR errors expected */ ! 553: xs->resid = 0; ! 554: xs->error = 0; ! 555: } ! 556: else ! 557: { ! 558: ! 559: s1 = &(mscp->mscp_sense); ! 560: s2 = &(xs->sense); ! 561: ! 562: if(mscp->ha_status != UHA_NO_ERR) ! 563: { ! 564: switch(mscp->ha_status) ! 565: { ! 566: case UHA_SBUS_TIMEOUT: /* No response */ ! 567: if (uha_debug & UHA_SHOWMISC) ! 568: { ! 569: printf("timeout reported back\n"); ! 570: } ! 571: xs->error = XS_TIMEOUT; ! 572: break; ! 573: case UHA_SBUS_OVER_UNDER: ! 574: if (uha_debug & UHA_SHOWMISC) ! 575: { ! 576: printf("scsi bus xfer over/underrun\n"); ! 577: } ! 578: xs->error = XS_DRIVER_STUFFUP; ! 579: break; ! 580: case UHA_BAD_SG_LIST: ! 581: if (uha_debug & UHA_SHOWMISC) ! 582: { ! 583: printf("bad sg list reported back\n"); ! 584: } ! 585: xs->error = XS_DRIVER_STUFFUP; ! 586: break; ! 587: default: /* Other scsi protocol messes */ ! 588: xs->error = XS_DRIVER_STUFFUP; ! 589: if (uha_debug & UHA_SHOWMISC) ! 590: { ! 591: printf("unexpected ha_status: %x\n", ! 592: mscp->ha_status); ! 593: } ! 594: } ! 595: ! 596: } ! 597: else ! 598: { ! 599: ! 600: if (mscp->targ_status != 0) ! 601: /**************************************************************************\ ! 602: * I have no information for any possible value of target status field * ! 603: * other than 0 means no error!! So I guess any error is unexpected in that * ! 604: * event!! * ! 605: \**************************************************************************/ ! 606: ! 607: { ! 608: if (uha_debug & UHA_SHOWMISC) ! 609: { ! 610: printf("unexpected targ_status: %x\n", ! 611: mscp->targ_status); ! 612: } ! 613: xs->error = XS_DRIVER_STUFFUP; ! 614: } ! 615: } ! 616: } ! 617: done: xs->flags |= ITSDONE; ! 618: uha_free_mscp(unit,mscp, xs->flags); ! 619: if(xs->when_done) ! 620: (*(xs->when_done))(xs->done_arg,xs->done_arg2); ! 621: } ! 622: ! 623: /***********************************************\ ! 624: * A mscp (and hence a mbx-out is put onto the * ! 625: * free list. * ! 626: \***********************************************/ ! 627: uha_free_mscp(unit,mscp, flags) ! 628: struct mscp *mscp; ! 629: { ! 630: unsigned int opri; ! 631: ! 632: if(scsi_debug & PRINTROUTINES) ! 633: printf("mscp%d(0x%x)> ",unit,flags); ! 634: if (!(flags & SCSI_NOMASK)) ! 635: opri = splbio(); ! 636: ! 637: mscp->next = uha_data[unit].free_mscp; ! 638: uha_data[unit].free_mscp = mscp; ! 639: mscp->flags = MSCP_FREE; ! 640: /***********************************************\ ! 641: * If there were none, wake abybody waiting for * ! 642: * one to come free, starting with queued entries* ! 643: \***********************************************/ ! 644: if (!mscp->next) { ! 645: wakeup(&uha_data[unit].free_mscp); ! 646: } ! 647: if (!(flags & SCSI_NOMASK)) ! 648: splx(opri); ! 649: } ! 650: ! 651: /***********************************************\ ! 652: * Get a free mscp (and hence mbox-out entry) * ! 653: \***********************************************/ ! 654: struct mscp * ! 655: uha_get_mscp(unit,flags) ! 656: { ! 657: unsigned opri; ! 658: struct mscp *rc; ! 659: ! 660: if(scsi_debug & PRINTROUTINES) ! 661: printf("<mscp%d(0x%x) ",unit,flags); ! 662: if (!(flags & SCSI_NOMASK)) ! 663: opri = splbio(); ! 664: /***********************************************\ ! 665: * If we can and have to, sleep waiting for one * ! 666: * to come free * ! 667: \***********************************************/ ! 668: while ((!(rc = uha_data[unit].free_mscp)) && (!(flags & SCSI_NOSLEEP))) ! 669: { ! 670: sleep(&uha_data[unit].free_mscp, PRIBIO); ! 671: } ! 672: if (rc) ! 673: { ! 674: uha_data[unit].free_mscp = rc->next; ! 675: rc->flags = MSCP_ACTIVE; ! 676: } ! 677: if (!(flags & SCSI_NOMASK)) ! 678: splx(opri); ! 679: return(rc); ! 680: } ! 681: ! 682: ! 683: ! 684: /***********************************************\ ! 685: * Start the board, ready for normal operation * ! 686: \***********************************************/ ! 687: ! 688: uha_init(unit) ! 689: int unit; ! 690: { ! 691: unsigned char ad[4]; ! 692: volatile unsigned char model; ! 693: volatile unsigned char submodel; ! 694: unsigned char config_reg1; ! 695: unsigned char config_reg2; ! 696: unsigned char dma_ch; ! 697: unsigned char irq_ch; ! 698: unsigned char uha_id; ! 699: int port = uha_data[unit].baseport; ! 700: int i; ! 701: int resetcount = FUDGE(delaycount) * 4000; ! 702: ! 703: model = inb(port + UHA_ID0); ! 704: submodel = inb(port + UHA_ID1); ! 705: if ((model != 0x56) & (submodel != 0x40)) ! 706: { /* printf("ultrastor 14f not responding\n"); */ ! 707: return(ENXIO); } ! 708: ! 709: printf("uha%d reading board settings, ",unit); ! 710: ! 711: config_reg1 = inb(port + UHA_CONF1); ! 712: config_reg2 = inb(port + UHA_CONF2); ! 713: dma_ch = (config_reg1 & 0xc0); ! 714: irq_ch = (config_reg1 & 0x30); ! 715: uha_id = (config_reg2 & 0x07); ! 716: ! 717: switch(dma_ch) ! 718: { ! 719: case UHA_DMA_CH5: ! 720: uha_data[unit].dma = 5; ! 721: printf("dma=5 "); ! 722: break; ! 723: case UHA_DMA_CH6: ! 724: uha_data[unit].dma = 6; ! 725: printf("dma=6 "); ! 726: break; ! 727: case UHA_DMA_CH7: ! 728: uha_data[unit].dma = 7; ! 729: printf("dma=7 "); ! 730: break; ! 731: default: ! 732: printf("illegal dma jumper setting\n"); ! 733: return(EIO); ! 734: } ! 735: switch(irq_ch) ! 736: { ! 737: case UHA_IRQ10: ! 738: uha_data[unit].vect = 10; ! 739: printf("int=10 "); ! 740: break; ! 741: case UHA_IRQ11: ! 742: uha_data[unit].vect = 11; ! 743: printf("int=11 "); ! 744: break; ! 745: case UHA_IRQ14: ! 746: uha_data[unit].vect = 14; ! 747: printf("int=14 "); ! 748: break; ! 749: case UHA_IRQ15: ! 750: uha_data[unit].vect = 15; ! 751: printf("int=15 "); ! 752: break; ! 753: default: ! 754: printf("illegal int jumper setting\n"); ! 755: return(EIO); ! 756: } ! 757: /* who are we on the scsi bus */ ! 758: printf("id=%x\n",uha_id); ! 759: uha_data[unit].our_id = uha_id; ! 760: ! 761: ! 762: /***********************************************\ ! 763: * link up all our MSCPs into a free list * ! 764: \***********************************************/ ! 765: for (i=0; i < NUM_CONCURRENT; i++) ! 766: { ! 767: uha_data[unit].mscps[i].next = uha_data[unit].free_mscp; ! 768: uha_data[unit].free_mscp = &uha_data[unit].mscps[i]; ! 769: uha_data[unit].free_mscp->flags = MSCP_FREE; ! 770: } ! 771: ! 772: /***********************************************\ ! 773: * Note that we are going and return (to probe) * ! 774: \***********************************************/ ! 775: outb(port + UHA_LINT, UHA_ASRST); ! 776: while( (resetcount--) && (!(inb(port + UHA_LINT)))); ! 777: if(resetcount == -1) ! 778: { ! 779: printf("uha%d: board timed out during reset\n",unit); ! 780: return(ENXIO); ! 781: } ! 782: ! 783: outb(port + UHA_SMASK, 0x81); /* make sure interrupts are enabled */ ! 784: uha_data[unit].flags |= UHA_INIT; ! 785: return(0); ! 786: } ! 787: ! 788: ! 789: ! 790: #ifndef min ! 791: #define min(x,y) (x < y ? x : y) ! 792: #endif min ! 793: ! 794: ! 795: void uhaminphys(bp) ! 796: struct buf *bp; ! 797: { ! 798: #ifdef MACH ! 799: #if !defined(OSF) ! 800: bp->b_flags |= B_NPAGES; /* can support scat/gather */ ! 801: #endif /* defined(OSF) */ ! 802: #endif MACH ! 803: if(bp->b_bcount > ((UHA_NSEG-1) * PAGESIZ)) ! 804: { ! 805: bp->b_bcount = ((UHA_NSEG-1) * PAGESIZ); ! 806: } ! 807: } ! 808: ! 809: /***********************************************\ ! 810: * start a scsi operation given the command and * ! 811: * the data address. Also needs the unit, target * ! 812: * and lu * ! 813: \***********************************************/ ! 814: int uha_scsi_cmd(xs) ! 815: struct scsi_xfer *xs; ! 816: { ! 817: struct scsi_sense_data *s1,*s2; ! 818: struct mscp *mscp; ! 819: struct uha_dma_seg *sg; ! 820: int seg; /* scatter gather seg being worked on */ ! 821: int i = 0; ! 822: int rc = 0; ! 823: int thiskv; ! 824: unsigned long int thisphys,nextphys; ! 825: int unit =xs->adapter; ! 826: int bytes_this_seg,bytes_this_page,datalen,flags; ! 827: struct iovec *iovp; ! 828: int s; ! 829: unsigned int stat; ! 830: int port = uha_data[unit].baseport; ! 831: unsigned long int templen; ! 832: ! 833: ! 834: if(scsi_debug & PRINTROUTINES) ! 835: printf("uha_scsi_cmd "); ! 836: /***********************************************\ ! 837: * get a mscp (mbox-out) to use. If the transfer * ! 838: * is from a buf (possibly from interrupt time) * ! 839: * then we can't allow it to sleep * ! 840: \***********************************************/ ! 841: flags = xs->flags; ! 842: if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */ ! 843: if(flags & ITSDONE) ! 844: { ! 845: printf("Already done?"); ! 846: xs->flags &= ~ITSDONE; ! 847: } ! 848: if(!(flags & INUSE)) ! 849: { ! 850: printf("Not in use?"); ! 851: xs->flags |= INUSE; ! 852: } ! 853: if (!(mscp = uha_get_mscp(unit,flags))) ! 854: { ! 855: xs->error = XS_DRIVER_STUFFUP; ! 856: return(TRY_AGAIN_LATER); ! 857: } ! 858: ! 859: cheat = mscp; ! 860: if(uha_debug & UHA_SHOWMSCPS) ! 861: printf("<start mscp(%x)>",mscp); ! 862: if(scsi_debug & SHOWCOMMANDS) ! 863: { ! 864: uha_show_scsi_cmd(xs); ! 865: } ! 866: mscp->xs = xs; ! 867: /***********************************************\ ! 868: * Put all the arguments for the xfer in the mscp * ! 869: \***********************************************/ ! 870: ! 871: if (flags & SCSI_RESET) ! 872: { ! 873: mscp->opcode = 0x04; ! 874: mscp->ca = 0x01; ! 875: } ! 876: else ! 877: { ! 878: mscp->opcode = 0x02; ! 879: mscp->ca = 0x01; ! 880: } ! 881: ! 882: if (flags & SCSI_DATA_IN) ! 883: { ! 884: mscp->xdir = 0x01; ! 885: } ! 886: if (flags & SCSI_DATA_OUT) ! 887: { ! 888: mscp->xdir = 0x02; ! 889: } ! 890: ! 891: if (xs->lu != 0) ! 892: { ! 893: xs->error = XS_DRIVER_STUFFUP; ! 894: uha_free_mscp(unit,mscp,flags); ! 895: return(HAD_ERROR); ! 896: } ! 897: ! 898: mscp->dcn = 0x00; ! 899: mscp->chan = 0x00; ! 900: mscp->target = xs->targ; ! 901: mscp->lun = xs->lu; ! 902: mscp->link.addr[0] = 0x00; ! 903: mscp->link.addr[1] = 0x00; ! 904: mscp->link.addr[2] = 0x00; ! 905: mscp->link.addr[3] = 0x00; ! 906: mscp->link_id = 0x00; ! 907: mscp->cdblen = xs->cmdlen; ! 908: scratch = KVTOPHYS(&(mscp->mscp_sense)); ! 909: mscp->sense.addr[0] = (scratch & 0xff); ! 910: mscp->sense.addr[1] = ((scratch >> 8) & 0xff); ! 911: mscp->sense.addr[2] = ((scratch >> 16) & 0xff); ! 912: mscp->sense.addr[3] = ((scratch >> 24) & 0xff); ! 913: mscp->senselen = sizeof(mscp->mscp_sense); ! 914: mscp->ha_status = 0x00; ! 915: mscp->targ_status = 0x00; ! 916: ! 917: if(xs->datalen) ! 918: { /* should use S/G only if not zero length */ ! 919: scratch = KVTOPHYS(mscp->uha_dma); ! 920: mscp->data.addr[0] = (scratch & 0xff); ! 921: mscp->data.addr[1] = ((scratch >> 8) & 0xff); ! 922: mscp->data.addr[2] = ((scratch >> 16) & 0xff); ! 923: mscp->data.addr[3] = ((scratch >> 24) & 0xff); ! 924: sg = mscp->uha_dma ; ! 925: seg = 0; ! 926: mscp->sgth = 0x01; ! 927: ! 928: if(flags & SCSI_DATA_UIO) ! 929: { ! 930: iovp = ((struct uio *)xs->data)->uio_iov; ! 931: datalen = ((struct uio *)xs->data)->uio_iovcnt; ! 932: xs->datalen = 0; ! 933: while ((datalen) && (seg < UHA_NSEG)) ! 934: { ! 935: scratch = (unsigned long)iovp->iov_base; ! 936: sg->addr.addr[0] = (scratch & 0xff); ! 937: sg->addr.addr[1] = ((scratch >> 8) & 0xff); ! 938: sg->addr.addr[2] = ((scratch >> 16) & 0xff); ! 939: sg->addr.addr[3] = ((scratch >> 24) & 0xff); ! 940: xs->datalen += *(unsigned long *)sg->len.len = iovp->iov_len; ! 941: if(scsi_debug & SHOWSCATGATH) ! 942: printf("(0x%x@0x%x)" ! 943: ,iovp->iov_len ! 944: ,iovp->iov_base); ! 945: sg++; ! 946: iovp++; ! 947: seg++; ! 948: datalen--; ! 949: } ! 950: } ! 951: else ! 952: { ! 953: /***********************************************\ ! 954: * Set up the scatter gather block * ! 955: \***********************************************/ ! 956: ! 957: if(scsi_debug & SHOWSCATGATH) ! 958: printf("%d @0x%x:- ",xs->datalen,xs->data); ! 959: datalen = xs->datalen; ! 960: thiskv = (int)xs->data; ! 961: thisphys = KVTOPHYS(thiskv); ! 962: templen = 0; ! 963: ! 964: while ((datalen) && (seg < UHA_NSEG)) ! 965: { ! 966: bytes_this_seg = 0; ! 967: ! 968: /* put in the base address */ ! 969: sg->addr.addr[0] = (thisphys & 0xff); ! 970: sg->addr.addr[1] = ((thisphys >> 8) & 0xff); ! 971: sg->addr.addr[2] = ((thisphys >> 16) & 0xff); ! 972: sg->addr.addr[3] = ((thisphys >> 24) & 0xff); ! 973: ! 974: if(scsi_debug & SHOWSCATGATH) ! 975: printf("0x%x",thisphys); ! 976: ! 977: /* do it at least once */ ! 978: nextphys = thisphys; ! 979: while ((datalen) && (thisphys == nextphys)) ! 980: /*********************************************\ ! 981: * This page is contiguous (physically) with * ! 982: * the the last, just extend the length * ! 983: \*********************************************/ ! 984: { ! 985: /* how far to the end of the page */ ! 986: nextphys = (thisphys & (~(PAGESIZ - 1))) ! 987: + PAGESIZ; ! 988: bytes_this_page = nextphys - thisphys; ! 989: /**** or the data ****/ ! 990: bytes_this_page = min(bytes_this_page ! 991: ,datalen); ! 992: bytes_this_seg += bytes_this_page; ! 993: datalen -= bytes_this_page; ! 994: ! 995: /* get more ready for the next page */ ! 996: thiskv = (thiskv & (~(PAGESIZ - 1))) ! 997: + PAGESIZ; ! 998: if(datalen) ! 999: thisphys = KVTOPHYS(thiskv); ! 1000: } ! 1001: /********************************************\ ! 1002: * next page isn't contiguous, finish the seg * ! 1003: \********************************************/ ! 1004: if(scsi_debug & SHOWSCATGATH) ! 1005: printf("(0x%x)",bytes_this_seg); ! 1006: sg->len.len[0] = (bytes_this_seg & 0xff); ! 1007: sg->len.len[1] = ((bytes_this_seg >> 8) & 0xff); ! 1008: sg->len.len[2] = ((bytes_this_seg >> 16) & 0xff); ! 1009: sg->len.len[3] = ((bytes_this_seg >> 24) & 0xff); ! 1010: templen += bytes_this_seg; ! 1011: sg++; ! 1012: seg++; ! 1013: } ! 1014: } /*end of iov/kv decision */ ! 1015: mscp->datalen.len[0] = (templen & 0xff); ! 1016: mscp->datalen.len[1] = ((templen >> 8) & 0xff); ! 1017: mscp->datalen.len[2] = ((templen >> 16) & 0xff); ! 1018: mscp->datalen.len[3] = ((templen >> 24) & 0xff); ! 1019: mscp->sg_num = seg; ! 1020: ! 1021: if(scsi_debug & SHOWSCATGATH) ! 1022: printf("\n"); ! 1023: if (datalen) ! 1024: { /* there's still data, must have run out of segs! */ ! 1025: printf("uha_scsi_cmd%d: more than %d DMA segs\n", ! 1026: unit,UHA_NSEG); ! 1027: xs->error = XS_DRIVER_STUFFUP; ! 1028: uha_free_mscp(unit,mscp,flags); ! 1029: return(HAD_ERROR); ! 1030: } ! 1031: ! 1032: } ! 1033: else ! 1034: { /* No data xfer, use non S/G values */ ! 1035: mscp->data.addr[0] = 0x00; ! 1036: mscp->data.addr[1] = 0x00; ! 1037: mscp->data.addr[2] = 0x00; ! 1038: mscp->data.addr[3] = 0x00; ! 1039: mscp->datalen.len[0] = 0x00; ! 1040: mscp->datalen.len[1] = 0x00; ! 1041: mscp->datalen.len[2] = 0x00; ! 1042: mscp->datalen.len[3] = 0x00; ! 1043: mscp->xdir = 0x03; ! 1044: mscp->sgth = 0x00; ! 1045: mscp->sg_num = 0x00; ! 1046: } ! 1047: ! 1048: /***********************************************\ ! 1049: * Put the scsi command in the mscp and start it * ! 1050: \***********************************************/ ! 1051: bcopy(xs->cmd, mscp->cdb, xs->cmdlen); ! 1052: ! 1053: /***********************************************\ ! 1054: * Usually return SUCCESSFULLY QUEUED * ! 1055: \***********************************************/ ! 1056: if (!(flags & SCSI_NOMASK)) ! 1057: { ! 1058: s = splbio(); ! 1059: uha_send_mbox(unit,mscp); ! 1060: uha_add_timeout(mscp,xs->timeout); ! 1061: splx(s); ! 1062: if(scsi_debug & TRACEINTERRUPTS) ! 1063: printf("cmd_sent "); ! 1064: return(SUCCESSFULLY_QUEUED); ! 1065: } ! 1066: /***********************************************\ ! 1067: * If we can't use interrupts, poll on completion* ! 1068: \***********************************************/ ! 1069: uha_send_mbox(unit,mscp); ! 1070: if(scsi_debug & TRACEINTERRUPTS) ! 1071: printf("cmd_wait "); ! 1072: do ! 1073: { ! 1074: if(uha_poll(unit,xs->timeout)) ! 1075: { ! 1076: if (!(xs->flags & SCSI_SILENT)) printf("cmd fail\n"); ! 1077: if(!(uha_abort(unit,mscp))) ! 1078: { ! 1079: printf("abort failed in wait\n"); ! 1080: uha_free_mscp(unit,mscp,flags); ! 1081: } ! 1082: xs->error = XS_DRIVER_STUFFUP; ! 1083: splx(s); ! 1084: return(HAD_ERROR); ! 1085: } ! 1086: } while (!(xs->flags & ITSDONE));/* something (?) else finished */ ! 1087: splx(s); ! 1088: scsi_debug = 0;uha_debug = 0; ! 1089: if(xs->error) ! 1090: { ! 1091: return(HAD_ERROR); ! 1092: } ! 1093: return(COMPLETE); ! 1094: } ! 1095: ! 1096: /* ! 1097: * +----------+ +----------+ +----------+ ! 1098: * uha_soonest--->| later |--->| later|--->| later|--->0 ! 1099: * | [Delta] | | [Delta] | | [Delta] | ! 1100: * 0<---|sooner |<---|sooner |<---|sooner |<---uha_latest ! 1101: * +----------+ +----------+ +----------+ ! 1102: * ! 1103: * uha_furtherest = sum(Delta[1..n]) ! 1104: */ ! 1105: uha_add_timeout(mscp,time) ! 1106: struct mscp *mscp; ! 1107: int time; ! 1108: { ! 1109: int timeprev; ! 1110: struct mscp *prev; ! 1111: int s = splbio(); ! 1112: ! 1113: if(prev = uha_latest) /* yes, an assign */ ! 1114: { ! 1115: timeprev = uha_furtherest; ! 1116: } ! 1117: else ! 1118: { ! 1119: timeprev = 0; ! 1120: } ! 1121: while(prev && (timeprev > time)) ! 1122: { ! 1123: timeprev -= prev->delta; ! 1124: prev = prev->sooner; ! 1125: } ! 1126: if(prev) ! 1127: { ! 1128: mscp->delta = time - timeprev; ! 1129: if( mscp->later = prev->later) /* yes an assign */ ! 1130: { ! 1131: mscp->later->sooner = mscp; ! 1132: mscp->later->delta -= mscp->delta; ! 1133: } ! 1134: else ! 1135: { ! 1136: uha_furtherest = time; ! 1137: uha_latest = mscp; ! 1138: } ! 1139: mscp->sooner = prev; ! 1140: prev->later = mscp; ! 1141: } ! 1142: else ! 1143: { ! 1144: if( mscp->later = uha_soonest) /* yes, an assign*/ ! 1145: { ! 1146: mscp->later->sooner = mscp; ! 1147: mscp->later->delta -= time; ! 1148: } ! 1149: else ! 1150: { ! 1151: uha_furtherest = time; ! 1152: uha_latest = mscp; ! 1153: } ! 1154: mscp->delta = time; ! 1155: mscp->sooner = (struct mscp *)0; ! 1156: uha_soonest = mscp; ! 1157: } ! 1158: splx(s); ! 1159: } ! 1160: ! 1161: uha_remove_timeout(mscp) ! 1162: struct mscp *mscp; ! 1163: { ! 1164: int s = splbio(); ! 1165: ! 1166: if(mscp->sooner) ! 1167: { ! 1168: mscp->sooner->later = mscp->later; ! 1169: } ! 1170: else ! 1171: { ! 1172: uha_soonest = mscp->later; ! 1173: } ! 1174: if(mscp->later) ! 1175: { ! 1176: mscp->later->sooner = mscp->sooner; ! 1177: mscp->later->delta += mscp->delta; ! 1178: } ! 1179: else ! 1180: { ! 1181: uha_latest = mscp->sooner; ! 1182: uha_furtherest -= mscp->delta; ! 1183: } ! 1184: mscp->sooner = mscp->later = (struct mscp *)0; ! 1185: splx(s); ! 1186: } ! 1187: ! 1188: ! 1189: extern int hz; ! 1190: #define ONETICK 500 /* milliseconds */ ! 1191: #define SLEEPTIME ((hz * 1000) / ONETICK) ! 1192: uha_timeout(arg) ! 1193: int arg; ! 1194: { ! 1195: struct mscp *mscp; ! 1196: int unit; ! 1197: int s = splbio(); ! 1198: unsigned int stat; ! 1199: int port = uha_data[unit].baseport; ! 1200: ! 1201: while( mscp = uha_soonest ) ! 1202: { ! 1203: if(mscp->delta <= ONETICK) ! 1204: /***********************************************\ ! 1205: * It has timed out, we need to do some work * ! 1206: \***********************************************/ ! 1207: { ! 1208: unit = mscp->xs->adapter; ! 1209: printf("uha%d:%d device timed out\n",unit ! 1210: ,mscp->xs->targ); ! 1211: if(uha_debug & UHA_SHOWMSCPS) ! 1212: uha_print_active_mscp(); ! 1213: ! 1214: /***************************************\ ! 1215: * Unlink it from the queue * ! 1216: \***************************************/ ! 1217: uha_remove_timeout(mscp); ! 1218: ! 1219: if((uha_abort(unit,mscp) !=1) || (mscp->flags = MSCP_ABORTED)) ! 1220: { ! 1221: printf("AGAIN"); ! 1222: mscp->xs->retries = 0; /* I MEAN IT ! */ ! 1223: uha_done(unit,mscp,FAIL); ! 1224: } ! 1225: else /* abort the operation that has timed out */ ! 1226: { ! 1227: printf("\n"); ! 1228: uha_add_timeout(mscp,2000 + ONETICK); ! 1229: mscp->flags = MSCP_ABORTED; ! 1230: } ! 1231: } ! 1232: else ! 1233: /***********************************************\ ! 1234: * It has not timed out, adjust and leave * ! 1235: \***********************************************/ ! 1236: { ! 1237: mscp->delta -= ONETICK; ! 1238: uha_furtherest -= ONETICK; ! 1239: break; ! 1240: } ! 1241: } ! 1242: splx(s); ! 1243: timeout(uha_timeout,arg,SLEEPTIME); ! 1244: } ! 1245: ! 1246: uha_show_scsi_cmd(struct scsi_xfer *xs) ! 1247: { ! 1248: u_char *b = (u_char *)xs->cmd; ! 1249: int i = 0; ! 1250: if(!(xs->flags & SCSI_RESET)) ! 1251: { ! 1252: printf("uha%d:%d:%d-" ! 1253: ,xs->adapter ! 1254: ,xs->targ ! 1255: ,xs->lu); ! 1256: while(i < xs->cmdlen ) ! 1257: { ! 1258: if(i) printf(","); ! 1259: printf("%x",b[i++]); ! 1260: } ! 1261: printf("-\n"); ! 1262: } ! 1263: else ! 1264: { ! 1265: printf("uha%d:%d:%d-RESET-\n" ! 1266: ,xs->adapter ! 1267: ,xs->targ ! 1268: ,xs->lu ! 1269: ); ! 1270: } ! 1271: } ! 1272: uha_print_mscp(mscp) ! 1273: struct mscp *mscp; ! 1274: { ! 1275: printf("mscp:%x op:%x cmdlen:%d senlen:%d\n" ! 1276: ,mscp ! 1277: ,mscp->opcode ! 1278: ,mscp->cdblen ! 1279: ,mscp->senselen); ! 1280: printf(" sg:%d sgnum:%x datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n" ! 1281: ,mscp->sgth ! 1282: ,mscp->sg_num ! 1283: ,mscp->datalen ! 1284: ,mscp->ha_status ! 1285: ,mscp->targ_status ! 1286: ,mscp->delta ! 1287: ,mscp->flags); ! 1288: uha_show_scsi_cmd(mscp->xs); ! 1289: } ! 1290: ! 1291: uha_print_active_mscp() ! 1292: { ! 1293: struct mscp *mscp; ! 1294: mscp = uha_soonest; ! 1295: ! 1296: while(mscp) ! 1297: { ! 1298: uha_print_mscp(mscp); ! 1299: mscp = mscp->later; ! 1300: } ! 1301: printf("Furtherest = %d\n",uha_furtherest); ! 1302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.