diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2000-02-05 22:20:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2000-02-05 22:20:40 +0000 |
commit | 1be6b642c8029081cd4100963cf7fe29e5302433 (patch) | |
tree | 1e27b6f913d1da40cc90528e8c7e1a15bba25254 /sys/dev/ic | |
parent | 456fb07557d109ce9616d179ed46717eeaa06b50 (diff) |
support new u2w cards; dante@mclink.it, merged by kwesterback@home.com
Diffstat (limited to 'sys/dev/ic')
-rw-r--r-- | sys/dev/ic/adw.c | 634 | ||||
-rw-r--r-- | sys/dev/ic/adw.h | 91 | ||||
-rw-r--r-- | sys/dev/ic/adwlib.c | 2329 | ||||
-rw-r--r-- | sys/dev/ic/adwlib.h | 611 | ||||
-rw-r--r-- | sys/dev/ic/adwmcode.c | 967 | ||||
-rw-r--r-- | sys/dev/ic/adwmcode.h | 15 |
6 files changed, 3368 insertions, 1279 deletions
diff --git a/sys/dev/ic/adw.c b/sys/dev/ic/adw.c index bd5c15860c3..e5f5272fca7 100644 --- a/sys/dev/ic/adw.c +++ b/sys/dev/ic/adw.c @@ -1,10 +1,9 @@ -/* $OpenBSD: adw.c,v 1.2 1999/08/04 23:27:48 niklas Exp $ */ -/* $NetBSD: adw.c,v 1.3 1998/10/10 00:28:33 thorpej Exp $ */ +/* $NetBSD: adw.c,v 1.13 2000/02/03 20:29:15 dante Exp $ */ /* * Generic driver for the Advanced Systems Inc. SCSI controllers * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -64,7 +63,7 @@ #include <dev/ic/adw.h> #ifndef DDB -#define Debugger() panic("should call debugger here (adv.c)") +#define Debugger() panic("should call debugger here (adw.c)") #endif /* ! DDB */ /******************************************************************************/ @@ -73,24 +72,26 @@ static void adw_enqueue __P((ADW_SOFTC *, struct scsi_xfer *, int)); static struct scsi_xfer *adw_dequeue __P((ADW_SOFTC *)); -static int adw_alloc_ccbs __P((ADW_SOFTC *)); +static int adw_alloc_controls __P((ADW_SOFTC *)); +static int adw_alloc_carriers __P((ADW_SOFTC *)); +static int adw_create_carriers __P((ADW_SOFTC *)); +static int adw_init_carrier __P((ADW_SOFTC *, ADW_CARRIER *)); static int adw_create_ccbs __P((ADW_SOFTC *, ADW_CCB *, int)); static void adw_free_ccb __P((ADW_SOFTC *, ADW_CCB *)); static void adw_reset_ccb __P((ADW_CCB *)); static int adw_init_ccb __P((ADW_SOFTC *, ADW_CCB *)); static ADW_CCB *adw_get_ccb __P((ADW_SOFTC *, int)); -static void adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *)); -static void adw_start_ccbs __P((ADW_SOFTC *)); +static int adw_queue_ccb __P((ADW_SOFTC *, ADW_CCB *, int)); static int adw_scsi_cmd __P((struct scsi_xfer *)); static int adw_build_req __P((struct scsi_xfer *, ADW_CCB *)); -static void adw_build_sglist __P((ADW_CCB *, ADW_SCSI_REQ_Q *)); +static void adw_build_sglist __P((ADW_CCB *, ADW_SCSI_REQ_Q *, ADW_SG_BLOCK *)); static void adwminphys __P((struct buf *)); -static void adw_wide_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *)); +static void adw_isr_callback __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *)); +static void adw_async_callback __P((ADW_SOFTC *, u_int8_t)); static int adw_poll __P((ADW_SOFTC *, struct scsi_xfer *, int)); static void adw_timeout __P((void *)); -static void adw_watchdog __P((void *)); /******************************************************************************/ @@ -100,16 +101,6 @@ struct cfdriver adw_cd = { NULL, "adw", DV_DULL }; - -struct scsi_adapter adw_switch = -{ - adw_scsi_cmd, /* called to start/enqueue a SCSI command */ - adwminphys, /* to limit the transfer to max device can do */ - 0, - 0, -}; - - /* the below structure is so we have a default dev struct for out link struct */ struct scsi_device adw_dev = { @@ -125,7 +116,7 @@ struct scsi_device adw_dev = /******************************************************************************/ -/* scsi_xfer queue routines */ +/* scsi_xfer queue routines */ /******************************************************************************/ /* @@ -169,21 +160,20 @@ adw_dequeue(sc) return (xs); } - /******************************************************************************/ -/* Control Blocks routines */ +/* Control Blocks routines */ /******************************************************************************/ static int -adw_alloc_ccbs(sc) +adw_alloc_controls(sc) ADW_SOFTC *sc; { bus_dma_segment_t seg; int error, rseg; /* - * Allocate the control blocks. + * Allocate the control structure. */ if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct adw_control), NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { @@ -198,6 +188,7 @@ adw_alloc_ccbs(sc) sc->sc_dev.dv_xname, error); return (error); } + /* * Create and load the DMA map used for the control blocks. */ @@ -215,11 +206,164 @@ adw_alloc_ccbs(sc) sc->sc_dev.dv_xname, error); return (error); } + + return (0); +} + + +static int +adw_alloc_carriers(sc) + ADW_SOFTC *sc; +{ + bus_dma_segment_t seg; + int error, rseg; + + /* + * Allocate the control structure. + */ + sc->sc_control->carriers = malloc(ADW_CARRIER_SIZE * ADW_MAX_CARRIER, + M_DEVBUF, M_WAITOK); + if(!sc->sc_control->carriers) { + printf("%s: malloc() failed in allocating carrier structures," + " error = %d\n", sc->sc_dev.dv_xname, error); + return (error); + } + + if ((error = bus_dmamem_alloc(sc->sc_dmat, + ADW_CARRIER_SIZE * ADW_MAX_CARRIER, + NBPG, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { + printf("%s: unable to allocate carrier structures," + " error = %d\n", sc->sc_dev.dv_xname, error); + return (error); + } + if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, + ADW_CARRIER_SIZE * ADW_MAX_CARRIER, + (caddr_t *) &sc->sc_control->carriers, + BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { + printf("%s: unable to map carrier structures," + " error = %d\n", sc->sc_dev.dv_xname, error); + return (error); + } + + /* + * Create and load the DMA map used for the control blocks. + */ + if ((error = bus_dmamap_create(sc->sc_dmat, + ADW_CARRIER_SIZE * ADW_MAX_CARRIER, 1, + ADW_CARRIER_SIZE * ADW_MAX_CARRIER, 0, BUS_DMA_NOWAIT, + &sc->sc_dmamap_carrier)) != 0) { + printf("%s: unable to create carriers DMA map," + " error = %d\n", sc->sc_dev.dv_xname, error); + return (error); + } + if ((error = bus_dmamap_load(sc->sc_dmat, + sc->sc_dmamap_carrier, sc->sc_control->carriers, + ADW_CARRIER_SIZE * ADW_MAX_CARRIER, NULL, + BUS_DMA_NOWAIT)) != 0) { + printf("%s: unable to load carriers DMA map," + " error = %d\n", sc->sc_dev.dv_xname, error); + return (error); + } + + error = bus_dmamap_create(sc->sc_dmat, ADW_CARRIER_SIZE* ADW_MAX_CARRIER, + 1, ADW_CARRIER_SIZE * ADW_MAX_CARRIER, + 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, + &sc->sc_control->dmamap_xfer); + if (error) { + printf("%s: unable to create Carrier DMA map, error = %d\n", + sc->sc_dev.dv_xname, error); + return (error); + } + return (0); } /* + * Create a set of Carriers and add them to the free list. Called once + * by adw_init(). We return the number of Carriers successfully created. + */ +static int +adw_create_carriers(sc) + ADW_SOFTC *sc; +{ + ADW_CARRIER *carr; + u_int32_t carr_next = NULL; + int i, error; + + for(i=0; i < ADW_MAX_CARRIER; i++) { + carr = (ADW_CARRIER *)(((u_int8_t *)sc->sc_control->carriers) + + (ADW_CARRIER_SIZE * i)); + if ((error = adw_init_carrier(sc, carr)) != 0) { + printf("%s: unable to initialize carrier, error = %d\n", + sc->sc_dev.dv_xname, error); + return (i); + } + carr->next_vpa = carr_next; + carr_next = carr->carr_pa; +carr->id = i; + } + sc->carr_freelist = carr; + return (i); +} + + +static int +adw_init_carrier(sc, carr) + ADW_SOFTC *sc; + ADW_CARRIER *carr; +{ + u_int32_t carr_pa; + int /*error, */hashnum; + + /* + * Create the DMA map for all of the Carriers. + */ +/* error = bus_dmamap_create(sc->sc_dmat, ADW_CARRIER_SIZE, + 1, ADW_CARRIER_SIZE, + 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, + &carr->dmamap_xfer); + if (error) { + printf("%s: unable to create Carrier DMA map, error = %d\n", + sc->sc_dev.dv_xname, error); + return (error); + } +*/ + /* + * put in the phystokv hash table + * Never gets taken out. + */ + carr_pa = ADW_CARRIER_ADDR(sc, carr); + carr->carr_pa = carr_pa; + hashnum = CARRIER_HASH(carr_pa); + carr->nexthash = sc->sc_carrhash[hashnum]; + sc->sc_carrhash[hashnum] = carr; + + return(0); +} + + +/* + * Given a physical address, find the Carrier that it corresponds to. + */ +ADW_CARRIER * +adw_carrier_phys_kv(sc, carr_phys) + ADW_SOFTC *sc; + u_int32_t carr_phys; +{ + int hashnum = CARRIER_HASH(carr_phys); + ADW_CARRIER *carr = sc->sc_carrhash[hashnum]; + + while (carr) { + if (carr->carr_pa == carr_phys) + break; + carr = carr->nexthash; + } + return (carr); +} + + +/* * Create a set of ccbs and add them to the free list. Called once * by adw_init(). We return the number of CCBs successfully created. */ @@ -232,7 +376,6 @@ adw_create_ccbs(sc, ccbstore, count) ADW_CCB *ccb; int i, error; - bzero(ccbstore, sizeof(ADW_CCB) * count); for (i = 0; i < count; i++) { ccb = &ccbstore[i]; if ((error = adw_init_ccb(sc, ccb)) != 0) { @@ -287,7 +430,7 @@ adw_init_ccb(sc, ccb) ADW_SOFTC *sc; ADW_CCB *ccb; { - int error; + int hashnum, error; /* * Create the DMA map for this CCB. @@ -297,10 +440,20 @@ adw_init_ccb(sc, ccb) ADW_MAX_SG_LIST, (ADW_MAX_SG_LIST - 1) * PAGE_SIZE, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer); if (error) { - printf("%s: unable to create DMA map, error = %d\n", + printf("%s: unable to create CCB DMA map, error = %d\n", sc->sc_dev.dv_xname, error); return (error); } + + /* + * put in the phystokv hash table + * Never gets taken out. + */ + ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr + + ADW_CCB_OFF(ccb); + hashnum = CCB_HASH(ccb->hashkey); + ccb->nexthash = sc->sc_ccbhash[hashnum]; + sc->sc_ccbhash[hashnum] = ccb; adw_reset_ccb(ccb); return (0); } @@ -346,46 +499,68 @@ out: /* - * Queue a CCB to be sent to the controller, and send it if possible. + * Given a physical address, find the ccb that it corresponds to. */ -static void -adw_queue_ccb(sc, ccb) - ADW_SOFTC *sc; - ADW_CCB *ccb; +ADW_CCB * +adw_ccb_phys_kv(sc, ccb_phys) + ADW_SOFTC *sc; + u_int32_t ccb_phys; { + int hashnum = CCB_HASH(ccb_phys); + ADW_CCB *ccb = sc->sc_ccbhash[hashnum]; - TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain); - - adw_start_ccbs(sc); + while (ccb) { + if (ccb->hashkey == ccb_phys) + break; + ccb = ccb->nexthash; + } + return (ccb); } -static void -adw_start_ccbs(sc) +/* + * Queue a CCB to be sent to the controller, and send it if possible. + */ +static int +adw_queue_ccb(sc, ccb, retry) ADW_SOFTC *sc; -{ ADW_CCB *ccb; + int retry; +{ + int errcode; + + if(!retry) + TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain); while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) { - if (ccb->flags & CCB_WATCHDOG) - untimeout(adw_watchdog, ccb); - if (AdvExeScsiQueue(sc, &ccb->scsiq) == ADW_BUSY) { - ccb->flags |= CCB_WATCHDOG; - timeout(adw_watchdog, ccb, - (ADW_WATCH_TIMEOUT * hz) / 1000); + errcode = AdvExeScsiQueue(sc, &ccb->scsiq); + switch(errcode) { + case ADW_SUCCESS: break; + + case ADW_BUSY: + printf("ADW_BUSY\n"); + return(ADW_BUSY); + + case ADW_ERROR: + printf("ADW_ERROR\n"); + TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain); + return(ADW_ERROR); } + TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain); if ((ccb->xs->flags & SCSI_POLL) == 0) timeout(adw_timeout, ccb, (ccb->timeout * hz) / 1000); } + + return(errcode); } /******************************************************************************/ -/* SCSI layer interfacing routines */ +/* SCSI layer interfacing routines */ /******************************************************************************/ @@ -409,7 +584,10 @@ adw_init(sc) } else { AdvResetChip(sc->sc_iot, sc->sc_ioh); - warn_code = AdvInitFromEEP(sc); + warn_code = (sc->chip_type == ADV_CHIP_ASC3550)? + AdvInitFrom3550EEP(sc) : + AdvInitFrom38C0800EEP(sc); + if (warn_code & ASC_WARN_EEPROM_CHKSUM) printf("%s: Bad checksum found. " "Setting default values\n", @@ -418,16 +596,10 @@ adw_init(sc) printf("%s: Bad bus termination setting." "Using automatic termination.\n", sc->sc_dev.dv_xname); - - /* - * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus - * Resets should be performed. - */ - if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) - AdvResetSCSIBus(sc); } - sc->isr_callback = (ulong) adw_wide_isr_callback; + sc->isr_callback = (ADW_CALLBACK) adw_isr_callback; + sc->async_callback = (ADW_CALLBACK) adw_async_callback; return (0); } @@ -440,10 +612,61 @@ adw_attach(sc) int i, error; + TAILQ_INIT(&sc->sc_free_ccb); + TAILQ_INIT(&sc->sc_waiting_ccb); + LIST_INIT(&sc->sc_queue); + + + /* + * Allocate the Control Blocks. + */ + error = adw_alloc_controls(sc); + if (error) + return; /* (error) */ ; + + bzero(sc->sc_control, sizeof(struct adw_control)); + + /* + * Create and initialize the Control Blocks. + */ + i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB); + if (i == 0) { + printf("%s: unable to create Control Blocks\n", + sc->sc_dev.dv_xname); + return; /* (ENOMEM) */ ; + } else if (i != ADW_MAX_CCB) { + printf("%s: WARNING: only %d of %d Control Blocks" + " created\n", + sc->sc_dev.dv_xname, i, ADW_MAX_CCB); + } + + /* + * Create and initialize the Carriers. + */ + error = adw_alloc_carriers(sc); + if (error) + return; /* (error) */ ; + + bzero(sc->sc_control->carriers, ADW_CARRIER_SIZE * ADW_MAX_CARRIER); + + i = adw_create_carriers(sc); + if (i == 0) { + printf("%s: unable to create Carriers\n", + sc->sc_dev.dv_xname); + return; /* (ENOMEM) */ ; + } else if (i != ADW_MAX_CARRIER) { + printf("%s: WARNING: only %d of %d Carriers created\n", + sc->sc_dev.dv_xname, i, ADW_MAX_CARRIER); + } + + /* * Initialize the ASC3550. */ - switch (AdvInitAsc3550Driver(sc)) { + error = (sc->chip_type == ADV_CHIP_ASC3550)? + AdvInitAsc3550Driver(sc) : + AdvInitAsc38C0800Driver(sc); + switch (error) { case ASC_IERR_MCODE_CHKSUM: panic("%s: Microcode checksum error", sc->sc_dev.dv_xname); @@ -464,45 +687,34 @@ adw_attach(sc) " one of the connectors", sc->sc_dev.dv_xname); break; + + case ASC_IERR_NO_CARRIER: + panic("%s: no carrier", + sc->sc_dev.dv_xname); + break; + + case ASC_WARN_BUSRESET_ERROR: + printf("%s: WARNING: Bus Reset Error\n", + sc->sc_dev.dv_xname); + break; } + /* + * Fill in the adapter. + */ + sc->sc_adapter.scsi_cmd = adw_scsi_cmd; + sc->sc_adapter.scsi_minphys = adwminphys; /* * fill in the prototype scsi_link. */ sc->sc_link.adapter_softc = sc; sc->sc_link.adapter_target = sc->chip_scsi_id; - sc->sc_link.adapter = &adw_switch; + sc->sc_link.adapter = &sc->sc_adapter; sc->sc_link.device = &adw_dev; sc->sc_link.openings = 4; - sc->sc_link.adapter_buswidth = ADW_MAX_TID; - - - TAILQ_INIT(&sc->sc_free_ccb); - TAILQ_INIT(&sc->sc_waiting_ccb); - LIST_INIT(&sc->sc_queue); - - - /* - * Allocate the Control Blocks. - */ - error = adw_alloc_ccbs(sc); - if (error) - return; /* (error) */ ; + sc->sc_link.adapter_buswidth = ADW_MAX_TID+1; - /* - * Create and initialize the Control Blocks. - */ - i = adw_create_ccbs(sc, sc->sc_control->ccbs, ADW_MAX_CCB); - if (i == 0) { - printf("%s: unable to create control blocks\n", - sc->sc_dev.dv_xname); - return; /* (ENOMEM) */ ; - } else if (i != ADW_MAX_CCB) { - printf("%s: WARNING: only %d of %d control blocks" - " created\n", - sc->sc_dev.dv_xname, i, ADW_MAX_CCB); - } config_found(&sc->sc_dev, &sc->sc_link, scsiprint); } @@ -529,7 +741,7 @@ adw_scsi_cmd(xs) struct scsi_link *sc_link = xs->sc_link; ADW_SOFTC *sc = sc_link->adapter_softc; ADW_CCB *ccb; - int s, fromqueue = 1, dontqueue = 0; + int s, fromqueue = 1, dontqueue = 0, retry = 0; s = splbio(); /* protect the queue */ @@ -597,10 +809,21 @@ adw_scsi_cmd(xs) ccb->timeout = xs->timeout; if (adw_build_req(xs, ccb)) { +retryagain: s = splbio(); - adw_queue_ccb(sc, ccb); + retry = adw_queue_ccb(sc, ccb, retry); splx(s); + switch(retry) { + case ADW_BUSY: + goto retryagain; + + case ADW_ERROR: + xs->error = XS_DRIVER_STUFFUP; + return (COMPLETE); + + } + /* * Usually return SUCCESSFULLY QUEUED */ @@ -638,10 +861,10 @@ adw_build_req(xs, ccb) bzero(scsiqp, sizeof(ADW_SCSI_REQ_Q)); /* - * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the CCB structure. + * Set the ADW_SCSI_REQ_Q 'ccb_ptr' to point to the + * physical CCB structure. */ - scsiqp->ccb_ptr = (ulong) ccb; - + scsiqp->ccb_ptr = ccb->hashkey; /* * Build the ADW_SCSI_REQ_Q request. @@ -655,10 +878,12 @@ adw_build_req(xs, ccb) scsiqp->target_id = sc_link->target; scsiqp->target_lun = sc_link->lun; - scsiqp->vsense_addr = (ulong) & ccb->scsi_sense; + scsiqp->vsense_addr = & ccb->scsi_sense; scsiqp->sense_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr + - ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense); - scsiqp->sense_len = sizeof(struct scsi_sense_data); + ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsi_sense); +/* scsiqp->sense_addr = ccb->hashkey + + offsetof(struct adw_ccb, scsi_sense); +*/ scsiqp->sense_len = sizeof(struct scsi_sense_data); /* * Build ADW_SCSI_REQ_Q for a scatter-gather buffer command. @@ -671,15 +896,15 @@ adw_build_req(xs, ccb) if (xs->flags & SCSI_DATA_UIO) { error = bus_dmamap_load_uio(dmat, ccb->dmamap_xfer, (struct uio *) xs->data, - (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : - BUS_DMA_WAITOK); + (xs->flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK); } else -#endif /* TFS */ +#endif /* TFS */ { error = bus_dmamap_load(dmat, ccb->dmamap_xfer, xs->data, xs->datalen, NULL, - (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT : - BUS_DMA_WAITOK); + (xs->flags & SCSI_NOSLEEP) ? + BUS_DMA_NOWAIT : BUS_DMA_WAITOK); } if (error) { @@ -698,19 +923,17 @@ adw_build_req(xs, ccb) return (0); } bus_dmamap_sync(dmat, ccb->dmamap_xfer, - (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD : - BUS_DMASYNC_PREWRITE); + (xs->flags & SCSI_DATA_IN) ? + BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); /* * Build scatter-gather list. */ scsiqp->data_cnt = xs->datalen; - scsiqp->vdata_addr = (ulong) xs->data; + scsiqp->vdata_addr = xs->data; scsiqp->data_addr = ccb->dmamap_xfer->dm_segs[0].ds_addr; - scsiqp->sg_list_ptr = &ccb->sg_block[0]; - bzero(scsiqp->sg_list_ptr, - sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK); - adw_build_sglist(ccb, scsiqp); + bzero(ccb->sg_block, sizeof(ADW_SG_BLOCK) * ADW_NUM_SG_BLOCK); + adw_build_sglist(ccb, scsiqp, ccb->sg_block); } else { /* * No data xfer, use non S/G values. @@ -718,7 +941,6 @@ adw_build_req(xs, ccb) scsiqp->data_cnt = 0; scsiqp->vdata_addr = 0; scsiqp->data_addr = 0; - scsiqp->sg_list_ptr = NULL; } return (1); @@ -729,23 +951,21 @@ adw_build_req(xs, ccb) * Build scatter-gather list for Wide Boards. */ static void -adw_build_sglist(ccb, scsiqp) +adw_build_sglist(ccb, scsiqp, sg_block) ADW_CCB *ccb; ADW_SCSI_REQ_Q *scsiqp; + ADW_SG_BLOCK *sg_block; { - struct scsi_xfer *xs = ccb->xs; - ADW_SOFTC *sc = xs->sc_link->adapter_softc; - ADW_SG_BLOCK *sg_block = scsiqp->sg_list_ptr; - ulong sg_block_next_addr; /* block and its next */ - ulong sg_block_physical_addr; - int sg_block_index, i; /* how many SG entries */ + u_long sg_block_next_addr; /* block and its next */ + u_int32_t sg_block_physical_addr; + int i; /* how many SG entries */ bus_dma_segment_t *sg_list = &ccb->dmamap_xfer->dm_segs[0]; int sg_elem_cnt = ccb->dmamap_xfer->dm_nsegs; - sg_block_next_addr = (ulong) sg_block; /* allow math operation */ - sg_block_physical_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr + - ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, sg_block[0]); + sg_block_next_addr = (u_long) sg_block; /* allow math operation */ + sg_block_physical_addr = ccb->hashkey + + offsetof(struct adw_ccb, sg_block[0]); scsiqp->sg_real_addr = sg_block_physical_addr; /* @@ -753,17 +973,14 @@ adw_build_sglist(ccb, scsiqp) * then split the request into multiple sg-list blocks. */ - sg_block_index = 0; do { - sg_block->first_entry_no = sg_block_index; for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { sg_block->sg_list[i].sg_addr = sg_list->ds_addr; sg_block->sg_list[i].sg_count = sg_list->ds_len; if (--sg_elem_cnt == 0) { /* last entry, get out */ - scsiqp->sg_entry_cnt = sg_block_index + i + 1; - sg_block->last_entry_no = sg_block_index + i; + sg_block->sg_cnt = i + i; sg_block->sg_ptr = NULL; /* next link = NULL */ return; } @@ -772,12 +989,10 @@ adw_build_sglist(ccb, scsiqp) sg_block_next_addr += sizeof(ADW_SG_BLOCK); sg_block_physical_addr += sizeof(ADW_SG_BLOCK); - sg_block_index += NO_OF_SG_PER_BLOCK; - sg_block->sg_ptr = (ADW_SG_BLOCK *) sg_block_physical_addr; - sg_block->last_entry_no = sg_block_index - 1; + sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; + sg_block->sg_ptr = sg_block_physical_addr; sg_block = (ADW_SG_BLOCK *) sg_block_next_addr; /* virt. addr */ - } - while (1); + } while (1); } @@ -789,18 +1004,18 @@ adw_intr(arg) struct scsi_xfer *xs; - AdvISR(sc); - - /* - * If there are queue entries in the software queue, try to - * run the first one. We should be more or less guaranteed - * to succeed, since we just freed a CCB. - * - * NOTE: adw_scsi_cmd() relies on our calling it with - * the first entry in the queue. - */ - if ((xs = sc->sc_queue.lh_first) != NULL) - (void) adw_scsi_cmd(xs); + if(AdvISR(sc) != ADW_FALSE) { + /* + * If there are queue entries in the software queue, try to + * run the first one. We should be more or less guaranteed + * to succeed, since we just freed a CCB. + * + * NOTE: adw_scsi_cmd() relies on our calling it with + * the first entry in the queue. + */ + if ((xs = sc->sc_queue.lh_first) != NULL) + (void) adw_scsi_cmd(xs); + } return (1); } @@ -847,78 +1062,76 @@ adw_timeout(arg) * If it has been through before, then a previous abort has failed, * don't try abort again, reset the bus instead. */ - if (ccb->flags & CCB_ABORT) { - /* abort timed out */ - printf(" AGAIN. Resetting Bus\n"); - /* Lets try resetting the bus! */ + if (ccb->flags & CCB_ABORTED) { + /* + * Abort Timed Out + * Lets try resetting the bus! + */ + printf(" AGAIN. Resetting SCSI Bus\n"); + ccb->flags &= ~CCB_ABORTED; + /* AdvResetSCSIBus() will call sbreset_callback() */ AdvResetSCSIBus(sc); - ccb->timeout = ADW_ABORT_TIMEOUT; - adw_queue_ccb(sc, ccb); } else { - /* abort the operation that has timed out */ + /* + * Abort the operation that has timed out + */ printf("\n"); - ADW_ABORT_CCB(sc, ccb); xs->error = XS_TIMEOUT; - ccb->timeout = ADW_ABORT_TIMEOUT; - ccb->flags |= CCB_ABORT; - adw_queue_ccb(sc, ccb); + ccb->flags |= CCB_ABORTING; + /* ADW_ABORT_CCB() will implicitly call isr_callback() */ + ADW_ABORT_CCB(sc, ccb); } splx(s); } -static void -adw_watchdog(arg) - void *arg; -{ - ADW_CCB *ccb = arg; - struct scsi_xfer *xs = ccb->xs; - struct scsi_link *sc_link = xs->sc_link; - ADW_SOFTC *sc = sc_link->adapter_softc; - int s; - - s = splbio(); - - ccb->flags &= ~CCB_WATCHDOG; - adw_start_ccbs(sc); - - splx(s); -} - - /******************************************************************************/ -/* NARROW and WIDE boards Interrupt callbacks */ +/* WIDE boards Interrupt callbacks */ /******************************************************************************/ /* - * adw_wide_isr_callback() - Second Level Interrupt Handler called by AdvISR() + * adw__isr_callback() - Second Level Interrupt Handler called by AdvISR() * * Interrupt callback function for the Wide SCSI Adv Library. */ static void -adw_wide_isr_callback(sc, scsiq) +adw_isr_callback(sc, scsiq) ADW_SOFTC *sc; ADW_SCSI_REQ_Q *scsiq; { bus_dma_tag_t dmat = sc->sc_dmat; - ADW_CCB *ccb = (ADW_CCB *) scsiq->ccb_ptr; - struct scsi_xfer *xs = ccb->xs; + ADW_CCB *ccb; + struct scsi_xfer *xs; struct scsi_sense_data *s1, *s2; - //int underrun = ASC_FALSE; +// int s; + ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr); + untimeout(adw_timeout, ccb); +/* if(ccb->flags & CCB_ABORTING) { + printf("Retrying request\n"); + ccb->flags &= ~CCB_ABORTING; + ccb->flags |= CCB_ABORTED; + s = splbio(); + adw_queue_ccb(sc, ccb); + splx(s); + return; + } +*/ + xs = ccb->xs; + /* * If we were a data transfer, unload the map that described * the data buffer. */ if (xs->datalen) { bus_dmamap_sync(dmat, ccb->dmamap_xfer, - (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD : - BUS_DMASYNC_POSTWRITE); + (xs->flags & SCSI_DATA_IN) ? + BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(dmat, ccb->dmamap_xfer); } if ((ccb->flags & CCB_ALLOC) == 0) { @@ -949,31 +1162,38 @@ adw_wide_isr_callback(sc, scsiq) xs->error = XS_DRIVER_STUFFUP; break; } - /* - * If there was an underrun without any other error, - * set DID_ERROR to indicate the underrun error. - * - * Note: There is no way yet to indicate the number - * of underrun bytes. - */ - /* - * if (xs->error == XS_NOERROR && underrun == ASC_TRUE) { - * scp->result = HOST_BYTE(DID_UNDERRUN); } - */ break; + break; case QD_WITH_ERROR: switch (scsiq->host_status) { case QHSTA_NO_ERROR: - if (scsiq->scsi_status == SS_CHK_CONDITION) { + switch(scsiq->scsi_status) { + case SS_CHK_CONDITION: + case SS_CMD_TERMINATED: s1 = &ccb->scsi_sense; s2 = &xs->sense; *s2 = *s1; xs->error = XS_SENSE; - } else { + break; + case SS_TARGET_BUSY: + case SS_RSERV_CONFLICT: + case SS_QUEUE_FULL: xs->error = XS_DRIVER_STUFFUP; + break; + case SS_CONDITION_MET: + case SS_INTERMID: + case SS_INTERMID_COND_MET: + xs->error = XS_DRIVER_STUFFUP; + break; + case SS_GOOD: + break; } break; + case QHSTA_M_SEL_TIMEOUT: + xs->error = XS_DRIVER_STUFFUP; + break; + default: /* Some other QHSTA error occurred. */ xs->error = XS_DRIVER_STUFFUP; @@ -982,13 +1202,51 @@ adw_wide_isr_callback(sc, scsiq) break; case QD_ABORTED_BY_HOST: + xs->error = XS_DRIVER_STUFFUP; + break; + default: xs->error = XS_DRIVER_STUFFUP; break; } - adw_free_ccb(sc, ccb); xs->flags |= ITSDONE; scsi_done(xs); } + + +/* + * adv_async_callback() - Adv Library asynchronous event callback function. + */ +static void +adw_async_callback(sc, code) + ADW_SOFTC *sc; + u_int8_t code; +{ + switch (code) { + case ADV_ASYNC_SCSI_BUS_RESET_DET: + /* + * The firmware detected a SCSI Bus reset. + */ + break; + + case ADV_ASYNC_RDMA_FAILURE: + /* + * Handle RDMA failure by resetting the SCSI Bus and + * possibly the chip if it is unresponsive. Log the error + * with a unique code. + */ + AdvResetSCSIBus(sc); + break; + + case ADV_HOST_SCSI_BUS_RESET: + /* + * Host generated SCSI bus reset occurred. + */ + break; + + default: + break; + } +} diff --git a/sys/dev/ic/adw.h b/sys/dev/ic/adw.h index d05355a2ce0..fa9c4c3d5e0 100644 --- a/sys/dev/ic/adw.h +++ b/sys/dev/ic/adw.h @@ -1,11 +1,10 @@ -/* $OpenBSD: adw.h,v 1.2 1998/12/30 15:13:04 downsj Exp $ */ -/* $NetBSD: adw.h,v 1.1 1998/09/26 16:10:41 dante Exp $ */ +/* $NetBSD: adw.h,v 1.5 2000/02/03 20:29:15 dante Exp $ */ /* * Generic driver definitions and exported functions for the Advanced * Systems Inc. SCSI controllers * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -45,10 +44,55 @@ /******************************************************************************/ typedef int (* ADW_ISR_CALLBACK) (ADW_SOFTC *, ADW_SCSI_REQ_Q *); -typedef int (* ADW_SBRESET_CALLBACK) (ADW_SOFTC *); +typedef void (* ADW_ASYNC_CALLBACK) (ADW_SOFTC *, u_int8_t); -/* per request scatter-gather element limit */ -#define ADW_MAX_SG_LIST 64 + +/* + * Every adw_carrier structure _MUST_ always be aligned on a 16 bytes boundary + */ +struct adw_carrier { +/* ---------- the microcode wants the field below ---------- */ + u_int32_t unused; /* Carrier Virtual Address -UNUSED- */ + u_int32_t carr_pa; /* Carrier Physical Address */ + u_int32_t areq_vpa; /* ADW_SCSI_REQ_Q Physical Address */ + /* + * next_vpa [31:4] Carrier Physical Next Pointer + * + * next_vpa [3:1] Reserved Bits + * next_vpa [0] Done Flag set in Response Queue. + */ + u_int32_t next_vpa; +/* ---------- ---------- */ + struct adw_carrier *nexthash; /* Carrier Virtual Address */ + + int id; + /* + * This DMA map maps the buffer involved in the carrier transfer. + */ +// bus_dmamap_t dmamap_xfer; +}; + +typedef struct adw_carrier ADW_CARRIER; + +#define ADW_CARRIER_SIZE ((((int)((sizeof(ADW_CARRIER)-1)/16))+1)*16) + + +/* + * Mask used to eliminate low 4 bits of carrier 'next_vpa' field. + */ +#define ASC_NEXT_VPA_MASK 0xFFFFFFF0 + +#define ASC_RQ_DONE 0x00000001 +#define ASC_CQ_STOPPER 0x00000000 + +#define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK) + + +/* + * per request scatter-gather element limit + * We could have up to 256 SG lists. + */ +#define ADW_MAX_SG_LIST 255 /* * Scatter-Gather Definitions per request. @@ -61,14 +105,18 @@ typedef int (* ADW_SBRESET_CALLBACK) (ADW_SOFTC *); ((ADW_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK) -struct adw_ccb -{ - ADW_SG_BLOCK sg_block[ADW_NUM_SG_BLOCK]; +struct adw_ccb { ADW_SCSI_REQ_Q scsiq; + ADW_SG_BLOCK sg_block[ADW_NUM_SG_BLOCK]; + + ADW_CARRIER *carr_list; /* carriers involved */ - struct scsi_sense_data scsi_sense; + struct scsi_sense_data scsi_sense; TAILQ_ENTRY(adw_ccb) chain; + struct adw_ccb *nexthash; + u_int32_t hashkey; + struct scsi_xfer *xs; /* the scsi_xfer for this cmd */ int flags; /* see below */ @@ -82,19 +130,26 @@ struct adw_ccb typedef struct adw_ccb ADW_CCB; /* flags for ADW_CCB */ -#define CCB_ALLOC 0x01 -#define CCB_ABORT 0x02 -#define CCB_WATCHDOG 0x10 +#define CCB_ALLOC 0x01 +#define CCB_ABORTING 0x02 +#define CCB_ABORTED 0x04 -#define ADW_MAX_CCB 64 +#define ADW_MAX_CARRIER 20 /* Max. number of host commands (253) */ +#define ADW_MAX_CCB 16 /* Max. number commands per device (63) */ -struct adw_control -{ - ADW_CCB ccbs[ADW_MAX_CCB]; /* all our control blocks */ +struct adw_control { + ADW_CCB ccbs[ADW_MAX_CCB]; /* all our control blocks */ + ADW_CARRIER *carriers; /* all our carriers */ + bus_dmamap_t dmamap_xfer; }; /* + * Offset of a carrier from the beginning of the carriers DMA mapping. + */ +#define ADW_CARRIER_ADDR(sc, x) ((sc)->sc_dmamap_carrier->dm_segs[0].ds_addr + \ + (((u_long)x) - ((u_long)(sc)->sc_control->carriers))) +/* * Offset of a CCB from the beginning of the control DMA mapping. */ #define ADW_CCB_OFF(c) (offsetof(struct adw_control, ccbs[0]) + \ @@ -105,6 +160,8 @@ struct adw_control int adw_init __P((ADW_SOFTC *sc)); void adw_attach __P((ADW_SOFTC *sc)); int adw_intr __P((void *arg)); +ADW_CCB *adw_ccb_phys_kv __P((ADW_SOFTC *, u_int32_t)); +ADW_CARRIER *adw_carrier_phys_kv __P((ADW_SOFTC *, u_int32_t)); /******************************************************************************/ diff --git a/sys/dev/ic/adwlib.c b/sys/dev/ic/adwlib.c index 89fffccb186..f7654463205 100644 --- a/sys/dev/ic/adwlib.c +++ b/sys/dev/ic/adwlib.c @@ -1,9 +1,9 @@ -/* $NetBSD: adwlib.c,v 1.2 1998/09/26 19:54:22 dante Exp $ */ +/* $NetBSD: adwlib.c,v 1.7 2000/02/03 20:29:15 dante Exp $ */ /* * Low level routines for the Advanced Systems Inc. SCSI controllers chips * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -41,8 +41,8 @@ */ /* * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters - * - * Copyright (c) 1995-1998 Advanced System Products, Inc. + * + * Copyright (c) 1995-1999 Advanced System Products, Inc. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -65,6 +65,8 @@ #include <scsi/scsi_all.h> #include <scsi/scsiconf.h> +#include <dev/pci/pcidevs.h> + #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/pmap.h> @@ -76,18 +78,20 @@ /* Static Functions */ -static u_int16_t AdvGetEEPConfig __P((bus_space_tag_t, bus_space_handle_t, - ADWEEP_CONFIG *)); -static u_int16_t AdvReadEEPWord __P((bus_space_tag_t, bus_space_handle_t, - int)); +static u_int16_t AdvGet3550EEPConfig __P((bus_space_tag_t, bus_space_handle_t, + ADW_EEP_3550_CONFIG *)); +static u_int16_t AdvGet38C0800EEPConfig __P((bus_space_tag_t, bus_space_handle_t, + ADW_EEP_38C0800_CONFIG *)); +static u_int16_t AdvReadEEPWord __P((bus_space_tag_t, bus_space_handle_t, int)); static void AdvWaitEEPCmd __P((bus_space_tag_t, bus_space_handle_t)); -static void AdvSetEEPConfig __P((bus_space_tag_t, bus_space_handle_t, - ADWEEP_CONFIG *)); -static int AdvSendScsiCmd __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *)); +static void AdvSet3550EEPConfig __P((bus_space_tag_t, bus_space_handle_t, + ADW_EEP_3550_CONFIG *)); +static void AdvSet38C0800EEPConfig __P((bus_space_tag_t, bus_space_handle_t, + ADW_EEP_38C0800_CONFIG *)); static void AdvInquiryHandling __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *)); -static void DvcSleepMilliSecond __P((ulong)); -static void DvcDelayMicroSecond __P((ulong)); +static void AdvSleepMilliSecond __P((u_int32_t)); +static void AdvDelayMicroSecond __P((u_int32_t)); /* @@ -98,42 +102,107 @@ static void DvcDelayMicroSecond __P((ulong)); * Additional structure information can be found in advlib.h where * the structure is defined. */ -static ADWEEP_CONFIG -Default_EEPROM_Config = { - ADW_EEPROM_BIOS_ENABLE, /* cfg_msw */ - 0x0000, /* cfg_lsw */ - 0xFFFF, /* disc_enable */ - 0xFFFF, /* wdtr_able */ - 0xFFFF, /* sdtr_able */ - 0xFFFF, /* start_motor */ - 0xFFFF, /* tagqng_able */ - 0xFFFF, /* bios_scan */ - 0, /* scam_tolerant */ - 7, /* adapter_scsi_id */ - 0, /* bios_boot_delay */ - 3, /* scsi_reset_delay */ - 0, /* bios_id_lun */ - 0, /* termination */ - 0, /* reserved1 */ - 0xFFEF, /* bios_ctrl */ - 0xFFFF, /* ultra_able */ - 0, /* reserved2 */ +static ADW_EEP_3550_CONFIG +Default_3550_EEPROM_Config = { + ADW_EEPROM_BIOS_ENABLE, /* cfg_lsw */ + 0x0000, /* cfg_msw */ + 0xFFFF, /* disc_enable */ + 0xFFFF, /* wdtr_able */ + 0xFFFF, /* sdtr_able */ + 0xFFFF, /* start_motor */ + 0xFFFF, /* tagqng_able */ + 0xFFFF, /* bios_scan */ + 0, /* scam_tolerant */ + 7, /* adapter_scsi_id */ + 0, /* bios_boot_delay */ + 3, /* scsi_reset_delay */ + 0, /* bios_id_lun */ + 0, /* termination */ + 0, /* reserved1 */ + 0xFFE7, /* bios_ctrl */ + 0xFFFF, /* ultra_able */ + 0, /* reserved2 */ ASC_DEF_MAX_HOST_QNG, /* max_host_qng */ ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ - 0, /* dvc_cntl */ - 0, /* bug_fix */ - 0, /* serial_number_word1 */ - 0, /* serial_number_word2 */ - 0, /* serial_number_word3 */ - 0, /* check_sum */ + 0, /* dvc_cntl */ + 0, /* bug_fix */ + 0, /* serial_number_word1 */ + 0, /* serial_number_word2 */ + 0, /* serial_number_word3 */ + 0, /* check_sum */ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* oem_name[16] */ - 0, /* dvc_err_code */ - 0, /* adv_err_code */ - 0, /* adv_err_addr */ - 0, /* saved_dvc_err_code */ - 0, /* saved_adv_err_code */ - 0, /* saved_adv_err_addr */ - 0 /* num_of_err */ + 0, /* dvc_err_code */ + 0, /* adv_err_code */ + 0, /* adv_err_addr */ + 0, /* saved_dvc_err_code */ + 0, /* saved_adv_err_code */ + 0, /* saved_adv_err_addr */ + 0 /* num_of_err */ +}; + +static ADW_EEP_38C0800_CONFIG +Default_38C0800_EEPROM_Config = { + ADW_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ + 0x0000, /* 01 cfg_msw */ + 0xFFFF, /* 02 disc_enable */ + 0xFFFF, /* 03 wdtr_able */ + 0x4444, /* 04 sdtr_speed1 */ + 0xFFFF, /* 05 start_motor */ + 0xFFFF, /* 06 tagqng_able */ + 0xFFFF, /* 07 bios_scan */ + 0, /* 08 scam_tolerant */ + 7, /* 09 adapter_scsi_id */ + 0, /* bios_boot_delay */ + 3, /* 10 scsi_reset_delay */ + 0, /* bios_id_lun */ + 0, /* 11 termination_se */ + 0, /* termination_lvd */ + 0xFFE7, /* 12 bios_ctrl */ + 0x4444, /* 13 sdtr_speed2 */ + 0x4444, /* 14 sdtr_speed3 */ + ASC_DEF_MAX_HOST_QNG, /* 15 max_host_qng */ + ASC_DEF_MAX_DVC_QNG, /* max_dvc_qng */ + 0, /* 16 dvc_cntl */ + 0x4444, /* 17 sdtr_speed4 */ + 0, /* 18 serial_number_word1 */ + 0, /* 19 serial_number_word2 */ + 0, /* 20 serial_number_word3 */ + 0, /* 21 check_sum */ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, /* 22-29 oem_name[16] */ + 0, /* 30 dvc_err_code */ + 0, /* 31 adv_err_code */ + 0, /* 32 adv_err_addr */ + 0, /* 33 saved_dvc_err_code */ + 0, /* 34 saved_adv_err_code */ + 0, /* 35 saved_adv_err_addr */ + 0, /* 36 reserved */ + 0, /* 37 reserved */ + 0, /* 38 reserved */ + 0, /* 39 reserved */ + 0, /* 40 reserved */ + 0, /* 41 reserved */ + 0, /* 42 reserved */ + 0, /* 43 reserved */ + 0, /* 44 reserved */ + 0, /* 45 reserved */ + 0, /* 46 reserved */ + 0, /* 47 reserved */ + 0, /* 48 reserved */ + 0, /* 49 reserved */ + 0, /* 50 reserved */ + 0, /* 51 reserved */ + 0, /* 52 reserved */ + 0, /* 53 reserved */ + 0, /* 54 reserved */ + 0, /* 55 reserved */ + 0, /* 56 cisptr_lsw */ + 0, /* 57 cisprt_msw */ + PCI_VENDOR_ADVSYS, /* 58 subsysvid */ + PCI_PRODUCT_ADVSYS_U2W, /* 59 subsysid */ + 0, /* 60 reserved */ + 0, /* 61 reserved */ + 0, /* 62 reserved */ + 0 /* 63 reserved */ }; /* @@ -150,17 +219,20 @@ ADW_SOFTC *sc; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - u_int16_t warn_code; - u_int32_t sum; - int begin_addr; - int end_addr; - int code_sum; - int word; - int rql_addr; /* RISC Queue List address */ - int i; - u_int16_t scsi_cfg1; - u_int8_t biosmem[ASC_MC_BIOSLEN]; /* BIOS RISC Memory - * 0x40-0x8F */ + u_int16_t warn_code; + u_int32_t sum; + int begin_addr; + int end_addr; + u_int16_t code_sum; + int word; + int i, j; + int adv_asc3550_expanded_size; + u_int16_t scsi_cfg1; + u_int8_t tid; + u_int16_t bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory + 0x40-0x8F. */ + u_int16_t wdtr_able = 0, sdtr_able, tagqng_able; + u_int8_t max_cmd[ADW_MAX_TID + 1]; warn_code = 0; @@ -173,8 +245,32 @@ ADW_SOFTC *sc; * Note: This code makes the assumption, which is currently true, * that a chip reset does not clear RISC LRAM. */ - for (i = 0; i < ASC_MC_BIOSLEN; i++) { - ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_BIOSMEM + i, biosmem[i]); + for (i = 0; i < ASC_MC_BIOSLEN/2; i++) { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_BIOSMEM + (2*i), bios_mem[i]); + } + + /* + * Save current per TID negotiated values. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == 0x55AA) { + + u_int16_t bios_version, major, minor; + + bios_version = bios_mem[(ASC_MC_BIOS_VERSION-ASC_MC_BIOSMEM)/2]; + major = (bios_version >> 12) & 0xF; + minor = (bios_version >> 8) & 0xF; + if (major < 3 || (major == 3 && minor == 1)) { + /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ + ADW_READ_WORD_LRAM(iot, ioh, 0x120, wdtr_able); + } else { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, wdtr_able); + } + } + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sdtr_able); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); } /* @@ -183,15 +279,57 @@ ADW_SOFTC *sc; * Write the microcode image to RISC memory starting at address 0. */ ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); - for (word = 0; word < adv_mcode_size; word += 2) { - ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, - *((u_int16_t *) (&adv_mcode[word]))); + + /* Assume the following compressed format of the microcode buffer: + * + * 254 word (508 byte) table indexed by byte code followed + * by the following byte codes: + * + * 1-Byte Code: + * 00: Emit word 0 in table. + * 01: Emit word 1 in table. + * . + * FD: Emit word 253 in table. + * + * Multi-Byte Code: + * FE WW WW: (3 byte code) Word to emit is the next word WW WW. + * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. + */ + word = 0; + for (i = 253 * 2; i < adv_asc3550_mcode_size; i++) { + if (adv_asc3550_mcode[i] == 0xff) { + for (j = 0; j < adv_asc3550_mcode[i + 1]; j++) { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, + (((u_int16_t)adv_asc3550_mcode[i + 3] << 8) | + adv_asc3550_mcode[i + 2])); + word++; + } + i += 3; + } else if (adv_asc3550_mcode[i] == 0xfe) { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, + (((u_int16_t)adv_asc3550_mcode[i + 2] << 8) | + adv_asc3550_mcode[i + 1])); + i += 2; + word++; + } else { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, (((u_int16_t) + adv_asc3550_mcode[(adv_asc3550_mcode[i] * 2) + 1] <<8) | + adv_asc3550_mcode[adv_asc3550_mcode[i] * 2])); + word++; + } } /* - * Clear the rest of Condor's Internal RAM (8KB). + * Set 'word' for later use to clear the rest of memory and save + * the expanded mcode size. + */ + word *= 2; + adv_asc3550_expanded_size = word; + + /* + * Clear the rest of ASC-3550 Internal RAM (8KB). */ - for (; word < ADW_CONDOR_MEMSIZE; word += 2) { + for (; word < ADV_3550_MEMSIZE; word += 2) { ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, 0); } @@ -200,18 +338,21 @@ ADW_SOFTC *sc; */ sum = 0; ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); - for (word = 0; word < adv_mcode_size; word += 2) { + + for (word = 0; word < adv_asc3550_expanded_size; word += 2) { sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); } - if (sum != adv_mcode_chksum) + if (sum != adv_asc3550_mcode_chksum) { return ASC_IERR_MCODE_CHKSUM; + } /* * Restore the RISC memory BIOS region. */ - for (i = 0; i < ASC_MC_BIOSLEN; i++) { - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_BIOSMEM + i, biosmem[i]); + for (i = 0; i < ASC_MC_BIOSLEN/2; i++) { + ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); } /* @@ -221,22 +362,24 @@ ADW_SOFTC *sc; ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_BEGIN_ADDR, begin_addr); ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_END_ADDR, end_addr); code_sum = 0; + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, begin_addr); for (word = begin_addr; word < end_addr; word += 2) { - code_sum += *((u_int16_t *) (&adv_mcode[word])); + code_sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); } ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CODE_CHK_SUM, code_sum); /* - * Read microcode version and date. + * Read and save microcode version and date. */ - ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_DATE, sc->cfg.mcode_date); - ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_NUM, sc->cfg.mcode_version); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_DATE, + sc->cfg.mcode_date); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_NUM, + sc->cfg.mcode_version); /* - * Initialize microcode operating variables + * Set the chip type to indicate the ASC3550. */ - ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_ADAPTER_SCSI_ID, - sc->chip_scsi_id); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); /* * If the PCI Configuration Command Register "Parity Error Response @@ -245,32 +388,95 @@ ADW_SOFTC *sc; * to ignore DMA parity errors. */ if (sc->cfg.control_flag & CONTROL_FLAG_IGNORE_PERR) { + /* + * Note: Don't remove the use of a temporary variable in + * the following code, otherwise some C compiler + * might turn the following lines into a no-op. + */ ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CONTROL_FLAG, word); word |= CONTROL_FLAG_IGNORE_PERR; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CONTROL_FLAG, word); } + /* - * Set default microcode operating variables for WDTR, SDTR, and - * command tag queuing based on the EEPROM configuration values. + * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO + * threshold of 128 bytes. This register is only accessible to the host. + */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, + START_CTL_EMFU | READ_CMD_MRM); + + /* + * Microcode operating variables for WDTR, SDTR, and command tag + * queuing will be set in AdvInquiryHandling() based on what a + * device reports it is capable of in Inquiry byte 7. * - * These ADW_DVC_VAR fields and the microcode variables will be - * changed in AdvInquiryHandling() if it is found a device is - * incapable of a particular feature. + * If SCSI Bus Resets haev been disabled, then directly set + * SDTR and WDTR from the EEPROM configuration. This will allow + * the BIOS and warm boot to work without a SCSI bus hang on + * the Inquiry caused by host and target mismatched DTR values. + * Without the SCSI Bus Reset, before an Inquiry a device can't + * be assumed to be in Asynchronous, Narrow mode. */ + if ((sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, + sc->wdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, + sc->sdtr_able); + } /* - * Set the microcode ULTRA target mask from EEPROM value. The - * SDTR target mask overrides the ULTRA target mask in the - * microcode so it is safe to set this value without determining - * whether the device supports SDTR. + * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID + * bitmask. These values determine the maximum SDTR speed negotiated + * with a device. + * + * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them + * without determining here whether the device supports SDTR. * - * Note: There is no way to know whether a device supports ULTRA - * speed without attempting a SDTR ULTRA speed negotiation with - * the device. The device will reject the speed if it does not - * support it by responding with an SDTR message containing a - * slower speed. + * 4-bit speed SDTR speed name + * =========== =============== + * 0000b (0x0) SDTR disabled + * 0001b (0x1) 5 Mhz + * 0010b (0x2) 10 Mhz + * 0011b (0x3) 20 Mhz (Ultra) + * 0100b (0x4) 40 Mhz (LVD/Ultra2) + * 0101b (0x5) 80 Mhz (LVD2/Ultra3) + * 0110b (0x6) Undefined + * . + * 1111b (0xF) Undefined + */ + word = 0; + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + if (ADW_TID_TO_TIDMASK(tid) & sc->ultra_able) { + /* Set Ultra speed for TID 'tid'. */ + word |= (0x3 << (4 * (tid % 4))); + } else { + /* Set Fast speed for TID 'tid'. */ + word |= (0x2 << (4 * (tid % 4))); + } + /* Check if done with sdtr_speed1. */ + if (tid == 3) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED1, word); + word = 0; + /* Check if done with sdtr_speed2. */ + } else if (tid == 7) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED2, word); + word = 0; + /* Check if done with sdtr_speed3. */ + } else if (tid == 11) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED3, word); + word = 0; + /* Check if done with sdtr_speed4. */ + } else if (tid == 15) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED4, word); + /* End of loop. */ + } + } + + /* + * Set microcode operating variable for the disconnect per TID bitmask. */ - ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_ULTRA_ABLE, sc->ultra_able); ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DISC_ENABLE, sc->cfg.disc_enable); @@ -281,7 +487,8 @@ ADW_SOFTC *sc; * after it is started below. */ ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SCSI_CFG0, - ADW_PARITY_EN | ADW_SEL_TMO_LONG | ADW_OUR_ID_EN | sc->chip_scsi_id); + ADW_PARITY_EN | ADW_SEL_TMO_LONG | ADW_OUR_ID_EN | + sc->chip_scsi_id); /* * Determine SCSI_CFG1 Microcode Default Value. @@ -297,9 +504,10 @@ ADW_SOFTC *sc; * If all three connectors are in use, return an error. */ if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || - (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { + (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { return ASC_IERR_ILLEGAL_CONNECTION; } + /* * If the internal narrow cable is reversed all of the SCSI_CTRL * register signals will be set. Check for and return an error if @@ -307,7 +515,6 @@ ADW_SOFTC *sc; */ if ((ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { - return ASC_IERR_REVERSED_CABLE; } @@ -315,63 +522,52 @@ ADW_SOFTC *sc; * If this is a differential board and a single-ended device * is attached to one of the connectors, return an error. */ - if ((scsi_cfg1 & ADW_DIFF_MODE) && (scsi_cfg1 & ADW_DIFF_SENSE) == 0) + if ((scsi_cfg1 & ADW_DIFF_MODE) && (scsi_cfg1 & ADW_DIFF_SENSE) == 0) { return ASC_IERR_SINGLE_END_DEVICE; + } /* * If automatic termination control is enabled, then set the - * termination value based on a table listed in advlib.h. + * termination value based on a table listed in a_condor.h. * * If manual termination was specified with an EEPROM setting - * then 'termination' was set-up in AdvInitFromEEP() and + * then 'termination' was set-up in AdvInitFrom3550EEPROM() and * is ready to be 'ored' into SCSI_CFG1. */ if (sc->cfg.termination == 0) { /* - * The software always controls termination by setting - * ADW_TERM_CTL_SEL. - * If ADW_TERM_CTL_SEL were set to 0, the hardware would - * set termination. + * The software always controls termination by setting TERM_CTL_SEL. + * If TERM_CTL_SEL were set to 0, the hardware would set termination. */ sc->cfg.termination |= ADW_TERM_CTL_SEL; - switch (scsi_cfg1 & ADW_CABLE_DETECT) { - /* ADW_TERM_CTL_H: on, ADW_TERM_CTL_L: on */ - case 0x3: - case 0x7: - case 0xB: - case 0xD: - case 0xE: - case 0xF: - sc->cfg.termination |= (ADW_TERM_CTL_H | - ADW_TERM_CTL_L); - break; + switch(scsi_cfg1 & ADW_CABLE_DETECT) { + /* TERM_CTL_H: on, TERM_CTL_L: on */ + case 0x3: case 0x7: case 0xB: case 0xD: case 0xE: case 0xF: + sc->cfg.termination |= (ADW_TERM_CTL_H | ADW_TERM_CTL_L); + break; - /* ADW_TERM_CTL_H: on, ADW_TERM_CTL_L: off */ - case 0x1: - case 0x5: - case 0x9: - case 0xA: - case 0xC: - sc->cfg.termination |= ADW_TERM_CTL_H; - break; + /* TERM_CTL_H: on, TERM_CTL_L: off */ + case 0x1: case 0x5: case 0x9: case 0xA: case 0xC: + sc->cfg.termination |= ADW_TERM_CTL_H; + break; - /* ADW_TERM_CTL_H: off, ADW_TERM_CTL_L: off */ - case 0x2: - case 0x6: - break; + /* TERM_CTL_H: off, TERM_CTL_L: off */ + case 0x2: case 0x6: + break; } } + /* - * Clear any set ADW_TERM_CTL_H and ADW_TERM_CTL_L bits. + * Clear any set TERM_CTL_H and TERM_CTL_L bits. */ scsi_cfg1 &= ~ADW_TERM_CTL; /* - * Invert the ADW_TERM_CTL_H and ADW_TERM_CTL_L bits and then - * set 'scsi_cfg1'. The ADW_TERM_POL bit does not need to be + * Invert the TERM_CTL_H and TERM_CTL_L bits and then + * set 'scsi_cfg1'. The TERM_POL bit does not need to be * referenced, because the hardware internally inverts - * the Termination High and Low bits if ADW_TERM_POL is set. + * the Termination High and Low bits if TERM_POL is set. */ scsi_cfg1 |= (ADW_TERM_CTL_SEL | (~sc->cfg.termination & ADW_TERM_CTL)); @@ -385,7 +581,21 @@ ADW_SOFTC *sc; * after it is started below. */ ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SCSI_CFG1, - ADW_FLTR_11_TO_20NS | scsi_cfg1); + ADW_FLTR_DISABLE | scsi_cfg1); + + /* + * Set MEM_CFG Microcode Default Value + * + * The microcode will set the MEM_CFG register using this value + * after it is started below. + * + * MEM_CFG may be accessed as a word or byte, but only bits 0-7 + * are defined. + * + * ASC-3550 has 8KB internal memory. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_MEM_CFG, + ADW_BIOS_EN | ADW_RAM_SZ_8KB); /* * Set SEL_MASK Microcode Default Value @@ -394,70 +604,641 @@ ADW_SOFTC *sc; * after it is started below. */ ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SEL_MASK, - ADW_TID_TO_TIDMASK(sc->chip_scsi_id)); + ADW_TID_TO_TIDMASK(sc->chip_scsi_id)); + /* - * Link all the RISC Queue Lists together in a doubly-linked - * NULL terminated list. + * Set-up the Host->RISC Initiator Command Queue (ICQ). + */ + + if ((sc->icq_sp = sc->carr_freelist) == NULL) { + return ASC_IERR_NO_CARRIER; + } + sc->carr_freelist = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(sc->icq_sp->next_vpa)); + + /* + * The first command issued will be placed in the stopper carrier. + */ + sc->icq_sp->next_vpa = ASC_CQ_STOPPER; + + /* + * Set RISC ICQ physical address start value. + */ + ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_ICQ, sc->icq_sp->carr_pa); + + /* + * Set-up the RISC->Host Initiator Response Queue (IRQ). + */ + if ((sc->irq_sp = sc->carr_freelist) == NULL) { + return ASC_IERR_NO_CARRIER; + } + sc->carr_freelist = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(sc->irq_sp->next_vpa)); + + /* + * The first command completed by the RISC will be placed in + * the stopper. * - * Skip the NULL (0) queue which is not used. + * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is + * completed the RISC will set the ASC_RQ_STOPPER bit. + */ + sc->irq_sp->next_vpa = ASC_CQ_STOPPER; + + /* + * Set RISC IRQ physical address start value. + */ + ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_IRQ, sc->irq_sp->carr_pa); + sc->carr_pending_cnt = 0; + + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES, + (ADW_INTR_ENABLE_HOST_INTR | ADW_INTR_ENABLE_GLOBAL_INTR)); + + /* + * Note: Don't remove the use of a temporary variable in + * the following code, otherwise some C compiler + * might turn the following lines into a no-op. */ - for (i = 1, rql_addr = ASC_MC_RISC_Q_LIST_BASE+ASC_MC_RISC_Q_LIST_SIZE; - i < ASC_MC_RISC_Q_TOTAL_CNT; - i++, rql_addr += ASC_MC_RISC_Q_LIST_SIZE) { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_BEGIN_ADDR, word); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_PC, word); + + /* finally, finally, gentlemen, start your engine */ + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_RUN); + + /* + * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus + * Resets should be performed. The RISC has to be running + * to issue a SCSI Bus Reset. + */ + if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) + { /* - * Set the current RISC Queue List's RQL_FWD and - * RQL_BWD pointers in a one word write and set - * the state (RQL_STATE) to free. + * If the BIOS Signature is present in memory, restore the + * BIOS Handshake Configuration Table and do not perform + * a SCSI Bus Reset. */ - ADW_WRITE_WORD_LRAM(iot, ioh, rql_addr, - ((i + 1) + ((i - 1) << 8))); - ADW_WRITE_BYTE_LRAM(iot, ioh, rql_addr + RQL_STATE, - ASC_MC_QS_FREE); + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == + 0x55AA) { + /* + * Restore per TID negotiated values. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, + wdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, + sdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, + tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + ADW_WRITE_BYTE_LRAM(iot, ioh, + ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + } else { + if (AdvResetCCB(sc) != ADW_TRUE) { + warn_code = ASC_WARN_BUSRESET_ERROR; + } + } } + return warn_code; +} + +/* + * Initialize the ASC-38C0800. + * + * On failure set the ADV_DVC_VAR field 'err_code' and return ADW_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + */ +int +AdvInitAsc38C0800Driver(sc) +ADW_SOFTC *sc; +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + u_int16_t warn_code; + u_int32_t sum; + int begin_addr; + int end_addr; + u_int16_t code_sum; + int word; + int i, j; + int adv_asc38C0800_expanded_size; + u_int16_t scsi_cfg1; + u_int8_t byte; + u_int8_t tid; + u_int16_t bios_mem[ASC_MC_BIOSLEN/2]; /* BIOS RISC Memory + 0x40-0x8F. */ + u_int16_t wdtr_able, sdtr_able, tagqng_able; + u_int8_t max_cmd[ADW_MAX_TID + 1]; + + + warn_code = 0; + /* - * Set the Host and RISC Queue List pointers. + * Save the RISC memory BIOS region before writing the microcode. + * The BIOS may already be loaded and using its RISC LRAM region + * so its region must be saved and restored. * - * Both sets of pointers are initialized with the same values: - * ASC_MC_RISC_Q_FIRST(0x01) and ASC_MC_RISC_Q_LAST (0xFF). + * Note: This code makes the assumption, which is currently true, + * that a chip reset does not clear RISC LRAM. */ - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_READY, - ASC_MC_RISC_Q_FIRST); - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_DONE, - ASC_MC_RISC_Q_LAST); + for (i = 0; i < ASC_MC_BIOSLEN/2; i++) { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_BIOSMEM + (2 * i), bios_mem[i]); + } - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_RISC_NEXT_READY, - ASC_MC_RISC_Q_FIRST); - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_RISC_NEXT_DONE, - ASC_MC_RISC_Q_LAST); + /* + * Save current per TID negotiated values. + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, wdtr_able); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sdtr_able); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } /* - * Finally, set up the last RISC Queue List (255) with - * a NULL forward pointer. + * RAM BIST (RAM Built-In Self Test) + * + * Address : I/O base + offset 0x38h register (byte). + * Function: Bit 7-6(RW) : RAM mode + * Normal Mode : 0x00 + * Pre-test Mode : 0x40 + * RAM Test Mode : 0x80 + * Bit 5 : unused + * Bit 4(RO) : Done bit + * Bit 3-0(RO) : Status + * Host Error : 0x08 + * Int_RAM Error : 0x04 + * RISC Error : 0x02 + * SCSI Error : 0x01 + * No Error : 0x00 + * + * Note: RAM BIST code should be put right here, before loading the + * microcode and after saving the RISC memory BIOS region. */ - ADW_WRITE_WORD_LRAM(iot, ioh, rql_addr, - (ASC_MC_NULL_Q + ((i - 1) << 8))); - ADW_WRITE_BYTE_LRAM(iot, ioh, rql_addr + RQL_STATE, ASC_MC_QS_FREE); - ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES, - (ADW_INTR_ENABLE_HOST_INTR | ADW_INTR_ENABLE_GLOBAL_INTR)); + /* + * LRAM Pre-test + * + * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. + * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return + * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset + * to NORMAL_MODE, return an error too. + */ + for (i = 0; i < 2; i++) { + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, PRE_TEST_MODE); + AdvSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 || (byte & 0x0F) != + PRE_TEST_VALUE) { + return ASC_IERR_BIST_PRE_TEST; + } + + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, NORMAL_MODE); + AdvSleepMilliSecond(10); /* Wait for 10ms before reading back. */ + if (ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST) + != NORMAL_VALUE) { + return ASC_IERR_BIST_PRE_TEST; + } + } + + /* + * LRAM Test - It takes about 1.5 ms to run through the test. + * + * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. + * If Done bit not set or Status not 0, save register byte, set the + * err_code, and return an error. + */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, RAM_TEST_MODE); + AdvSleepMilliSecond(10); /* Wait for 10ms before checking status. */ + + byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST); + if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { + /* Get here if Done bit not set or Status not 0. */ + return ASC_IERR_BIST_RAM_TEST; + } + + /* We need to reset back to normal mode after LRAM test passes. */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_RAM_BIST, NORMAL_MODE); + + /* + * Load the Microcode + * + * Write the microcode image to RISC memory starting at address 0. + * + */ + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); + + /* Assume the following compressed format of the microcode buffer: + * + * 254 word (508 byte) table indexed by byte code followed + * by the following byte codes: + * + * 1-Byte Code: + * 00: Emit word 0 in table. + * 01: Emit word 1 in table. + * . + * FD: Emit word 253 in table. + * + * Multi-Byte Code: + * FE WW WW: (3 byte code) Word to emit is the next word WW WW. + * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. + */ + word = 0; + for (i = 253 * 2; i < adv_asc38C0800_mcode_size; i++) { + if (adv_asc38C0800_mcode[i] == 0xff) { + for (j = 0; j < adv_asc38C0800_mcode[i + 1]; j++) { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, + (((u_int16_t) + adv_asc38C0800_mcode[i + 3] << 8) | + adv_asc38C0800_mcode[i + 2])); + word++; + } + i += 3; + } else if (adv_asc38C0800_mcode[i] == 0xfe) { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, (((u_int16_t) + adv_asc38C0800_mcode[i + 2] << 8) | + adv_asc38C0800_mcode[i + 1])); + i += 2; + word++; + } else { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, (((u_int16_t) + adv_asc38C0800_mcode[(adv_asc38C0800_mcode[i] * 2) + 1] << 8) | + adv_asc38C0800_mcode[adv_asc38C0800_mcode[i] * 2])); + word++; + } + } + + /* + * Set 'word' for later use to clear the rest of memory and save + * the expanded mcode size. + */ + word *= 2; + adv_asc38C0800_expanded_size = word; + + /* + * Clear the rest of ASC-38C0800 Internal RAM (16KB). + */ + for (; word < ADV_38C0800_MEMSIZE; word += 2) { + ADW_WRITE_WORD_AUTO_INC_LRAM(iot, ioh, 0); + } + + /* + * Verify the microcode checksum. + */ + sum = 0; + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, 0); + + for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) { + sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); + } + + if (sum != adv_asc38C0800_mcode_chksum) { + return ASC_IERR_MCODE_CHKSUM; + } + + /* + * Restore the RISC memory BIOS region. + */ + for (i = 0; i < ASC_MC_BIOSLEN/2; i++) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_BIOSMEM + (2 * i), + bios_mem[i]); + } + /* + * Calculate and write the microcode code checksum to the microcode + * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_BEGIN_ADDR, begin_addr); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_END_ADDR, end_addr); + code_sum = 0; + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RAM_ADDR, begin_addr); + for (word = begin_addr; word < end_addr; word += 2) { + code_sum += ADW_READ_WORD_AUTO_INC_LRAM(iot, ioh); + } + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CODE_CHK_SUM, code_sum); + + /* + * Read microcode version and date. + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_DATE, + sc->cfg.mcode_date); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_VERSION_NUM, + sc->cfg.mcode_version); + + /* + * Set the chip type to indicate the ASC38C0800. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); + + /* + * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. + * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current + * cable detection and then we are able to read C_DET[3:0]. + * + * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 + * Microcode Default Value' section below. + */ + scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1, + scsi_cfg1 | ADW_DIS_TERM_DRV); + + /* + * If the PCI Configuration Command Register "Parity Error Response + * Control" Bit was clear (0), then set the microcode variable + * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode + * to ignore DMA parity errors. + */ + if (sc->cfg.control_flag & CONTROL_FLAG_IGNORE_PERR) { + /* + * Note: Don't remove the use of a temporary variable in + * the following code, otherwise some C compiler + * might turn the following lines into a no-op. + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CONTROL_FLAG, word); + word |= CONTROL_FLAG_IGNORE_PERR; + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_CONTROL_FLAG, word); + } + + /* + * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] + * bits for the default FIFO threshold. + * + * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. + * + * For DMA Errata #4 set the BC_THRESH_ENB bit. + */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, + BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); + + /* + * Microcode operating variables for WDTR, SDTR, and command tag + * queuing will be set in AdvInquiryHandling() based on what a + * device reports it is capable of in Inquiry byte 7. + * + * If SCSI Bus Resets have been disabled, then directly set + * SDTR and WDTR from the EEPROM configuration. This will allow + * the BIOS and warm boot to work without a SCSI bus hang on + * the Inquiry caused by host and target mismatched DTR values. + * Without the SCSI Bus Reset, before an Inquiry a device can't + * be assumed to be in Asynchronous, Narrow mode. + */ + if ((sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, sc->wdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sc->sdtr_able); + } + + /* + * Set microcode operating variables for DISC and SDTR_SPEED1, + * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM + * configuration values. + * + * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, + * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them + * without determining here whether the device supports SDTR. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DISC_ENABLE, sc->cfg.disc_enable); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED1, sc->sdtr_speed1); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED2, sc->sdtr_speed2); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED3, sc->sdtr_speed3); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_SPEED4, sc->sdtr_speed4); + + /* + * Set SCSI_CFG0 Microcode Default Value. + * + * The microcode will set the SCSI_CFG0 register using this value + * after it is started below. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SCSI_CFG0, + ADW_PARITY_EN | ADW_SEL_TMO_LONG | ADW_OUR_ID_EN | + sc->chip_scsi_id); + + /* + * Determine SCSI_CFG1 Microcode Default Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + + /* Read current SCSI_CFG1 Register value. */ + scsi_cfg1 = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); + + /* + * If the internal narrow cable is reversed all of the SCSI_CTRL + * register signals will be set. Check for and return an error if + * this condition is found. + */ + if ((ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CTRL) & 0x3F07) == + 0x3F07) { + return ASC_IERR_REVERSED_CABLE; + } + + /* + * All kind of combinations of devices attached to one of four connectors + * are acceptable except HVD device attached. For example, LVD device can + * be attached to SE connector while SE device attached to LVD connector. + * If LVD device attached to SE connector, it only runs up to Ultra speed. + * + * If an HVD device is attached to one of LVD connectors, return an error. + * However, there is no way to detect HVD device attached to SE connectors. + */ + if (scsi_cfg1 & ADW_HVD) { + return ASC_IERR_HVD_DEVICE; + } + + /* + * If either SE or LVD automatic termination control is enabled, then + * set the termination value based on a table listed in a_condor.h. + * + * If manual termination was specified with an EEPROM setting then + * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to + * be 'ored' into SCSI_CFG1. + */ + if ((sc->cfg.termination & ADW_TERM_SE) == 0) { + /* SE automatic termination control is enabled. */ + switch(scsi_cfg1 & ADW_C_DET_SE) { + /* TERM_SE_HI: on, TERM_SE_LO: on */ + case 0x1: case 0x2: case 0x3: + sc->cfg.termination |= ADW_TERM_SE; + break; + + /* TERM_SE_HI: on, TERM_SE_LO: off */ + case 0x0: + sc->cfg.termination |= ADW_TERM_SE_HI; + break; + } + } + + if ((sc->cfg.termination & ADW_TERM_LVD) == 0) { + /* LVD automatic termination control is enabled. */ + switch(scsi_cfg1 & ADW_C_DET_LVD) { + /* TERM_LVD_HI: on, TERM_LVD_LO: on */ + case 0x4: case 0x8: case 0xC: + sc->cfg.termination |= ADW_TERM_LVD; + break; + + /* TERM_LVD_HI: off, TERM_LVD_LO: off */ + case 0x0: + break; + } + } + + /* + * Clear any set TERM_SE and TERM_LVD bits. + */ + scsi_cfg1 &= (~ADW_TERM_SE & ~ADW_TERM_LVD); + + /* + * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. + */ + scsi_cfg1 |= (~sc->cfg.termination & 0xF0); + + /* + * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits + * and set possibly modified termination control bits in the Microcode + * SCSI_CFG1 Register Value. + */ + scsi_cfg1 &= (~ADW_BIG_ENDIAN & ~ADW_DIS_TERM_DRV & + ~ADW_TERM_POL & ~ADW_HVD_LVD_SE); + + /* + * Set SCSI_CFG1 Microcode Default Value + * + * Set possibly modified termination control and reset DIS_TERM_DRV + * bits in the Microcode SCSI_CFG1 Register Value. + * + * The microcode will set the SCSI_CFG1 register using this value + * after it is started below. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); + + /* + * Set MEM_CFG Microcode Default Value + * + * The microcode will set the MEM_CFG register using this value + * after it is started below. + * + * MEM_CFG may be accessed as a word or byte, but only bits 0-7 + * are defined. + * + * ASC-38C0800 has 16KB internal memory. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_MEM_CFG, + ADW_BIOS_EN | ADW_RAM_SZ_16KB); + + /* + * Set SEL_MASK Microcode Default Value + * + * The microcode will set the SEL_MASK register using this value + * after it is started below. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_DEFAULT_SEL_MASK, + ADW_TID_TO_TIDMASK(sc->chip_scsi_id)); + + + /* + * Set-up the Host->RISC Initiator Command Queue (ICQ). + */ + + if ((sc->icq_sp = sc->carr_freelist) == NULL) { + return ASC_IERR_NO_CARRIER; + } + sc->carr_freelist = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(sc->icq_sp->next_vpa)); + + + /* + * The first command issued will be placed in the stopper carrier. + */ + sc->icq_sp->next_vpa = ASC_CQ_STOPPER; + + /* + * Set RISC ICQ physical address start value. + */ + ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_ICQ, sc->icq_sp->carr_pa); + + /* + * Set-up the RISC->Host Initiator Response Queue (IRQ). + */ + if ((sc->irq_sp = sc->carr_freelist) == NULL) { + return ASC_IERR_NO_CARRIER; + } + sc->carr_freelist = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(sc->irq_sp->next_vpa)); + + /* + * The first command completed by the RISC will be placed in + * the stopper. + * + * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is + * completed the RISC will set the ASC_RQ_STOPPER bit. + */ + sc->irq_sp->next_vpa = ASC_CQ_STOPPER; + + /* + * Set RISC IRQ physical address start value. + */ + ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_IRQ, sc->irq_sp->carr_pa); + sc->carr_pending_cnt = 0; + + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_INTR_ENABLES, + (ADW_INTR_ENABLE_HOST_INTR | ADW_INTR_ENABLE_GLOBAL_INTR)); + /* + * Note: Don't remove the use of a temporary variable in + * the following code, otherwise some C compiler + * might turn the following lines into a no-op. + */ ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_CODE_BEGIN_ADDR, word); ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_PC, word); /* finally, finally, gentlemen, start your engine */ ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_RUN); + /* + * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus + * Resets should be performed. The RISC has to be running + * to issue a SCSI Bus Reset. + */ + if (sc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { + /* + * If the BIOS Signature is present in memory, restore the + * BIOS Handshake Configuration Table and do not perform + * a SCSI Bus Reset. + */ + if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM)/2] == + 0x55AA) { + /* + * Restore per TID negotiated values. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, wdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, + tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + ADW_WRITE_BYTE_LRAM(iot, ioh, + ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + } else { + if (AdvResetCCB(sc) != ADW_TRUE) { + warn_code = ASC_WARN_BUSRESET_ERROR; + } + } + } + return warn_code; } + /* - * Read the board's EEPROM configuration. Set fields in ADW_SOFTC and - * ADW_DVC_CFG based on the EEPROM settings. The chip is stopped while + * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and + * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while * all of this is done. * - * On failure set the ADW_DVC_VAR field 'err_code' and return ADW_ERROR. + * On failure set the ADV_DVC_VAR field 'err_code' and return ADW_ERROR. * * For a non-fatal error return a warning code. If there are no warnings * then 0 is returned. @@ -465,14 +1246,14 @@ ADW_SOFTC *sc; * Note: Chip is stopped on entry. */ int -AdvInitFromEEP(sc) - ADW_SOFTC *sc; +AdvInitFrom3550EEP(sc) +ADW_SOFTC *sc; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - u_int16_t warn_code; - ADWEEP_CONFIG eep_config; - int eep_chksum, i; + u_int16_t warn_code; + ADW_EEP_3550_CONFIG eep_config; + int i; warn_code = 0; @@ -482,17 +1263,15 @@ AdvInitFromEEP(sc) * * Set default values if a bad checksum is found. */ - eep_chksum = AdvGetEEPConfig(iot, ioh, &eep_config); - - if (eep_chksum != eep_config.check_sum) { + if (AdvGet3550EEPConfig(iot, ioh, &eep_config) != eep_config.check_sum){ warn_code |= ASC_WARN_EEPROM_CHKSUM; /* * Set EEPROM default values. */ - for (i = 0; i < sizeof(ADWEEP_CONFIG); i++) { - *((u_int8_t *) & eep_config + i) = - *((u_int8_t *) & Default_EEPROM_Config + i); + for (i = 0; i < sizeof(ADW_EEP_3550_CONFIG); i++) { + *((u_int8_t *) &eep_config + i) = + *((u_int8_t *) &Default_3550_EEPROM_Config + i); } /* @@ -502,14 +1281,17 @@ AdvInitFromEEP(sc) */ eep_config.serial_number_word3 = AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 1); + eep_config.serial_number_word2 = AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 2); + eep_config.serial_number_word1 = AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 3); - AdvSetEEPConfig(iot, ioh, &eep_config); + + AdvSet3550EEPConfig(iot, ioh, &eep_config); } /* - * Set ADW_DVC_VAR and ADW_DVC_CFG variables from the + * Set sc_VAR and sc_CFG variables from the * EEPROM configuration that was read. * * This is the mapping of EEPROM fields to Adv Library fields. @@ -524,7 +1306,6 @@ AdvInitFromEEP(sc) sc->chip_scsi_id = (eep_config.adapter_scsi_id & ADW_MAX_TID); sc->start_motor = eep_config.start_motor; sc->scsi_reset_wait = eep_config.scsi_reset_delay; - sc->cfg.bios_boot_wait = eep_config.bios_boot_delay; sc->bios_ctrl = eep_config.bios_ctrl; sc->no_scam = eep_config.scam_tolerant; sc->cfg.serial1 = eep_config.serial_number_word1; @@ -537,7 +1318,8 @@ AdvInitFromEEP(sc) */ if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; - } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { + } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) + { /* If the value is zero, assume it is uninitialized. */ if (eep_config.max_host_qng == 0) { eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; @@ -545,6 +1327,7 @@ AdvInitFromEEP(sc) eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; } } + if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { @@ -555,6 +1338,7 @@ AdvInitFromEEP(sc) eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; } } + /* * If 'max_dvc_qng' is greater than 'max_host_qng', then * set 'max_dvc_qng' to 'max_host_qng'. @@ -562,8 +1346,9 @@ AdvInitFromEEP(sc) if (eep_config.max_dvc_qng > eep_config.max_host_qng) { eep_config.max_dvc_qng = eep_config.max_host_qng; } + /* - * Set ADW_DVC_VAR 'max_host_qng' and ADW_DVC_CFG 'max_dvc_qng' + * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' * values based on possibly adjusted EEPROM values. */ sc->max_host_qng = eep_config.max_host_qng; @@ -572,31 +1357,31 @@ AdvInitFromEEP(sc) /* * If the EEPROM 'termination' field is set to automatic (0), then set - * the ADW_DVC_CFG 'termination' field to automatic also. + * the ADV_DVC_CFG 'termination' field to automatic also. * * If the termination is specified with a non-zero 'termination' - * value check that a legal value is set and set the ADW_DVC_CFG + * value check that a legal value is set and set the ADV_DVC_CFG * 'termination' field appropriately. */ if (eep_config.termination == 0) { - sc->cfg.termination = 0; /* auto termination */ + sc->cfg.termination = 0; /* auto termination */ } else { /* Enable manual control with low off / high off. */ if (eep_config.termination == 1) { sc->cfg.termination = ADW_TERM_CTL_SEL; - /* Enable manual control with low off / high on. */ + /* Enable manual control with low off / high on. */ } else if (eep_config.termination == 2) { sc->cfg.termination = ADW_TERM_CTL_SEL | ADW_TERM_CTL_H; - /* Enable manual control with low on / high on. */ + /* Enable manual control with low on / high on. */ } else if (eep_config.termination == 3) { sc->cfg.termination = ADW_TERM_CTL_SEL | ADW_TERM_CTL_H | ADW_TERM_CTL_L; } else { /* - * The EEPROM 'termination' field contains a bad value. - * Use automatic termination instead. + * The EEPROM 'termination' field contains a bad value. Use + * automatic termination instead. */ sc->cfg.termination = 0; warn_code |= ASC_WARN_EEPROM_TERMINATION; @@ -606,88 +1391,346 @@ AdvInitFromEEP(sc) return warn_code; } + +/* + * Read the board's EEPROM configuration. Set fields in ADV_DVC_VAR and + * ADV_DVC_CFG based on the EEPROM settings. The chip is stopped while + * all of this is done. + * + * On failure set the ADV_DVC_VAR field 'err_code' and return ADW_ERROR. + * + * For a non-fatal error return a warning code. If there are no warnings + * then 0 is returned. + * + * Note: Chip is stopped on entry. + */ +int +AdvInitFrom38C0800EEP(sc) +ADW_SOFTC *sc; +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + u_int16_t warn_code; + ADW_EEP_38C0800_CONFIG eep_config; + int i; + u_int8_t tid, termination; + u_int16_t sdtr_speed = 0; + + + warn_code = 0; + + /* + * Read the board's EEPROM configuration. + * + * Set default values if a bad checksum is found. + */ + if (AdvGet38C0800EEPConfig(iot, ioh, &eep_config) != + eep_config.check_sum) { + warn_code |= ASC_WARN_EEPROM_CHKSUM; + + /* + * Set EEPROM default values. + */ + for (i = 0; i < sizeof(ADW_EEP_38C0800_CONFIG); i++) { + *((u_int8_t *) &eep_config + i) = + *((u_int8_t *)&Default_38C0800_EEPROM_Config+i); + } + + /* + * Assume the 6 byte board serial number that was read + * from EEPROM is correct even if the EEPROM checksum + * failed. + */ + eep_config.serial_number_word3 = + AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 1); + + eep_config.serial_number_word2 = + AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 2); + + eep_config.serial_number_word1 = + AdvReadEEPWord(iot, ioh, ASC_EEP_DVC_CFG_END - 3); + + AdvSet38C0800EEPConfig(iot, ioh, &eep_config); + } + /* + * Set ADV_DVC_VAR and ADV_DVC_CFG variables from the + * EEPROM configuration that was read. + * + * This is the mapping of EEPROM fields to Adv Library fields. + */ + sc->wdtr_able = eep_config.wdtr_able; + sc->sdtr_speed1 = eep_config.sdtr_speed1; + sc->sdtr_speed2 = eep_config.sdtr_speed2; + sc->sdtr_speed3 = eep_config.sdtr_speed3; + sc->sdtr_speed4 = eep_config.sdtr_speed4; + sc->tagqng_able = eep_config.tagqng_able; + sc->cfg.disc_enable = eep_config.disc_enable; + sc->max_host_qng = eep_config.max_host_qng; + sc->max_dvc_qng = eep_config.max_dvc_qng; + sc->chip_scsi_id = (eep_config.adapter_scsi_id & ADW_MAX_TID); + sc->start_motor = eep_config.start_motor; + sc->scsi_reset_wait = eep_config.scsi_reset_delay; + sc->bios_ctrl = eep_config.bios_ctrl; + sc->no_scam = eep_config.scam_tolerant; + sc->cfg.serial1 = eep_config.serial_number_word1; + sc->cfg.serial2 = eep_config.serial_number_word2; + sc->cfg.serial3 = eep_config.serial_number_word3; + + /* + * For every Target ID if any of its 'sdtr_speed[1234]' bits + * are set, then set an 'sdtr_able' bit for it. + */ + sc->sdtr_able = 0; + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + if (tid == 0) { + sdtr_speed = sc->sdtr_speed1; + } else if (tid == 4) { + sdtr_speed = sc->sdtr_speed2; + } else if (tid == 8) { + sdtr_speed = sc->sdtr_speed3; + } else if (tid == 12) { + sdtr_speed = sc->sdtr_speed4; + } + if (sdtr_speed & ADW_MAX_TID) { + sc->sdtr_able |= (1 << tid); + } + sdtr_speed >>= 4; + } + + /* + * Set the host maximum queuing (max. 253, min. 16) and the per device + * maximum queuing (max. 63, min. 4). + */ + if (eep_config.max_host_qng > ASC_DEF_MAX_HOST_QNG) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else if (eep_config.max_host_qng < ASC_DEF_MIN_HOST_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_host_qng == 0) { + eep_config.max_host_qng = ASC_DEF_MAX_HOST_QNG; + } else { + eep_config.max_host_qng = ASC_DEF_MIN_HOST_QNG; + } + } + + if (eep_config.max_dvc_qng > ASC_DEF_MAX_DVC_QNG) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else if (eep_config.max_dvc_qng < ASC_DEF_MIN_DVC_QNG) { + /* If the value is zero, assume it is uninitialized. */ + if (eep_config.max_dvc_qng == 0) { + eep_config.max_dvc_qng = ASC_DEF_MAX_DVC_QNG; + } else { + eep_config.max_dvc_qng = ASC_DEF_MIN_DVC_QNG; + } + } + + /* + * If 'max_dvc_qng' is greater than 'max_host_qng', then + * set 'max_dvc_qng' to 'max_host_qng'. + */ + if (eep_config.max_dvc_qng > eep_config.max_host_qng) { + eep_config.max_dvc_qng = eep_config.max_host_qng; + } + + /* + * Set ADV_DVC_VAR 'max_host_qng' and ADV_DVC_VAR 'max_dvc_qng' + * values based on possibly adjusted EEPROM values. + */ + sc->max_host_qng = eep_config.max_host_qng; + sc->max_dvc_qng = eep_config.max_dvc_qng; + + /* + * If the EEPROM 'termination' field is set to automatic (0), then set + * the ADV_DVC_CFG 'termination' field to automatic also. + * + * If the termination is specified with a non-zero 'termination' + * value check that a legal value is set and set the ADV_DVC_CFG + * 'termination' field appropriately. + */ + if (eep_config.termination_se == 0) { + termination = 0; /* auto termination for SE */ + } else { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_se == 1) { + termination = 0; + + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_se == 2) { + termination = ADW_TERM_SE_HI; + + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_se == 3) { + termination = ADW_TERM_SE; + } else { + /* + * The EEPROM 'termination_se' field contains + * a bad value. + * Use automatic termination instead. + */ + termination = 0; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } + } + + if (eep_config.termination_lvd == 0) { + /* auto termination for LVD */ + sc->cfg.termination = termination; + } else + { + /* Enable manual control with low off / high off. */ + if (eep_config.termination_lvd == 1) { + sc->cfg.termination = termination; + + /* Enable manual control with low off / high on. */ + } else if (eep_config.termination_lvd == 2) { + sc->cfg.termination = termination | ADW_TERM_LVD_HI; + + /* Enable manual control with low on / high on. */ + } else if (eep_config.termination_lvd == 3) { + sc->cfg.termination = termination | ADW_TERM_LVD; + } else { + /* + * The EEPROM 'termination_lvd' field contains a bad value. + * Use automatic termination instead. + */ + sc->cfg.termination = termination; + warn_code |= ASC_WARN_EEPROM_TERMINATION; + } + } + + return warn_code; +} + + /* * Read EEPROM configuration into the specified buffer. * * Return a checksum based on the EEPROM configuration read. */ -static u_int16_t -AdvGetEEPConfig(iot, ioh, cfg_buf) - bus_space_tag_t iot; - bus_space_handle_t ioh; - ADWEEP_CONFIG *cfg_buf; +static u_int16_t +AdvGet3550EEPConfig(iot, ioh, cfg_buf) + bus_space_tag_t iot; + bus_space_handle_t ioh; + ADW_EEP_3550_CONFIG *cfg_buf; +{ + u_int16_t wval, chksum; + u_int16_t *wbuf; + int eep_addr; + + + wbuf = (u_int16_t *) cfg_buf; + chksum = 0; + + for (eep_addr = ASC_EEP_DVC_CFG_BEGIN; + eep_addr < ASC_EEP_DVC_CFG_END; + eep_addr++, wbuf++) { + wval = AdvReadEEPWord(iot, ioh, eep_addr); + chksum += wval; + *wbuf = wval; + } + + *wbuf = AdvReadEEPWord(iot, ioh, eep_addr); + wbuf++; + for (eep_addr = ASC_EEP_DVC_CTL_BEGIN; + eep_addr < ASC_EEP_MAX_WORD_ADDR; + eep_addr++, wbuf++) { + *wbuf = AdvReadEEPWord(iot, ioh, eep_addr); + } + + return chksum; +} + + +/* + * Read EEPROM configuration into the specified buffer. + * + * Return a checksum based on the EEPROM configuration read. + */ +static u_int16_t +AdvGet38C0800EEPConfig(iot, ioh, cfg_buf) + bus_space_tag_t iot; + bus_space_handle_t ioh; + ADW_EEP_38C0800_CONFIG *cfg_buf; { - u_int16_t wval, chksum; - u_int16_t *wbuf; - int eep_addr; + u_int16_t wval, chksum; + u_int16_t *wbuf; + int eep_addr; + wbuf = (u_int16_t *) cfg_buf; chksum = 0; for (eep_addr = ASC_EEP_DVC_CFG_BEGIN; - eep_addr < ASC_EEP_DVC_CFG_END; - eep_addr++, wbuf++) { + eep_addr < ASC_EEP_DVC_CFG_END; + eep_addr++, wbuf++) { wval = AdvReadEEPWord(iot, ioh, eep_addr); chksum += wval; *wbuf = wval; } + *wbuf = AdvReadEEPWord(iot, ioh, eep_addr); wbuf++; for (eep_addr = ASC_EEP_DVC_CTL_BEGIN; - eep_addr < ASC_EEP_MAX_WORD_ADDR; - eep_addr++, wbuf++) { + eep_addr < ASC_EEP_MAX_WORD_ADDR; + eep_addr++, wbuf++) { *wbuf = AdvReadEEPWord(iot, ioh, eep_addr); } + return chksum; } + /* * Read the EEPROM from specified location */ -static u_int16_t +static u_int16_t AdvReadEEPWord(iot, ioh, eep_word_addr) - bus_space_tag_t iot; - bus_space_handle_t ioh; - int eep_word_addr; + bus_space_tag_t iot; + bus_space_handle_t ioh; + int eep_word_addr; { ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, - ASC_EEP_CMD_READ | eep_word_addr); - AdvWaitEEPCmd(iot, iot); + ASC_EEP_CMD_READ | eep_word_addr); + AdvWaitEEPCmd(iot, ioh); + return ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_DATA); } + /* * Wait for EEPROM command to complete */ static void AdvWaitEEPCmd(iot, ioh) - bus_space_tag_t iot; - bus_space_handle_t ioh; + bus_space_tag_t iot; + bus_space_handle_t ioh; { - DvcSleepMilliSecond(1); + int eep_delay_ms; - for (;;) { + + for (eep_delay_ms = 0; eep_delay_ms < ASC_EEP_DELAY_MS; eep_delay_ms++){ if (ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD) & - ASC_EEP_CMD_DONE) { + ASC_EEP_CMD_DONE) { break; } - DvcSleepMilliSecond(1); + AdvSleepMilliSecond(1); } - return; + ADW_READ_WORD_REGISTER(iot, ioh, IOPW_EE_CMD); } + /* * Write the EEPROM from 'cfg_buf'. */ static void -AdvSetEEPConfig(iot, ioh, cfg_buf) - bus_space_tag_t iot; - bus_space_handle_t ioh; - ADWEEP_CONFIG *cfg_buf; +AdvSet3550EEPConfig(iot, ioh, cfg_buf) + bus_space_tag_t iot; + bus_space_handle_t ioh; + ADW_EEP_3550_CONFIG *cfg_buf; { - u_int16_t *wbuf; - u_int16_t addr, chksum; + u_int16_t *wbuf; + u_int16_t addr, chksum; + wbuf = (u_int16_t *) cfg_buf; chksum = 0; @@ -696,171 +1739,398 @@ AdvSetEEPConfig(iot, ioh, cfg_buf) AdvWaitEEPCmd(iot, ioh); /* - * Write EEPROM from word 0 to word 15 + * Write EEPROM from word 0 to word 20 */ for (addr = ASC_EEP_DVC_CFG_BEGIN; addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++) { chksum += *wbuf; ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); - ADW_WRITE_WORD_REGISTER(iot, ioh, - IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iot, ioh); - DvcSleepMilliSecond(ASC_EEP_DELAY_MS); + AdvSleepMilliSecond(ASC_EEP_DELAY_MS); } /* - * Write EEPROM checksum at word 18 + * Write EEPROM checksum at word 21 */ ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, chksum); ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE | addr); + ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iot, ioh); - wbuf++; /* skip over check_sum */ + wbuf++; /* skip over check_sum */ /* - * Write EEPROM OEM name at words 19 to 26 + * Write EEPROM OEM name at words 22 to 29 */ for (addr = ASC_EEP_DVC_CTL_BEGIN; addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++) { ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); - ADW_WRITE_WORD_REGISTER(iot, ioh, - IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); AdvWaitEEPCmd(iot, ioh); } + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, - ASC_EEP_CMD_WRITE_DISABLE); + ASC_EEP_CMD_WRITE_DISABLE); AdvWaitEEPCmd(iot, ioh); + return; } + /* - * This function resets the chip and SCSI bus - * - * It is up to the caller to add a delay to let the bus settle after - * calling this function. - * - * The SCSI_CFG0, SCSI_CFG1, and MEM_CFG registers are set-up in - * AdvInitAsc3550Driver(). Here when doing a write to one of these - * registers read first and then write. - * - * Note: A SCSI Bus Reset can not be done until after the EEPROM - * configuration is read to determine whether SCSI Bus Resets - * should be performed. + * Write the EEPROM from 'cfg_buf'. */ -void -AdvResetChip(iot, ioh) - bus_space_tag_t iot; - bus_space_handle_t ioh; +static void +AdvSet38C0800EEPConfig(iot, ioh, cfg_buf) + bus_space_tag_t iot; + bus_space_handle_t ioh; + ADW_EEP_38C0800_CONFIG *cfg_buf; { - u_int16_t word; - u_int8_t byte; + u_int16_t *wbuf; + u_int16_t addr, chksum; + wbuf = (u_int16_t *) cfg_buf; + chksum = 0; + + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); + AdvWaitEEPCmd(iot, ioh); + /* - * Reset Chip. + * Write EEPROM from word 0 to word 20 */ - ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, - ADW_CTRL_REG_CMD_RESET); - DvcSleepMilliSecond(100); - ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, - ADW_CTRL_REG_CMD_WR_IO_REG); + for (addr = ASC_EEP_DVC_CFG_BEGIN; + addr < ASC_EEP_DVC_CFG_END; addr++, wbuf++) { + chksum += *wbuf; + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iot, ioh); + AdvSleepMilliSecond(ASC_EEP_DELAY_MS); + } /* - * Initialize Chip registers. - * - * Note: Don't remove the use of a temporary variable in the following - * code, otherwise the Microsoft C compiler will turn the following - * lines into a no-op. + * Write EEPROM checksum at word 21 */ - byte = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_MEM_CFG); - byte |= RAM_SZ_8KB; - ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_MEM_CFG, byte); - - word = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1); - word &= ~BIG_ENDIAN; - ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CFG1, word); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, chksum); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iot, ioh); + wbuf++; /* skip over check_sum */ /* - * Setting the START_CTL_EMFU 3:2 bits sets a FIFO threshold - * of 128 bytes. This register is only accessible to the host. + * Write EEPROM OEM name at words 22 to 29 */ - ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_DMA_CFG0, - START_CTL_EMFU | READ_CMD_MRM); + for (addr = ASC_EEP_DVC_CTL_BEGIN; + addr < ASC_EEP_MAX_WORD_ADDR; addr++, wbuf++) { + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_DATA, *wbuf); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE | addr); + AdvWaitEEPCmd(iot, ioh); + } + + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_EE_CMD, + ASC_EEP_CMD_WRITE_DISABLE); + AdvWaitEEPCmd(iot, ioh); + + return; } + /* - * Description: - * Send a SCSI request to the ASC3550 chip + * AdvExeScsiQueue() - Send a request to the RISC microcode program. * - * If there is no SG list for the request, set 'sg_entry_cnt' to 0. + * Allocate a carrier structure, point the carrier to the ADW_SCSI_REQ_Q, + * add the carrier to the ICQ (Initiator Command Queue), and tickle the + * RISC to notify it a new command is ready to be executed. * - * If 'sg_real_addr' is non-zero on entry, AscGetSGList() will not be - * called. It is assumed the caller has already initialized 'sg_real_addr'. + * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be + * set to SCSI_MAX_RETRY. * * Return: - * ADW_SUCCESS(1) - the request is in the mailbox - * ADW_BUSY(0) - total request count > 253, try later - * ADW_ERROR(-1) - invalid scsi request Q + * ADW_SUCCESS(1) - The request was successfully queued. + * ADW_BUSY(0) - Resource unavailable; Retry again after pending + * request completes. + * ADW_ERROR(-1) - Invalid ADW_SCSI_REQ_Q request structure + * host IC error. */ int AdvExeScsiQueue(sc, scsiq) - ADW_SOFTC *sc; - ADW_SCSI_REQ_Q *scsiq; +ADW_SOFTC *sc; +ADW_SCSI_REQ_Q *scsiq; +{ + bus_space_tag_t iot = sc->sc_iot; + bus_space_handle_t ioh = sc->sc_ioh; + ADW_CCB *ccb; + long req_size; + u_int32_t req_paddr; + ADW_CARRIER *new_carrp/*, *ccb_carr; + int i*/; + + + /* + * The ADW_SCSI_REQ_Q 'target_id' field should never exceed ADW_MAX_TID. + */ + if (scsiq->target_id > ADW_MAX_TID) { + scsiq->host_status = QHSTA_M_INVALID_DEVICE; + scsiq->done_status = QD_WITH_ERROR; + return ADW_ERROR; + } + + ccb = adw_ccb_phys_kv(sc, scsiq->ccb_ptr); + ccb->carr_list = sc->icq_sp; + + /* + * Allocate a carrier ensuring at least one carrier always + * remains on the freelist and initialize fields. + */ + if ((new_carrp = sc->carr_freelist) == NULL) { + return ADW_BUSY; + } + sc->carr_freelist = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(new_carrp->next_vpa)); + sc->carr_pending_cnt++; + + /* + * Set the carrier to be a stopper by setting 'next_vpa' + * to the stopper value. The current stopper will be changed + * below to point to the new stopper. + */ + new_carrp->next_vpa = ASC_CQ_STOPPER; + + req_size = sizeof(ADW_SCSI_REQ_Q); + req_paddr = sc->sc_dmamap_control->dm_segs[0].ds_addr + + ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsiq); + + /* Save physical address of ADW_SCSI_REQ_Q and Carrier. */ + scsiq->scsiq_rptr = req_paddr; + + /* + * Every ADV_CARR_T.carr_pa is byte swapped to little-endian + * order during initialization. + */ + scsiq->carr_pa = sc->icq_sp->carr_pa; + scsiq->carr_va = sc->icq_sp->carr_pa; + + /* + * Use the current stopper to send the ADW_SCSI_REQ_Q command to + * the microcode. The newly allocated stopper will become the new + * stopper. + */ + sc->icq_sp->areq_vpa = req_paddr; + + /* + * Set the 'next_vpa' pointer for the old stopper to be the + * physical address of the new stopper. The RISC can only + * follow physical addresses. + */ + sc->icq_sp->next_vpa = new_carrp->carr_pa; + + /* + * Set the host adapter stopper pointer to point to the new carrier. + */ + sc->icq_sp = new_carrp; + +/* ccb_carr = ccb->carr_list; + while(ccb_carr != ASC_CQ_STOPPER) { + bus_dmamap_load(sc->sc_dmat, ccb_carr->dmamap_xfer, + ccb_carr, ADW_CARRIER_SIZE, + NULL, BUS_DMA_NOWAIT); + bus_dmamap_sync(sc->sc_dmat, ccb_carr->dmamap_xfer, 0, + ccb_carr->dmamap_xfer->dm_mapsize, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + ccb_carr = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(ccb_carr->next_vpa)); + } + + ccb_carr = sc->irq_sp; + for(i=0; i<2 && ccb_carr != ASC_CQ_STOPPER; i++) { + bus_dmamap_load(sc->sc_dmat, ccb_carr->dmamap_xfer, + ccb_carr, ADW_CARRIER_SIZE, + NULL, BUS_DMA_NOWAIT); + bus_dmamap_sync(sc->sc_dmat, ccb_carr->dmamap_xfer, 0, + ccb_carr->dmamap_xfer->dm_mapsize, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + ccb_carr = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(ccb_carr->next_vpa)); + } +*/ + bus_dmamap_load(sc->sc_dmat, sc->sc_control->dmamap_xfer, + sc->sc_control->carriers, ADW_CARRIER_SIZE * ADW_MAX_CARRIER, + NULL, BUS_DMA_NOWAIT); + bus_dmamap_sync(sc->sc_dmat, sc->sc_control->dmamap_xfer, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* + * Tickle the RISC to tell it to read its Command Queue Head pointer. + */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_A); + if (sc->chip_type == ADV_CHIP_ASC3550) + { + /* + * Clear the tickle value. In the ASC-3550 the RISC flag + * command 'clr_tickle_a' does not work unless the host + * value is cleared. + */ + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_NOP); + } + + return ADW_SUCCESS; +} + + +void +AdvResetChip(iot, ioh) + bus_space_tag_t iot; + bus_space_handle_t ioh; { - return AdvSendScsiCmd(sc, scsiq); + + /* + * Reset Chip. + */ + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, + ADW_CTRL_REG_CMD_RESET); + AdvSleepMilliSecond(100); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, + ADW_CTRL_REG_CMD_WR_IO_REG); } + /* * Reset SCSI Bus and purge all outstanding requests. * * Return Value: - * ADW_TRUE(1) - All requests are purged and SCSI Bus is reset. - * - * Note: Should always return ADW_TRUE. + * ADW_TRUE(1) - All requests are purged and SCSI Bus is reset. + * ADW_FALSE(0) - Microcode command failed. + * ADW_ERROR(-1) - Microcode command timed-out. Microcode or IC + * may be hung which requires driver recovery. */ int AdvResetCCB(sc) - ADW_SOFTC *sc; +ADW_SOFTC *sc; { - int status; + int status; - status = AdvSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET, 0L, 0); + /* + * Send the SCSI Bus Reset idle start idle command which asserts + * the SCSI Bus Reset signal. + */ + status = AdvSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_START, 0L); + if (status != ADW_TRUE) + { + return status; + } - AdvResetSCSIBus(sc); + /* + * Delay for the specified SCSI Bus Reset hold time. + * + * The hold time delay is done on the host because the RISC has no + * microsecond accurate timer. + */ + AdvDelayMicroSecond((u_int16_t) ASC_SCSI_RESET_HOLD_TIME_US); + + /* + * Send the SCSI Bus Reset end idle command which de-asserts + * the SCSI Bus Reset signal and purges any pending requests. + */ + status = AdvSendIdleCmd(sc, (u_int16_t) IDLE_CMD_SCSI_RESET_END, 0L); + if (status != ADW_TRUE) + { + return status; + } + + AdvSleepMilliSecond((u_int32_t) sc->scsi_reset_wait * 1000); return status; } + /* - * Reset SCSI Bus and delay. + * Reset chip and SCSI Bus. + * + * Return Value: + * ADW_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. + * ADW_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. */ -void +int AdvResetSCSIBus(sc) - ADW_SOFTC *sc; +ADW_SOFTC *sc; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - u_int16_t scsi_ctrl; + int status; + u_int16_t wdtr_able, sdtr_able, tagqng_able; + u_int8_t tid, max_cmd[ADW_MAX_TID + 1]; + u_int16_t bios_sig; + /* + * Save current per TID negotiated values. + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, wdtr_able); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sdtr_able); + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) + { + ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } + + /* + * Force the AdvInitAsc3550/38C0800Driver() function to + * perform a SCSI Bus Reset by clearing the BIOS signature word. + * The initialization functions assumes a SCSI Bus Reset is not + * needed if the BIOS signature word is present. + */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_BIOS_SIGNATURE, bios_sig); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_BIOS_SIGNATURE, 0); + + /* + * Stop chip and reset it. + */ + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_RISC_CSR, ADW_RISC_CSR_STOP); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, + ADW_CTRL_REG_CMD_RESET); + AdvSleepMilliSecond(100); + ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_CTRL_REG, + ADW_CTRL_REG_CMD_WR_IO_REG); /* - * The microcode currently sets the SCSI Bus Reset signal while - * handling the AdvSendIdleCmd() IDLE_CMD_SCSI_RESET command above. - * But the SCSI Bus Reset Hold Time in the uCode is not deterministic - * (it may in fact be for less than the SCSI Spec. minimum of 25 us). - * Therefore on return the Adv Library sets the SCSI Bus Reset signal - * for ASC_SCSI_RESET_HOLD_TIME_US, which is defined to be greater - * than 25 us. + * Reset Adv Library error code, if any, and try + * re-initializing the chip. */ - scsi_ctrl = ADW_READ_WORD_REGISTER(iot, ioh, IOPW_SCSI_CTRL); - ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CTRL, - scsi_ctrl | ADW_SCSI_CTRL_RSTOUT); - DvcDelayMicroSecond((u_int16_t) ASC_SCSI_RESET_HOLD_TIME_US); - ADW_WRITE_WORD_REGISTER(iot, ioh, IOPW_SCSI_CTRL, - scsi_ctrl & ~ADW_SCSI_CTRL_RSTOUT); + if (sc->chip_type == ADV_CHIP_ASC38C0800) { + status = AdvInitAsc38C0800Driver(sc); + } else { + status = AdvInitAsc3550Driver(sc); + } + + /* Translate initialization return value to status value. */ + if (status == 0) { + status = ADW_TRUE; + } else { + status = ADW_FALSE; + } + + /* + * Restore the BIOS signature word. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_BIOS_SIGNATURE, bios_sig); + + /* + * Restore per TID negotiated values. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, wdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, sdtr_able); + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, tagqng_able); + for (tid = 0; tid <= ADW_MAX_TID; tid++) { + ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_NUMBER_OF_MAX_CMD + tid, + max_cmd[tid]); + } - DvcSleepMilliSecond((ulong) sc->scsi_reset_wait * 1000); + return status; } @@ -870,7 +2140,7 @@ AdvResetSCSIBus(sc) * This function is called by a driver's interrupt service routine. * The function disables and re-enables interrupts. * - * When a microcode idle command is completed, the ADW_DVC_VAR + * When a microcode idle command is completed, the ADV_DVC_VAR * 'idle_cmd_done' field is set to ADW_TRUE. * * Note: AdvISR() can be called when interrupts are disabled or even @@ -885,72 +2155,109 @@ AdvResetSCSIBus(sc) */ int AdvISR(sc) - ADW_SOFTC *sc; +ADW_SOFTC *sc; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - u_int8_t int_stat; - u_int16_t next_done_loc, target_bit; - int completed_q; - ADW_SCSI_REQ_Q *scsiq; - ASC_REQ_SENSE *sense_data; - int ret; - + u_int8_t int_stat; + u_int16_t target_bit; + ADW_CARRIER *free_carrp/*, *ccb_carr*/; + u_int32_t irq_next_pa; + ADW_SCSI_REQ_Q *scsiq; + ADW_CCB *ccb; +// int i; - ret = (ADW_IS_INT_PENDING(iot, ioh)) ? ADW_TRUE : ADW_FALSE; /* Reading the register clears the interrupt. */ int_stat = ADW_READ_BYTE_REGISTER(iot, ioh, IOPB_INTR_STATUS_REG); - if (int_stat & ADW_INTR_STATUS_INTRB) { - sc->idle_cmd_done = ADW_TRUE; + if ((int_stat & (ADW_INTR_STATUS_INTRA | ADW_INTR_STATUS_INTRB | + ADW_INTR_STATUS_INTRC)) == 0) { + return ADW_FALSE; } + + bus_dmamap_sync(sc->sc_dmat, sc->sc_control->dmamap_xfer, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, sc->sc_control->dmamap_xfer); + +/* ccb_carr = sc->irq_sp; + for(i=0; i<2 && ccb_carr != ASC_CQ_STOPPER; i++) { + bus_dmamap_sync(sc->sc_dmat, ccb_carr->dmamap_xfer, 0, + ccb_carr->dmamap_xfer->dm_mapsize, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, ccb_carr->dmamap_xfer); + ccb_carr = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(ccb_carr->next_vpa)); + } +*/ /* - * Notify the driver of a hardware detected SCSI Bus Reset. + * Notify the driver of an asynchronous microcode condition by + * calling the ADV_DVC_VAR.async_callback function. The function + * is passed the microcode ASC_MC_INTRB_CODE byte value. */ - if (int_stat & ADW_INTR_STATUS_INTRC) { - if (sc->sbreset_callback) { - (*(ADW_SBRESET_CALLBACK) sc->sbreset_callback) (sc); + if (int_stat & ADW_INTR_STATUS_INTRB) { + u_int8_t intrb_code; + + ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_INTRB_CODE, intrb_code); + if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && + sc->carr_pending_cnt != 0) { + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_A); + if (sc->chip_type == ADV_CHIP_ASC3550) { + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_NOP); + } + } + + if (sc->async_callback != 0) { + (*(ADW_ASYNC_CALLBACK)sc->async_callback)(sc, intrb_code); } } + /* - * ASC_MC_HOST_NEXT_DONE (0x129) is actually the last completed RISC - * Queue List request. Its forward pointer (RQL_FWD) points to the - * current completed RISC Queue List request. + * Check if the IRQ stopper carrier contains a completed request. */ - ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_DONE, next_done_loc); - next_done_loc = ASC_MC_RISC_Q_LIST_BASE + - (next_done_loc * ASC_MC_RISC_Q_LIST_SIZE) + RQL_FWD; - - ADW_READ_BYTE_LRAM(iot, ioh, next_done_loc, completed_q); - - /* Loop until all completed Q's are processed. */ - while (completed_q != ASC_MC_NULL_Q) { - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_DONE, - completed_q); - - next_done_loc = ASC_MC_RISC_Q_LIST_BASE + - (completed_q * ASC_MC_RISC_Q_LIST_SIZE); - + while (((irq_next_pa = sc->irq_sp->next_vpa) & ASC_RQ_DONE) != 0) + { /* - * Read the ADW_SCSI_REQ_Q virtual address pointer from - * the RISC list entry. The microcode has changed the - * ADW_SCSI_REQ_Q physical address to its virtual address. + * Get a pointer to the newly completed ADW_SCSI_REQ_Q structure. + * The RISC will have set 'areq_vpa' to a virtual address. * - * Refer to comments at the end of AdvSendScsiCmd() for - * more information on the RISC list structure. + * The firmware will have copied the ASC_SCSI_REQ_Q.ccb_ptr + * field to the carrier ADV_CARR_T.areq_vpa field. The conversion + * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' + * in AdvExeScsiQueue(). */ - { - ushort lsw, msw; - ADW_READ_WORD_LRAM(iot, ioh, - next_done_loc + RQL_PHYADDR, lsw); - ADW_READ_WORD_LRAM(iot, ioh, - next_done_loc + RQL_PHYADDR + 2, msw); - - scsiq = (ADW_SCSI_REQ_Q *) - (((u_int32_t) msw << 16) | lsw); + ccb = adw_ccb_phys_kv(sc, sc->irq_sp->areq_vpa); + scsiq = &ccb->scsiq; + scsiq->ccb_ptr = sc->irq_sp->areq_vpa; + +/* ccb_carr = ccb->carr_list; + while(ccb_carr != ASC_CQ_STOPPER) { + bus_dmamap_sync(sc->sc_dmat, ccb_carr->dmamap_xfer, 0, + ccb_carr->dmamap_xfer->dm_mapsize, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, ccb_carr->dmamap_xfer); + ccb_carr = adw_carrier_phys_kv(sc, + ASC_GET_CARRP(ccb_carr->next_vpa)); } + bus_dmamap_sync(sc->sc_dmat, sc->irq_sp->dmamap_xfer, 0, + sc->irq_sp->dmamap_xfer->dm_mapsize, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->sc_dmat, sc->irq_sp->dmamap_xfer); +*/ + /* + * Advance the stopper pointer to the next carrier + * ignoring the lower four bits. Free the previous + * stopper carrier. + */ + free_carrp = sc->irq_sp; + sc->irq_sp = adw_carrier_phys_kv(sc, ASC_GET_CARRP(irq_next_pa)); + + free_carrp->next_vpa = sc->carr_freelist->carr_pa; + sc->carr_freelist = free_carrp; + sc->carr_pending_cnt--; + + target_bit = ADW_TID_TO_TIDMASK(scsiq->target_id); /* @@ -961,41 +2268,22 @@ AdvISR(sc) /* * Check Condition handling */ - if ((scsiq->done_status == QD_WITH_ERROR) && - (scsiq->scsi_status == SS_CHK_CONDITION) && - (sense_data = (ASC_REQ_SENSE *) scsiq->vsense_addr) != 0 && - (scsiq->orig_sense_len - scsiq->sense_len) >= - ASC_MIN_SENSE_LEN) { - /* - * Command returned with a check condition and valid - * sense data. - */ - } /* * If the command that completed was a SCSI INQUIRY and * LUN 0 was sent the command, then process the INQUIRY * command information for the device. */ - else if (scsiq->done_status == QD_NO_ERROR && - scsiq->cdb[0] == INQUIRY && - scsiq->target_lun == 0) { + if (scsiq->done_status == QD_NO_ERROR && + scsiq->cdb[0] == INQUIRY && + scsiq->target_lun == 0) { AdvInquiryHandling(sc, scsiq); } - /* Change the RISC Queue List state to free. */ - ADW_WRITE_BYTE_LRAM(iot, ioh, - next_done_loc + RQL_STATE, ASC_MC_QS_FREE); - - /* Get the RISC Queue List forward pointer. */ - ADW_READ_BYTE_LRAM(iot, ioh, - next_done_loc + RQL_FWD, completed_q); /* * Notify the driver of the completed request by passing * the ADW_SCSI_REQ_Q pointer to its callback function. */ - sc->cur_host_qng--; - scsiq->a_flag |= ADW_SCSIQ_DONE; - (*(ADW_ISR_CALLBACK) sc->isr_callback) (sc, scsiq); + (*(ADW_ISR_CALLBACK)sc->isr_callback)(sc, scsiq); /* * Note: After the driver callback function is called, 'scsiq' * can no longer be referenced. @@ -1004,31 +2292,44 @@ AdvISR(sc) * requests... */ } - return ret; + + return ADW_TRUE; } + /* * Send an idle command to the chip and wait for completion. * - * Interrupts do not have to be enabled on entry. + * Command completion is polled for once per microsecond. + * + * The function can be called from anywhere including an interrupt handler. + * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() + * functions to prevent reentrancy. * * Return Values: * ADW_TRUE - command completed successfully * ADW_FALSE - command failed + * ADW_ERROR - command timed out */ int -AdvSendIdleCmd(sc, idle_cmd, idle_cmd_parameter, flags) - ADW_SOFTC *sc; - u_int16_t idle_cmd; - u_int32_t idle_cmd_parameter; - int flags; +AdvSendIdleCmd(sc, idle_cmd, idle_cmd_parameter) +ADW_SOFTC *sc; +u_int16_t idle_cmd; +u_int32_t idle_cmd_parameter; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - u_int32_t i; - int ret; + int result; + u_int32_t i, j; - sc->idle_cmd_done = 0; + + /* + * Clear the idle command status which is set by the microcode + * to a non-zero value to indicate when the command is completed. + * The non-zero result is one of the IDLE_CMD_STATUS_* values + * defined in a_advlib.h. + */ + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_IDLE_CMD_STATUS, (u_int16_t) 0); /* * Write the idle command value after the idle command parameter @@ -1036,155 +2337,39 @@ AdvSendIdleCmd(sc, idle_cmd, idle_cmd_parameter, flags) * followed, the microcode may process the idle command before the * parameters have been written to LRAM. */ - ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_IDLE_PARA_STAT, - idle_cmd_parameter); + ADW_WRITE_DWORD_LRAM(iot, ioh, ASC_MC_IDLE_CMD_PARAMETER, + idle_cmd_parameter); ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_IDLE_CMD, idle_cmd); /* - * If the 'flags' argument contains the ADW_NOWAIT flag, then - * return with success. + * Tickle the RISC to tell it to process the idle command. */ - if (flags & ADW_NOWAIT) - return ADW_TRUE; - - for (i = 0; i < SCSI_WAIT_10_SEC * SCSI_MS_PER_SEC; i++) { + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_B); + if (sc->chip_type == ADV_CHIP_ASC3550) { /* - * 'idle_cmd_done' is set by AdvISR(). + * Clear the tickle value. In the ASC-3550 the RISC flag + * command 'clr_tickle_b' does not work unless the host + * value is cleared. */ - if (sc->idle_cmd_done) - break; - - DvcSleepMilliSecond(1); - - /* - * If interrupts were disabled on entry to AdvSendIdleCmd(), - * then they will still be disabled here. Call AdvISR() to - * check for the idle command completion. - */ - (void) AdvISR(sc); + ADW_WRITE_BYTE_REGISTER(iot, ioh, IOPB_TICKLE, ADV_TICKLE_NOP); } - if (sc->idle_cmd_done == ADW_FALSE) { - return ADW_FALSE; - } else { - ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_IDLE_PARA_STAT, ret); - return ret; - } -} - -/* - * Send the SCSI request block to the adapter - * - * Each of the 255 Adv Library/Microcode RISC Lists or mailboxes has the - * following structure: - * - * 0: RQL_FWD - RISC list forward pointer (1 byte) - * 1: RQL_BWD - RISC list backward pointer (1 byte) - * 2: RQL_STATE - RISC list state byte - free, ready, done, aborted (1 byte) - * 3: RQL_TID - request target id (1 byte) - * 4: RQL_PHYADDR - ADW_SCSI_REQ_Q physical pointer (4 bytes) - * - * Return: - * ADW_SUCCESS(1) - the request is in the mailbox - * ADW_BUSY(0) - total request count > 253, try later - */ -static int -AdvSendScsiCmd(sc, scsiq) - ADW_SOFTC *sc; - ADW_SCSI_REQ_Q *scsiq; -{ - bus_space_tag_t iot = sc->sc_iot; - bus_space_handle_t ioh = sc->sc_ioh; - ADW_CCB *ccb = (ADW_CCB *) scsiq->ccb_ptr; - u_int16_t next_ready_loc; - u_int8_t next_ready_loc_fwd; - long req_size; - u_int32_t q_phy_addr; - - - if (sc->cur_host_qng >= sc->max_host_qng) { - return ADW_BUSY; - } else { - sc->cur_host_qng++; + /* Wait for up to 100 millisecond for the idle command to timeout. */ + for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { + /* Poll once each microsecond for command completion. */ + for (j = 0; j < SCSI_US_PER_MSEC; j++) { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_IDLE_CMD_STATUS, result); + if (result != 0) { + return result; + } + AdvDelayMicroSecond(1); + } } - /* - * Clear the ADW_SCSI_REQ_Q done flag. - */ - scsiq->a_flag &= ~ADW_SCSIQ_DONE; - - /* - * Save the original sense buffer length. - * - * After the request completes 'sense_len' will be set to the residual - * byte count of the Auto-Request Sense if a command returns CHECK - * CONDITION and the Sense Data is valid indicated by 'host_status' not - * being set to QHSTA_M_AUTO_REQ_SENSE_FAIL. To determine the valid - * Sense Data Length subtract 'sense_len' from 'orig_sense_len'. - */ - scsiq->orig_sense_len = scsiq->sense_len; - - ADW_READ_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_READY, next_ready_loc); - next_ready_loc = ASC_MC_RISC_Q_LIST_BASE + - (next_ready_loc * ASC_MC_RISC_Q_LIST_SIZE); - - /* - * Write the physical address of the Q to the mailbox. - * We need to skip the first four bytes, because the microcode - * uses them internally for linking Q's together. - */ - req_size = sizeof(ADW_SCSI_REQ_Q); - q_phy_addr = sc->sc_dmamap_control->dm_segs[0].ds_addr + - ADW_CCB_OFF(ccb) + offsetof(struct adw_ccb, scsiq); - - scsiq->scsiq_ptr = scsiq; - - /* - * The RISC list structure, which 'next_ready_loc' is a pointer - * to in microcode LRAM, has the format detailed in the comment - * header for this function. - * - * Write the ADW_SCSI_REQ_Q physical pointer to - * 'next_ready_loc' request. - */ - ADW_WRITE_DWORD_LRAM(iot, ioh, next_ready_loc + RQL_PHYADDR, - q_phy_addr); - - /* Write target_id to 'next_ready_loc' request. */ - ADW_WRITE_BYTE_LRAM(iot, ioh, next_ready_loc + RQL_TID, - scsiq->target_id); - - /* - * Set the ASC_MC_HOST_NEXT_READY (0x128) microcode variable to - * the 'next_ready_loc' request forward pointer. - * - * Do this *before* changing the 'next_ready_loc' queue to QS_READY. - * After the state is changed to QS_READY 'RQL_FWD' will be changed - * by the microcode. - * - * NOTE: The temporary variable 'next_ready_loc_fwd' is required to - * prevent some compilers from optimizing out 'AdvReadByteLram()' if - * it were used as the 3rd argument to 'AdvWriteByteLram()'. - */ - ADW_READ_BYTE_LRAM(iot, ioh, next_ready_loc + RQL_FWD, - next_ready_loc_fwd); - ADW_WRITE_BYTE_LRAM(iot, ioh, ASC_MC_HOST_NEXT_READY, - next_ready_loc_fwd); - - /* - * Change the state of 'next_ready_loc' request from QS_FREE to - * QS_READY which will cause the microcode to pick it up and - * execute it. - * - * Can't reference 'next_ready_loc' after changing the request - * state to QS_READY. The microcode now owns the request. - */ - ADW_WRITE_BYTE_LRAM(iot, ioh, next_ready_loc + RQL_STATE, - ASC_MC_QS_READY); - - return ADW_SUCCESS; + return ADW_ERROR; } + /* * Inquiry Information Byte 7 Handling * @@ -1194,15 +2379,16 @@ AdvSendScsiCmd(sc, scsiq) */ static void AdvInquiryHandling(sc, scsiq) - ADW_SOFTC *sc; - ADW_SCSI_REQ_Q *scsiq; +ADW_SOFTC *sc; +ADW_SCSI_REQ_Q *scsiq; { bus_space_tag_t iot = sc->sc_iot; bus_space_handle_t ioh = sc->sc_ioh; - ASC_SCSI_INQUIRY *inq; - u_int16_t cfg_word; - u_int16_t tidmask; - u_int8_t tid; + u_int8_t tid; + ADW_SCSI_INQUIRY *inq; + u_int16_t tidmask; + u_int16_t cfg_word; + /* * AdvInquiryHandling() requires up to INQUIRY information Byte 7 @@ -1213,16 +2399,19 @@ AdvInquiryHandling(sc, scsiq) * length and the ADW_SCSI_REQ_Q 'data_cnt' field is set by the * microcode to the transfer residual count. */ + if (scsiq->cdb[4] < 8 || (scsiq->cdb[4] - scsiq->data_cnt) < 8) { return; } + tid = scsiq->target_id; - inq = (ASC_SCSI_INQUIRY *) scsiq->vdata_addr; + + inq = (ADW_SCSI_INQUIRY *) scsiq->vdata_addr; /* * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. */ - if (inq->byte3.rsp_data_fmt < 2 && inq->byte2.ansi_apr_ver < 2) { + if (inq->rsp_data_fmt < 2 && inq->ansi_apr_ver < 2) { return; } else { /* @@ -1235,6 +2424,7 @@ AdvInquiryHandling(sc, scsiq) */ tidmask = ADW_TID_TO_TIDMASK(tid); + /* * Wide Transfers * @@ -1243,26 +2433,38 @@ AdvInquiryHandling(sc, scsiq) * device's 'wdtr_able' bit and write the new value to the * microcode. */ - if ((sc->wdtr_able & tidmask) && inq->byte7.WBus16) { +#ifndef FAILSAFE +#ifdef SCSI_ADW_WDTR_DISABLE + if(!(tid & SCSI_ADW_WDTR_DISABLE) +#endif /* SCSI_ADW_WDTR_DISABLE */ + if ((sc->wdtr_able & tidmask) && inq->WBus16) { ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, - cfg_word); + cfg_word); if ((cfg_word & tidmask) == 0) { cfg_word |= tidmask; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_ABLE, - cfg_word); + cfg_word); /* - * Clear the microcode "WDTR negotiation" done - * indicator for the target to cause it - * to negotiate with the new setting set above. + * Clear the microcode "SDTR negotiation" and "WDTR + * negotiation" done indicators for the target to cause + * it to negotiate with the new setting set above. + * WDTR when accepted causes the target to enter + * asynchronous mode, so SDTR must be negotiated. */ + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_DONE, + cfg_word); + cfg_word &= ~tidmask; + ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_DONE, + cfg_word); ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_WDTR_DONE, - cfg_word); + cfg_word); cfg_word &= ~tidmask; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_WDTR_DONE, - cfg_word); + cfg_word); } } + /* * Synchronous Transfers * @@ -1270,31 +2472,34 @@ AdvInquiryHandling(sc, scsiq) * supports synchronous transfers, then turn on the device's * 'sdtr_able' bit. Write the new value to the microcode. */ - if ((sc->sdtr_able & tidmask) && inq->byte7.Sync) { - ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, - cfg_word); +#ifdef SCSI_ADW_SDTR_DISABLE + if(!(tid & SCSI_ADW_SDTR_DISABLE) +#endif /* SCSI_ADW_SDTR_DISABLE */ + if ((sc->sdtr_able & tidmask) && inq->Sync) { + ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, cfg_word); if ((cfg_word & tidmask) == 0) { cfg_word |= tidmask; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_ABLE, - cfg_word); + cfg_word); /* - * Clear the microcode "SDTR negotiation" done - * indicator for the target to cause it - * to negotiate with the new setting set above. + * Clear the microcode "SDTR negotiation" done indicator + * for the target to cause it to negotiate with the new + * setting set above. */ ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_SDTR_DONE, - cfg_word); + cfg_word); cfg_word &= ~tidmask; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_SDTR_DONE, - cfg_word); + cfg_word); } } + /* - * If the EEPROM enabled Tag Queuing for device and the - * device supports Tag Queuing, then turn on the device's + * If the EEPROM enabled Tag Queuing for the device and the + * device supports Tag Queueing, then turn on the device's * 'tagqng_enable' bit in the microcode and set the microcode - * maximum command count to the ADW_DVC_VAR 'max_dvc_qng' + * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' * value. * * Tag Queuing is disabled for the BIOS which runs in polled @@ -1302,31 +2507,39 @@ AdvInquiryHandling(sc, scsiq) * disabling Tag Queuing in the BIOS devices with Tag Queuing * bugs will at least work with the BIOS. */ - if ((sc->tagqng_able & tidmask) && inq->byte7.CmdQue) { +#ifdef SCSI_ADW_TAGQ_DISABLE + if(!(tid & SCSI_ADW_TAGQ_DISABLE) +#endif /* SCSI_ADW_TAGQ_DISABLE */ + if ((sc->tagqng_able & tidmask) && inq->CmdQue) { ADW_READ_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, - cfg_word); + cfg_word); cfg_word |= tidmask; ADW_WRITE_WORD_LRAM(iot, ioh, ASC_MC_TAGQNG_ABLE, - cfg_word); + cfg_word); + ADW_WRITE_BYTE_LRAM(iot, ioh, - ASC_MC_NUMBER_OF_MAX_CMD + tid, - sc->max_dvc_qng); + ASC_MC_NUMBER_OF_MAX_CMD + tid, + sc->max_dvc_qng); } +#endif /* FAILSAFE */ } } + static void -DvcSleepMilliSecond(n) - ulong n; +AdvSleepMilliSecond(n) +u_int32_t n; { DELAY(n * 1000); } + static void -DvcDelayMicroSecond(n) - ulong n; +AdvDelayMicroSecond(n) +u_int32_t n; { DELAY(n); } + diff --git a/sys/dev/ic/adwlib.h b/sys/dev/ic/adwlib.h index 8b6bacb918c..bd75e3064ae 100644 --- a/sys/dev/ic/adwlib.h +++ b/sys/dev/ic/adwlib.h @@ -1,11 +1,10 @@ -/* $OpenBSD: adwlib.h,v 1.1 1998/11/17 06:14:58 downsj Exp $ */ -/* $NetBSD: adwlib.h,v 1.1 1998/09/26 16:10:42 dante Exp $ */ +/* $NetBSD: adwlib.h,v 1.7 2000/02/03 20:29:16 dante Exp $ */ /* * Definitions for low level routines and data structures * for the Advanced Systems Inc. SCSI controllers chips. * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -61,8 +60,8 @@ * --- Adv Library Constants and Macros */ -#define ADW_LIB_VERSION_MAJOR 3 -#define ADW_LIB_VERSION_MINOR 45 +#define ADW_LIB_VERSION_MAJOR 5 +#define ADW_LIB_VERSION_MINOR 2 /* * Define Adv Reset Hold Time grater than 25 uSec. @@ -104,7 +103,17 @@ * Default values are maintained in a_init.c in the structure * Default_EEPROM_Config. */ -typedef struct adweep_config +#define ADV_EEPROM_BIG_ENDIAN 0x8000 /* EEPROM Bit 15 */ +#define ADV_EEPROM_BIOS_ENABLE 0x4000 /* EEPROM Bit 14 */ +/* + * For the ASC3550 Bit 13 is Termination Polarity control bit. + * For later ICs Bit 13 controls whether the CIS (Card Information + * Service Section) is loaded from EEPROM. + */ +#define ADV_EEPROM_TERM_POL 0x2000 /* EEPROM Bit 13 */ +#define ADV_EEPROM_CIS_LD 0x2000 /* EEPROM Bit 13 */ + +typedef struct adw_eep_3550_config { /* Word Offset, Description */ @@ -172,7 +181,108 @@ typedef struct adweep_config u_int16_t saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ u_int16_t saved_adv_err_addr; /* 35 saved last uc error address */ u_int16_t num_of_err; /* 36 number of error */ -} ADWEEP_CONFIG; +} ADW_EEP_3550_CONFIG; + +typedef struct adw_eep_38C0800_config +{ + /* Word Offset, Description */ + + u_int16_t cfg_lsw; /* 00 power up initialization */ + /* bit 13 set - Load CIS */ + /* bit 14 set - BIOS Enable */ + /* bit 15 set - Big Endian Mode */ + u_int16_t cfg_msw; /* 01 unused */ + u_int16_t disc_enable; /* 02 disconnect enable */ + u_int16_t wdtr_able; /* 03 Wide DTR able */ + u_int16_t sdtr_speed1; /* 04 SDTR Speed TID 0-3 */ + u_int16_t start_motor; /* 05 send start up motor */ + u_int16_t tagqng_able; /* 06 tag queuing able */ + u_int16_t bios_scan; /* 07 BIOS device control */ + u_int16_t scam_tolerant; /* 08 no scam */ + + u_int8_t adapter_scsi_id; /* 09 Host Adapter ID */ + u_int8_t bios_boot_delay; /* power up wait */ + + u_int8_t scsi_reset_delay; /* 10 reset delay */ + u_int8_t bios_id_lun; /* first boot device scsi id & lun */ + /* high nibble is lun */ + /* low nibble is scsi id */ + + u_int8_t termination_se; /* 11 0 - automatic */ + /* 1 - low off / high off */ + /* 2 - low off / high on */ + /* 3 - low on / high on */ + /* There is no low on / high off */ + + u_int8_t termination_lvd; /* 11 0 - automatic */ + /* 1 - low off / high off */ + /* 2 - low off / high on */ + /* 3 - low on / high on */ + /* There is no low on / high off */ + + u_int16_t bios_ctrl; /* 12 BIOS control bits */ + /* bit 0 set: BIOS don't act as initiator. */ + /* bit 1 set: BIOS > 1 GB support */ + /* bit 2 set: BIOS > 2 Disk Support */ + /* bit 3 set: BIOS don't support removables */ + /* bit 4 set: BIOS support bootable CD */ + /* bit 5 set: BIOS scan enabled */ + /* bit 6 set: BIOS support multiple LUNs */ + /* bit 7 set: BIOS display of message */ + /* bit 8 set: */ + /* bit 9 set: Reset SCSI bus during init. */ + /* bit 10 set: */ + /* bit 11 set: No verbose initialization. */ + /* bit 12 set: SCSI parity enabled */ + /* bit 13 set: */ + /* bit 14 set: */ + /* bit 15 set: */ + u_int16_t sdtr_speed2; /* 13 SDTR speed TID 4-7 */ + u_int16_t sdtr_speed3; /* 14 SDTR speed TID 8-11 */ + u_int8_t max_host_qng; /* 15 maximum host queueing */ + u_int8_t max_dvc_qng; /* maximum per device queuing */ + u_int16_t dvc_cntl; /* 16 control bit for driver */ + u_int16_t sdtr_speed4; /* 17 SDTR speed 4 TID 12-15 */ + u_int16_t serial_number_word1; /* 18 Board serial number word 1 */ + u_int16_t serial_number_word2; /* 19 Board serial number word 2 */ + u_int16_t serial_number_word3; /* 20 Board serial number word 3 */ + u_int16_t check_sum; /* 21 EEP check sum */ + u_int8_t oem_name[16]; /* 22 OEM name */ + u_int16_t dvc_err_code; /* 30 last device driver error code */ + u_int16_t adv_err_code; /* 31 last uc and Adv Lib error code */ + u_int16_t adv_err_addr; /* 32 last uc error address */ + u_int16_t saved_dvc_err_code; /* 33 saved last dev. driver error code */ + u_int16_t saved_adv_err_code; /* 34 saved last uc and Adv Lib error code */ + u_int16_t saved_adv_err_addr; /* 35 saved last uc error address */ + u_int16_t reserved36; /* 36 reserved */ + u_int16_t reserved37; /* 37 reserved */ + u_int16_t reserved38; /* 38 reserved */ + u_int16_t reserved39; /* 39 reserved */ + u_int16_t reserved40; /* 40 reserved */ + u_int16_t reserved41; /* 41 reserved */ + u_int16_t reserved42; /* 42 reserved */ + u_int16_t reserved43; /* 43 reserved */ + u_int16_t reserved44; /* 44 reserved */ + u_int16_t reserved45; /* 45 reserved */ + u_int16_t reserved46; /* 46 reserved */ + u_int16_t reserved47; /* 47 reserved */ + u_int16_t reserved48; /* 48 reserved */ + u_int16_t reserved49; /* 49 reserved */ + u_int16_t reserved50; /* 50 reserved */ + u_int16_t reserved51; /* 51 reserved */ + u_int16_t reserved52; /* 52 reserved */ + u_int16_t reserved53; /* 53 reserved */ + u_int16_t reserved54; /* 54 reserved */ + u_int16_t reserved55; /* 55 reserved */ + u_int16_t cisptr_lsw; /* 56 CIS PTR LSW */ + u_int16_t cisprt_msw; /* 57 CIS PTR MSW */ + u_int16_t subsysvid; /* 58 SubSystem Vendor ID */ + u_int16_t subsysid; /* 59 SubSystem ID */ + u_int16_t reserved60; /* 60 reserved */ + u_int16_t reserved61; /* 61 reserved */ + u_int16_t reserved62; /* 62 reserved */ + u_int16_t reserved63; /* 63 reserved */ +} ADW_EEP_38C0800_CONFIG; /* * EEPROM Commands @@ -201,15 +311,15 @@ typedef struct adweep_config #define BIOS_CTRL_INIT_VERBOSE 0x0800 #define BIOS_CTRL_SCSI_PARITY 0x1000 -/* - * ASC 3550 Internal Memory Size - 8KB - */ -#define ADW_CONDOR_MEMSIZE 0x2000 /* 8 KB Internal Memory */ +#define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ +#define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */ -/* - * ASC 3550 I/O Length - 64 bytes - */ -#define ADW_CONDOR_IOLEN 0x40 /* I/O Port Range in bytes */ +#define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ +#define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */ + +#define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ +#define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */ +#define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */ /* * Byte I/O register address from base of 'iop_base'. @@ -228,15 +338,15 @@ typedef struct adweep_config #define IOPB_RES_ADDR_B 0x0B #define IOPB_RES_ADDR_C 0x0C #define IOPB_RES_ADDR_D 0x0D -#define IOPB_RES_ADDR_E 0x0E +#define IOPB_SOFT_OVER_WR 0x0E #define IOPB_RES_ADDR_F 0x0F #define IOPB_MEM_CFG 0x10 #define IOPB_RES_ADDR_11 0x11 -#define IOPB_RES_ADDR_12 0x12 +#define IOPB_GPIO_DATA 0x12 #define IOPB_RES_ADDR_13 0x13 #define IOPB_FLASH_PAGE 0x14 #define IOPB_RES_ADDR_15 0x15 -#define IOPB_RES_ADDR_16 0x16 +#define IOPB_GPIO_CNTL 0x16 #define IOPB_RES_ADDR_17 0x17 #define IOPB_FLASH_DATA 0x18 #define IOPB_RES_ADDR_19 0x19 @@ -270,9 +380,9 @@ typedef struct adweep_config #define IOPB_RES_ADDR_35 0x35 #define IOPB_RES_ADDR_36 0x36 #define IOPB_RES_ADDR_37 0x37 -#define IOPB_RES_ADDR_38 0x38 -#define IOPB_RES_ADDR_39 0x39 -#define IOPB_RES_ADDR_3A 0x3A +#define IOPB_RAM_BIST 0x38 +#define IOPB_PLL_TEST 0x39 +#define IOPB_PCI_INT_CFG 0x3A #define IOPB_RES_ADDR_3B 0x3B #define IOPB_RFIFO_CNT 0x3C #define IOPB_RES_ADDR_3D 0x3D @@ -324,8 +434,8 @@ typedef struct adweep_config #define IOPDW_RES_ADDR_8 0x08 #define IOPDW_RES_ADDR_C 0x0C #define IOPDW_RES_ADDR_10 0x10 -#define IOPDW_RES_ADDR_14 0x14 -#define IOPDW_RES_ADDR_18 0x18 +#define IOPDW_COMMA 0x14 +#define IOPDW_COMMB 0x18 #define IOPDW_RES_ADDR_1C 0x1C #define IOPDW_SDMA_ADDR0 0x20 #define IOPDW_SDMA_ADDR1 0x24 @@ -375,6 +485,11 @@ typedef struct adweep_config #define ADW_CTRL_REG_CMD_WR_PCI_CFG_SPACE 0x00C3 #define ADW_CTRL_REG_CMD_RD_PCI_CFG_SPACE 0x00C2 +#define ADV_TICKLE_NOP 0x00 +#define ADV_TICKLE_A 0x01 +#define ADV_TICKLE_B 0x02 +#define ADV_TICKLE_C 0x03 + #define ADW_SCSI_CTRL_RSTOUT 0x2000 #define ADW_IS_INT_PENDING(iot, ioh) \ @@ -414,6 +529,28 @@ typedef struct adweep_config #define ADW_TERM_CTL_L 0x0010 /* Enable External SCSI Lower Termination */ #define ADW_CABLE_DETECT 0x000F /* External SCSI Cable Connection Status */ +/* + * Addendum for ASC-38C0800 Chip + */ +#define ADW_DIS_TERM_DRV 0x4000 /* 1: Read c_det[3:0], 0: cannot read */ +#define ADW_HVD_LVD_SE 0x1C00 /* Device Detect Bits */ +#define ADW_HVD 0x1000 /* HVD Device Detect */ +#define ADW_LVD 0x0800 /* LVD Device Detect */ +#define ADW_SE 0x0400 /* SE Device Detect */ +#define ADW_TERM_LVD 0x00C0 /* LVD Termination Bits */ +#define ADW_TERM_LVD_HI 0x0080 /* Enable LVD Upper Termination */ +#define ADW_TERM_LVD_LO 0x0040 /* Enable LVD Lower Termination */ +#define ADW_TERM_SE 0x0030 /* SE Termination Bits */ +#define ADW_TERM_SE_HI 0x0020 /* Enable SE Upper Termination */ +#define ADW_TERM_SE_LO 0x0010 /* Enable SE Lower Termination */ +#define ADW_C_DET_LVD 0x000C /* LVD Cable Detect Bits */ +#define ADW_C_DET3 0x0008 /* Cable Detect for LVD External Wide */ +#define ADW_C_DET2 0x0004 /* Cable Detect for LVD Internal Wide */ +#define ADW_C_DET_SE 0x0003 /* SE Cable Detect Bits */ +#define ADW_C_DET1 0x0002 /* Cable Detect for SE Internal Wide */ +#define ADW_C_DET0 0x0001 /* Cable Detect for SE Internal Narrow */ + + #define CABLE_ILLEGAL_A 0x7 /* x 0 0 0 | on on | Illegal (all 3 connectors are used) */ @@ -452,15 +589,15 @@ typedef struct adweep_config /* * MEM_CFG Register bit definitions */ -#define BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */ -#define FAST_EE_CLK 0x20 /* Diagnostic Bit */ -#define RAM_SZ 0x1C /* Specify size of RAM to RISC */ -#define RAM_SZ_2KB 0x00 /* 2 KB */ -#define RAM_SZ_4KB 0x04 /* 4 KB */ -#define RAM_SZ_8KB 0x08 /* 8 KB */ -#define RAM_SZ_16KB 0x0C /* 16 KB */ -#define RAM_SZ_32KB 0x10 /* 32 KB */ -#define RAM_SZ_64KB 0x14 /* 64 KB */ +#define ADW_BIOS_EN 0x40 /* BIOS Enable MIO:14,EEP:14 */ +#define ADW_FAST_EE_CLK 0x20 /* Diagnostic Bit */ +#define ADW_RAM_SZ 0x1C /* Specify size of RAM to RISC */ +#define ADW_RAM_SZ_2KB 0x00 /* 2 KB */ +#define ADW_RAM_SZ_4KB 0x04 /* 4 KB */ +#define ADW_RAM_SZ_8KB 0x08 /* 8 KB */ +#define ADW_RAM_SZ_16KB 0x0C /* 16 KB */ +#define ADW_RAM_SZ_32KB 0x10 /* 32 KB */ +#define ADW_RAM_SZ_64KB 0x14 /* 64 KB */ /* * DMA_CFG0 Register bit definitions @@ -486,6 +623,22 @@ typedef struct adweep_config #define READ_CMD_MRL 0x02 /* Memory Read Long */ #define READ_CMD_MRM 0x03 /* Memory Read Multiple (default) */ +/* + * ASC-38C0800 RAM BIST Register bit definitions + */ +#define RAM_TEST_MODE 0x80 +#define PRE_TEST_MODE 0x40 +#define NORMAL_MODE 0x00 +#define RAM_TEST_DONE 0x10 +#define RAM_TEST_STATUS 0x0F +#define RAM_TEST_HOST_ERROR 0x08 +#define RAM_TEST_INTRAM_ERROR 0x04 +#define RAM_TEST_RISC_ERROR 0x02 +#define RAM_TEST_SCSI_ERROR 0x01 +#define RAM_TEST_SUCCESS 0x00 +#define PRE_TEST_VALUE 0x05 +#define NORMAL_VALUE 0x00 + /* * Adv Library Status Definitions @@ -501,6 +654,7 @@ typedef struct adweep_config /* * ASC_DVC_VAR 'warn_code' values */ +#define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */ #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */ @@ -517,14 +671,18 @@ typedef struct adweep_config */ #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */ #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ +#define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */ #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ +#define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */ #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */ #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */ -#define ASC_IERR_RW_LRAM 0x8000 /* read/write local RAM error */ +#define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */ +#define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */ +#define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */ /* * Fixed locations of microcode operating variables. @@ -532,37 +690,38 @@ typedef struct adweep_config #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ #define ASC_MC_CODE_END_ADDR 0x002A /* microcode end address */ #define ASC_MC_CODE_CHK_SUM 0x002C /* microcode code checksum */ -#define ASC_MC_STACK_BEGIN 0x002E /* microcode stack begin */ -#define ASC_MC_STACK_END 0x0030 /* microcode stack end */ #define ASC_MC_VERSION_DATE 0x0038 /* microcode version */ #define ASC_MC_VERSION_NUM 0x003A /* microcode number */ -#define ASCV_VER_SERIAL_W 0x003C /* used in dos_init */ #define ASC_MC_BIOSMEM 0x0040 /* BIOS RISC Memory Start */ #define ASC_MC_BIOSLEN 0x0050 /* BIOS RISC Memory Length */ -#define ASC_MC_HALTCODE 0x0094 /* microcode halt code */ -#define ASC_MC_CALLERPC 0x0096 /* microcode halt caller PC */ -#define ASC_MC_ADAPTER_SCSI_ID 0x0098 /* one ID byte + reserved */ -#define ASC_MC_ULTRA_ABLE 0x009C -#define ASC_MC_SDTR_ABLE 0x009E /* Sync. Transfer TID bitmask. */ +#define ASC_MC_BIOS_SIGNATURE 0x0058 /* BIOS Signature 0x55AA */ +#define ASC_MC_BIOS_VERSION 0x005A /* BIOS Version (2 bytes) */ +#define ASC_MC_SDTR_SPEED1 0x0090 /* SDTR Speed for TID 0-3 */ +#define ASC_MC_SDTR_SPEED2 0x0092 /* SDTR Speed for TID 4-7 */ +#define ASC_MC_SDTR_SPEED3 0x0094 /* SDTR Speed for TID 8-11 */ +#define ASC_MC_SDTR_SPEED4 0x0096 /* SDTR Speed for TID 12-15 */ +#define ASC_MC_CHIP_TYPE 0x009A +#define ASC_MC_INTRB_CODE 0x009B +#define ASC_MC_WDTR_ABLE 0x009C +#define ASC_MC_SDTR_ABLE 0x009E #define ASC_MC_TAGQNG_ABLE 0x00A0 #define ASC_MC_DISC_ENABLE 0x00A2 +#define ASC_MC_IDLE_CMD_STATUS 0x00A4 #define ASC_MC_IDLE_CMD 0x00A6 -#define ASC_MC_IDLE_PARA_STAT 0x00A8 +#define ASC_MC_IDLE_CMD_PARAMETER 0x00A8 #define ASC_MC_DEFAULT_SCSI_CFG0 0x00AC #define ASC_MC_DEFAULT_SCSI_CFG1 0x00AE #define ASC_MC_DEFAULT_MEM_CFG 0x00B0 #define ASC_MC_DEFAULT_SEL_MASK 0x00B2 -#define ASC_MC_RISC_NEXT_READY 0x00B4 -#define ASC_MC_RISC_NEXT_DONE 0x00B5 #define ASC_MC_SDTR_DONE 0x00B6 #define ASC_MC_NUMBER_OF_QUEUED_CMD 0x00C0 #define ASC_MC_NUMBER_OF_MAX_CMD 0x00D0 #define ASC_MC_DEVICE_HSHK_CFG_TABLE 0x0100 -#define ASC_MC_WDTR_ABLE 0x0120 /* Wide Transfer TID bitmask. */ #define ASC_MC_CONTROL_FLAG 0x0122 /* Microcode control flag. */ #define ASC_MC_WDTR_DONE 0x0124 -#define ASC_MC_HOST_NEXT_READY 0x0128 /* Host Next Ready RQL Entry. */ -#define ASC_MC_HOST_NEXT_DONE 0x0129 /* Host Next Done RQL Entry. */ +#define ASC_MC_CAM_MODE_MASK 0x015E /* CAM mode TID bitmask. */ +#define ASC_MC_ICQ 0x0160 +#define ASC_MC_IRQ 0x0164 /* * BIOS LRAM variable absolute offsets. @@ -571,7 +730,6 @@ typedef struct adweep_config #define BIOS_CODELEN 0x56 #define BIOS_SIGNATURE 0x58 #define BIOS_VERSION 0x5A -#define BIOS_SIGNATURE 0x58 /* * Microcode Control Flags @@ -588,59 +746,32 @@ typedef struct adweep_config #define HSHK_CFG_RATE 0x0F00 #define HSHK_CFG_OFFSET 0x001F -/* - * LRAM RISC Queue Lists (LRAM addresses 0x1200 - 0x19FF) - * - * Each of the 255 Adv Library/Microcode RISC queue lists or mailboxes - * starting at LRAM address 0x1200 is 8 bytes and has the following - * structure. Only 253 of these are actually used for command queues. - */ - -#define ASC_MC_RISC_Q_LIST_BASE 0x1200 -#define ASC_MC_RISC_Q_LIST_SIZE 0x0008 -#define ASC_MC_RISC_Q_TOTAL_CNT 0x00FF /* Num. queue slots in LRAM. */ -#define ASC_MC_RISC_Q_FIRST 0x0001 -#define ASC_MC_RISC_Q_LAST 0x00FF - #define ASC_DEF_MAX_HOST_QNG 0xFD /* Max. number of host commands (253) */ #define ASC_DEF_MIN_HOST_QNG 0x10 /* Min. number of host commands (16) */ #define ASC_DEF_MAX_DVC_QNG 0x3F /* Max. number commands per device (63) */ #define ASC_DEF_MIN_DVC_QNG 0x04 /* Min. number commands per device (4) */ -/* RISC Queue List structure - 8 bytes */ -#define RQL_FWD 0 /* forward pointer (1 byte) */ -#define RQL_BWD 1 /* backward pointer (1 byte) */ -#define RQL_STATE 2 /* state byte - free, ready, done, aborted (1 byte) */ -#define RQL_TID 3 /* request target id (1 byte) */ -#define RQL_PHYADDR 4 /* request physical pointer (4 bytes) */ - -/* RISC Queue List state values */ -#define ASC_MC_QS_FREE 0x00 -#define ASC_MC_QS_READY 0x01 -#define ASC_MC_QS_DONE 0x40 -#define ASC_MC_QS_ABORTED 0x80 - -/* RISC Queue List pointer values */ -#define ASC_MC_NULL_Q 0x00 /* NULL_Q == 0 */ -#define ASC_MC_BIOS_Q 0xFF /* BIOS_Q = 255 */ - -/* ASC_SCSI_REQ_Q 'cntl' field values */ -#define ASC_MC_QC_START_MOTOR 0x02 /* Issue start motor. */ -#define ASC_MC_QC_NO_OVERRUN 0x04 /* Don't report overrun. */ -#define ASC_MC_QC_FIRST_DMA 0x08 /* Internal microcode flag. */ -#define ASC_MC_QC_ABORTED 0x10 /* Request aborted by host. */ -#define ASC_MC_QC_REQ_SENSE 0x20 /* Auto-Request Sense. */ -#define ASC_MC_QC_DOS_REQ 0x80 /* Request issued by DOS. */ - - +#define ASC_QC_DATA_CHECK 0x01 /* Require ASC_QC_DATA_OUT set or clear. */ +#define ASC_QC_DATA_OUT 0x02 /* Data out DMA transfer. */ +#define ASC_QC_START_MOTOR 0x04 /* Send auto-start motor before request. */ +#define ASC_QC_NO_OVERRUN 0x08 /* Don't report overrun. */ +#define ASC_QC_FREEZE_TIDQ 0x10 /* Freeze TID queue after request. XXX TBD */ + +#define ASC_QSC_NO_DISC 0x01 /* Don't allow disconnect for request. */ +#define ASC_QSC_NO_TAGMSG 0x02 /* Don't allow tag queuing for request. */ +#define ASC_QSC_NO_SYNC 0x04 /* Don't use Synch. transfer on request. */ +#define ASC_QSC_NO_WIDE 0x08 /* Don't use Wide transfer on request. */ +#define ASC_QSC_REDO_DTR 0x10 /* Renegotiate WDTR/SDTR before request. */ /* - * ASC_SCSI_REQ_Q 'a_flag' definitions - * - * The Adv Library should limit use to the lower nibble (4 bits) of - * a_flag. Drivers are free to use the upper nibble (4 bits) of a_flag. + * Note: If a Tag Message is to be sent and neither ASC_QSC_HEAD_TAG or + * ASC_QSC_ORDERED_TAG is set, then a Simple Tag Message (0x20) is used. */ -#define ADW_POLL_REQUEST 0x01 /* poll for request completion */ -#define ADW_SCSIQ_DONE 0x02 /* request done */ +#define ASC_QSC_HEAD_TAG 0x40 /* Use Head Tag Message (0x21). */ +#define ASC_QSC_ORDERED_TAG 0x80 /* Use Ordered Tag Message (0x22). */ + +#define ADV_CHIP_ASC3550 0x01 /* Ultra-Wide IC */ +#define ADV_CHIP_ASC38C0800 0x02 /* Ultra2-Wide/LVD IC */ +#define ADV_CHIP_ASC38C1600 0x03 /* Ultra3-Wide/LVD2 IC */ /* * Adapter temporary configuration structure @@ -665,12 +796,27 @@ typedef struct adw_dvc_cfg { u_int16_t pci_slot_info; /* high byte device/function number */ /* bits 7-3 device num., bits 2-0 function num. */ /* low byte bus num. */ - u_int16_t bios_boot_wait; /* BIOS boot time delay */ u_int16_t serial1; /* EEPROM serial number word 1 */ u_int16_t serial2; /* EEPROM serial number word 2 */ u_int16_t serial3; /* EEPROM serial number word 3 */ } ADW_DVC_CFG; + +#define NO_OF_SG_PER_BLOCK 15 + +typedef struct adw_sg_block { + u_int8_t reserved1; + u_int8_t reserved2; + u_int8_t reserved3; + u_int8_t sg_cnt; /* Valid entries in block. */ + u_int32_t sg_ptr; /* links to next sg block */ + struct { + u_int32_t sg_addr; /* SG element address */ + u_int32_t sg_count; /* SG element count */ + } sg_list[NO_OF_SG_PER_BLOCK]; +} ADW_SG_BLOCK; + + /* * Adapter operation variable structure. * @@ -683,6 +829,16 @@ typedef struct adw_dvc_cfg { * this field may be set, but later if a device is found to be incapable * of the feature, the field is cleared. */ +#define CCB_HASH_SIZE 32 /* hash table size for phystokv */ +#define CCB_HASH_SHIFT 9 +#define CCB_HASH(x) ((((x)) >> CCB_HASH_SHIFT) & (CCB_HASH_SIZE - 1)) + +#define CARRIER_HASH_SIZE 32 /* hash table size for phystokv */ +#define CARRIER_HASH_SHIFT 9 +#define CARRIER_HASH(x) ((((x)) >> CARRIER_HASH_SHIFT) & (CARRIER_HASH_SIZE - 1)) + +typedef int (* ADW_CALLBACK) (int); + typedef struct adw_softc { struct device sc_dev; @@ -691,35 +847,46 @@ typedef struct adw_softc { bus_space_handle_t sc_ioh; bus_dma_tag_t sc_dmat; bus_dmamap_t sc_dmamap_control; /* maps the control structures */ + bus_dmamap_t sc_dmamap_carrier; /* maps the carrier structures */ void *sc_ih; struct adw_control *sc_control; /* control structures */ + + struct adw_carrier *sc_carrhash[CARRIER_HASH_SIZE]; + struct adw_ccb *sc_ccbhash[CCB_HASH_SIZE]; TAILQ_HEAD(, adw_ccb) sc_free_ccb, sc_waiting_ccb; struct scsi_link sc_link; /* prototype for devs */ + struct scsi_adapter sc_adapter; - LIST_HEAD(, scsi_xfer) sc_queue; + LIST_HEAD(, scsi_xfer) sc_queue; struct scsi_xfer *sc_queuelast; - u_int32_t sc_flags; /* see below sc_flags values */ - + ADW_CALLBACK isr_callback; /* pointer to function, called in AdvISR() */ + ADW_CALLBACK async_callback; /* pointer to function, called in AdvISR() */ u_int16_t bios_ctrl; /* BIOS control word, EEPROM word 12 */ - ulong isr_callback; /* pointer to function, called in AdvISR() */ - ulong sbreset_callback; /* pointer to function, called in AdvISR() */ u_int16_t wdtr_able; /* try WDTR for a device */ u_int16_t sdtr_able; /* try SDTR for a device */ u_int16_t ultra_able; /* try SDTR Ultra speed for a device */ + u_int16_t sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ + u_int16_t sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ + u_int16_t sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ + u_int16_t sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ u_int16_t tagqng_able; /* try tagged queuing with a device */ - u_int8_t max_dvc_qng; /* maximum number of tagged commands per device */ u_int16_t start_motor; /* start motor command allowed */ + u_int8_t max_dvc_qng; /* maximum number of tagged commands per device */ u_int8_t scsi_reset_wait; /* delay in seconds after scsi bus reset */ u_int8_t chip_no; /* should be assigned by caller */ u_int8_t max_host_qng; /* maximum number of Q'ed command allowed */ - u_int8_t cur_host_qng; /* total number of queue command */ u_int8_t irq_no; /* IRQ number */ + u_int8_t chip_type; /* chip SCSI target ID */ u_int16_t no_scam; /* scam_tolerant of EEPROM */ - u_int16_t idle_cmd_done; /* microcode idle command done set by AdvISR() */ - ulong drv_ptr; /* driver pointer to private structure */ + u_int32_t drv_ptr; /* driver pointer to private structure */ u_int8_t chip_scsi_id; /* chip SCSI target ID */ + u_int8_t bist_err_code; + u_int16_t carr_pending_cnt; /* Count of pending carriers. */ + struct adw_carrier *carr_freelist; /* Carrier free list. */ + struct adw_carrier *icq_sp; /* Initiator command queue stopper pointer. */ + struct adw_carrier *irq_sp; /* Initiator response queue stopper pointer. */ /* * Note: The following fields will not be used after initialization. The * driver may discard the buffer after initialization is done. @@ -727,27 +894,6 @@ typedef struct adw_softc { ADW_DVC_CFG cfg; /* temporary configuration structure */ } ADW_SOFTC; -/* sc_flags values */ -#define ADW_WIDE_BOARD 0x04 - - -#define ADW_IS_NARROW_BOARD(sc) (((sc)->sc_flags & ADW_WIDE_BOARD) == 0) -#define ADW_IS_WIDE_BOARD(sc) ((sc)->sc_flags & ADW_WIDE_BOARD) - - -#define NO_OF_SG_PER_BLOCK 15 - -typedef struct adw_sg_block { - u_int8_t reserved1; - u_int8_t reserved2; - u_int8_t first_entry_no; /* starting entry number */ - u_int8_t last_entry_no; /* last entry number */ - struct adw_sg_block *sg_ptr; /* links to the next sg block */ - struct { - u_int32_t sg_addr; /* SG element address */ - u_int32_t sg_count; /* SG element count */ - } sg_list[NO_OF_SG_PER_BLOCK]; -} ADW_SG_BLOCK; /* * ADW_SCSI_REQ_Q - microcode request structure @@ -759,51 +905,38 @@ typedef struct adw_sg_block { */ typedef struct adw_scsi_req_q { u_int8_t cntl; /* Ucode flags and state (ASC_MC_QC_*). */ - u_int8_t sg_entry_cnt; /* SG element count. Zero for no SG. */ + u_int8_t target_cmd; u_int8_t target_id; /* Device target identifier. */ u_int8_t target_lun; /* Device target logical unit number. */ - ulong data_addr; /* Data buffer physical address. */ + u_int32_t data_addr; /* Data buffer physical address. */ u_int32_t data_cnt; /* Data count. Ucode sets to residual. */ - ulong sense_addr; /* Sense buffer physical address. */ - ulong ccb_ptr; /* Driver request pointer. */ - u_int8_t a_flag; /* Adv Library flag field. */ - u_int8_t sense_len; /* Auto-sense length. Ucode sets to residual. */ + u_int32_t sense_addr; /* Sense buffer physical address. */ + u_int32_t carr_pa; /* Carrier p-address */ + u_int8_t mflag; /* Adv Library flag field. */ + u_int8_t sense_len; /* Auto-sense length. uCode sets to residual. */ u_int8_t cdb_len; /* SCSI CDB length. */ - u_int8_t tag_code; /* SCSI-2 Tag Queue Code: 00, 20-22. */ + u_int8_t scsi_cntl; u_int8_t done_status; /* Completion status. */ u_int8_t scsi_status; /* SCSI status byte. (see below) */ u_int8_t host_status; /* Ucode host status. */ - u_int8_t ux_sg_ix; /* Ucode working SG variable. */ + u_int8_t sg_working_ix; /* Ucode working SG variable. */ u_int8_t cdb[12]; /* SCSI command block. */ - ulong sg_real_addr; /* SG list physical address. */ - struct adw_scsi_req_q *free_scsiq_link; - ulong ux_wk_data_cnt; /* Saved data count at disconnection. */ - struct adw_scsi_req_q *scsiq_ptr; - ADW_SG_BLOCK *sg_list_ptr; /* SG list virtual address. */ + u_int32_t sg_real_addr; /* SG list physical address. */ + u_int32_t scsiq_rptr; /* Iternal pointer to ADW_SCSI_REQ_Q */ + u_int32_t sg_working_data_cnt; + u_int32_t ccb_ptr; /* CCB Physical Address */ + u_int32_t carr_va; /* Carrier v-address (unused) */ /* * End of microcode structure - 60 bytes. The rest of the structure * is used by the Adv Library and ignored by the microcode. */ - ulong vsense_addr; /* Sense buffer virtual address. */ - ulong vdata_addr; /* Data buffer virtual address. */ + struct scsi_sense_data *vsense_addr; /* Sense buffer virtual address. */ + u_char *vdata_addr; /* Data buffer virtual address. */ u_int8_t orig_sense_len; /* Original length of sense buffer. */ u_int8_t pads[3]; /* padding bytes (align to long) */ } ADW_SCSI_REQ_Q; /* - * scsi_status conditions - */ -#define SS_GOOD 0x00 -#define SS_CHK_CONDITION 0x02 -#define SS_CONDITION_MET 0x04 -#define SS_TARGET_BUSY 0x08 -#define SS_INTERMID 0x10 -#define SS_INTERMID_COND_MET 0x14 -#define SS_RSERV_CONFLICT 0x18 -#define SS_CMD_TERMINATED 0x22 -#define SS_QUEUE_FULL 0x28 - -/* * Microcode idle loop commands */ #define IDLE_CMD_COMPLETED 0 @@ -812,7 +945,12 @@ typedef struct adw_scsi_req_q { #define IDLE_CMD_SEND_INT 0x0004 #define IDLE_CMD_ABORT 0x0008 #define IDLE_CMD_DEVICE_RESET 0x0010 -#define IDLE_CMD_SCSI_RESET 0x0020 +#define IDLE_CMD_SCSI_RESET_START 0x0020 /* Assert SCSI Bus Reset */ +#define IDLE_CMD_SCSI_RESET_END 0x0040 /* Deassert SCSI Bus Reset */ +#define IDLE_CMD_SCSIREQ 0x0080 + +#define IDLE_CMD_STATUS_SUCCESS 0x0001 +#define IDLE_CMD_STATUS_FAILURE 0x0002 /* * AdvSendIdleCmd() flag definitions. @@ -822,8 +960,17 @@ typedef struct adw_scsi_req_q { /* * Wait loop time out values. */ -#define SCSI_WAIT_10_SEC 10 /* 10 seconds */ -#define SCSI_MS_PER_SEC 1000 /* milliseconds per second */ +#define SCSI_WAIT_10_SEC 10UL /* 10 seconds */ +#define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */ +#define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */ +#define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */ +#define SCSI_MAX_RETRY 10 /* retry count */ + +#define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */ +#define ADV_ASYNC_SCSI_BUS_RESET_DET 0x02 /* Detected SCSI Bus Reset. */ +#define ADV_ASYNC_CARRIER_READY_FAILURE 0x03 /* Carrier Ready failure. */ + +#define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ /* Read byte from a register. */ @@ -923,8 +1070,7 @@ do { \ * ADW_FALSE(0) - Queue was not found on the active queue list. */ #define ADW_ABORT_CCB(sc, ccb_ptr) \ - AdvSendIdleCmd((sc), (u_int16_t) IDLE_CMD_ABORT, \ - (ulong) (ccb_ptr), 0) + AdvSendIdleCmd((sc), (u_int16_t) IDLE_CMD_ABORT, (ccb_ptr)->hashkey) /* * Send a Bus Device Reset Message to the specified target ID. @@ -938,13 +1084,12 @@ do { \ * are not purged. */ #define ADW_RESET_DEVICE(sc, target_id) \ - AdvSendIdleCmd((sc), (u_int16_t) IDLE_CMD_DEVICE_RESET, \ - (ulong) (target_id), 0) + AdvSendIdleCmd((sc), (u_int16_t) IDLE_CMD_DEVICE_RESET, (target_id), 0) /* * SCSI Wide Type definition. */ -#define ADW_SCSI_BIT_ID_TYPE ushort +#define ADW_SCSI_BIT_ID_TYPE u_int16_t /* * AdvInitScsiTarget() 'cntl_flag' options. @@ -982,69 +1127,98 @@ do { \ #define QHSTA_M_SXFR_XFR_OFLW 0x12 /* SXFR_STATUS Transfer Overflow */ #define QHSTA_M_SXFR_XFR_PH_ERR 0x24 /* SXFR_STATUS Transfer Phase Error */ #define QHSTA_M_SXFR_UNKNOWN_ERROR 0x25 /* SXFR_STATUS Unknown Error */ +#define QHSTA_M_SCSI_BUS_RESET 0x30 /* Request aborted from SBR */ +#define QHSTA_M_SCSI_BUS_RESET_UNSOL 0x31 /* Request aborted from unsol. SBR */ +#define QHSTA_M_BUS_DEVICE_RESET 0x32 /* Request aborted from BDR */ +#define QHSTA_M_DIRECTION_ERR 0x35 /* Data Phase mismatch */ +#define QHSTA_M_DIRECTION_ERR_HUNG 0x36 /* Data Phase mismatch and bus hang */ #define QHSTA_M_WTM_TIMEOUT 0x41 #define QHSTA_M_BAD_CMPL_STATUS_IN 0x42 #define QHSTA_M_NO_AUTO_REQ_SENSE 0x43 #define QHSTA_M_AUTO_REQ_SENSE_FAIL 0x44 #define QHSTA_M_INVALID_DEVICE 0x45 /* Bad target ID */ +#define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */ +#define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ /* * SCSI Iquiry structure */ -typedef struct -{ - u_int8_t peri_dvc_type:5; - u_int8_t peri_qualifier:3; -} ASC_SCSI_INQ0; - -typedef struct -{ - u_int8_t dvc_type_modifier:7; - u_int8_t rmb:1; -} ASC_SCSI_INQ1; - -typedef struct -{ - u_int8_t ansi_apr_ver:3; - u_int8_t ecma_ver:3; - u_int8_t iso_ver:2; -} ASC_SCSI_INQ2; - -typedef struct -{ - u_int8_t rsp_data_fmt:4; - u_int8_t res:2; - u_int8_t TemIOP:1; - u_int8_t aenc:1; -} ASC_SCSI_INQ3; +typedef struct { + u_int8_t peri_dvc_type : 5; /* peripheral device type */ + u_int8_t peri_qualifier : 3; /* peripheral qualifier */ + u_int8_t dvc_type_modifier : 7; /* device type modifier (for SCSI I) */ + u_int8_t rmb : 1; /* RMB - removable medium bit */ + u_int8_t ansi_apr_ver : 3; /* ANSI approved version */ + u_int8_t ecma_ver : 3; /* ECMA version */ + u_int8_t iso_ver : 2; /* ISO version */ + u_int8_t rsp_data_fmt : 4; /* response data format */ + /* 0 SCSI 1 */ + /* 1 CCS */ + /* 2 SCSI-2 */ + /* 3-F reserved */ + u_int8_t res1 : 2; /* reserved */ + u_int8_t TemIOP : 1; /* terminate I/O process bit (see 5.6.22) */ + u_int8_t aenc : 1; /* asynch. event notification (processor) */ + u_int8_t add_len; /* additional length */ + u_int8_t res2; /* reserved */ + u_int8_t res3; /* reserved */ + u_int8_t StfRe : 1; /* soft reset implemented */ + u_int8_t CmdQue : 1; /* command queuing */ + u_int8_t res4 : 1; /* reserved */ + u_int8_t Linked : 1; /* linked command for this logical unit */ + u_int8_t Sync : 1; /* synchronous data transfer */ + u_int8_t WBus16 : 1; /* wide bus 16 bit data transfer */ + u_int8_t WBus32 : 1; /* wide bus 32 bit data transfer */ + u_int8_t RelAdr : 1; /* relative addressing mode */ + u_int8_t vendor_id[8]; /* vendor identification */ + u_int8_t product_id[16]; /* product identification */ + u_int8_t product_rev_level[4]; /* product revision level */ + u_int8_t vendor_specific[20]; /* vendor specific */ + u_int8_t IUS : 1; /* information unit supported */ + u_int8_t QAS : 1; /* quick arbitrate supported */ + u_int8_t Clocking : 2; /* clocking field */ + u_int8_t res5 : 4; /* reserved */ + u_int8_t res6; /* reserved */ +} ADW_SCSI_INQUIRY; /* 58 bytes */ -typedef struct -{ - u_int8_t StfRe:1; - u_int8_t CmdQue:1; - u_int8_t Reserved:1; - u_int8_t Linked:1; - u_int8_t Sync:1; - u_int8_t WBus16:1; - u_int8_t WBus32:1; - u_int8_t RelAdr:1; -} ASC_SCSI_INQ7; - -typedef struct -{ - ASC_SCSI_INQ0 byte0; - ASC_SCSI_INQ1 byte1; - ASC_SCSI_INQ2 byte2; - ASC_SCSI_INQ3 byte3; - u_int8_t add_len; - u_int8_t res1; - u_int8_t res2; - ASC_SCSI_INQ7 byte7; - u_int8_t vendor_id[8]; - u_int8_t product_id[16]; - u_int8_t product_rev_level[4]; -} ASC_SCSI_INQUIRY; +#define SS_GOOD 0x00 +#define SS_CHK_CONDITION 0x02 +#define SS_CONDITION_MET 0x04 +#define SS_TARGET_BUSY 0x08 +#define SS_INTERMID 0x10 +#define SS_INTERMID_COND_MET 0x14 +#define SS_RSERV_CONFLICT 0x18 +#define SS_CMD_TERMINATED 0x22 +#define SS_QUEUE_FULL 0x28 +#define MS_CMD_DONE 0x00 +#define MS_EXTEND 0x01 +#define MS_SDTR_LEN 0x03 +#define MS_SDTR_CODE 0x01 +#define MS_WDTR_LEN 0x02 +#define MS_WDTR_CODE 0x03 +#define MS_MDP_LEN 0x05 +#define MS_MDP_CODE 0x00 +#define M1_SAVE_DATA_PTR 0x02 +#define M1_RESTORE_PTRS 0x03 +#define M1_DISCONNECT 0x04 +#define M1_INIT_DETECTED_ERR 0x05 +#define M1_ABORT 0x06 +#define M1_MSG_REJECT 0x07 +#define M1_NO_OP 0x08 +#define M1_MSG_PARITY_ERR 0x09 +#define M1_LINK_CMD_DONE 0x0A +#define M1_LINK_CMD_DONE_WFLAG 0x0B +#define M1_BUS_DVC_RESET 0x0C +#define M1_ABORT_TAG 0x0D +#define M1_CLR_QUEUE 0x0E +#define M1_INIT_RECOVERY 0x0F +#define M1_RELEASE_RECOVERY 0x10 +#define M1_KILL_IO_PROC 0x11 +#define M2_QTAG_MSG_SIMPLE 0x20 +#define M2_QTAG_MSG_HEAD 0x21 +#define M2_QTAG_MSG_ORDERED 0x22 +#define M2_IGNORE_WIDE_RESIDUE 0x23 #define ASC_MAX_SENSE_LEN 32 @@ -1078,14 +1252,15 @@ typedef struct asc_req_sense { * Adv Library functions available to drivers. */ -int AdvInitFromEEP __P((ADW_SOFTC *)); +int AdvInitAsc3550Driver __P((ADW_SOFTC *)); +int AdvInitAsc38C0800Driver __P((ADW_SOFTC *)); +int AdvInitFrom3550EEP __P((ADW_SOFTC *)); +int AdvInitFrom38C0800EEP __P((ADW_SOFTC *)); int AdvExeScsiQueue __P((ADW_SOFTC *, ADW_SCSI_REQ_Q *)); int AdvISR __P((ADW_SOFTC *)); -int AdvSendIdleCmd __P((ADW_SOFTC *, u_int16_t, u_int32_t, int)); -int AdvInitGetConfig __P((ADW_SOFTC *)); -int AdvInitAsc3550Driver __P((ADW_SOFTC *)); void AdvResetChip __P((bus_space_tag_t, bus_space_handle_t)); -void AdvResetSCSIBus __P((ADW_SOFTC *)); +int AdvSendIdleCmd __P((ADW_SOFTC *, u_int16_t, u_int32_t)); +int AdvResetSCSIBus __P((ADW_SOFTC *)); int AdvResetCCB __P((ADW_SOFTC *)); #define offsetof(type, member) ((size_t)(&((type *)0)->member)) diff --git a/sys/dev/ic/adwmcode.c b/sys/dev/ic/adwmcode.c index 30315e73417..0f534808caf 100644 --- a/sys/dev/ic/adwmcode.c +++ b/sys/dev/ic/adwmcode.c @@ -1,11 +1,10 @@ -/* $OpenBSD: adwmcode.c,v 1.1 1998/11/17 06:14:58 downsj Exp $ */ -/* $NetBSD: adwmcode.c,v 1.1 1998/09/26 16:10:42 dante Exp $ */ +/* $NetBSD: adwmcode.c,v 1.2 2000/02/03 20:29:16 dante Exp $ */ /* * Generic driver definitions and exported functions for the Advanced * Systems Inc. SCSI controllers * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -62,300 +61,684 @@ * This is the uCode for the Wide board RISC cpu. * This code is loaded into Lram during initializzation procedure. */ -u_int8_t adv_mcode[] = { - 0x9C, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0x44, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x01, 0xD6, 0x11, 0x00, 0x00, 0x70, 0x01, - 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x10, 0x2D, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x56, 0x34, 0x12, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x0C, 0x1C, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF2, 0xD6, 0x0A, - 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x3E, 0x57, 0x3C, 0x56, 0x0C, 0x1C, 0x00, 0xFC, - 0xA6, 0x00, 0x01, 0x58, 0xAA, 0x13, 0x20, 0xF0, 0xA6, 0x03, 0x06, 0xEC, 0xB9, 0x00, 0x0E, 0x47, - 0x03, 0xE6, 0x10, 0x00, 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0x06, 0xEA, 0xB9, 0x00, 0x47, 0x4B, - 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x4E, 0x12, 0x03, 0xF6, 0xC0, 0x00, - 0x00, 0xF2, 0x68, 0x0A, 0x41, 0x58, 0x03, 0xF6, 0xD0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x49, 0x44, - 0x59, 0xF0, 0x0A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x44, 0x58, 0x00, 0xF2, - 0xE2, 0x0D, 0x02, 0xCC, 0x4A, 0xE4, 0x01, 0x00, 0x55, 0xF0, 0x08, 0x03, 0x45, 0xF4, 0x02, 0x00, - 0x83, 0x5A, 0x04, 0xCC, 0x01, 0x4A, 0x12, 0x12, 0x00, 0xF2, 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4, - 0x01, 0x00, 0xE9, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0xFA, 0x10, 0x0E, 0x47, 0x03, 0xE6, 0x10, 0x00, - 0xCE, 0x45, 0x02, 0x13, 0x3E, 0x57, 0xCE, 0x47, 0x97, 0x13, 0x04, 0xEC, 0xB4, 0x00, 0x00, 0xF2, - 0xE2, 0x0D, 0x00, 0xCD, 0x48, 0xE4, 0x00, 0x00, 0x12, 0x12, 0x3E, 0x57, 0x06, 0xCC, 0x45, 0xF4, - 0x02, 0x00, 0x83, 0x5A, 0x00, 0xCC, 0x00, 0xEA, 0xB4, 0x00, 0x92, 0x10, 0x00, 0xF0, 0x8C, 0x01, - 0x43, 0xF0, 0x5C, 0x02, 0x44, 0xF0, 0x60, 0x02, 0x45, 0xF0, 0x64, 0x02, 0x46, 0xF0, 0x68, 0x02, - 0x47, 0xF0, 0x6E, 0x02, 0x48, 0xF0, 0x9E, 0x02, 0xB9, 0x54, 0x62, 0x10, 0x00, 0x1C, 0x5A, 0x10, - 0x02, 0x1C, 0x56, 0x10, 0x1E, 0x1C, 0x52, 0x10, 0x00, 0xF2, 0x1E, 0x11, 0x50, 0x10, 0x06, 0xFC, - 0xA8, 0x00, 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x4E, 0x0A, 0x8C, 0x10, 0x01, 0xF6, 0x01, 0x00, - 0x01, 0xFA, 0xA8, 0x00, 0x00, 0xF2, 0x2C, 0x0B, 0x06, 0x10, 0xB9, 0x54, 0x01, 0xFA, 0xA8, 0x00, - 0x03, 0xF6, 0xBE, 0x00, 0x00, 0xF2, 0x58, 0x0A, 0x01, 0xFC, 0xA8, 0x00, 0x20, 0x10, 0x58, 0x1C, - 0x00, 0xF2, 0x1C, 0x0B, 0x5A, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54, 0x00, 0xFA, 0xA6, 0x00, - 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x72, 0x01, 0x01, 0xF6, 0x01, 0x00, 0x38, 0x54, - 0x00, 0xFA, 0xA6, 0x00, 0x01, 0xFA, 0xA8, 0x00, 0x20, 0x1C, 0x00, 0xF0, 0x80, 0x01, 0x03, 0xF6, - 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x0A, 0x13, 0x00, 0xF2, 0x38, 0x10, 0x00, 0xF2, - 0x54, 0x0F, 0x24, 0x10, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x02, 0xF6, 0xD0, 0x00, - 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x49, 0x44, 0x5B, 0xF0, 0x04, 0x03, 0x00, 0xF2, 0x9C, 0x0F, - 0x00, 0xF0, 0x80, 0x01, 0x00, 0xF2, 0x14, 0x10, 0x0C, 0x1C, 0x02, 0x4B, 0xBF, 0x57, 0x9E, 0x43, - 0x77, 0x57, 0x07, 0x4B, 0x20, 0xF0, 0xA6, 0x03, 0x40, 0x1C, 0x1E, 0xF0, 0x30, 0x03, 0x26, 0xF0, - 0x2C, 0x03, 0xA0, 0xF0, 0x1A, 0x03, 0x11, 0xF0, 0xA6, 0x03, 0x12, 0x10, 0x9F, 0xF0, 0x3E, 0x03, - 0x46, 0x1C, 0x82, 0xE7, 0x05, 0x00, 0x9E, 0xE7, 0x11, 0x00, 0x00, 0xF0, 0x06, 0x0A, 0x0C, 0x1C, - 0x48, 0x1C, 0x46, 0x1C, 0x38, 0x54, 0x00, 0xEC, 0xBA, 0x00, 0x08, 0x44, 0x00, 0xEA, 0xBA, 0x00, - 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x08, 0x44, 0x00, 0x4C, 0x82, 0xE7, 0x02, 0x00, - 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x70, 0x03, 0x00, 0xF2, 0x60, 0x0B, - 0x06, 0xF0, 0x80, 0x03, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, - 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0x55, 0xF0, 0xAC, 0x04, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2, - 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x01, 0xF0, - 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x46, 0x1C, 0x0C, 0x1C, 0x67, 0x1B, 0xBF, 0x57, 0x77, 0x57, - 0x02, 0x4B, 0x48, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x96, 0xF0, 0xBC, 0x03, - 0xB1, 0xF0, 0xC0, 0x03, 0x1E, 0xF0, 0xFC, 0x09, 0x85, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0xBE, 0x00, - 0x98, 0x57, 0x14, 0x12, 0x01, 0xE6, 0x0C, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, - 0x01, 0xF0, 0x7C, 0x02, 0x00, 0xF0, 0x8A, 0x02, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, - 0x01, 0x48, 0x55, 0xF0, 0x98, 0x04, 0x03, 0x82, 0x03, 0xFC, 0xA0, 0x00, 0x9B, 0x57, 0x40, 0x12, - 0x69, 0x18, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x42, 0x04, 0x69, 0x08, 0x00, 0xF2, 0x12, 0x11, - 0x85, 0xF0, 0x02, 0x0A, 0x68, 0x08, 0x4C, 0x44, 0x28, 0x12, 0x44, 0x48, 0x03, 0xF6, 0xE0, 0x00, - 0x00, 0xF2, 0x68, 0x0A, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xCC, 0x01, 0x48, 0x55, 0xF0, - 0x98, 0x04, 0x4C, 0x44, 0xEF, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x14, 0x10, 0x08, 0x10, - 0x68, 0x18, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x04, 0x80, 0x18, 0xE4, 0x10, 0x00, 0x28, 0x12, - 0x01, 0xE6, 0x06, 0x00, 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00, - 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00, - 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00, - 0x0C, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA, 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x82, 0xE7, - 0x02, 0x00, 0x1C, 0x90, 0x40, 0x5C, 0x00, 0x16, 0x01, 0xE6, 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D, - 0x01, 0xF0, 0x80, 0x01, 0x1E, 0xF0, 0x80, 0x01, 0x00, 0xF0, 0xA0, 0x04, 0x42, 0x5B, 0x06, 0xF7, - 0x03, 0x00, 0x46, 0x59, 0xBF, 0x57, 0x77, 0x57, 0x01, 0xE6, 0x80, 0x00, 0x07, 0x80, 0x31, 0x44, - 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x56, 0x13, 0x20, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x4E, 0x12, - 0x00, 0xFC, 0xA2, 0x00, 0x98, 0x57, 0x55, 0xF0, 0x1C, 0x05, 0x31, 0xE4, 0x40, 0x00, 0x00, 0xFC, - 0xA0, 0x00, 0x98, 0x57, 0x36, 0x12, 0x4C, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x89, 0x48, 0x00, 0xF2, - 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x82, 0xE7, 0x06, 0x00, 0x1B, 0x80, 0x48, 0xE4, 0x22, 0x00, - 0x5B, 0xF0, 0x0C, 0x05, 0x48, 0xE4, 0x20, 0x00, 0x59, 0xF0, 0x10, 0x05, 0x00, 0xE6, 0x20, 0x00, - 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x2E, 0x05, 0x83, 0x80, 0x04, 0x10, 0x00, 0xF2, - 0xA2, 0x0D, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x26, 0x01, 0x01, 0xEA, 0x27, 0x01, 0x04, 0x80, - 0x18, 0xE4, 0x10, 0x00, 0x36, 0x12, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x01, 0xE6, 0x06, 0x00, - 0x04, 0x80, 0x18, 0xE4, 0x01, 0x00, 0x04, 0x12, 0x01, 0xE6, 0x0D, 0x00, 0x00, 0xF2, 0x4E, 0x0D, - 0x00, 0xF2, 0x12, 0x11, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x04, 0xE6, 0x02, 0x00, - 0x9E, 0xE7, 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xFC, 0x20, 0x01, - 0x98, 0x57, 0x34, 0x12, 0x00, 0xFC, 0x24, 0x01, 0x98, 0x57, 0x2C, 0x13, 0xB9, 0x54, 0x00, 0xF2, - 0xF6, 0x0E, 0x86, 0xF0, 0xA8, 0x05, 0x03, 0xF6, 0x01, 0x00, 0x00, 0xF2, 0x8C, 0x0E, 0x85, 0xF0, - 0x9E, 0x05, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00, 0x00, 0xFC, - 0x24, 0x01, 0xB0, 0x57, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFC, 0x9E, 0x00, 0x98, 0x57, 0x5A, 0x12, - 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57, 0x52, 0x13, 0x03, 0xE6, 0x0C, 0x00, 0x00, 0xFC, 0x9C, 0x00, - 0x98, 0x57, 0x04, 0x13, 0x03, 0xE6, 0x19, 0x00, 0x05, 0xE6, 0x08, 0x00, 0x00, 0xF6, 0x00, 0x01, - 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x04, 0x13, 0x05, 0xE6, - 0x0F, 0x00, 0xB9, 0x54, 0x00, 0xF2, 0xF6, 0x0E, 0x86, 0xF0, 0x0A, 0x06, 0x00, 0xF2, 0xBA, 0x0E, - 0x85, 0xF0, 0x00, 0x06, 0x82, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x82, 0xE7, 0x02, 0x00, - 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0xF2, - 0xF6, 0x0E, 0x9C, 0x32, 0x4E, 0x1C, 0x32, 0x1C, 0x00, 0xF2, 0x92, 0x0D, 0x30, 0x1C, 0x82, 0xE7, - 0x04, 0x00, 0xB1, 0xF0, 0x22, 0x06, 0x0A, 0xF0, 0x3E, 0x06, 0x05, 0xF0, 0xD6, 0x06, 0x06, 0xF0, - 0xDC, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x04, 0x80, - 0x18, 0xE4, 0x20, 0x00, 0x30, 0x12, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80, - 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, - 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x99, 0xA4, 0x00, 0xF2, 0x12, 0x11, - 0x09, 0xE7, 0x00, 0x00, 0x9A, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x34, 0x12, 0x09, 0xE7, - 0x1B, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x21, 0x80, 0x18, 0xE4, 0xE0, 0x00, 0x09, 0x48, 0x00, 0xF2, - 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF2, - 0x12, 0x11, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x09, 0xE7, 0x00, 0x00, 0x00, 0xF0, - 0x0C, 0x09, 0xBB, 0x55, 0x9A, 0x81, 0x03, 0xF7, 0x20, 0x00, 0x09, 0x6F, 0x93, 0x45, 0x55, 0xF0, - 0xE2, 0x06, 0xB1, 0xF0, 0xC2, 0x06, 0x0A, 0xF0, 0xBA, 0x06, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, - 0xFC, 0x09, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0x47, 0x10, 0x09, 0xE7, 0x08, 0x00, - 0x41, 0x10, 0x05, 0x80, 0x48, 0xE4, 0x00, 0x00, 0x1E, 0x12, 0x00, 0xE6, 0x11, 0x00, 0x00, 0xEA, - 0xB8, 0x00, 0x00, 0xF2, 0xB6, 0x10, 0x2C, 0x90, 0xAE, 0x90, 0x08, 0x50, 0x8A, 0x50, 0x38, 0x54, - 0x1F, 0x40, 0x00, 0xF2, 0xB4, 0x0D, 0x08, 0x10, 0x08, 0x90, 0x8A, 0x90, 0x30, 0x50, 0xB2, 0x50, - 0x9C, 0x32, 0x0C, 0x92, 0x8E, 0x92, 0x38, 0x54, 0x04, 0x80, 0x30, 0xE4, 0x08, 0x00, 0x04, 0x40, - 0x0C, 0x1C, 0x00, 0xF6, 0x03, 0x00, 0xB1, 0xF0, 0x26, 0x07, 0x9E, 0xF0, 0x3A, 0x07, 0x01, 0x48, - 0x55, 0xF0, 0xFC, 0x09, 0x0C, 0x1C, 0x10, 0x44, 0xED, 0x10, 0x0B, 0xF0, 0x5E, 0x07, 0x0C, 0xF0, - 0x62, 0x07, 0x05, 0xF0, 0x52, 0x07, 0x06, 0xF0, 0x58, 0x07, 0x09, 0xF0, 0x24, 0x09, 0x00, 0xF0, - 0x02, 0x0A, 0x00, 0xF2, 0x60, 0x0B, 0xCF, 0x10, 0x09, 0xE7, 0x08, 0x00, 0xC9, 0x10, 0x2E, 0x1C, - 0x02, 0x10, 0x2C, 0x1C, 0xAA, 0xF0, 0x64, 0x07, 0xAC, 0xF0, 0x72, 0x07, 0x40, 0x10, 0x34, 0x1C, - 0xF3, 0x10, 0xAD, 0xF0, 0x7C, 0x07, 0xC8, 0x10, 0x36, 0x1C, 0xE9, 0x10, 0x2B, 0xF0, 0x82, 0x08, - 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFE, 0x20, 0x12, 0x01, 0x58, 0xD2, 0xF0, 0x82, 0x08, 0x76, 0x18, - 0x18, 0xF4, 0x03, 0x00, 0xEC, 0x12, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xE2, 0x12, - 0x0B, 0xF0, 0x64, 0x07, 0x0C, 0xF0, 0x64, 0x07, 0x36, 0x1C, 0x34, 0x1C, 0xB7, 0x10, 0x38, 0x54, - 0xB9, 0x54, 0x84, 0x80, 0x19, 0xE4, 0x20, 0x00, 0xB2, 0x13, 0x85, 0x80, 0x81, 0x48, 0x66, 0x12, - 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x58, 0x13, 0x1F, 0x80, 0x08, 0x44, 0xC8, 0x44, 0x9F, 0x12, - 0x1F, 0x40, 0x34, 0x91, 0xB6, 0x91, 0x44, 0x55, 0xE5, 0x55, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49, - 0xBB, 0x55, 0x82, 0x81, 0xC0, 0x55, 0x48, 0xF4, 0x0F, 0x00, 0x5A, 0xF0, 0x1A, 0x08, 0x4A, 0xE4, - 0x17, 0x00, 0xD5, 0xF0, 0xFA, 0x07, 0x02, 0xF6, 0x0F, 0x00, 0x02, 0xF4, 0x02, 0x00, 0x02, 0xEA, - 0xB8, 0x00, 0x04, 0x91, 0x86, 0x91, 0x02, 0x4B, 0x2C, 0x90, 0x08, 0x50, 0x2E, 0x90, 0x0A, 0x50, - 0x2C, 0x51, 0xAE, 0x51, 0x00, 0xF2, 0xB6, 0x10, 0x38, 0x54, 0x00, 0xF2, 0xB4, 0x0D, 0x56, 0x10, - 0x34, 0x91, 0xB6, 0x91, 0x0C, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x08, 0x00, 0x41, 0x12, 0x0C, 0x91, - 0x8E, 0x91, 0x04, 0x80, 0x18, 0xE4, 0xF7, 0x00, 0x04, 0x40, 0x30, 0x90, 0xB2, 0x90, 0x36, 0x10, - 0x02, 0x80, 0x48, 0xE4, 0x10, 0x00, 0x31, 0x12, 0x82, 0xE7, 0x10, 0x00, 0x84, 0x80, 0x19, 0xE4, - 0x20, 0x00, 0x10, 0x13, 0x0C, 0x90, 0x8E, 0x90, 0x5D, 0xF0, 0x78, 0x07, 0x0C, 0x58, 0x8D, 0x58, - 0x00, 0xF0, 0x64, 0x07, 0x38, 0x54, 0xB9, 0x54, 0x19, 0x80, 0xF1, 0x10, 0x3A, 0x55, 0x19, 0x81, - 0xBB, 0x55, 0x10, 0x90, 0x92, 0x90, 0x10, 0x58, 0x91, 0x58, 0x14, 0x59, 0x95, 0x59, 0x00, 0xF0, - 0x64, 0x07, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x06, 0x12, 0x6C, 0x19, 0x19, 0x41, 0x7C, 0x10, - 0x6C, 0x19, 0x0C, 0x51, 0xED, 0x19, 0x8E, 0x51, 0x6B, 0x18, 0x18, 0xF4, 0x00, 0xFF, 0x02, 0x13, - 0x6A, 0x10, 0x01, 0x58, 0xD2, 0xF0, 0xC0, 0x08, 0x76, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x0A, 0x12, - 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0x06, 0x13, 0x9E, 0xE7, 0x16, 0x00, 0x4C, 0x10, - 0xD1, 0xF0, 0xCA, 0x08, 0x9E, 0xE7, 0x17, 0x00, 0x42, 0x10, 0xD0, 0xF0, 0xD4, 0x08, 0x9E, 0xE7, - 0x19, 0x00, 0x38, 0x10, 0xCF, 0xF0, 0xDE, 0x08, 0x9E, 0xE7, 0x20, 0x00, 0x2E, 0x10, 0xCE, 0xF0, - 0xE8, 0x08, 0x9E, 0xE7, 0x21, 0x00, 0x24, 0x10, 0xCD, 0xF0, 0xF2, 0x08, 0x9E, 0xE7, 0x22, 0x00, - 0x1A, 0x10, 0xCC, 0xF0, 0x04, 0x09, 0x84, 0x80, 0x19, 0xE4, 0x04, 0x00, 0x06, 0x12, 0x9E, 0xE7, - 0x12, 0x00, 0x08, 0x10, 0xCB, 0xF0, 0x0C, 0x09, 0x9E, 0xE7, 0x24, 0x00, 0xB1, 0xF0, 0x0C, 0x09, - 0x05, 0xF0, 0x1E, 0x09, 0x09, 0xF0, 0x24, 0x09, 0x1E, 0xF0, 0xFC, 0x09, 0xE4, 0x10, 0x00, 0xF2, - 0x60, 0x0B, 0xE9, 0x10, 0x9C, 0x32, 0x82, 0xE7, 0x20, 0x00, 0x32, 0x1C, 0xE9, 0x09, 0x00, 0xF2, - 0x12, 0x11, 0x85, 0xF0, 0x02, 0x0A, 0x69, 0x08, 0x01, 0xF0, 0x44, 0x09, 0x1E, 0xF0, 0xFC, 0x09, - 0x00, 0xF0, 0x38, 0x09, 0x30, 0x44, 0x06, 0x12, 0x9E, 0xE7, 0x42, 0x00, 0xB8, 0x10, 0x04, 0xF6, - 0x01, 0x00, 0xB3, 0x45, 0x74, 0x12, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, 0x22, 0x13, 0x4B, 0xE4, - 0x02, 0x00, 0x36, 0x12, 0x4B, 0xE4, 0x28, 0x00, 0xAC, 0x13, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, - 0xC8, 0x11, 0x03, 0xF6, 0xD0, 0x00, 0xFA, 0x14, 0x82, 0xE7, 0x01, 0x00, 0x00, 0xF0, 0x80, 0x01, - 0x9E, 0xE7, 0x44, 0x00, 0x4B, 0xE4, 0x02, 0x00, 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x76, 0x10, - 0x00, 0xF2, 0xA2, 0x0D, 0x03, 0xE6, 0x02, 0x00, 0x6C, 0x10, 0x00, 0xF2, 0xA2, 0x0D, 0x19, 0x82, - 0x34, 0x46, 0x0A, 0x13, 0x03, 0xE6, 0x02, 0x00, 0x9E, 0xE7, 0x43, 0x00, 0x68, 0x10, 0x04, 0x80, - 0x30, 0xE4, 0x20, 0x00, 0x04, 0x40, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, 0x82, 0xE7, - 0x01, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x08, 0x03, 0x04, 0x80, 0x18, 0xE4, 0x20, 0x00, - 0x06, 0x12, 0x03, 0xE6, 0x02, 0x00, 0x3E, 0x10, 0x04, 0x80, 0x18, 0xE4, 0x02, 0x00, 0x3A, 0x12, - 0x04, 0x80, 0x18, 0xE4, 0xFD, 0x00, 0x04, 0x40, 0x1C, 0x1C, 0x9D, 0xF0, 0xEA, 0x09, 0x1C, 0x1C, - 0x9D, 0xF0, 0xF0, 0x09, 0xC1, 0x10, 0x9E, 0xE7, 0x13, 0x00, 0x0A, 0x10, 0x9E, 0xE7, 0x41, 0x00, - 0x04, 0x10, 0x9E, 0xE7, 0x24, 0x00, 0x00, 0xFC, 0xBE, 0x00, 0x98, 0x57, 0xD5, 0xF0, 0x8A, 0x02, - 0x04, 0xE6, 0x04, 0x00, 0x06, 0x10, 0x04, 0xE6, 0x04, 0x00, 0x9D, 0x41, 0x1C, 0x42, 0x9F, 0xE7, - 0x00, 0x00, 0x06, 0xF7, 0x02, 0x00, 0x03, 0xF6, 0xE0, 0x00, 0x3C, 0x14, 0x44, 0x58, 0x45, 0x58, - 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2, 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x3C, 0x14, 0x1E, 0x1C, - 0x00, 0xF0, 0x80, 0x01, 0x12, 0x1C, 0x22, 0x1C, 0xD2, 0x14, 0x00, 0xF0, 0x72, 0x01, 0x83, 0x59, - 0x03, 0xDC, 0x73, 0x57, 0x80, 0x5D, 0x00, 0x16, 0x83, 0x59, 0x03, 0xDC, 0x38, 0x54, 0x70, 0x57, - 0x33, 0x54, 0x3B, 0x54, 0x80, 0x5D, 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x38, 0x54, 0x00, 0xCC, - 0x00, 0x16, 0x03, 0x57, 0x83, 0x59, 0x00, 0x4C, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4, 0x01, 0x00, - 0x0E, 0x12, 0x48, 0xE4, 0x05, 0x00, 0x08, 0x12, 0x00, 0xF2, 0xBC, 0x11, 0x00, 0xF2, 0xC8, 0x11, - 0xC1, 0x5A, 0x3A, 0x55, 0x02, 0xEC, 0xB5, 0x00, 0x45, 0x59, 0x00, 0xF2, 0xF6, 0x0D, 0x83, 0x58, - 0x30, 0xE7, 0x00, 0x00, 0x10, 0x4D, 0x30, 0xE7, 0x40, 0x00, 0x10, 0x4F, 0x38, 0x90, 0xBA, 0x90, - 0x10, 0x5C, 0x80, 0x5C, 0x83, 0x5A, 0x10, 0x4E, 0x04, 0xEA, 0xB5, 0x00, 0x43, 0x5B, 0x03, 0xF4, - 0xE0, 0x00, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x0A, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, - 0x00, 0xF2, 0x38, 0x10, 0x00, 0x16, 0x08, 0x1C, 0x00, 0xFC, 0xAC, 0x00, 0x06, 0x58, 0x67, 0x18, - 0x18, 0xF4, 0x8F, 0xE1, 0x01, 0xFC, 0xAE, 0x00, 0x19, 0xF4, 0x70, 0x1E, 0xB0, 0x54, 0x07, 0x58, - 0x00, 0xFC, 0xB0, 0x00, 0x08, 0x58, 0x00, 0xFC, 0xB2, 0x00, 0x09, 0x58, 0x0A, 0x1C, 0x00, 0xE6, - 0x0F, 0x00, 0x00, 0xEA, 0xB9, 0x00, 0x38, 0x54, 0x00, 0xFA, 0x24, 0x01, 0x00, 0xFA, 0xB6, 0x00, - 0x18, 0x1C, 0x14, 0x1C, 0x10, 0x1C, 0x32, 0x1C, 0x12, 0x1C, 0x00, 0x16, 0x3E, 0x57, 0x0C, 0x14, - 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47, 0xF5, 0x13, 0x00, 0x16, 0x00, 0xF2, 0xA2, 0x0D, - 0x02, 0x4B, 0x03, 0xF6, 0xE0, 0x00, 0x00, 0xF2, 0x68, 0x0A, 0x01, 0x48, 0x20, 0x12, 0x44, 0x58, - 0x45, 0x58, 0x9E, 0xE7, 0x15, 0x00, 0x9C, 0xE7, 0x04, 0x00, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0xF2, - 0x7E, 0x10, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, 0x7A, 0x0A, 0x1E, 0x1C, 0xD5, 0x10, 0x00, 0x16, - 0x69, 0x08, 0x48, 0xE4, 0x04, 0x00, 0x64, 0x12, 0x48, 0xE4, 0x02, 0x00, 0x20, 0x12, 0x48, 0xE4, - 0x03, 0x00, 0x1A, 0x12, 0x48, 0xE4, 0x08, 0x00, 0x14, 0x12, 0x48, 0xE4, 0x01, 0x00, 0xF0, 0x12, - 0x48, 0xE4, 0x07, 0x00, 0x12, 0x12, 0x01, 0xE6, 0x07, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, - 0x12, 0x11, 0x05, 0xF0, 0x60, 0x0B, 0x00, 0x16, 0x00, 0xE6, 0x01, 0x00, 0x00, 0xEA, 0x99, 0x00, - 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0xE7, 0x12, 0x48, 0xE4, 0x06, 0x00, 0xE1, 0x12, 0x01, 0xE6, - 0x06, 0x00, 0x00, 0xF2, 0x4E, 0x0D, 0x00, 0xF2, 0x12, 0x11, 0x04, 0xE6, 0x02, 0x00, 0x9E, 0xE7, - 0x15, 0x00, 0x01, 0xF0, 0x1C, 0x0A, 0x00, 0xF0, 0x02, 0x0A, 0x00, 0x16, 0x02, 0x80, 0x48, 0xE4, - 0x10, 0x00, 0x1C, 0x12, 0x82, 0xE7, 0x08, 0x00, 0x3C, 0x56, 0x03, 0x82, 0x00, 0xF2, 0xE2, 0x0D, - 0x30, 0xE7, 0x08, 0x00, 0x04, 0xF7, 0x70, 0x01, 0x06, 0xF7, 0x02, 0x00, 0x00, 0xF0, 0x80, 0x01, - 0x6C, 0x19, 0xED, 0x19, 0x5D, 0xF0, 0xD4, 0x0B, 0x44, 0x55, 0xE5, 0x55, 0x59, 0xF0, 0x52, 0x0C, - 0x04, 0x55, 0xA5, 0x55, 0x1F, 0x80, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80, 0x49, 0x44, - 0x2E, 0x13, 0x01, 0xEC, 0xB8, 0x00, 0x41, 0xE4, 0x02, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x49, 0xE4, - 0x11, 0x00, 0x59, 0xF0, 0x2E, 0x0C, 0x01, 0xE6, 0x17, 0x00, 0x01, 0xEA, 0xB8, 0x00, 0x02, 0x4B, - 0x88, 0x90, 0xAC, 0x50, 0x8A, 0x90, 0xAE, 0x50, 0x01, 0xEC, 0xB8, 0x00, 0x82, 0x48, 0x82, 0x80, - 0x10, 0x44, 0x02, 0x4B, 0x1F, 0x40, 0xC0, 0x44, 0x00, 0xF2, 0xB4, 0x0D, 0x04, 0x55, 0xA5, 0x55, - 0x9F, 0x10, 0x0C, 0x51, 0x8E, 0x51, 0x30, 0x90, 0xB2, 0x90, 0x00, 0x56, 0xA1, 0x56, 0x30, 0x50, - 0xB2, 0x50, 0x34, 0x90, 0xB6, 0x90, 0x40, 0x56, 0xE1, 0x56, 0x34, 0x50, 0xB6, 0x50, 0x65, 0x10, - 0xB1, 0xF0, 0x70, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0xE9, 0x09, 0x4B, 0xE4, 0x03, 0x00, 0x78, 0x12, - 0x4B, 0xE4, 0x02, 0x00, 0x01, 0x13, 0xB1, 0xF0, 0x86, 0x0C, 0x85, 0xF0, 0xCA, 0x0B, 0x69, 0x08, - 0x48, 0xE4, 0x03, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0xCA, 0x0B, - 0xE8, 0x09, 0x3C, 0x56, 0x00, 0xFC, 0x20, 0x01, 0x98, 0x57, 0x02, 0x13, 0xBB, 0x45, 0x4B, 0xE4, - 0x00, 0x00, 0x08, 0x12, 0x03, 0xE6, 0x01, 0x00, 0x04, 0xF6, 0x00, 0x80, 0xA8, 0x14, 0xD2, 0x14, - 0x30, 0x1C, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x10, 0x13, 0x00, 0xFC, 0xB6, 0x00, 0x98, 0x57, - 0x02, 0x13, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B, 0x00, 0xFC, 0x24, 0x01, 0xB0, 0x57, - 0x00, 0xFA, 0x24, 0x01, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B, - 0x00, 0xF2, 0x8C, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0xB1, 0xF0, 0xF8, 0x0C, 0x85, 0xF0, 0x86, 0x0B, - 0x69, 0x08, 0x48, 0xE4, 0x01, 0x00, 0xD5, 0xF0, 0x86, 0x0B, 0xFC, 0x14, 0x42, 0x58, 0x6C, 0x14, - 0x80, 0x14, 0x30, 0x1C, 0x4A, 0xF4, 0x02, 0x00, 0x55, 0xF0, 0x86, 0x0B, 0x4A, 0xF4, 0x01, 0x00, - 0x0E, 0x12, 0x02, 0x80, 0x48, 0xE4, 0x03, 0x00, 0x06, 0x13, 0x3E, 0x1C, 0x00, 0xF0, 0x8E, 0x0B, - 0x00, 0xFC, 0xB6, 0x00, 0xB0, 0x57, 0x00, 0xFA, 0xB6, 0x00, 0x4C, 0x1C, 0x3E, 0x1C, 0x00, 0xF2, - 0x12, 0x11, 0x86, 0xF0, 0x8E, 0x0B, 0x00, 0xF2, 0xBA, 0x0E, 0x00, 0xF0, 0x8E, 0x0B, 0x4C, 0x1C, - 0xB1, 0xF0, 0x50, 0x0D, 0x85, 0xF0, 0x5C, 0x0D, 0x69, 0x08, 0xF3, 0x10, 0x86, 0xF0, 0x64, 0x0D, - 0x4E, 0x1C, 0x89, 0x48, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, - 0x00, 0xDC, 0x18, 0xF4, 0xFF, 0x7F, 0x30, 0x56, 0x00, 0x5C, 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, - 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x18, 0xF4, 0x00, 0x80, 0x30, 0x56, 0x00, 0x5C, - 0x00, 0x16, 0x00, 0xF6, 0x00, 0x01, 0x00, 0x57, 0x00, 0x57, 0x03, 0x58, 0x00, 0xDC, 0x0B, 0x58, - 0x00, 0x16, 0x03, 0xF6, 0x24, 0x01, 0x00, 0xF2, 0x58, 0x0A, 0x03, 0xF6, 0xB6, 0x00, 0x00, 0xF2, - 0x58, 0x0A, 0x00, 0x16, 0x02, 0xEC, 0xB8, 0x00, 0x02, 0x49, 0x18, 0xF4, 0xFF, 0x00, 0x00, 0x54, - 0x00, 0x54, 0x00, 0x54, 0x00, 0xF4, 0x08, 0x00, 0xE1, 0x18, 0x80, 0x54, 0x03, 0x58, 0x00, 0xDD, - 0x01, 0xDD, 0x02, 0xDD, 0x03, 0xDC, 0x02, 0x4B, 0x30, 0x50, 0xB2, 0x50, 0x34, 0x51, 0xB6, 0x51, - 0x00, 0x16, 0x45, 0x5A, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56, 0x05, 0xF4, - 0x02, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x1D, 0xF4, 0xFF, 0x00, 0x85, 0x56, 0x85, 0x56, 0x85, 0x56, - 0x05, 0xF4, 0x00, 0x12, 0x83, 0x5A, 0x00, 0x16, 0x38, 0x54, 0xBB, 0x55, 0x3C, 0x56, 0xBD, 0x56, - 0x00, 0xF2, 0x12, 0x11, 0x85, 0xF0, 0x82, 0x0E, 0xE9, 0x09, 0xC1, 0x59, 0x00, 0xF2, 0x12, 0x11, - 0x85, 0xF0, 0x82, 0x0E, 0xE8, 0x0A, 0x83, 0x55, 0x83, 0x55, 0x4B, 0xF4, 0x90, 0x01, 0x5C, 0xF0, - 0x36, 0x0E, 0xBD, 0x56, 0x40, 0x10, 0x4B, 0xF4, 0x30, 0x00, 0x59, 0xF0, 0x48, 0x0E, 0x01, 0xF6, - 0x0C, 0x00, 0x00, 0xF6, 0x01, 0x00, 0x2E, 0x10, 0x02, 0xFC, 0x9C, 0x00, 0x9A, 0x57, 0x14, 0x13, - 0x4B, 0xF4, 0x64, 0x00, 0x59, 0xF0, 0x64, 0x0E, 0x03, 0xF6, 0x64, 0x00, 0x01, 0xF6, 0x19, 0x00, - 0x00, 0xF6, 0x01, 0x00, 0x43, 0xF4, 0x33, 0x00, 0x56, 0xF0, 0x76, 0x0E, 0x04, 0xF4, 0x00, 0x01, - 0x43, 0xF4, 0x19, 0x00, 0xF3, 0x10, 0xB4, 0x56, 0xC3, 0x58, 0x02, 0xFC, 0x9E, 0x00, 0x9A, 0x57, - 0x08, 0x13, 0x3C, 0x56, 0x00, 0xF6, 0x02, 0x00, 0x00, 0x16, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00, - 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x02, 0x00, 0x00, 0xF2, 0x12, 0x11, - 0x86, 0xF0, 0xB8, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xB8, 0x0E, - 0x4E, 0x1C, 0x89, 0x49, 0x00, 0xF2, 0x12, 0x11, 0x00, 0x16, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, - 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x09, 0xE7, 0x03, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, - 0xF2, 0x0E, 0x09, 0xE7, 0x01, 0x00, 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x89, 0x49, - 0x00, 0xF2, 0x12, 0x11, 0x86, 0xF0, 0xF2, 0x0E, 0x4E, 0x1C, 0x89, 0x4A, 0x00, 0xF2, 0x12, 0x11, - 0x00, 0x16, 0x3C, 0x56, 0x00, 0x16, 0x00, 0xEC, 0x26, 0x01, 0x48, 0xE4, 0x01, 0x00, 0x1E, 0x13, - 0x38, 0x44, 0x00, 0xEA, 0x26, 0x01, 0x49, 0xF4, 0x00, 0x00, 0x04, 0x12, 0x4E, 0x1C, 0x02, 0x10, - 0x4C, 0x1C, 0x01, 0xEC, 0x27, 0x01, 0x89, 0x48, 0x00, 0xF2, 0x12, 0x11, 0x02, 0x14, 0x00, 0x16, - 0x85, 0xF0, 0x52, 0x0F, 0x38, 0x54, 0x00, 0xEA, 0x99, 0x00, 0x00, 0xF2, 0x60, 0x0B, 0x02, 0x80, - 0x48, 0xE4, 0x06, 0x00, 0x1C, 0x13, 0x00, 0xEC, 0x99, 0x00, 0x48, 0xE4, 0x01, 0x00, 0x0A, 0x12, - 0x04, 0x80, 0x30, 0xE4, 0x01, 0x00, 0x04, 0x40, 0x08, 0x10, 0x04, 0x80, 0x18, 0xE4, 0xFE, 0x00, - 0x04, 0x40, 0x00, 0x16, 0x02, 0xF6, 0xE0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x81, 0x48, - 0x22, 0x12, 0x00, 0x4E, 0x83, 0x5A, 0x90, 0x4C, 0x20, 0xE7, 0x00, 0x00, 0xC3, 0x58, 0x1B, 0xF4, - 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12, 0x8B, 0x55, 0x83, 0x59, - 0x00, 0x4E, 0x00, 0x16, 0x00, 0x4E, 0x02, 0xF6, 0xF0, 0x00, 0x02, 0x57, 0x03, 0x59, 0x00, 0x4E, - 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x20, 0xE7, 0x00, 0x00, 0x00, 0x16, 0x02, 0xF6, 0xF0, 0x00, - 0x02, 0x57, 0x03, 0x59, 0x01, 0xCC, 0x00, 0x4E, 0x83, 0x5A, 0x30, 0xE7, 0x00, 0x00, 0x80, 0x4C, - 0xC3, 0x58, 0x1B, 0xF4, 0xFF, 0x00, 0x83, 0x55, 0x83, 0x55, 0x83, 0x55, 0x03, 0xF4, 0x00, 0x12, - 0x83, 0x59, 0x00, 0x4E, 0x00, 0x16, 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x3A, 0x55, - 0x02, 0xCC, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0xC0, 0x5A, 0x40, 0x5C, 0x38, 0x54, 0x00, 0xCD, - 0x01, 0xCC, 0x4A, 0x46, 0x0A, 0x13, 0x83, 0x59, 0x00, 0x4C, 0x01, 0x48, 0x16, 0x13, 0x0C, 0x10, - 0xC5, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x00, 0x4C, 0x01, 0x48, 0x08, 0x13, 0x05, 0xF6, 0xF0, 0x00, - 0x05, 0x57, 0x08, 0x10, 0x45, 0x58, 0x00, 0xF2, 0xF6, 0x0D, 0x8D, 0x56, 0x83, 0x5A, 0x80, 0x4C, - 0x05, 0x17, 0x00, 0x16, 0x02, 0x4B, 0x06, 0xF7, 0x04, 0x00, 0x62, 0x0B, 0x03, 0x82, 0x00, 0xF2, - 0xE2, 0x0D, 0x02, 0x80, 0x00, 0x4C, 0x45, 0xF4, 0x02, 0x00, 0x52, 0x14, 0x06, 0xF7, 0x02, 0x00, - 0x06, 0x14, 0x00, 0xF2, 0x54, 0x0F, 0x00, 0x16, 0x02, 0x4B, 0x01, 0xF6, 0xFF, 0x00, 0x38, 0x1C, - 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x1D, 0xF7, 0x3C, 0x00, 0xB8, 0xF0, - 0x4E, 0x10, 0x9C, 0x14, 0x01, 0x48, 0x1C, 0x13, 0x0E, 0xF7, 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00, - 0xAF, 0x19, 0x03, 0x42, 0x45, 0xF4, 0x02, 0x00, 0x83, 0x5A, 0x02, 0xCC, 0x02, 0x41, 0x45, 0xF4, - 0x02, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0, 0x3E, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x01, 0xF6, - 0xFF, 0x00, 0x38, 0x1C, 0x05, 0xF4, 0x04, 0x00, 0x83, 0x5A, 0x18, 0xDF, 0x19, 0xDF, 0x0E, 0xF7, - 0x3C, 0x00, 0x03, 0xF7, 0x04, 0x00, 0x0F, 0x79, 0x1C, 0xF7, 0x3C, 0x00, 0xB8, 0xF0, 0x9C, 0x10, - 0x4E, 0x14, 0x01, 0x48, 0x06, 0x13, 0x45, 0xF4, 0x04, 0x00, 0x00, 0x16, 0x91, 0x44, 0xD5, 0xF0, - 0x82, 0x10, 0x00, 0xF0, 0x9E, 0x02, 0x02, 0xF6, 0xFF, 0x00, 0x38, 0x1C, 0x2C, 0xBC, 0xAE, 0xBC, - 0xE2, 0x08, 0x00, 0xEC, 0xB8, 0x00, 0x02, 0x48, 0x1D, 0xF7, 0x80, 0x00, 0xB8, 0xF0, 0xCC, 0x10, - 0x1E, 0x14, 0x01, 0x48, 0x0E, 0x13, 0x0E, 0xF7, 0x80, 0x00, 0x38, 0x54, 0x03, 0x58, 0xAF, 0x19, - 0x82, 0x48, 0x00, 0x16, 0x82, 0x48, 0x12, 0x45, 0xD5, 0xF0, 0xBA, 0x10, 0x00, 0xF0, 0x9E, 0x02, - 0x39, 0xF0, 0xF8, 0x10, 0x38, 0x44, 0x00, 0x16, 0x7E, 0x18, 0x18, 0xF4, 0x03, 0x00, 0x04, 0x13, - 0x61, 0x18, 0x00, 0x16, 0x38, 0x1C, 0x00, 0xFC, 0x22, 0x01, 0x18, 0xF4, 0x01, 0x00, 0xF1, 0x12, - 0xE3, 0x10, 0x30, 0x44, 0x30, 0x44, 0x30, 0x44, 0xB1, 0xF0, 0x18, 0x11, 0x00, 0x16, 0x3E, 0x57, - 0x03, 0xF6, 0xE0, 0x00, 0x03, 0x57, 0x83, 0x59, 0x04, 0xCC, 0x01, 0x4A, 0x6A, 0x12, 0x45, 0x5A, - 0x00, 0xF2, 0xF6, 0x0D, 0x02, 0x4B, 0x70, 0x14, 0x34, 0x13, 0x02, 0x80, 0x48, 0xE4, 0x08, 0x00, - 0x18, 0x12, 0x9C, 0xE7, 0x02, 0x00, 0x9E, 0xE7, 0x15, 0x00, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, - 0x7A, 0x0A, 0x1E, 0x1C, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x30, 0xE4, 0x10, 0x00, 0x04, 0x40, - 0x00, 0xF2, 0xE2, 0x0D, 0x20, 0xE7, 0x01, 0x00, 0x01, 0xF6, 0x01, 0x00, 0x00, 0x16, 0x04, 0xDC, - 0x01, 0x4A, 0x24, 0x12, 0x45, 0x5A, 0x00, 0xF2, 0xF6, 0x0D, 0x43, 0x5B, 0x06, 0xEC, 0x98, 0x00, - 0x00, 0xF2, 0x38, 0x10, 0xC6, 0x59, 0x20, 0x14, 0x0A, 0x13, 0x00, 0xF2, 0xC6, 0x0F, 0x00, 0xF2, - 0x14, 0x10, 0xA7, 0x10, 0x83, 0x5A, 0xD7, 0x10, 0x0E, 0x47, 0x07, 0xE6, 0x10, 0x00, 0xCE, 0x47, - 0x5A, 0xF0, 0x20, 0x11, 0xB9, 0x54, 0x00, 0x16, 0x14, 0x90, 0x96, 0x90, 0x02, 0xFC, 0xA8, 0x00, - 0x03, 0xFC, 0xAA, 0x00, 0x48, 0x55, 0x02, 0x13, 0xC9, 0x55, 0x00, 0x16, 0x00, 0xEC, 0xBA, 0x00, - 0x10, 0x44, 0x00, 0xEA, 0xBA, 0x00, 0x00, 0x16, 0x03, 0xF6, 0xC0, 0x00, 0x00, 0xF2, 0x68, 0x0A, - 0x10, 0x44, 0x00, 0x4C, 0x00, 0x16 +u_int8_t adv_asc3550_mcode[] = { + 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x00, 0xfc, 0x48, 0xe4, 0x01, 0x00, 0x18, 0xe4, + 0x00, 0xf6, 0x01, 0xf6, 0x18, 0x80, 0x48, 0x19, 0x02, 0x00, 0xff, 0xff, 0x03, 0xf6, 0x00, 0xfa, + 0xff, 0x00, 0x82, 0xe7, 0x01, 0xfa, 0x9e, 0xe7, 0x09, 0xe7, 0x3a, 0x0e, 0x00, 0xea, 0x01, 0xe6, + 0x55, 0xf0, 0x03, 0x00, 0x08, 0x00, 0x18, 0xf4, 0x3e, 0x01, 0x3e, 0x57, 0x04, 0x00, 0x85, 0xf0, + 0x00, 0xe6, 0x00, 0xec, 0x1e, 0xf0, 0x32, 0xf0, 0x34, 0x19, 0x86, 0xf0, 0xd0, 0x01, 0xd5, 0xf0, + 0xde, 0x0c, 0x98, 0x57, 0xbc, 0x00, 0x0c, 0x1c, 0x0e, 0x13, 0x38, 0x54, 0xb1, 0xf0, 0xb4, 0x00, + 0x01, 0xfc, 0x03, 0xfc, 0xd8, 0x0c, 0x00, 0x57, 0x01, 0xf0, 0x02, 0x13, 0x03, 0xe6, 0x10, 0x00, + 0x18, 0x40, 0x3e, 0x1c, 0x6c, 0x01, 0x6e, 0x01, 0xbd, 0x00, 0xe0, 0x00, 0x02, 0x48, 0x02, 0x80, + 0x08, 0x12, 0x30, 0xe4, 0x3c, 0x00, 0x4e, 0x01, 0x64, 0x12, 0x80, 0x00, 0x9c, 0x15, 0xbb, 0x00, + 0x00, 0x4e, 0x01, 0x01, 0x01, 0xea, 0x04, 0x12, 0x9e, 0x0f, 0xb6, 0x00, 0xb9, 0x54, 0xe2, 0x0f, + 0x00, 0x80, 0x06, 0xf7, 0x10, 0x44, 0x24, 0x01, 0x28, 0x01, 0x32, 0x00, 0x3c, 0x01, 0x3c, 0x56, + 0x3e, 0x00, 0x4b, 0xe4, 0x4c, 0x1c, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, + 0x76, 0x01, 0x78, 0x01, 0xe2, 0x0c, 0x00, 0x01, 0x02, 0xee, 0x02, 0xfc, 0x03, 0x58, 0x03, 0xf7, + 0x04, 0x80, 0x05, 0xfc, 0x08, 0x44, 0x09, 0xf0, 0x0f, 0x00, 0x1b, 0x80, 0x20, 0x01, 0x38, 0x1c, + 0x40, 0x00, 0x40, 0x15, 0x4b, 0xf4, 0x4e, 0x1c, 0x5b, 0xf0, 0x5d, 0xf0, 0xaa, 0x00, 0xbb, 0x55, + 0xbe, 0x00, 0xc0, 0x00, 0xe0, 0x08, 0xe0, 0x14, 0xec, 0x0f, 0x00, 0x4c, 0x00, 0xdc, 0x02, 0x4a, + 0x05, 0x00, 0x05, 0xf0, 0x05, 0xf8, 0x06, 0x13, 0x08, 0x13, 0x0c, 0x00, 0x0e, 0x47, 0x0e, 0xf7, + 0x19, 0x00, 0x20, 0x00, 0x2a, 0x01, 0x30, 0x0e, 0x32, 0x1c, 0x36, 0x00, 0x45, 0x5a, 0x59, 0xf0, + 0x62, 0x0a, 0x69, 0x08, 0x72, 0x0b, 0x83, 0x59, 0xb8, 0xf0, 0xbd, 0x56, 0xcc, 0x12, 0xec, 0x17, + 0xee, 0x0f, 0xf0, 0x00, 0xf8, 0x17, 0x01, 0x48, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0x10, 0x04, 0xea, + 0x04, 0xf6, 0x04, 0xfc, 0x05, 0x80, 0x05, 0xe6, 0x06, 0x00, 0x06, 0x12, 0x0a, 0x10, 0x0b, 0xf0, + 0x0c, 0x10, 0x0c, 0xf0, 0x12, 0x10, 0x26, 0x0e, 0x30, 0x1c, 0x33, 0x00, 0x34, 0x00, 0x38, 0x44, + 0x40, 0x5c, 0x4a, 0xe4, 0x62, 0x1a, 0x68, 0x08, 0x68, 0x54, 0x83, 0x55, 0x83, 0x5a, 0x8c, 0x14, + 0x8e, 0x0a, 0x90, 0x14, 0x91, 0x44, 0xa4, 0x00, 0xb0, 0x57, 0xb5, 0x00, 0xba, 0x00, 0xce, 0x45, + 0xd0, 0x00, 0xd8, 0x16, 0xe1, 0x00, 0xe7, 0x00, 0x00, 0x54, 0x01, 0x58, 0x02, 0x10, 0x02, 0xe6, + 0x03, 0xa1, 0x04, 0x13, 0x06, 0x83, 0x06, 0xf0, 0x07, 0x00, 0x0a, 0x00, 0x0a, 0x12, 0x0a, 0xf0, + 0x0c, 0x04, 0x0c, 0x12, 0x0c, 0x90, 0x10, 0x10, 0x10, 0x13, 0x12, 0x1c, 0x17, 0x00, 0x19, 0xe4, + 0x1a, 0x10, 0x1c, 0x00, 0x1c, 0x12, 0x1d, 0xf7, 0x1e, 0x13, 0x20, 0x1c, 0x20, 0xe7, 0x22, 0x01, + 0x26, 0x01, 0x2a, 0x12, 0x30, 0xe7, 0x34, 0x1c, 0x36, 0x1c, 0x38, 0x12, 0x41, 0x58, 0x43, 0x48, + 0x44, 0x55, 0x46, 0x1c, 0x4c, 0x0e, 0x4e, 0xe4, 0x52, 0x14, 0x5c, 0xf0, 0x72, 0x02, 0x74, 0x03, + 0x77, 0x57, 0x89, 0x48, 0x8e, 0x90, 0x99, 0x00, 0x9b, 0x00, 0x9c, 0x32, 0x9e, 0x00, 0xa8, 0x00, + 0xb9, 0x00, 0xba, 0x06, 0xbc, 0x12, 0xbf, 0x57, 0xc0, 0x01, 0xfe, 0x9c, 0xf0, 0x26, 0x02, 0xfe, + 0x00, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xfe, 0xc2, 0x01, 0xfe, 0x56, 0x19, 0x00, 0xfc, 0xfe, 0x80, + 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x6a, 0x13, 0xfe, 0x05, 0x05, 0xff, 0x40, 0x00, 0x00, 0x0d, + 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x10, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, + 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, + 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xfc, 0x2b, 0x51, 0x0c, 0x01, 0xfe, 0xea, 0x0e, 0xfe, 0x04, 0xf7, + 0xfc, 0x51, 0x0c, 0x1d, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x20, 0xf0, 0xd0, 0x04, + 0x56, 0x4b, 0x02, 0xfe, 0x1c, 0x0d, 0x01, 0xfe, 0x7c, 0x0d, 0xfe, 0xe9, 0x12, 0x02, 0xfe, 0x04, + 0x03, 0xfe, 0x28, 0x1c, 0x04, 0xfe, 0xa6, 0x00, 0xfe, 0xdd, 0x12, 0x4e, 0x12, 0xfe, 0xa6, 0x00, + 0xc5, 0xfe, 0x48, 0xf0, 0xfe, 0x7c, 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0x96, 0x02, 0xfe, 0x4a, 0xf0, + 0xfe, 0xb4, 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x46, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x4c, 0x02, 0xfe, + 0x43, 0xf0, 0xfe, 0x3a, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x3e, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x42, + 0x02, 0x09, 0x0c, 0x9e, 0x09, 0x06, 0x12, 0xbb, 0x02, 0x26, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, + 0xfe, 0x02, 0x1c, 0xfe, 0xed, 0x10, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x4c, 0x17, + 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xf7, 0x0e, 0x78, 0x01, 0xab, 0x02, 0x26, 0x17, 0x55, 0x4a, + 0xbd, 0x01, 0xfe, 0x60, 0x0f, 0x0e, 0x78, 0x01, 0x8b, 0xfe, 0xbd, 0x10, 0x0e, 0x78, 0x01, 0x8b, + 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, 0x1c, 0x09, 0x06, 0x12, 0xbb, 0x2b, 0x22, 0x26, + 0xfe, 0x3d, 0xf0, 0xfe, 0xf8, 0x01, 0x27, 0xfe, 0x8a, 0x02, 0xfe, 0x5a, 0x1c, 0xd5, 0xfe, 0x14, + 0x1c, 0x17, 0xfe, 0x30, 0x00, 0x4a, 0xbd, 0x01, 0xfe, 0x50, 0x0f, 0x09, 0x06, 0x12, 0xbb, 0x02, + 0xfe, 0xc2, 0x01, 0x21, 0x2a, 0x05, 0x10, 0x35, 0xfe, 0x69, 0x10, 0x09, 0x06, 0x12, 0xbb, 0xfe, + 0x04, 0xec, 0x2a, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01, 0x46, 0x7f, 0xfe, 0x05, 0xf6, 0xf7, 0x01, + 0xfe, 0x76, 0x16, 0x0a, 0x41, 0x89, 0x38, 0x11, 0x47, 0x1d, 0xca, 0x08, 0x1c, 0x09, 0x43, 0x01, + 0x71, 0x02, 0x26, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x2c, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b, + 0xfe, 0x28, 0x10, 0x0e, 0xc0, 0x01, 0x15, 0xe6, 0x0e, 0x79, 0x01, 0x15, 0xfe, 0x49, 0x54, 0x74, + 0xfe, 0x12, 0x03, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x71, 0x02, 0x26, 0x2b, 0x7f, 0xfe, 0x02, 0xe8, + 0x2f, 0xfb, 0xfe, 0x9e, 0x43, 0xf0, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xd0, 0xfe, 0x40, 0x1c, + 0x22, 0xef, 0xfe, 0x26, 0xf0, 0xfe, 0x70, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x5e, 0x03, 0xfe, 0x11, + 0xf0, 0xd0, 0xfe, 0x0e, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x7e, 0x03, 0xe9, 0x13, 0xfe, 0x11, 0x00, + 0x02, 0x62, 0x2b, 0xfe, 0x48, 0x1c, 0xe9, 0x22, 0xef, 0x34, 0xef, 0xfe, 0x82, 0xf0, 0xfe, 0x84, + 0x03, 0x2d, 0x21, 0xbe, 0x6a, 0x16, 0xbe, 0x0e, 0x79, 0x01, 0x15, 0x6a, 0x7d, 0x08, 0x1c, 0x09, + 0x43, 0x01, 0x46, 0x11, 0x3d, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x71, 0xf5, 0x11, 0xfe, 0xe4, 0x00, + 0x2e, 0xfe, 0xca, 0x03, 0x22, 0x32, 0x1f, 0xfe, 0xda, 0x03, 0x01, 0x4c, 0xcb, 0xfe, 0xea, 0x03, + 0x6b, 0x92, 0xcf, 0xfe, 0xaa, 0x06, 0x02, 0x28, 0x04, 0x78, 0x29, 0x18, 0xfe, 0x1c, 0x05, 0x17, + 0x85, 0x01, 0x44, 0x01, 0x97, 0x01, 0x9a, 0x34, 0xfe, 0x5c, 0x02, 0x02, 0xee, 0xe9, 0x2b, 0x51, + 0x19, 0xfe, 0x67, 0x1b, 0xfb, 0xf0, 0xfe, 0x48, 0x1c, 0x8c, 0x01, 0xfa, 0xac, 0xfe, 0x96, 0xf0, + 0xfe, 0x24, 0x04, 0x2e, 0xfe, 0x28, 0x04, 0x34, 0x26, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x18, + 0xfe, 0x08, 0x05, 0x3e, 0x90, 0x9f, 0x2f, 0x82, 0x6e, 0x22, 0x32, 0x1f, 0x28, 0x04, 0x78, 0x29, + 0xfe, 0x10, 0x12, 0x17, 0x85, 0x01, 0x44, 0x34, 0xfe, 0x5c, 0x02, 0x02, 0xee, 0x31, 0xfe, 0xa0, + 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x5e, 0x12, 0x0a, 0x07, 0x06, 0xfe, 0x56, 0x12, 0x23, 0x24, 0x91, + 0x01, 0x0b, 0x82, 0x6e, 0x1f, 0xfe, 0xd8, 0x04, 0x23, 0x24, 0x91, 0x01, 0x0b, 0x1f, 0x28, 0x23, + 0x24, 0xb3, 0xfe, 0x4c, 0x44, 0xfe, 0x32, 0x12, 0x57, 0xfe, 0x44, 0x48, 0x08, 0xd6, 0xfe, 0x4c, + 0x54, 0x74, 0xfe, 0x08, 0x05, 0x7f, 0x9f, 0x2f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x48, + 0x13, 0x3f, 0x05, 0xfe, 0xcc, 0x00, 0xfe, 0x40, 0x13, 0x0a, 0x07, 0x06, 0xe5, 0xfe, 0x06, 0x10, + 0x23, 0x24, 0xb3, 0x0a, 0x07, 0x37, 0xda, 0x17, 0xa4, 0x0a, 0x07, 0x06, 0x4b, 0x17, 0xfe, 0x0d, + 0x00, 0x01, 0x44, 0x34, 0xfe, 0xc0, 0x0c, 0x02, 0x28, 0x39, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, + 0x90, 0xb0, 0x03, 0x17, 0xa4, 0x01, 0x44, 0x34, 0x26, 0x22, 0x26, 0x02, 0xfe, 0x10, 0x05, 0xfe, + 0x42, 0x5b, 0x51, 0x19, 0xfe, 0x46, 0x59, 0xfb, 0xf0, 0x17, 0x45, 0xfe, 0x07, 0x80, 0xfe, 0x31, + 0x44, 0x0a, 0x07, 0x0c, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x05, 0x19, 0xfe, 0x70, 0x12, 0x6d, + 0x07, 0x06, 0xfe, 0x60, 0x13, 0x04, 0xfe, 0xa2, 0x00, 0x29, 0x18, 0xfe, 0xa8, 0x05, 0xfe, 0x31, + 0xe4, 0x70, 0x6d, 0x07, 0x0c, 0xfe, 0x4a, 0x13, 0x04, 0xfe, 0xa0, 0x00, 0x29, 0xfe, 0x42, 0x12, + 0x5a, 0x2e, 0xfe, 0x68, 0x05, 0x22, 0x32, 0xf1, 0x01, 0x0b, 0x25, 0xfe, 0xc0, 0x05, 0x11, 0xfe, + 0xe3, 0x00, 0x2d, 0x6d, 0xfe, 0x4a, 0xf0, 0xfe, 0x92, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0x8c, 0x05, + 0xa8, 0x20, 0xfe, 0x21, 0x00, 0xa6, 0x20, 0xfe, 0x22, 0x00, 0x9e, 0x20, 0x89, 0xfe, 0x09, 0x48, + 0x01, 0x0b, 0x25, 0xfe, 0xc0, 0x05, 0xfe, 0xe2, 0x08, 0x6d, 0x07, 0xd9, 0x4b, 0x01, 0x96, 0x20, + 0x06, 0x16, 0xe0, 0x4a, 0xfe, 0x27, 0x01, 0x0a, 0x07, 0x37, 0xe1, 0x4e, 0x01, 0xb9, 0x17, 0xa4, + 0x0a, 0x07, 0x06, 0x4b, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x44, 0x01, 0x97, 0x01, 0x9a, 0x34, 0xfe, + 0xc0, 0x0c, 0x02, 0x28, 0x04, 0xfe, 0x9c, 0x00, 0x29, 0xfe, 0x3e, 0x12, 0x04, 0x53, 0x29, 0xfe, + 0x36, 0x13, 0x4e, 0x01, 0xb9, 0x25, 0xfe, 0x38, 0x06, 0x0e, 0x06, 0x6d, 0x07, 0x1a, 0xfe, 0x02, + 0x12, 0x77, 0x01, 0xfe, 0x26, 0x14, 0x1f, 0xfe, 0x2e, 0x06, 0x11, 0xc2, 0x01, 0x4c, 0x11, 0xfe, + 0xe5, 0x00, 0x04, 0x53, 0xbc, 0x0f, 0x53, 0x04, 0xf6, 0x29, 0xfe, 0x62, 0x12, 0x04, 0x4d, 0x29, + 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x9e, 0x18, 0x01, 0xfe, 0xf0, 0x18, 0xe7, 0xa3, 0x1a, 0x08, 0x63, + 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b, 0x50, 0xc9, 0xa3, 0x6c, 0x4e, 0x01, 0xb9, 0x25, 0xfe, + 0xa2, 0x06, 0x6d, 0x07, 0x1e, 0xa5, 0x95, 0x0e, 0x55, 0x01, 0xfe, 0x54, 0x14, 0x1f, 0xfe, 0x98, + 0x06, 0x11, 0xc2, 0x01, 0x4c, 0x11, 0xfe, 0xe5, 0x00, 0x04, 0x4d, 0xbc, 0x0f, 0x4d, 0x09, 0x06, + 0x01, 0xb9, 0xf5, 0x73, 0x8c, 0x01, 0xfa, 0xac, 0x11, 0xfe, 0xe2, 0x00, 0x2e, 0xf9, 0x22, 0x32, + 0xcf, 0xfe, 0xd6, 0x06, 0x81, 0xfe, 0x74, 0x07, 0xcb, 0xfe, 0x7c, 0x07, 0x6b, 0x92, 0x02, 0x28, + 0x0a, 0x07, 0x0c, 0xfe, 0x2e, 0x12, 0x14, 0x19, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00, + 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01, 0x0b, 0x14, 0x00, 0x02, 0xfe, 0x4c, + 0x08, 0x68, 0x07, 0x1e, 0xe5, 0x0a, 0x07, 0x1e, 0xfe, 0x30, 0x13, 0x14, 0xfe, 0x1b, 0x00, 0x01, + 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x00, 0x01, 0x0b, 0x14, 0x06, 0x01, + 0x0b, 0x14, 0x00, 0x02, 0xfe, 0x2a, 0x0b, 0x77, 0xfe, 0x9a, 0x81, 0x67, 0x89, 0xfe, 0x09, 0x6f, + 0xfe, 0x93, 0x45, 0x18, 0xfe, 0x84, 0x07, 0x2e, 0xfe, 0x5c, 0x07, 0x22, 0x32, 0xcf, 0xfe, 0x54, + 0x07, 0x6b, 0x92, 0x81, 0xfe, 0x74, 0x07, 0x02, 0x28, 0x01, 0x4c, 0x02, 0xf9, 0x14, 0x1a, 0x02, + 0xf9, 0xfe, 0x9c, 0xf7, 0xfe, 0xec, 0x07, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x75, 0xfe, 0xd2, + 0x07, 0x0f, 0x5d, 0x12, 0x5e, 0x0a, 0x41, 0x70, 0x38, 0x01, 0xfe, 0x34, 0x18, 0x05, 0x10, 0x83, + 0xfe, 0x83, 0xe7, 0x88, 0xa6, 0xfe, 0x03, 0x40, 0x0a, 0x41, 0x45, 0x38, 0x01, 0xc1, 0xaf, 0xfe, + 0x1f, 0x40, 0x16, 0x61, 0x01, 0xfe, 0xde, 0x12, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x34, + 0x51, 0xfe, 0xb6, 0x51, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0f, 0x5b, 0x12, 0x5c, 0xd2, 0xf2, + 0x0f, 0x3a, 0x12, 0x3b, 0xfe, 0x60, 0x10, 0x0a, 0x07, 0x70, 0xe1, 0xfe, 0x2c, 0x90, 0xfe, 0xae, + 0x90, 0x0f, 0x5d, 0x12, 0x5e, 0x0a, 0x07, 0x45, 0xc9, 0x01, 0xc1, 0xfe, 0x1f, 0x80, 0x16, 0x61, + 0xfe, 0x34, 0x90, 0xfe, 0xb6, 0x90, 0x0f, 0x5f, 0x12, 0x60, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, + 0x0f, 0x5b, 0x12, 0x5c, 0xa2, 0x07, 0x45, 0x2c, 0xd2, 0xf2, 0x0f, 0x3a, 0x12, 0x3b, 0xa8, 0xfe, + 0x28, 0x90, 0xfe, 0xaa, 0x90, 0x0f, 0x3a, 0x12, 0x3b, 0x0f, 0x42, 0x12, 0x58, 0x0a, 0x41, 0x1a, + 0x38, 0x2b, 0x08, 0x80, 0x2e, 0xfe, 0x62, 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x76, 0x08, 0x9b, 0x18, + 0x32, 0x2b, 0x52, 0xfe, 0xed, 0x10, 0xa7, 0xfe, 0x9a, 0x08, 0xa9, 0xfe, 0xb6, 0x08, 0x81, 0xfe, + 0x8e, 0x08, 0xcb, 0xfe, 0x94, 0x08, 0x6b, 0x92, 0x02, 0x28, 0x01, 0x4c, 0xfe, 0xc9, 0x10, 0x14, + 0x1a, 0xfe, 0xc9, 0x10, 0x68, 0x07, 0x06, 0xfe, 0x10, 0x12, 0x68, 0x07, 0x0c, 0x40, 0x0a, 0x07, + 0x0c, 0xfe, 0x7e, 0x12, 0xfe, 0x2e, 0x1c, 0xaa, 0x68, 0x07, 0x06, 0x40, 0x68, 0x07, 0x0c, 0xfe, + 0x6a, 0x12, 0xfe, 0x2c, 0x1c, 0xa2, 0x07, 0x45, 0xd4, 0xa2, 0x41, 0x45, 0xfe, 0x05, 0x40, 0xd2, + 0xf2, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0xfe, 0xaa, 0xf0, 0xfe, 0x4e, 0x09, 0xfe, 0xac, 0xf0, + 0xfe, 0xee, 0x08, 0xfe, 0x92, 0x10, 0xe3, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xfa, 0x08, + 0x02, 0xfe, 0x5c, 0x0a, 0xe4, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xb8, 0xfe, 0x6b, 0x18, 0x1b, + 0xfe, 0x00, 0xfe, 0xda, 0xc5, 0xfe, 0xd2, 0xf0, 0xb8, 0xfe, 0x76, 0x18, 0x1b, 0x19, 0x18, 0xb8, + 0x04, 0xdf, 0x1b, 0x06, 0x18, 0xb8, 0xa7, 0x7a, 0xa9, 0x7a, 0xe3, 0xe4, 0xfe, 0xb1, 0x10, 0x8c, + 0x5a, 0x39, 0x17, 0xa4, 0x01, 0x44, 0x13, 0xfe, 0x35, 0x00, 0x34, 0x62, 0x13, 0x8d, 0x02, 0x62, + 0xfe, 0x74, 0x18, 0x1b, 0xfe, 0x00, 0xf8, 0x18, 0x7a, 0x51, 0x1e, 0x01, 0xfe, 0x7c, 0x0d, 0xd1, + 0x08, 0x1c, 0x09, 0x43, 0x01, 0x71, 0x21, 0x2f, 0x3e, 0x51, 0x19, 0x02, 0x7a, 0xfe, 0x98, 0x80, + 0xd7, 0x0c, 0x27, 0xfe, 0x3e, 0x0a, 0x0a, 0x07, 0x70, 0xfe, 0x82, 0x12, 0x0a, 0x07, 0x1a, 0xfe, + 0x66, 0x13, 0x21, 0x61, 0x6a, 0xc8, 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, + 0x04, 0x91, 0xfe, 0x86, 0x91, 0x64, 0x2f, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x75, 0xfe, 0xea, + 0x08, 0x04, 0x5d, 0x30, 0x5e, 0x0f, 0xae, 0x12, 0x8d, 0x9c, 0x5d, 0x9d, 0x5e, 0x01, 0xc1, 0xaf, + 0x64, 0x2f, 0x16, 0x61, 0xa1, 0x42, 0x69, 0x58, 0x65, 0x5f, 0x31, 0x60, 0xe8, 0xfe, 0xe5, 0x55, + 0xfe, 0x04, 0xfa, 0x42, 0xfe, 0x05, 0xfa, 0x58, 0x01, 0xfe, 0xde, 0x12, 0xfe, 0x36, 0x10, 0x2d, + 0x0f, 0xae, 0x0f, 0x8d, 0x65, 0x5f, 0x31, 0x60, 0xaa, 0x0a, 0x07, 0x1a, 0x18, 0xfe, 0xea, 0x08, + 0x65, 0x3a, 0x31, 0x3b, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x38, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x10, + 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x7a, 0x0a, 0x07, 0x1a, 0x18, + 0xfe, 0xea, 0x08, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x38, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x77, + 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x3f, 0x05, 0xc3, 0x18, 0xfe, 0xf6, 0x08, + 0x11, 0xc3, 0xfe, 0x98, 0x80, 0xd7, 0x0c, 0xfe, 0x14, 0x13, 0x04, 0x3a, 0x30, 0x3b, 0x75, 0xfe, + 0xf6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x7a, 0x2d, 0x4e, 0xfe, 0x19, 0x80, 0xfe, + 0xf1, 0x10, 0x0a, 0x07, 0x0c, 0xa5, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x8e, 0x10, 0xfe, + 0x6c, 0x19, 0x9c, 0x3a, 0xfe, 0xed, 0x19, 0x9d, 0x3b, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xfe, + 0x6b, 0x18, 0x1b, 0xfe, 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc5, 0xfe, 0xd2, 0xf0, 0xfe, 0xd6, + 0x0a, 0xfe, 0x76, 0x18, 0x1b, 0x19, 0xce, 0x04, 0xdf, 0x1b, 0x06, 0x84, 0x13, 0xfe, 0x16, 0x00, + 0x02, 0x62, 0xfe, 0xd1, 0xf0, 0xfe, 0xe8, 0x0a, 0x17, 0x80, 0x01, 0x44, 0x13, 0xd6, 0xfe, 0x42, + 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xee, 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xfa, 0x0a, + 0x13, 0xfe, 0x22, 0x00, 0x02, 0x62, 0xfe, 0xcb, 0xf0, 0xfe, 0x06, 0x0b, 0x13, 0xfe, 0x24, 0x00, + 0x02, 0x62, 0xfe, 0xd0, 0xf0, 0xfe, 0x10, 0x0b, 0x13, 0x88, 0xd8, 0xfe, 0xcf, 0xf0, 0xfe, 0x1a, + 0x0b, 0x13, 0x89, 0xd3, 0xfe, 0xcc, 0xf0, 0xfe, 0x2a, 0x0b, 0xfe, 0x84, 0x80, 0xd7, 0x1a, 0x4b, + 0x13, 0xfe, 0x12, 0x00, 0x2b, 0x08, 0x80, 0x2e, 0xfe, 0x30, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x44, + 0x0b, 0x9b, 0x18, 0x32, 0x2b, 0x52, 0xfe, 0xed, 0x10, 0xa7, 0x28, 0xa9, 0x28, 0x2b, 0xf5, 0x2e, + 0xfe, 0x50, 0x0b, 0x22, 0x32, 0x81, 0xfe, 0x6c, 0x0b, 0x6b, 0x92, 0xa7, 0xfe, 0xec, 0x07, 0xa9, + 0xfe, 0xec, 0x07, 0x02, 0x28, 0x01, 0x4c, 0xfe, 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xe3, 0xe4, + 0x8c, 0x82, 0x6e, 0xfe, 0x89, 0xf0, 0x28, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0x01, 0x0b, 0x82, 0x6e, + 0x1f, 0x28, 0x23, 0x24, 0x91, 0x34, 0xfe, 0xa8, 0x0b, 0x22, 0x32, 0x02, 0xfe, 0x9c, 0x0b, 0x9b, + 0x40, 0x13, 0xfe, 0x42, 0x00, 0x02, 0x62, 0xa0, 0x06, 0xfe, 0x81, 0x49, 0x96, 0x0a, 0x07, 0x0c, + 0xfe, 0x5a, 0x13, 0x13, 0x00, 0x59, 0x0c, 0xfe, 0x6a, 0x12, 0x59, 0xfe, 0x28, 0x00, 0x27, 0xfe, + 0xee, 0x0c, 0x0e, 0x79, 0x01, 0x15, 0x05, 0x00, 0x84, 0x36, 0xfe, 0x28, 0x00, 0x02, 0xfe, 0xee, + 0x0c, 0x01, 0x97, 0x01, 0x9a, 0x0e, 0xc0, 0x01, 0xfe, 0x44, 0x0e, 0xb2, 0x08, 0x3d, 0x09, 0x99, + 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b, 0x02, 0x26, 0x13, 0xfe, 0x44, 0x00, + 0x59, 0x0c, 0xa5, 0x36, 0x0c, 0xfe, 0xc0, 0x10, 0x01, 0x96, 0x36, 0x0c, 0xfe, 0xb6, 0x10, 0x01, + 0x96, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xfe, 0x0a, 0x13, 0x36, 0x0c, 0x13, 0xfe, 0x43, 0x00, + 0xfe, 0xa2, 0x10, 0x0a, 0x41, 0x0c, 0x38, 0x01, 0x97, 0x01, 0x9a, 0xb2, 0x08, 0x3d, 0x09, 0x99, + 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01, 0x7b, 0x51, 0x0c, 0xb2, 0x1d, 0xca, 0x02, + 0xfe, 0x48, 0x03, 0x0a, 0x07, 0x0c, 0xce, 0x36, 0x0c, 0x13, 0x00, 0xfe, 0x54, 0x10, 0x68, 0x07, + 0x1e, 0xfe, 0x50, 0x12, 0x0a, 0x07, 0x1e, 0xfe, 0x48, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, + 0xfe, 0xac, 0x0c, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0xb2, 0x0c, 0x0a, 0x41, 0x1e, 0x38, + 0xfe, 0x95, 0x10, 0x13, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0c, 0x77, 0xfe, 0x26, 0x10, 0x13, + 0xfe, 0x13, 0x00, 0xd3, 0x13, 0xfe, 0x47, 0x00, 0xa6, 0x13, 0xfe, 0x41, 0x00, 0x9e, 0x13, 0xfe, + 0x24, 0x00, 0x04, 0x78, 0x29, 0x27, 0xee, 0x77, 0xfe, 0x04, 0xe6, 0x1e, 0xfe, 0x9d, 0x41, 0xfe, + 0x1c, 0x42, 0xb2, 0x01, 0xea, 0x02, 0x26, 0xd5, 0x17, 0x0c, 0x4a, 0xf4, 0xdd, 0x17, 0xfe, 0x31, + 0x00, 0x4a, 0xbd, 0x01, 0xfe, 0x50, 0x0f, 0x02, 0xfe, 0xc2, 0x01, 0x1d, 0xfe, 0x06, 0xec, 0xf8, + 0x86, 0x36, 0x37, 0xbf, 0x35, 0x1d, 0xfe, 0x06, 0xea, 0xf8, 0xfe, 0x47, 0x4b, 0x95, 0xfe, 0x75, + 0x57, 0x04, 0x56, 0xfe, 0x98, 0x56, 0xfe, 0x28, 0x12, 0x0e, 0x79, 0xfe, 0xf4, 0x14, 0x4e, 0xe6, + 0x0e, 0xc0, 0xfe, 0xea, 0x14, 0xfe, 0x49, 0x54, 0x8f, 0xfe, 0x62, 0x0d, 0x0e, 0x1c, 0xfe, 0xde, + 0x14, 0xfe, 0x44, 0x48, 0x02, 0xfe, 0x48, 0x03, 0x0e, 0x56, 0xfe, 0xc8, 0x14, 0x86, 0x36, 0x37, + 0xbf, 0x35, 0x1d, 0xfe, 0xce, 0x47, 0xfe, 0xbd, 0x13, 0x02, 0x26, 0x21, 0x2a, 0x05, 0x10, 0xfe, + 0x78, 0x12, 0x2d, 0x16, 0x55, 0x16, 0xad, 0x21, 0x47, 0x4e, 0x4a, 0x47, 0x9b, 0xfe, 0x0c, 0x13, + 0xfe, 0xbc, 0xf0, 0xfe, 0xfe, 0x0d, 0x08, 0x06, 0x16, 0x55, 0x01, 0xfe, 0x06, 0x16, 0x04, 0xfe, + 0x38, 0x01, 0x30, 0xfe, 0x3a, 0x01, 0x75, 0xfe, 0x02, 0x0e, 0x04, 0xfe, 0x38, 0x01, 0x1b, 0xfe, + 0xf0, 0xff, 0x0f, 0xfe, 0x60, 0x01, 0x04, 0xfe, 0x3a, 0x01, 0x0f, 0xfe, 0x62, 0x01, 0x20, 0x06, + 0x16, 0x47, 0xfe, 0x04, 0xec, 0x2a, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01, 0x46, 0x7f, 0xfe, 0x05, + 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x76, 0x16, 0x11, 0x47, 0xca, 0x08, 0x06, 0x03, 0x2d, 0x03, + 0x21, 0x55, 0xfe, 0xf7, 0x12, 0x21, 0xad, 0x6a, 0x16, 0xad, 0x05, 0x80, 0xfe, 0x93, 0x13, 0xfe, + 0x24, 0x1c, 0x17, 0x19, 0x4a, 0xf4, 0xdd, 0xfe, 0xd9, 0x10, 0x93, 0xfe, 0x03, 0xdc, 0xfe, 0x73, + 0x57, 0xfe, 0x80, 0x5d, 0x03, 0x93, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, + 0xfe, 0x03, 0x57, 0x93, 0x2d, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0x93, 0x7d, 0x03, 0x01, + 0xfe, 0xae, 0x16, 0x3f, 0x05, 0x47, 0xfe, 0x0a, 0x13, 0x08, 0x1c, 0x09, 0x43, 0xd3, 0x01, 0x97, + 0x01, 0x9a, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x46, 0x11, 0xfe, 0xe9, 0x00, 0x0a, 0x07, 0x89, 0xfe, + 0x52, 0x13, 0x01, 0xfe, 0x38, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0x0f, 0xfe, 0x64, 0x01, + 0xfe, 0x16, 0x90, 0x0f, 0xfe, 0x66, 0x01, 0x0a, 0x07, 0x45, 0xe5, 0xfe, 0x03, 0x80, 0x52, 0x3e, + 0x11, 0x76, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x90, 0x01, 0x71, 0xfe, 0x62, 0x08, 0x6a, 0x3e, 0x11, + 0x76, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x90, 0x01, 0x71, 0x64, 0x2f, 0x11, 0x76, 0x08, 0x2a, 0x09, + 0x3c, 0x1d, 0x90, 0x01, 0x7b, 0x03, 0xfe, 0x08, 0x1c, 0x04, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, + 0x04, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x04, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x04, 0xfe, + 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x20, 0x6c, 0x16, 0xf8, 0x2d, 0x0f, 0x53, 0x0f, + 0x4d, 0x20, 0x10, 0x16, 0x2a, 0x16, 0x3c, 0x57, 0xa0, 0xd6, 0x08, 0x2a, 0x09, 0x3c, 0x1d, 0x01, + 0x7b, 0x7f, 0x11, 0x76, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x2a, 0x0f, 0xd5, 0x8c, 0xfe, + 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x1d, 0xfe, 0x0c, 0x14, 0x86, 0xfe, 0x07, + 0xe6, 0x37, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x96, 0x0e, 0x3d, 0x01, 0x15, 0x05, + 0x10, 0x2c, 0x0e, 0x1c, 0x01, 0x15, 0x05, 0x10, 0xda, 0xfe, 0x44, 0x58, 0x3e, 0xfe, 0x01, 0xec, + 0xbd, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1e, 0x9f, 0x2f, 0x01, 0xea, + 0xfe, 0xc9, 0x10, 0x03, 0x2b, 0x82, 0x6e, 0x23, 0x24, 0xb3, 0x05, 0x1e, 0xfe, 0x48, 0x12, 0x05, + 0x0c, 0xfe, 0x4c, 0x12, 0x05, 0x19, 0xfe, 0x30, 0x12, 0x05, 0xcc, 0x18, 0xfe, 0xf4, 0x10, 0x05, + 0xfe, 0x23, 0x00, 0x18, 0xfe, 0x00, 0x11, 0x05, 0x06, 0x18, 0xfe, 0x5e, 0x11, 0x05, 0x1a, 0xfe, + 0x12, 0x12, 0x05, 0x00, 0x18, 0x28, 0x17, 0xcc, 0x01, 0x44, 0xc6, 0x39, 0x01, 0x0b, 0x81, 0x4c, + 0x03, 0x39, 0x11, 0xfe, 0xcc, 0x00, 0x02, 0x26, 0x39, 0x3f, 0x05, 0xc3, 0xfe, 0xe3, 0x13, 0x65, + 0x3a, 0x31, 0x3b, 0x75, 0xfe, 0xb2, 0x10, 0x0a, 0x07, 0x70, 0xfe, 0x72, 0x12, 0xa1, 0x42, 0x69, + 0x58, 0xe8, 0xfe, 0xe5, 0x55, 0x8f, 0xfe, 0x7c, 0x10, 0x21, 0x61, 0xfe, 0x26, 0x13, 0x04, 0xae, + 0x30, 0x8d, 0x75, 0xfe, 0xd2, 0x0c, 0x0f, 0x5d, 0x12, 0x5e, 0x2d, 0x0f, 0xae, 0x0f, 0x8d, 0x01, + 0xc1, 0x20, 0x6c, 0x52, 0x16, 0x61, 0x01, 0xfe, 0xde, 0x12, 0xa1, 0x42, 0x69, 0x58, 0xfe, 0x04, + 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x42, 0xfe, 0x05, 0xfa, 0x58, 0xfe, 0x91, 0x10, 0x04, + 0x5f, 0x30, 0x60, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0f, 0x5f, 0x12, 0x60, 0xa8, 0xa1, 0x42, + 0x69, 0x58, 0xe8, 0xfe, 0xe5, 0x55, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, + 0x0f, 0x5b, 0x12, 0x5c, 0x0a, 0x07, 0x70, 0xfe, 0x1e, 0x12, 0x21, 0x61, 0xfe, 0x1f, 0x40, 0x04, + 0x5d, 0x30, 0x5e, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x04, 0x5f, 0x30, 0x60, 0xfe, 0x34, 0x50, + 0xfe, 0xb6, 0x50, 0x04, 0x5b, 0x30, 0x5c, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x04, 0x3a, 0x30, + 0x3b, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0x02, 0x98, 0x20, 0x06, 0x16, 0xf3, 0x02, 0x7c, 0x39, + 0x01, 0x0b, 0x1f, 0x4f, 0x23, 0x24, 0xb3, 0x05, 0x06, 0x27, 0x4f, 0x3f, 0x05, 0xc3, 0x27, 0x7c, + 0x01, 0xfa, 0x1b, 0x50, 0x18, 0x4f, 0x0a, 0x07, 0x0c, 0xdc, 0x65, 0x3a, 0x31, 0x3b, 0xfe, 0x0a, + 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x9c, 0x3a, 0x9d, 0x3b, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, + 0x7c, 0xfe, 0x19, 0x81, 0xfe, 0x0a, 0x45, 0xfe, 0x19, 0x41, 0x02, 0x7c, 0x39, 0x01, 0x0b, 0x1f, + 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0x59, 0x19, 0xfe, 0x94, 0x12, 0x59, 0x0c, 0x4b, + 0x02, 0x4f, 0x2e, 0xfe, 0x7e, 0x11, 0x22, 0x32, 0x1f, 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0x91, 0x05, + 0x19, 0x27, 0x4f, 0x01, 0x0b, 0x1f, 0xfe, 0xf6, 0x0f, 0x23, 0x24, 0xfe, 0xe8, 0x09, 0x57, 0x04, + 0xfe, 0x9c, 0x00, 0x29, 0x35, 0xfe, 0xbb, 0x45, 0x59, 0x00, 0x40, 0x36, 0x06, 0xa0, 0x50, 0xfe, + 0xc0, 0x14, 0xfe, 0xf8, 0x14, 0xac, 0x3f, 0x05, 0xc2, 0xfe, 0x16, 0x13, 0x04, 0xf6, 0x29, 0xce, + 0x04, 0x4d, 0x29, 0x35, 0x5a, 0x02, 0x7c, 0xfe, 0xc0, 0x5d, 0xfe, 0xe4, 0x14, 0xfe, 0x03, 0x17, + 0x04, 0x53, 0xbc, 0x0f, 0x53, 0x5a, 0x39, 0x01, 0x0b, 0x25, 0x98, 0x01, 0xfe, 0x26, 0x14, 0x02, + 0x98, 0x2e, 0x40, 0x22, 0x32, 0x1f, 0x4f, 0x23, 0x24, 0x91, 0x05, 0x06, 0x27, 0x4f, 0xfe, 0xf6, + 0x14, 0xfe, 0x42, 0x58, 0xfe, 0x70, 0x14, 0xfe, 0x92, 0x14, 0xac, 0xfe, 0x4a, 0xf4, 0x0c, 0x18, + 0x4f, 0xfe, 0x4a, 0xf4, 0x06, 0xd1, 0x3f, 0x05, 0xc2, 0xc9, 0x02, 0x7c, 0x04, 0x4d, 0xbc, 0x0f, + 0x4d, 0x5a, 0x39, 0x01, 0x0b, 0x25, 0x98, 0x01, 0xfe, 0x54, 0x14, 0x02, 0x98, 0x25, 0xfe, 0x70, + 0x12, 0x73, 0xf1, 0x73, 0x03, 0x34, 0xfe, 0x6c, 0x12, 0x6b, 0xfe, 0x6c, 0x12, 0x5a, 0x39, 0x01, + 0x0b, 0xfe, 0xe3, 0x10, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b, 0xfe, 0xff, 0x7f, + 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0x1b, + 0x50, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, + 0x03, 0x08, 0x63, 0xff, 0x02, 0x00, 0x57, 0x66, 0x7e, 0xfe, 0x0b, 0x58, 0x03, 0x0e, 0x53, 0x01, + 0x8b, 0x0e, 0x4d, 0x01, 0x8b, 0x03, 0xc8, 0x1b, 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, + 0x1a, 0x66, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x64, 0x2f, + 0x0f, 0x5b, 0x12, 0x5c, 0x9c, 0x5f, 0x9d, 0x60, 0x03, 0xfe, 0x62, 0x18, 0xfe, 0x82, 0x5a, 0xfe, + 0xe1, 0x1a, 0xb6, 0xfe, 0x02, 0x58, 0x03, 0x01, 0xfe, 0x9e, 0x18, 0xfe, 0x42, 0x48, 0x77, 0x57, + 0x95, 0x01, 0x0b, 0x1f, 0xfe, 0x1e, 0x14, 0x23, 0x24, 0xfe, 0xe9, 0x09, 0xfe, 0xc1, 0x59, 0x01, + 0x0b, 0x1f, 0xfe, 0x1e, 0x14, 0x23, 0x24, 0xfe, 0xe8, 0x0a, 0x04, 0xf6, 0x29, 0xfe, 0xc4, 0x12, + 0x2d, 0xb1, 0x1e, 0xdc, 0x59, 0xcd, 0x74, 0xfe, 0x6c, 0x13, 0x4b, 0x08, 0x06, 0x09, 0xcd, 0xa0, + 0xfe, 0x00, 0x10, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa6, 0xff, 0x02, 0x83, 0x55, 0xb1, + 0x19, 0xfe, 0x12, 0x13, 0x72, 0xfe, 0x30, 0x00, 0x8f, 0xfe, 0xc6, 0x13, 0x09, 0x85, 0x08, 0x06, + 0xfe, 0x56, 0x10, 0xb1, 0x0c, 0xfe, 0x16, 0x13, 0x72, 0xfe, 0x64, 0x00, 0x8f, 0xfe, 0xc6, 0x13, + 0x0e, 0xfe, 0x64, 0x00, 0x09, 0x88, 0x08, 0x06, 0xfe, 0x28, 0x10, 0xb1, 0x06, 0xfe, 0x60, 0x13, + 0x72, 0xfe, 0xc8, 0x00, 0x8f, 0xfe, 0xc6, 0x13, 0x0e, 0xfe, 0xc8, 0x00, 0x09, 0x55, 0x08, 0x06, + 0xa8, 0x72, 0xfe, 0x90, 0x01, 0xed, 0xfe, 0xd2, 0x13, 0x95, 0xaa, 0xfe, 0x43, 0xf4, 0xad, 0xfe, + 0x56, 0xf0, 0xfe, 0xe4, 0x13, 0xfe, 0x04, 0xf4, 0x63, 0xfe, 0x43, 0xf4, 0x88, 0xfe, 0xf3, 0x10, + 0xb0, 0x01, 0xfe, 0xae, 0x12, 0x1b, 0x50, 0xd4, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6c, 0xed, + 0xfe, 0x18, 0x14, 0xa3, 0x6c, 0xfe, 0x14, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x1a, 0xed, + 0xfe, 0x18, 0x14, 0xa3, 0x1a, 0x9e, 0x57, 0x95, 0x08, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, + 0x03, 0x57, 0x08, 0x0c, 0x03, 0x14, 0x06, 0x01, 0x0b, 0x25, 0xec, 0x14, 0x0c, 0x01, 0x0b, 0x25, + 0xec, 0x14, 0x19, 0x01, 0x0b, 0x25, 0xec, 0x73, 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x03, 0x14, 0x06, + 0x01, 0x0b, 0x25, 0xb7, 0x14, 0x19, 0x01, 0x0b, 0x25, 0xb7, 0x14, 0x06, 0x01, 0x0b, 0x25, 0xb7, + 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x25, 0xb7, 0x73, 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x03, 0x57, 0x03, + 0x21, 0xe0, 0x05, 0x06, 0xfe, 0x44, 0x13, 0xaf, 0x16, 0xe0, 0xfe, 0x49, 0xf4, 0x00, 0x4b, 0x73, + 0xc6, 0x5a, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x0b, 0x3f, 0x05, 0xfe, 0xe3, 0x00, + 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0xd6, 0x14, 0x2d, 0x16, 0xf3, 0x01, 0x4c, 0x21, 0xf3, 0x05, 0x06, + 0x40, 0x0a, 0x41, 0x06, 0x38, 0x03, 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0x43, 0x58, 0x01, 0x15, 0x05, + 0x10, 0xfe, 0x1e, 0x12, 0x48, 0xe7, 0x8e, 0x01, 0x2c, 0xfe, 0x90, 0x4d, 0xde, 0x10, 0xfe, 0xc5, + 0x59, 0x01, 0x2c, 0xfe, 0x8d, 0x56, 0xb6, 0x48, 0x03, 0x48, 0x31, 0x8a, 0x01, 0x15, 0x48, 0x8e, + 0x01, 0x2c, 0xe2, 0x10, 0xde, 0x10, 0x31, 0x54, 0x72, 0x1c, 0x84, 0x0e, 0x56, 0x01, 0xab, 0x03, + 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0xc3, 0x58, 0x01, 0x15, 0x05, 0x10, 0xfe, 0x1a, 0x12, 0x48, 0xe7, + 0x8e, 0x01, 0x2c, 0xe2, 0x10, 0xfe, 0x80, 0x4d, 0xfe, 0xc5, 0x59, 0x01, 0x2c, 0x48, 0x03, 0x48, + 0x31, 0x54, 0x01, 0x15, 0x48, 0x8e, 0x01, 0x2c, 0xe2, 0x10, 0xde, 0x10, 0x31, 0x54, 0x72, 0x1c, + 0x84, 0x0e, 0x56, 0x01, 0xab, 0x03, 0x0f, 0x54, 0x12, 0x8a, 0xfe, 0x43, 0x58, 0x01, 0x15, 0xfe, + 0x42, 0x48, 0x8e, 0x01, 0x2c, 0xfe, 0xc0, 0x5a, 0xb0, 0xfe, 0x00, 0xcd, 0xfe, 0x01, 0xcc, 0xfe, + 0x4a, 0x46, 0xdc, 0x93, 0x7d, 0x05, 0x10, 0xfe, 0x2e, 0x13, 0x69, 0x54, 0xfe, 0x4d, 0xf4, 0x1c, + 0xfe, 0x1c, 0x13, 0x0e, 0x56, 0x01, 0x8b, 0xaa, 0xfe, 0x40, 0x4c, 0xfe, 0xc5, 0x58, 0x01, 0x2c, + 0xfe, 0x00, 0x07, 0x7d, 0x05, 0x10, 0x84, 0x69, 0x8a, 0xfe, 0x05, 0x57, 0xfe, 0x08, 0x10, 0xfe, + 0x45, 0x58, 0x01, 0x2c, 0xfe, 0x8d, 0x56, 0xb6, 0xfe, 0x80, 0x4c, 0xfe, 0x05, 0x17, 0x03, 0x09, + 0x10, 0x6f, 0x67, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xdb, + 0x37, 0x94, 0xfe, 0x1a, 0x16, 0x01, 0xfe, 0x28, 0x17, 0xfe, 0x0c, 0x13, 0x87, 0x37, 0x67, 0xfe, + 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xba, 0x27, 0xfe, 0x0a, 0x16, 0xfe, 0xe2, 0x10, 0x09, 0x10, + 0x6f, 0x04, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1a, 0xfe, 0x18, 0x58, 0x04, 0xfe, 0x66, 0x01, + 0xfe, 0x19, 0x58, 0x87, 0x1a, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x67, + 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1a, 0x94, 0xfe, 0x64, 0x16, 0xfe, 0xbe, + 0x14, 0x35, 0x03, 0xba, 0x27, 0xfe, 0x3c, 0x16, 0xfe, 0xa4, 0x10, 0x09, 0x10, 0x6f, 0xb6, 0xfe, + 0x18, 0xdf, 0xfe, 0x19, 0xdf, 0xdb, 0x42, 0x94, 0xfe, 0x86, 0x16, 0xfe, 0x9c, 0x14, 0xfe, 0x18, + 0x13, 0x87, 0x42, 0x67, 0x1e, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0xa2, 0x07, 0xfe, 0x7f, + 0x00, 0xfe, 0x05, 0x40, 0x03, 0xba, 0x27, 0xfe, 0x7a, 0x16, 0xfe, 0x6c, 0x10, 0x09, 0x10, 0x6f, + 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x87, 0xd9, 0x67, 0x1e, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, + 0xd9, 0x94, 0xfe, 0xc6, 0x16, 0xfe, 0x5c, 0x14, 0x35, 0x03, 0xba, 0x27, 0xfe, 0xb2, 0x16, 0xfe, + 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x10, 0x6f, 0xfe, 0x18, 0xfe, 0x5d, 0xfe, 0x19, 0xfe, 0x5e, 0xc8, + 0xdb, 0x45, 0x94, 0xfe, 0xec, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x87, 0x45, 0x4e, 0xfe, + 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, + 0x00, 0x64, 0x2f, 0x03, 0x64, 0x2f, 0xfe, 0x12, 0x45, 0x27, 0xfe, 0xdc, 0x16, 0x17, 0x06, 0x4a, + 0xf4, 0xdd, 0x02, 0x26, 0xfe, 0x39, 0xf0, 0xfe, 0x30, 0x17, 0x2d, 0x03, 0xfe, 0x7e, 0x18, 0x1b, + 0x19, 0x83, 0x08, 0x0d, 0x03, 0x6f, 0x04, 0xdf, 0x1b, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, + 0x1d, 0x0e, 0x1c, 0x01, 0x15, 0x05, 0x10, 0x40, 0x3e, 0xfe, 0x78, 0x14, 0xfe, 0x34, 0x12, 0x50, + 0x86, 0x36, 0x37, 0xbf, 0xfe, 0xe9, 0x13, 0x1d, 0x0e, 0x3d, 0x01, 0x15, 0x05, 0x10, 0x40, 0x3e, + 0xfe, 0x56, 0x14, 0xe1, 0x50, 0x86, 0x36, 0x37, 0xbf, 0xfe, 0xe9, 0x13, 0x09, 0x0c, 0x03, 0xfe, + 0x9c, 0xe7, 0x0c, 0x13, 0xfe, 0x15, 0x00, 0x90, 0x9f, 0x2f, 0x01, 0xea, 0x09, 0x06, 0x03, 0x0a, + 0x41, 0x37, 0x38, 0x08, 0x3d, 0x09, 0x99, 0x01, 0x46, 0x11, 0x47, 0x08, 0x1c, 0x09, 0x43, 0x01, + 0x7b, 0x09, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x65, 0xf7, 0x31, 0x76, 0xfe, 0x48, + 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x03, 0x21, 0xbe, 0x52, 0x16, 0xbe, 0x03, 0x0e, 0xc0, 0x01, 0x15, + 0xe6, 0x0e, 0x79, 0x01, 0x15, 0xfe, 0x49, 0x44, 0x27, 0xfe, 0x26, 0x18, 0x0e, 0x1c, 0x01, 0x15, + 0x05, 0x10, 0x40, 0x0e, 0x56, 0x01, 0xab, 0x0e, 0x79, 0x01, 0x15, 0x52, 0x7d, 0x03, 0xfe, 0x40, + 0x5e, 0xfe, 0xe2, 0x08, 0xfe, 0xc0, 0x4c, 0x21, 0x3c, 0x05, 0x10, 0xfe, 0x52, 0x12, 0x3e, 0x05, + 0x00, 0xfe, 0x18, 0x12, 0xfe, 0xe1, 0x18, 0xfe, 0x19, 0xf4, 0xfe, 0x7f, 0x00, 0xd4, 0xfe, 0xe2, + 0x08, 0x52, 0x3e, 0x3f, 0x05, 0x76, 0xa5, 0xfe, 0x82, 0x48, 0xfe, 0x01, 0x80, 0xfe, 0xd7, 0x10, + 0xfe, 0xc4, 0x48, 0x08, 0x2a, 0x09, 0x3c, 0xfe, 0x40, 0x5f, 0x1d, 0x01, 0x46, 0x11, 0xfe, 0xdd, + 0x00, 0xfe, 0x14, 0x46, 0x08, 0x2a, 0x09, 0x3c, 0x01, 0x46, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x40, + 0x4a, 0x6a, 0xfe, 0x06, 0x17, 0xfe, 0x01, 0x07, 0xfe, 0x82, 0x48, 0xfe, 0x04, 0x17, 0x03, 0xeb, + 0x19, 0x74, 0xfe, 0xae, 0x18, 0x04, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xeb, + 0xcc, 0x74, 0xfe, 0xc0, 0x18, 0x04, 0xfe, 0x92, 0x00, 0xc7, 0x1e, 0xd8, 0xeb, 0xfe, 0x0b, 0x00, + 0x74, 0xfe, 0xd2, 0x18, 0x04, 0xfe, 0x94, 0x00, 0xc7, 0x1a, 0xfe, 0x08, 0x10, 0x04, 0xfe, 0x96, + 0x00, 0xc7, 0x85, 0xfe, 0x4e, 0x45, 0xd1, 0xfe, 0x0a, 0x45, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, + 0x10, 0x1b, 0x6c, 0x03, 0x05, 0x80, 0xfe, 0x5a, 0xf0, 0xfe, 0xfe, 0x18, 0x20, 0xfe, 0x09, 0x00, + 0xfe, 0x34, 0x10, 0x05, 0x1e, 0xfe, 0x5a, 0xf0, 0xfe, 0x0c, 0x19, 0x20, 0xcd, 0xfe, 0x26, 0x10, + 0x05, 0x19, 0x83, 0x20, 0x85, 0xd8, 0x05, 0x0c, 0x83, 0x20, 0x88, 0xfe, 0x0e, 0x10, 0x05, 0x06, + 0x83, 0x20, 0x55, 0xc6, 0xaf, 0x03, 0x17, 0xfe, 0x09, 0x00, 0x01, 0x44, 0x2e, 0xfe, 0x3c, 0x19, + 0x04, 0x6e, 0xb0, 0x03, 0x22, 0xfe, 0x54, 0x19, 0xfe, 0x14, 0xf0, 0x0b, 0x2e, 0xfe, 0x50, 0x19, + 0x03, 0xff, 0x15, 0x00, 0x00, }; -u_int16_t adv_mcode_size = sizeof(adv_mcode); /* 0x11D6 */ +u_int16_t adv_asc3550_mcode_size = sizeof(adv_asc3550_mcode); /* 0x13E5 */ /* * This checksum is used to compare with that one that will be calculated * at run time. * This is performed to ensure the uCode is correctly loaded into the Lram. */ -u_int32_t adv_mcode_chksum = 0x03494981UL; +u_int32_t adv_asc3550_mcode_chksum = 0x04FFFF0E; + + + +u_int8_t adv_asc38C0800_mcode[] = { + 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x00, 0xfc, 0x48, 0xe4, 0x01, 0x00, 0x18, 0xe4, + 0x00, 0xf6, 0x01, 0xf6, 0x18, 0x80, 0x02, 0x00, 0x40, 0x1a, 0x00, 0xfa, 0xff, 0xff, 0x03, 0xf6, + 0xff, 0x00, 0x82, 0xe7, 0x01, 0xfa, 0x9e, 0xe7, 0x09, 0xe7, 0x1a, 0x0f, 0x00, 0xea, 0x01, 0xe6, + 0x03, 0x00, 0x55, 0xf0, 0x18, 0xf4, 0x1e, 0xf0, 0x3e, 0x57, 0x04, 0x00, 0x3e, 0x01, 0x85, 0xf0, + 0x00, 0xe6, 0x03, 0xfc, 0x08, 0x00, 0x2c, 0x1a, 0x32, 0xf0, 0x86, 0xf0, 0xbe, 0x0d, 0xd4, 0x01, + 0xd5, 0xf0, 0x00, 0xec, 0x01, 0xfc, 0x38, 0x54, 0x98, 0x57, 0xbc, 0x00, 0x0c, 0x1c, 0xb1, 0xf0, + 0x3c, 0x00, 0xb4, 0x00, 0xb8, 0x0d, 0x00, 0x57, 0x01, 0xf0, 0x02, 0x13, 0x02, 0xfc, 0x03, 0xe6, + 0x10, 0x00, 0x18, 0x40, 0x3e, 0x1c, 0x44, 0x13, 0x6c, 0x01, 0x6e, 0x01, 0xbd, 0x00, 0xe0, 0x00, + 0x02, 0x80, 0x30, 0xe4, 0x3e, 0x00, 0x74, 0x01, 0x76, 0x01, 0x7c, 0x16, 0x80, 0x00, 0xb9, 0x54, + 0xbb, 0x00, 0xee, 0x13, 0x00, 0x4e, 0x01, 0x01, 0x01, 0xea, 0x02, 0x48, 0x02, 0xfa, 0x04, 0x12, + 0x08, 0x12, 0x3c, 0x56, 0x4e, 0x01, 0x5d, 0xf0, 0x7a, 0x01, 0x7e, 0x10, 0xb6, 0x00, 0xc2, 0x10, + 0xee, 0x08, 0x00, 0x80, 0x05, 0xfc, 0x10, 0x44, 0x24, 0x01, 0x28, 0x01, 0x32, 0x00, 0x3c, 0x01, + 0x40, 0x00, 0x4b, 0xe4, 0x4b, 0xf4, 0x4c, 0x1c, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, + 0x78, 0x01, 0x7c, 0x01, 0xbb, 0x55, 0xc2, 0x0d, 0x00, 0x01, 0x02, 0xee, 0x03, 0x58, 0x03, 0xf7, + 0x03, 0xfa, 0x04, 0x80, 0x08, 0x44, 0x09, 0xf0, 0x0f, 0x00, 0x1b, 0x80, 0x20, 0x01, 0x38, 0x1c, + 0x4e, 0x1c, 0x5b, 0xf0, 0x62, 0x0a, 0xaa, 0x00, 0xbe, 0x00, 0xc0, 0x00, 0xc0, 0x15, 0xcc, 0x10, + 0x00, 0x4c, 0x00, 0xdc, 0x02, 0x4a, 0x04, 0xfc, 0x05, 0x00, 0x05, 0xf0, 0x05, 0xf8, 0x06, 0x13, + 0x06, 0xf7, 0x08, 0x13, 0x0a, 0x10, 0x0c, 0x00, 0x0e, 0x47, 0x0e, 0xf7, 0x10, 0x0f, 0x20, 0x00, + 0x20, 0x16, 0x2a, 0x01, 0x32, 0x1c, 0x36, 0x00, 0x42, 0x54, 0x44, 0x55, 0x45, 0x5a, 0x52, 0x0c, + 0x59, 0xf0, 0x5c, 0xf0, 0x69, 0x08, 0x6e, 0x0b, 0x83, 0x59, 0xb8, 0xf0, 0xbd, 0x56, 0xcc, 0x18, + 0xce, 0x10, 0xd8, 0x18, 0xf0, 0x00, 0x01, 0x48, 0x04, 0x10, 0x04, 0xea, 0x04, 0xf6, 0x05, 0x80, + 0x05, 0xe6, 0x06, 0x00, 0x06, 0x0f, 0x06, 0x12, 0x0b, 0xf0, 0x0c, 0x10, 0x0c, 0xf0, 0x10, 0x13, + 0x12, 0x10, 0x19, 0x00, 0x19, 0xe4, 0x30, 0x1c, 0x33, 0x00, 0x34, 0x00, 0x38, 0x44, 0x40, 0x5c, + 0x4a, 0xe4, 0x62, 0x1a, 0x68, 0x08, 0x68, 0x54, 0x6c, 0x15, 0x70, 0x15, 0x83, 0x55, 0x83, 0x5a, + 0x91, 0x44, 0xa4, 0x00, 0xac, 0x13, 0xb0, 0x57, 0xb5, 0x00, 0xb8, 0x17, 0xba, 0x00, 0xce, 0x45, + 0xd0, 0x00, 0xe1, 0x00, 0xe5, 0x55, 0xe7, 0x00, 0x00, 0x54, 0x01, 0x58, 0x02, 0x10, 0x02, 0xe6, + 0x03, 0xa1, 0x04, 0x13, 0x06, 0x83, 0x06, 0xf0, 0x07, 0x00, 0x0a, 0x00, 0x0a, 0x12, 0x0a, 0xf0, + 0x0c, 0x12, 0x0c, 0x13, 0x0c, 0x90, 0x0e, 0x13, 0x10, 0x04, 0x10, 0x10, 0x12, 0x1c, 0x19, 0x81, + 0x1a, 0x10, 0x1c, 0x00, 0x1c, 0x12, 0x1d, 0xf7, 0x1e, 0x13, 0x20, 0x1c, 0x20, 0xe7, 0x22, 0x01, + 0x26, 0x01, 0x2a, 0x12, 0x2c, 0x0f, 0x30, 0xe7, 0x32, 0x15, 0x34, 0x1c, 0x36, 0x1c, 0x38, 0x12, + 0x3a, 0x55, 0x3f, 0x00, 0x41, 0x58, 0x43, 0x48, 0x46, 0x1c, 0x4e, 0xe4, 0x76, 0x02, 0x77, 0x57, + 0x78, 0x03, 0x89, 0x48, 0x8e, 0x90, 0x98, 0x80, 0x99, 0x00, 0xfe, 0x9c, 0xf0, 0x27, 0x02, 0xfe, + 0xe0, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xfe, 0xc6, 0x01, 0xfe, 0x56, 0x1a, 0x00, 0xfe, 0xc4, 0x01, + 0xfe, 0x84, 0x01, 0xff, 0x03, 0x00, 0x00, 0xfe, 0x6a, 0x13, 0xfe, 0x05, 0x05, 0xff, 0x40, 0x00, + 0x00, 0x0e, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x10, 0xff, 0xff, 0xff, 0x1f, + 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11, 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, + 0xff, 0x21, 0x00, 0x00, 0xfe, 0x04, 0xf7, 0xfe, 0xc4, 0x01, 0x2e, 0x88, 0x0b, 0x01, 0xfe, 0xca, + 0x0f, 0xfe, 0x04, 0xf7, 0xfe, 0xc4, 0x01, 0x88, 0x0b, 0x1c, 0x2e, 0xfe, 0x3d, 0xf0, 0xfe, 0xfc, + 0x01, 0xfe, 0x20, 0xf0, 0xdc, 0x04, 0x5f, 0x4f, 0x02, 0xfe, 0xfc, 0x0d, 0x01, 0xfe, 0x5c, 0x0e, + 0xfe, 0xe9, 0x12, 0x02, 0xfe, 0x08, 0x03, 0xfe, 0x28, 0x1c, 0x04, 0xfe, 0xa6, 0x00, 0xfe, 0xdd, + 0x12, 0x47, 0x12, 0xfe, 0xa6, 0x00, 0xcd, 0xfe, 0x48, 0xf0, 0xfe, 0x80, 0x02, 0xfe, 0x49, 0xf0, + 0xfe, 0x9a, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xb8, 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x4a, 0x02, 0xfe, + 0x47, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x3e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x42, + 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x46, 0x02, 0x09, 0x0b, 0xa4, 0x09, 0x06, 0x12, 0xc1, 0x02, 0x27, + 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, 0x1c, 0xfe, 0xed, 0x10, 0xfe, 0x1e, 0x1c, 0xfe, + 0xe9, 0x10, 0x01, 0xfe, 0x2c, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xfe, 0xa8, 0x00, 0x0f, + 0x7c, 0x01, 0xaa, 0x02, 0x27, 0x17, 0x5e, 0x4c, 0xc4, 0x01, 0xfe, 0x40, 0x10, 0x0f, 0x7c, 0x01, + 0x8e, 0xfe, 0xbd, 0x10, 0x0f, 0x7c, 0x01, 0x8e, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, 0x58, + 0x1c, 0x09, 0x06, 0x12, 0xc1, 0x2e, 0x1b, 0x27, 0xfe, 0x3d, 0xf0, 0xfe, 0xfc, 0x01, 0x28, 0xfe, + 0x8e, 0x02, 0xfe, 0x5a, 0x1c, 0xde, 0xfe, 0x14, 0x1c, 0x17, 0xfe, 0x30, 0x00, 0x4c, 0xc4, 0x01, + 0xfe, 0x30, 0x10, 0x09, 0x06, 0x12, 0xc1, 0x02, 0xfe, 0xc6, 0x01, 0x29, 0x2d, 0x05, 0x10, 0x35, + 0xfe, 0x69, 0x10, 0x09, 0x06, 0x12, 0xc1, 0xfe, 0x04, 0xec, 0x2d, 0x08, 0x2d, 0x09, 0x3e, 0x1c, + 0x01, 0x45, 0x82, 0xfe, 0x05, 0xf6, 0xfe, 0xa8, 0x00, 0x01, 0xfe, 0x56, 0x17, 0x0a, 0x41, 0x8f, + 0x39, 0x11, 0x48, 0x1c, 0xd2, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x90, 0x02, 0x27, 0x0f, 0x3f, 0x01, + 0x15, 0x05, 0x10, 0xdb, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0xfe, 0x28, 0x10, 0x0f, 0xc8, 0x01, + 0x15, 0xf2, 0x0f, 0x7d, 0x01, 0x15, 0xfe, 0x49, 0x54, 0x79, 0xfe, 0x16, 0x03, 0x08, 0x1e, 0x09, + 0x52, 0x01, 0x90, 0x02, 0x27, 0x2e, 0x82, 0xfe, 0x02, 0xe8, 0x31, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, + 0x43, 0xf7, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xdc, 0xfe, 0x40, 0x1c, 0x1b, 0xf8, 0xfe, 0x26, + 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x62, 0x03, 0xfe, 0x11, 0xf0, 0xdc, 0xfe, 0x0e, + 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x82, 0x03, 0xf4, 0x13, 0xfe, 0x11, 0x00, 0x02, 0x6b, 0x2e, 0xfe, + 0x48, 0x1c, 0xf4, 0x1b, 0xf8, 0x34, 0xf8, 0xfe, 0x82, 0xf0, 0xfe, 0x88, 0x03, 0x2b, 0x29, 0xc6, + 0x72, 0x16, 0xc6, 0x0f, 0x7d, 0x01, 0x15, 0x72, 0x80, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x45, 0x11, + 0x3f, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x90, 0xfe, 0x9c, 0x32, 0x11, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, + 0xce, 0x03, 0x1b, 0x32, 0x1f, 0xfe, 0xde, 0x03, 0x01, 0x55, 0xd3, 0xfe, 0xee, 0x03, 0x73, 0x97, + 0xd7, 0xfe, 0xae, 0x06, 0x02, 0x26, 0x04, 0x7c, 0x2c, 0x19, 0xfe, 0x20, 0x05, 0x17, 0x8b, 0x01, + 0x3b, 0x01, 0x9f, 0x01, 0xa1, 0x34, 0xfe, 0x60, 0x02, 0x02, 0xf6, 0xf4, 0x2e, 0x88, 0x18, 0xfe, + 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xf7, 0xfe, 0x48, 0x1c, 0x92, 0x01, 0xfe, 0x9c, 0x13, 0xb3, 0xfe, + 0x96, 0xf0, 0xfe, 0x28, 0x04, 0x2f, 0xfe, 0x2c, 0x04, 0x34, 0x27, 0x0f, 0x3f, 0x01, 0x15, 0x05, + 0x10, 0x19, 0xfe, 0x0c, 0x05, 0x4d, 0x7a, 0xa5, 0x31, 0x86, 0x76, 0x1b, 0x32, 0x1f, 0x26, 0x04, + 0x7c, 0x2c, 0xfe, 0x10, 0x12, 0x17, 0x8b, 0x01, 0x3b, 0x34, 0xfe, 0x60, 0x02, 0x02, 0xf6, 0x21, + 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x5e, 0x12, 0x0a, 0x07, 0x06, 0xfe, 0x56, 0x12, 0x24, + 0x23, 0x9a, 0x01, 0x0c, 0x86, 0x76, 0x1f, 0xfe, 0xdc, 0x04, 0x24, 0x23, 0x9a, 0x01, 0x0c, 0x1f, + 0x26, 0x24, 0x23, 0xba, 0xfe, 0x4c, 0x44, 0xfe, 0x32, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x08, 0xfe, + 0x93, 0x00, 0xfe, 0x4c, 0x54, 0x79, 0xfe, 0x0c, 0x05, 0x82, 0xa5, 0x31, 0xfe, 0x06, 0x80, 0xfe, + 0x48, 0x47, 0xfe, 0x48, 0x13, 0x40, 0x05, 0xfe, 0xcc, 0x00, 0xfe, 0x40, 0x13, 0x0a, 0x07, 0x06, + 0xef, 0xfe, 0x06, 0x10, 0x24, 0x23, 0xba, 0x0a, 0x07, 0x38, 0xe2, 0x17, 0xa9, 0x0a, 0x07, 0x06, + 0x4f, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x3b, 0x34, 0xfe, 0xa0, 0x0d, 0x02, 0x26, 0x3a, 0x11, 0xfe, + 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xb7, 0x03, 0x17, 0xa9, 0x01, 0x3b, 0x34, 0x27, 0x1b, 0x27, 0x02, + 0xfe, 0x14, 0x05, 0xfe, 0x42, 0x5b, 0x88, 0x18, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xf7, 0x17, + 0x46, 0xfe, 0x07, 0x80, 0xfe, 0x31, 0x44, 0x0a, 0x07, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, + 0x05, 0x18, 0xfe, 0x70, 0x12, 0x75, 0x07, 0x06, 0xfe, 0x60, 0x13, 0x04, 0xfe, 0xa2, 0x00, 0x2c, + 0x19, 0xfe, 0xac, 0x05, 0xfe, 0x31, 0xe4, 0x60, 0x75, 0x07, 0x0b, 0xfe, 0x4a, 0x13, 0x04, 0xfe, + 0xa0, 0x00, 0x2c, 0xfe, 0x42, 0x12, 0x63, 0x2f, 0xfe, 0x6c, 0x05, 0x1b, 0x32, 0xf9, 0x01, 0x0c, + 0x25, 0xfe, 0xc4, 0x05, 0x11, 0xfe, 0xe3, 0x00, 0x2b, 0x75, 0xfe, 0x4a, 0xf0, 0xfe, 0x96, 0x05, + 0xfe, 0x49, 0xf0, 0xfe, 0x90, 0x05, 0xad, 0x20, 0xfe, 0x21, 0x00, 0x8a, 0x20, 0xfe, 0x22, 0x00, + 0xa4, 0x20, 0x8f, 0xfe, 0x09, 0x48, 0x01, 0x0c, 0x25, 0xfe, 0xc4, 0x05, 0xfe, 0xe2, 0x08, 0x75, + 0x07, 0xe1, 0x4f, 0x01, 0xc2, 0x20, 0x06, 0x16, 0xe8, 0x4c, 0xfe, 0x27, 0x01, 0x0a, 0x07, 0x38, + 0xe9, 0x47, 0x01, 0xbd, 0x17, 0xa9, 0x0a, 0x07, 0x06, 0x4f, 0x17, 0xfe, 0x0d, 0x00, 0x01, 0x3b, + 0x01, 0x9f, 0x01, 0xa1, 0x34, 0xfe, 0xa0, 0x0d, 0x02, 0x26, 0x04, 0xfe, 0x9c, 0x00, 0x2c, 0xfe, + 0x3e, 0x12, 0x04, 0x5c, 0x2c, 0xfe, 0x36, 0x13, 0x47, 0x01, 0xbd, 0x25, 0xfe, 0x3c, 0x06, 0x0f, + 0x06, 0x75, 0x07, 0x22, 0xfe, 0x02, 0x12, 0x6a, 0x01, 0xfe, 0x06, 0x15, 0x1f, 0xfe, 0x32, 0x06, + 0x11, 0xc9, 0x01, 0x55, 0x11, 0xfe, 0xe5, 0x00, 0x04, 0x5c, 0xc3, 0x0d, 0x5c, 0x04, 0xfe, 0x9e, + 0x00, 0x2c, 0xfe, 0x62, 0x12, 0x04, 0x56, 0x2c, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x7e, 0x19, 0x01, + 0xfe, 0xe8, 0x19, 0xf3, 0xa8, 0xf1, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0x1a, 0x59, + 0xd1, 0xa8, 0x74, 0x47, 0x01, 0xbd, 0x25, 0xfe, 0xa6, 0x06, 0x75, 0x07, 0x1d, 0xab, 0x9e, 0x0f, + 0x5e, 0x01, 0xfe, 0x34, 0x15, 0x1f, 0xfe, 0x9c, 0x06, 0x11, 0xc9, 0x01, 0x55, 0x11, 0xfe, 0xe5, + 0x00, 0x04, 0x56, 0xc3, 0x0d, 0x56, 0x09, 0x06, 0x01, 0xbd, 0xfe, 0x9c, 0x32, 0x78, 0x92, 0x01, + 0xfe, 0x9c, 0x13, 0xb3, 0x11, 0xfe, 0xe2, 0x00, 0x2f, 0xfe, 0xbe, 0x06, 0x1b, 0x32, 0xd7, 0xfe, + 0xda, 0x06, 0x85, 0xfe, 0x78, 0x07, 0xd3, 0xfe, 0x80, 0x07, 0x73, 0x97, 0x02, 0x26, 0x0a, 0x07, + 0x0b, 0xfe, 0x2e, 0x12, 0x14, 0x18, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, + 0x14, 0x00, 0x01, 0x0c, 0xfe, 0x99, 0xa4, 0x01, 0x0c, 0x14, 0x00, 0x02, 0xfe, 0x50, 0x08, 0x71, + 0x07, 0x1d, 0xef, 0x0a, 0x07, 0x1d, 0xfe, 0x30, 0x13, 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x0c, 0x14, + 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x00, 0x01, 0x0c, 0x14, 0x06, 0x01, 0x0c, 0x14, + 0x00, 0x02, 0xfe, 0x0a, 0x0c, 0x6a, 0xfe, 0x9a, 0x81, 0x6f, 0x8f, 0xfe, 0x09, 0x6f, 0xfe, 0x93, + 0x45, 0x19, 0xfe, 0x88, 0x07, 0x2f, 0xfe, 0x60, 0x07, 0x1b, 0x32, 0xd7, 0xfe, 0x58, 0x07, 0x73, + 0x97, 0x85, 0xfe, 0x78, 0x07, 0x02, 0x26, 0x01, 0x55, 0x02, 0xfe, 0xbe, 0x06, 0x14, 0x22, 0x02, + 0xfe, 0xbe, 0x06, 0xfe, 0x9c, 0xf7, 0xfe, 0xf0, 0x07, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x53, + 0xfe, 0xd6, 0x07, 0x0d, 0x66, 0x12, 0x67, 0x0a, 0x41, 0x60, 0x39, 0x01, 0xfe, 0x14, 0x19, 0x05, + 0x10, 0x87, 0xfe, 0x83, 0xe7, 0xfe, 0x95, 0x00, 0x8a, 0xfe, 0x03, 0x40, 0x0a, 0x41, 0x46, 0x39, + 0x01, 0xc5, 0xb6, 0xfe, 0x1f, 0x40, 0x16, 0x68, 0x01, 0xfe, 0xbe, 0x13, 0xfe, 0x08, 0x50, 0xfe, + 0x8a, 0x50, 0xfe, 0x34, 0x51, 0xfe, 0xb6, 0x51, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0d, 0x64, + 0x12, 0x65, 0xda, 0xfa, 0x0d, 0x3c, 0x12, 0x3d, 0xfe, 0x60, 0x10, 0x0a, 0x07, 0x60, 0xe9, 0xfe, + 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0d, 0x66, 0x12, 0x67, 0x0a, 0x07, 0x46, 0xd1, 0x01, 0xc5, 0xfe, + 0x1f, 0x80, 0x16, 0x68, 0xfe, 0x34, 0x90, 0xfe, 0xb6, 0x90, 0x0d, 0x43, 0x12, 0x44, 0xfe, 0x08, + 0x90, 0xfe, 0x8a, 0x90, 0x0d, 0x64, 0x12, 0x65, 0xa7, 0x07, 0x46, 0xdb, 0xda, 0xfa, 0x0d, 0x3c, + 0x12, 0x3d, 0xad, 0xfe, 0x28, 0x90, 0xfe, 0xaa, 0x90, 0x0d, 0x3c, 0x12, 0x3d, 0x0d, 0x30, 0x12, + 0x42, 0x2b, 0x0d, 0x54, 0x0d, 0x69, 0x0a, 0x41, 0x22, 0x39, 0x2e, 0x08, 0x84, 0x2f, 0xfe, 0x70, + 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x84, 0x08, 0xa3, 0x19, 0x32, 0x2e, 0x5b, 0xfe, 0xed, 0x10, 0xac, + 0xfe, 0xa8, 0x08, 0xae, 0xfe, 0xc4, 0x08, 0x85, 0xfe, 0x9c, 0x08, 0xd3, 0xfe, 0xa2, 0x08, 0x73, + 0x97, 0x02, 0x26, 0x01, 0x55, 0xfe, 0xc9, 0x10, 0x14, 0x22, 0xfe, 0xc9, 0x10, 0x71, 0x07, 0x06, + 0xfe, 0x10, 0x12, 0x71, 0x07, 0x0b, 0x50, 0x0a, 0x07, 0x0b, 0xfe, 0xa6, 0x12, 0xfe, 0x2e, 0x1c, + 0xb0, 0x71, 0x07, 0x06, 0x50, 0x71, 0x07, 0x0b, 0xfe, 0x92, 0x12, 0xfe, 0x2c, 0x1c, 0xa7, 0x07, + 0x46, 0xaf, 0xa7, 0x41, 0x46, 0xfe, 0x05, 0x40, 0xda, 0xfa, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, + 0xfe, 0xaa, 0xf0, 0xfe, 0xf6, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x24, 0x09, 0x02, 0xfe, 0x02, 0x0a, + 0xfe, 0xb7, 0xf0, 0xfe, 0x20, 0x09, 0xfe, 0x02, 0xf6, 0x1d, 0x6a, 0xfe, 0x70, 0x18, 0xfe, 0xf1, + 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, + 0xfe, 0x95, 0x59, 0x1b, 0x9b, 0xfe, 0x8c, 0xf0, 0xfe, 0x20, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x14, + 0x09, 0xed, 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x30, 0x09, 0x02, 0xfe, 0x3c, 0x0b, 0xee, + 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x9b, 0xfe, 0x6b, 0x18, 0x1a, 0xfe, 0x00, 0xfe, 0xe2, 0xcd, + 0xfe, 0xd2, 0xf0, 0x9b, 0xfe, 0x76, 0x18, 0x1a, 0x18, 0x19, 0x9b, 0x04, 0xe7, 0x1a, 0x06, 0x19, + 0x9b, 0xac, 0x58, 0xae, 0x58, 0xed, 0xee, 0xfe, 0x89, 0x10, 0x92, 0x63, 0x3a, 0x17, 0xa9, 0x01, + 0x3b, 0x13, 0xfe, 0x35, 0x00, 0x34, 0x6b, 0x13, 0x93, 0x02, 0x6b, 0xfb, 0xb2, 0x0b, 0xfe, 0x1a, + 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xf0, 0xdf, 0xfe, 0x74, 0x18, + 0x94, 0x95, 0x19, 0xfe, 0xf2, 0x08, 0x02, 0x58, 0x0a, 0x07, 0x60, 0xaf, 0x04, 0x30, 0x2a, 0x42, + 0x0d, 0x43, 0x12, 0x44, 0x83, 0x30, 0x5a, 0x42, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, + 0x54, 0xfe, 0xe5, 0x54, 0x36, 0x43, 0x21, 0x44, 0x04, 0x54, 0x2a, 0x69, 0x94, 0xfe, 0xe3, 0x54, + 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, 0x94, 0xfe, 0xe3, 0x54, 0x95, 0xca, 0x53, 0xfe, 0xf2, 0x08, + 0x02, 0x58, 0xfe, 0x37, 0xf0, 0xfe, 0xfe, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x84, 0x09, 0x02, 0x58, + 0xfb, 0xb2, 0x0b, 0x28, 0xfe, 0x1e, 0x0b, 0x36, 0x54, 0x21, 0x69, 0x53, 0x7a, 0x08, 0xfe, 0xc0, + 0x07, 0x47, 0x62, 0x00, 0xd9, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x30, 0x0a, 0x94, 0x99, + 0xfe, 0x48, 0x0a, 0x36, 0x54, 0x94, 0xfe, 0xe3, 0x54, 0x4e, 0x54, 0x70, 0x69, 0xfe, 0x14, 0x58, + 0xfe, 0x95, 0x58, 0x02, 0x58, 0x36, 0x54, 0x21, 0x69, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xf0, + 0x4e, 0x54, 0x4e, 0x69, 0x02, 0x58, 0x0a, 0x07, 0x60, 0xfe, 0x82, 0x12, 0x0a, 0x07, 0x22, 0xfe, + 0x66, 0x13, 0x29, 0x68, 0x72, 0xd0, 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, + 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6d, 0x31, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x53, 0xfe, 0xfa, + 0x08, 0x04, 0x66, 0x2a, 0x67, 0x0d, 0xb5, 0x12, 0x93, 0x4e, 0x66, 0x70, 0x67, 0x01, 0xc5, 0xb6, + 0x6d, 0x31, 0x16, 0x68, 0x83, 0x30, 0x5a, 0x42, 0x36, 0x43, 0x21, 0x44, 0x95, 0xca, 0xfe, 0x04, + 0xfa, 0x30, 0xfe, 0x05, 0xfa, 0x42, 0x01, 0xfe, 0xbe, 0x13, 0xfe, 0x36, 0x10, 0x2b, 0x0d, 0xb5, + 0x0d, 0x93, 0x36, 0x43, 0x21, 0x44, 0xb0, 0x0a, 0x07, 0x22, 0x19, 0xfe, 0xfa, 0x08, 0x36, 0x3c, + 0x21, 0x3d, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x39, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x10, 0x58, 0xfe, + 0x91, 0x58, 0x4e, 0x54, 0x70, 0x69, 0x02, 0xfe, 0x18, 0x0a, 0x0a, 0x07, 0x22, 0x19, 0xfe, 0xfa, + 0x08, 0x0a, 0x07, 0xfe, 0xf7, 0x00, 0x39, 0xf0, 0xdf, 0x6a, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, + 0xfe, 0xd3, 0x10, 0x40, 0x05, 0xcb, 0x19, 0xfe, 0x2c, 0x09, 0x11, 0xcb, 0xfb, 0xb2, 0x0b, 0xfe, + 0x14, 0x13, 0x04, 0x3c, 0x2a, 0x3d, 0x53, 0xfe, 0x2c, 0x09, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, + 0x02, 0x58, 0x2b, 0x47, 0xfe, 0x19, 0x80, 0xfe, 0xf1, 0x10, 0x0a, 0x07, 0x0b, 0xab, 0xfe, 0x6c, + 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x4e, 0x3c, 0xfe, 0xed, 0x19, 0x70, + 0x3d, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x1a, 0xfe, 0x00, 0xff, 0x35, 0xfe, + 0x74, 0x10, 0xcd, 0xfe, 0xd2, 0xf0, 0xfe, 0xb6, 0x0b, 0xfe, 0x76, 0x18, 0x1a, 0x18, 0xd6, 0x04, + 0xe7, 0x1a, 0x06, 0x89, 0x13, 0xfe, 0x16, 0x00, 0x02, 0x6b, 0xfe, 0xd1, 0xf0, 0xfe, 0xc8, 0x0b, + 0x17, 0x84, 0x01, 0x3b, 0x13, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xce, + 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xda, 0x0b, 0x13, 0xfe, 0x22, 0x00, 0x02, 0x6b, + 0xfe, 0xcb, 0xf0, 0xfe, 0xe6, 0x0b, 0x13, 0xfe, 0x24, 0x00, 0x02, 0x6b, 0xfe, 0xd0, 0xf0, 0xfe, + 0xf0, 0x0b, 0x13, 0xb1, 0xe0, 0xfe, 0xcf, 0xf0, 0xfe, 0xfa, 0x0b, 0x13, 0x8f, 0xdd, 0xfe, 0xcc, + 0xf0, 0xfe, 0x0a, 0x0c, 0xfe, 0x84, 0x80, 0xb2, 0x22, 0x4f, 0x13, 0xfe, 0x12, 0x00, 0x2e, 0x08, + 0x84, 0x2f, 0xfe, 0x10, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x24, 0x0c, 0xa3, 0x19, 0x32, 0x2e, 0x5b, + 0xfe, 0xed, 0x10, 0xac, 0x26, 0xae, 0x26, 0x2e, 0xfe, 0x9c, 0x32, 0x2f, 0xfe, 0x30, 0x0c, 0x1b, + 0x32, 0x85, 0xfe, 0x4c, 0x0c, 0x73, 0x97, 0xac, 0xfe, 0xf0, 0x07, 0xae, 0xfe, 0xf0, 0x07, 0x02, + 0x26, 0x01, 0x55, 0xfe, 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xed, 0xee, 0x92, 0x86, 0x76, 0xfe, + 0x89, 0xf0, 0x26, 0x24, 0x23, 0xfe, 0xe9, 0x09, 0x01, 0x0c, 0x86, 0x76, 0x1f, 0x26, 0x24, 0x23, + 0x9a, 0x34, 0xfe, 0x88, 0x0c, 0x1b, 0x32, 0x02, 0xfe, 0x7c, 0x0c, 0xa3, 0x50, 0x13, 0xfe, 0x42, + 0x00, 0x02, 0x6b, 0xa6, 0x06, 0xfe, 0x81, 0x49, 0xfe, 0xcc, 0x12, 0x0a, 0x07, 0x0b, 0xfe, 0x5a, + 0x13, 0x13, 0x00, 0x61, 0x0b, 0xfe, 0x6a, 0x12, 0x61, 0xfe, 0x28, 0x00, 0x28, 0xfe, 0xce, 0x0d, + 0x0f, 0x7d, 0x01, 0x15, 0x05, 0x00, 0x89, 0x37, 0xfe, 0x28, 0x00, 0x02, 0xfe, 0xce, 0x0d, 0x01, + 0x9f, 0x01, 0xa1, 0x0f, 0xc8, 0x01, 0xfe, 0x24, 0x0f, 0xb9, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, + 0x11, 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x02, 0x27, 0x13, 0xfe, 0x44, 0x00, 0x61, 0x0b, + 0xab, 0x37, 0x0b, 0xfe, 0xc0, 0x10, 0x01, 0xc2, 0x37, 0x0b, 0xfe, 0xb6, 0x10, 0x01, 0xc2, 0xfe, + 0x19, 0x82, 0xfe, 0x34, 0x46, 0xfe, 0x0a, 0x13, 0x37, 0x0b, 0x13, 0xfe, 0x43, 0x00, 0xfe, 0xa2, + 0x10, 0x0a, 0x41, 0x0b, 0x39, 0x01, 0x9f, 0x01, 0xa1, 0xb9, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, + 0x11, 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x88, 0x0b, 0xb9, 0x1c, 0xd2, 0x02, 0xfe, 0x4c, + 0x03, 0x0a, 0x07, 0x0b, 0xd6, 0x37, 0x0b, 0x13, 0x00, 0xfe, 0x54, 0x10, 0x71, 0x07, 0x1d, 0xfe, + 0x50, 0x12, 0x0a, 0x07, 0x1d, 0xfe, 0x48, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x8c, + 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x92, 0x0d, 0x0a, 0x41, 0x1d, 0x39, 0xfe, 0x95, + 0x10, 0x13, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x6a, 0xfe, 0x26, 0x10, 0x13, 0xfe, 0x13, + 0x00, 0xdd, 0x13, 0xfe, 0x47, 0x00, 0x8a, 0x13, 0xfe, 0x41, 0x00, 0xa4, 0x13, 0xfe, 0x24, 0x00, + 0x04, 0x7c, 0x2c, 0x28, 0xf6, 0x6a, 0xfe, 0x04, 0xe6, 0x1d, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, + 0xb9, 0x01, 0xea, 0x02, 0x27, 0xde, 0x17, 0x0b, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0x17, 0xfe, 0x31, + 0x00, 0x4c, 0xc4, 0x01, 0xfe, 0x30, 0x10, 0x02, 0xfe, 0xc6, 0x01, 0x1c, 0xfe, 0x06, 0xec, 0xfe, + 0xb9, 0x00, 0x8c, 0x37, 0x38, 0xc7, 0x35, 0x1c, 0xfe, 0x06, 0xea, 0xfe, 0xb9, 0x00, 0xfe, 0x47, + 0x4b, 0x9e, 0xfe, 0x75, 0x57, 0x04, 0x5f, 0xfe, 0x98, 0x56, 0xfe, 0x28, 0x12, 0x0f, 0x7d, 0xfe, + 0xf4, 0x14, 0x47, 0xf2, 0x0f, 0xc8, 0xfe, 0xea, 0x14, 0xfe, 0x49, 0x54, 0x98, 0xfe, 0x42, 0x0e, + 0x0f, 0x1e, 0xfe, 0xde, 0x14, 0xfe, 0x44, 0x48, 0x02, 0xfe, 0x4c, 0x03, 0x0f, 0x5f, 0xfe, 0xc8, + 0x14, 0x8c, 0x37, 0x38, 0xc7, 0x35, 0x1c, 0xfe, 0xce, 0x47, 0xfe, 0xbd, 0x13, 0x02, 0x27, 0x29, + 0x2d, 0x05, 0x10, 0xfe, 0x78, 0x12, 0x2b, 0x16, 0x5e, 0x16, 0xb4, 0x29, 0x48, 0x47, 0x4c, 0x48, + 0xa3, 0xd9, 0xfe, 0xbc, 0xf0, 0xfe, 0xde, 0x0e, 0x08, 0x06, 0x16, 0x5e, 0x01, 0xfe, 0xe6, 0x16, + 0x04, 0xfe, 0x38, 0x01, 0x2a, 0xfe, 0x3a, 0x01, 0x53, 0xfe, 0xe2, 0x0e, 0x04, 0xfe, 0x38, 0x01, + 0x1a, 0xfe, 0xf0, 0xff, 0x0d, 0xfe, 0x60, 0x01, 0x04, 0xfe, 0x3a, 0x01, 0x0d, 0xfe, 0x62, 0x01, + 0x20, 0x06, 0x16, 0x48, 0xfe, 0x04, 0xec, 0x2d, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x01, 0x45, 0x82, + 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x56, 0x17, 0x11, 0x48, 0xd2, 0x08, 0x06, 0x03, + 0x2b, 0x03, 0x29, 0x5e, 0xfe, 0xf7, 0x12, 0x29, 0xb4, 0x72, 0x16, 0xb4, 0x05, 0x84, 0xfe, 0x93, + 0x13, 0xfe, 0x24, 0x1c, 0x17, 0x18, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0xfe, 0xd9, 0x10, 0x9c, 0xfe, + 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0x9c, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, + 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0x9c, 0x2b, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, + 0x9c, 0x80, 0x03, 0x01, 0xfe, 0x8e, 0x17, 0x40, 0x05, 0x48, 0xfe, 0x0a, 0x13, 0x08, 0x1e, 0x09, + 0x52, 0xdd, 0x01, 0x9f, 0x01, 0xa1, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, 0x11, 0xfe, 0xe9, 0x00, + 0x0a, 0x07, 0x8f, 0xfe, 0x52, 0x13, 0x01, 0xfe, 0x18, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, + 0x0d, 0xfe, 0x64, 0x01, 0xfe, 0x16, 0x90, 0x0d, 0xfe, 0x66, 0x01, 0x0a, 0x07, 0x46, 0xef, 0xfe, + 0x03, 0x80, 0x5b, 0x4d, 0x11, 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x90, 0xfe, 0x62, + 0x08, 0x72, 0x4d, 0x11, 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x90, 0x6d, 0x31, 0x11, + 0x7b, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x7a, 0x01, 0x7e, 0x03, 0xfe, 0x08, 0x1c, 0x04, 0xfe, 0xac, + 0x00, 0xfe, 0x06, 0x58, 0x04, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x04, 0xfe, 0xb0, 0x00, 0xfe, + 0x08, 0x58, 0x04, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x20, 0x74, 0x16, 0xfe, + 0xb9, 0x00, 0x2b, 0x0d, 0x5c, 0x0d, 0x56, 0x20, 0x10, 0x16, 0x2d, 0x16, 0x3e, 0x51, 0xa6, 0xfe, + 0x93, 0x00, 0x08, 0x2d, 0x09, 0x3e, 0x1c, 0x01, 0x7e, 0x82, 0x11, 0x7b, 0xfe, 0x14, 0x56, 0xfe, + 0xd6, 0xf0, 0x8a, 0xde, 0x92, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x1c, + 0xfe, 0x0c, 0x14, 0x8c, 0xfe, 0x07, 0xe6, 0x38, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, + 0xc2, 0x0f, 0x3f, 0x01, 0x15, 0x05, 0x10, 0xdb, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0xe2, 0xfe, + 0x44, 0x58, 0x4d, 0xfe, 0x01, 0xec, 0xc4, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, + 0xe7, 0x1d, 0xa5, 0x31, 0x01, 0xea, 0xfe, 0xc9, 0x10, 0x03, 0x2e, 0x86, 0x76, 0x24, 0x23, 0xba, + 0x05, 0x1d, 0xfe, 0x48, 0x12, 0x05, 0x0b, 0xfe, 0x4c, 0x12, 0x05, 0x18, 0xfe, 0x30, 0x12, 0x05, + 0xd4, 0x19, 0xfe, 0xd4, 0x11, 0x05, 0xfe, 0x23, 0x00, 0x19, 0xfe, 0xe0, 0x11, 0x05, 0x06, 0x19, + 0xfe, 0x3e, 0x12, 0x05, 0x22, 0xfe, 0x12, 0x12, 0x05, 0x00, 0x19, 0x26, 0x17, 0xd4, 0x01, 0x3b, + 0xce, 0x3a, 0x01, 0x0c, 0x85, 0x55, 0x03, 0x3a, 0x11, 0xfe, 0xcc, 0x00, 0x02, 0x27, 0x3a, 0x40, + 0x05, 0xcb, 0xfe, 0xe3, 0x13, 0x36, 0x3c, 0x21, 0x3d, 0x53, 0xfe, 0x92, 0x11, 0x0a, 0x07, 0x60, + 0xfe, 0x72, 0x12, 0x83, 0x30, 0x5a, 0x42, 0x95, 0xca, 0x98, 0xfe, 0x5c, 0x11, 0x29, 0x68, 0xfe, + 0x26, 0x13, 0x04, 0xb5, 0x2a, 0x93, 0x53, 0xfe, 0xb2, 0x0d, 0x0d, 0x66, 0x12, 0x67, 0x2b, 0x0d, + 0xb5, 0x0d, 0x93, 0x01, 0xc5, 0x20, 0x74, 0x5b, 0x16, 0x68, 0x01, 0xfe, 0xbe, 0x13, 0x83, 0x30, + 0x5a, 0x42, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x30, 0xfe, 0x05, 0xfa, 0x42, + 0xfe, 0x91, 0x10, 0x04, 0x43, 0x2a, 0x44, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0d, 0x43, 0x12, + 0x44, 0xad, 0x83, 0x30, 0x5a, 0x42, 0x95, 0xca, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x00, 0x56, 0xfe, + 0xa1, 0x56, 0x0d, 0x64, 0x12, 0x65, 0x0a, 0x07, 0x60, 0xfe, 0x1e, 0x12, 0x29, 0x68, 0xfe, 0x1f, + 0x40, 0x04, 0x66, 0x2a, 0x67, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x04, 0x43, 0x2a, 0x44, 0xfe, + 0x34, 0x50, 0xfe, 0xb6, 0x50, 0x04, 0x64, 0x2a, 0x65, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x04, + 0x3c, 0x2a, 0x3d, 0xfe, 0x28, 0x50, 0xfe, 0xaa, 0x50, 0x02, 0xa0, 0x20, 0x06, 0x16, 0xfc, 0x02, + 0x7f, 0x3a, 0x01, 0x0c, 0x1f, 0x57, 0x24, 0x23, 0xba, 0x05, 0x06, 0x28, 0x57, 0x40, 0x05, 0xcb, + 0x28, 0x7f, 0x01, 0xfe, 0x9c, 0x13, 0x1a, 0x59, 0x19, 0x57, 0x0a, 0x07, 0x0b, 0xe4, 0x36, 0x3c, + 0x21, 0x3d, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x4e, 0x3c, 0x70, 0x3d, 0xfe, 0x0c, 0x51, + 0xfe, 0x8e, 0x51, 0x02, 0x7f, 0xdf, 0xfe, 0x0a, 0x45, 0xfe, 0x19, 0x41, 0x02, 0x7f, 0x3a, 0x01, + 0x0c, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23, 0xfe, 0xe9, 0x09, 0x61, 0x18, 0xfe, 0x94, 0x12, 0x61, + 0x0b, 0x4f, 0x02, 0x57, 0x2f, 0xfe, 0x5e, 0x12, 0x1b, 0x32, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23, + 0x9a, 0x05, 0x18, 0x28, 0x57, 0x01, 0x0c, 0x1f, 0xfe, 0xd6, 0x10, 0x24, 0x23, 0xfe, 0xe8, 0x09, + 0x51, 0x04, 0xfe, 0x9c, 0x00, 0x2c, 0x35, 0xfe, 0xbb, 0x45, 0x61, 0x00, 0x50, 0x37, 0x06, 0xa6, + 0x59, 0xfe, 0xc0, 0x14, 0xfe, 0xf8, 0x14, 0xb3, 0x40, 0x05, 0xc9, 0xfe, 0x16, 0x13, 0x04, 0xfe, + 0x9e, 0x00, 0x2c, 0xd6, 0x04, 0x56, 0x2c, 0x35, 0x63, 0x02, 0x7f, 0xfe, 0xc0, 0x5d, 0xfe, 0xe4, + 0x14, 0xfe, 0x03, 0x17, 0x04, 0x5c, 0xc3, 0x0d, 0x5c, 0x63, 0x3a, 0x01, 0x0c, 0x25, 0xa0, 0x01, + 0xfe, 0x06, 0x15, 0x02, 0xa0, 0x2f, 0xfe, 0xe8, 0x12, 0x1b, 0x32, 0x1f, 0x57, 0x24, 0x23, 0x9a, + 0x05, 0x06, 0x28, 0x57, 0xfe, 0xf6, 0x14, 0xfe, 0x42, 0x58, 0xfe, 0x70, 0x14, 0xfe, 0x92, 0x14, + 0xb3, 0xfe, 0x4a, 0xf4, 0x0b, 0x19, 0x57, 0xfe, 0x4a, 0xf4, 0x06, 0xd8, 0x40, 0x05, 0xc9, 0xd1, + 0x02, 0x7f, 0x04, 0x56, 0xc3, 0x0d, 0x56, 0x63, 0x3a, 0x01, 0x0c, 0x25, 0xa0, 0x01, 0xfe, 0x34, + 0x15, 0x02, 0xa0, 0x25, 0xfe, 0x50, 0x13, 0x78, 0xf9, 0x78, 0x03, 0x34, 0xfe, 0x4c, 0x13, 0x73, + 0xfe, 0x4c, 0x13, 0x63, 0x3a, 0x01, 0x0c, 0xfe, 0xe3, 0x10, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57, + 0x6e, 0x81, 0x1a, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x6c, 0xff, + 0x02, 0x00, 0x57, 0x6e, 0x81, 0x1a, 0x59, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x08, 0x6c, + 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0x03, 0x08, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x6e, 0x81, 0xfe, + 0x0b, 0x58, 0x03, 0x0f, 0x5c, 0x01, 0x8e, 0x0f, 0x56, 0x01, 0x8e, 0x03, 0xd0, 0x1a, 0x10, 0xff, + 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x22, 0x6e, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, + 0x7d, 0xfe, 0x03, 0x7c, 0x6d, 0x31, 0x0d, 0x64, 0x12, 0x65, 0x4e, 0x43, 0x70, 0x44, 0x03, 0xfe, + 0x62, 0x18, 0xfe, 0x82, 0x5a, 0xfe, 0xe1, 0x1a, 0xbf, 0xfe, 0x02, 0x58, 0x03, 0x01, 0xfe, 0x7e, + 0x19, 0xfe, 0x42, 0x48, 0x6a, 0x51, 0x9e, 0x01, 0x0c, 0x1f, 0xfe, 0xfe, 0x14, 0x24, 0x23, 0xfe, + 0xe9, 0x09, 0xfe, 0xc1, 0x59, 0x01, 0x0c, 0x1f, 0xfe, 0xfe, 0x14, 0x24, 0x23, 0xfe, 0xe8, 0x0a, + 0x04, 0xfe, 0x9e, 0x00, 0x2c, 0xfe, 0xc4, 0x12, 0x2b, 0xb8, 0x1d, 0xe4, 0x61, 0xd5, 0x79, 0xfe, + 0x4c, 0x14, 0x4f, 0x08, 0x06, 0x09, 0xd5, 0xa6, 0xfe, 0x00, 0x10, 0xfe, 0x78, 0x10, 0xff, 0x02, + 0x83, 0x55, 0x8a, 0xff, 0x02, 0x83, 0x55, 0xb8, 0x18, 0xfe, 0x12, 0x13, 0x62, 0xfe, 0x30, 0x00, + 0x98, 0xfe, 0xa6, 0x14, 0x09, 0x8b, 0x08, 0x06, 0xfe, 0x56, 0x10, 0xb8, 0x0b, 0xfe, 0x16, 0x13, + 0x62, 0xfe, 0x64, 0x00, 0x98, 0xfe, 0xa6, 0x14, 0x0f, 0xfe, 0x64, 0x00, 0x09, 0xb1, 0x08, 0x06, + 0xfe, 0x28, 0x10, 0xb8, 0x06, 0xfe, 0x60, 0x13, 0x62, 0xfe, 0xc8, 0x00, 0x98, 0xfe, 0xa6, 0x14, + 0x0f, 0xfe, 0xc8, 0x00, 0x09, 0x5e, 0x08, 0x06, 0xad, 0x62, 0xfe, 0x90, 0x01, 0x99, 0xfe, 0xb2, + 0x14, 0x9e, 0xb0, 0xfe, 0x43, 0xf4, 0xb4, 0xfe, 0x56, 0xf0, 0xfe, 0xc4, 0x14, 0xfe, 0x04, 0xf4, + 0x6c, 0xfe, 0x43, 0xf4, 0xb1, 0xfe, 0xf3, 0x10, 0xb7, 0x01, 0xfe, 0x8e, 0x13, 0x1a, 0x59, 0xaf, + 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x74, 0x99, 0xfe, 0xf8, 0x14, 0xa8, 0x74, 0xfe, 0x14, 0x10, + 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0xf1, 0x99, 0xfe, 0xf8, 0x14, 0xa8, 0xf1, 0xa4, 0x51, 0x9e, + 0x08, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x03, 0x51, 0x08, 0x0b, 0x03, 0x14, 0x06, 0x01, + 0x0c, 0x25, 0xec, 0x14, 0x0b, 0x01, 0x0c, 0x25, 0xec, 0x14, 0x18, 0x01, 0x0c, 0x25, 0xec, 0x78, + 0xfe, 0x89, 0x49, 0x01, 0x0c, 0x03, 0x14, 0x06, 0x01, 0x0c, 0x25, 0xbc, 0x14, 0x18, 0x01, 0x0c, + 0x25, 0xbc, 0x14, 0x06, 0x01, 0x0c, 0x25, 0xbc, 0xfe, 0x89, 0x49, 0x01, 0x0c, 0x25, 0xbc, 0x78, + 0xfe, 0x89, 0x4a, 0x01, 0x0c, 0x03, 0x51, 0x03, 0x29, 0xe8, 0x05, 0x06, 0x3b, 0xb6, 0x16, 0xe8, + 0xfe, 0x49, 0xf4, 0x00, 0x4f, 0x78, 0xce, 0x63, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf9, 0x01, + 0x0c, 0x40, 0x05, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0xb6, 0x15, 0x2b, 0x16, 0xfc, + 0x01, 0x55, 0x29, 0xfc, 0x05, 0x06, 0x50, 0x0a, 0x41, 0x06, 0x39, 0x03, 0x0d, 0x5d, 0x12, 0x91, + 0xfe, 0x43, 0x58, 0x01, 0x15, 0x05, 0x10, 0xfe, 0x1e, 0x12, 0x4a, 0xf3, 0x96, 0x01, 0x49, 0xfe, + 0x90, 0x4d, 0xe6, 0x10, 0xfe, 0xc5, 0x59, 0x01, 0x49, 0xfe, 0x8d, 0x56, 0xbf, 0x4a, 0x03, 0x4a, + 0x21, 0x91, 0x01, 0x15, 0x4a, 0x96, 0x01, 0x49, 0xeb, 0x10, 0xe6, 0x10, 0x21, 0x5d, 0x62, 0x1e, + 0x89, 0x0f, 0x5f, 0x01, 0xaa, 0x03, 0x0d, 0x5d, 0x12, 0x91, 0xfe, 0xc3, 0x58, 0x01, 0x15, 0x05, + 0x10, 0xfe, 0x1a, 0x12, 0x4a, 0xf3, 0x96, 0x01, 0x49, 0xeb, 0x10, 0xfe, 0x80, 0x4d, 0xfe, 0xc5, + 0x59, 0x01, 0x49, 0x4a, 0x03, 0x4a, 0x21, 0x5d, 0x01, 0x15, 0x4a, 0x96, 0x01, 0x49, 0xeb, 0x10, + 0xe6, 0x10, 0x21, 0x5d, 0x62, 0x1e, 0x89, 0x0f, 0x5f, 0x01, 0xaa, 0x03, 0x0d, 0x5d, 0x12, 0x91, + 0xfe, 0x43, 0x58, 0x01, 0x15, 0xfe, 0x42, 0x48, 0x96, 0x01, 0x49, 0xfe, 0xc0, 0x5a, 0xb7, 0xfe, + 0x00, 0xcd, 0xfe, 0x01, 0xcc, 0xfe, 0x4a, 0x46, 0xe4, 0x9c, 0x80, 0x05, 0x10, 0xfe, 0x2e, 0x13, + 0x5a, 0x5d, 0xfe, 0x4d, 0xf4, 0x1e, 0xfe, 0x1c, 0x13, 0x0f, 0x5f, 0x01, 0x8e, 0xb0, 0xfe, 0x40, + 0x4c, 0xfe, 0xc5, 0x58, 0x01, 0x49, 0xfe, 0x00, 0x07, 0x80, 0x05, 0x10, 0x89, 0x5a, 0x91, 0xfe, + 0x05, 0x57, 0xfe, 0x08, 0x10, 0xfe, 0x45, 0x58, 0x01, 0x49, 0xfe, 0x8d, 0x56, 0xbf, 0xfe, 0x80, + 0x4c, 0xfe, 0x05, 0x17, 0x03, 0x09, 0x10, 0x77, 0x6f, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, + 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xe3, 0x38, 0x9d, 0xfe, 0xfa, 0x16, 0x01, 0xfe, 0x08, 0x18, 0xd9, + 0x8d, 0x38, 0x6f, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xc0, 0x28, 0xfe, 0xea, 0x16, 0xfe, + 0xe2, 0x10, 0x09, 0x10, 0x77, 0x04, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x22, 0xfe, 0x18, 0x58, + 0x04, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x8d, 0x22, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, + 0xfe, 0x3c, 0x50, 0x6f, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x22, 0x9d, 0xfe, + 0x44, 0x17, 0xfe, 0xbe, 0x14, 0x35, 0x03, 0xc0, 0x28, 0xfe, 0x1c, 0x17, 0xfe, 0xa4, 0x10, 0x09, + 0x10, 0x77, 0xbf, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xdf, 0xe3, 0x30, 0x9d, 0xfe, 0x66, 0x17, 0xfe, + 0x9c, 0x14, 0xfe, 0x18, 0x13, 0x8d, 0x30, 0x6f, 0x1d, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, + 0xa7, 0x07, 0xfe, 0x7f, 0x00, 0xfe, 0x05, 0x40, 0x03, 0xc0, 0x28, 0xfe, 0x5a, 0x17, 0xfe, 0x6c, + 0x10, 0x09, 0x10, 0x77, 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x8d, 0xe1, 0x6f, 0x1d, 0xfe, 0x0f, + 0x79, 0xfe, 0x1c, 0xf7, 0xe1, 0x9d, 0xfe, 0xa6, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x03, 0xc0, 0x28, + 0xfe, 0x92, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x10, 0x77, 0xfe, 0x18, 0xfe, 0x66, 0xfe, + 0x19, 0xfe, 0x67, 0xd0, 0xe3, 0x46, 0x9d, 0xfe, 0xcc, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, + 0x8d, 0x46, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, + 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x6d, 0x31, 0x03, 0x6d, 0x31, 0xfe, 0x12, 0x45, 0x28, 0xfe, 0xbc, + 0x17, 0x17, 0x06, 0x4c, 0xfe, 0x9b, 0x00, 0xe5, 0x02, 0x27, 0xfe, 0x39, 0xf0, 0xfe, 0x10, 0x18, + 0x2b, 0x03, 0xfe, 0x7e, 0x18, 0x1a, 0x18, 0x87, 0x08, 0x0e, 0x03, 0x77, 0x04, 0xe7, 0x1a, 0x06, + 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x1c, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0x50, 0x4d, 0xfe, + 0x78, 0x14, 0xfe, 0x34, 0x12, 0x59, 0x8c, 0x37, 0x38, 0xc7, 0xfe, 0xe9, 0x13, 0x1c, 0x0f, 0x3f, + 0x01, 0x15, 0x05, 0x10, 0x50, 0x4d, 0xfe, 0x56, 0x14, 0xe9, 0x59, 0x8c, 0x37, 0x38, 0xc7, 0xfe, + 0xe9, 0x13, 0x09, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x13, 0xfe, 0x15, 0x00, 0x7a, 0xa5, 0x31, + 0x01, 0xea, 0x09, 0x06, 0x03, 0x0a, 0x41, 0x38, 0x39, 0x08, 0x3f, 0x09, 0xa2, 0x01, 0x45, 0x11, + 0x48, 0x08, 0x1e, 0x09, 0x52, 0x01, 0x7e, 0x09, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, + 0x36, 0xfe, 0xa8, 0x00, 0x21, 0x7b, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x03, 0x29, 0xc6, + 0x5b, 0x16, 0xc6, 0x03, 0x0f, 0xc8, 0x01, 0x15, 0xf2, 0x0f, 0x7d, 0x01, 0x15, 0xfe, 0x49, 0x44, + 0x28, 0xfe, 0x06, 0x19, 0x0f, 0x1e, 0x01, 0x15, 0x05, 0x10, 0x50, 0x0f, 0x5f, 0x01, 0xaa, 0x0f, + 0x7d, 0x01, 0x15, 0x5b, 0x80, 0x03, 0xfe, 0x40, 0x5e, 0xfe, 0xe2, 0x08, 0xfe, 0xc0, 0x4c, 0x29, + 0x3e, 0x05, 0x10, 0xfe, 0x52, 0x12, 0x4d, 0x05, 0x00, 0xfe, 0x18, 0x12, 0xfe, 0xe1, 0x18, 0xfe, + 0x19, 0xf4, 0xfe, 0x7f, 0x00, 0xaf, 0xfe, 0xe2, 0x08, 0x5b, 0x4d, 0x40, 0x05, 0x7b, 0xab, 0xfe, + 0x82, 0x48, 0xfe, 0x01, 0x80, 0xfe, 0xd7, 0x10, 0xfe, 0xc4, 0x48, 0x08, 0x2d, 0x09, 0x3e, 0xfe, + 0x40, 0x5f, 0x1c, 0x01, 0x45, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x14, 0x46, 0x08, 0x2d, 0x09, 0x3e, + 0x01, 0x45, 0x11, 0xfe, 0xdd, 0x00, 0xfe, 0x40, 0x4a, 0x72, 0xfe, 0x06, 0x17, 0xfe, 0x01, 0x07, + 0xfe, 0x82, 0x48, 0xfe, 0x04, 0x17, 0x03, 0xf5, 0x18, 0x79, 0xfe, 0x8e, 0x19, 0x04, 0xfe, 0x90, + 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xf5, 0xd4, 0x79, 0xfe, 0xa0, 0x19, 0x04, 0xfe, 0x92, + 0x00, 0xcf, 0x1d, 0xe0, 0xf5, 0xfe, 0x0b, 0x00, 0x79, 0xfe, 0xb2, 0x19, 0x04, 0xfe, 0x94, 0x00, + 0xcf, 0x22, 0xfe, 0x08, 0x10, 0x04, 0xfe, 0x96, 0x00, 0xcf, 0x8b, 0xfe, 0x4e, 0x45, 0xd8, 0xfe, + 0x0a, 0x45, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, 0x10, 0x1a, 0x74, 0xfe, 0x08, 0x1c, 0xfe, 0x67, + 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0xd8, 0xfe, 0x48, 0xf4, 0x18, 0x99, + 0xfe, 0xe6, 0x19, 0x08, 0x18, 0x03, 0x05, 0x84, 0xfe, 0x5a, 0xf0, 0xfe, 0xf6, 0x19, 0x20, 0xfe, + 0x09, 0x00, 0xfe, 0x34, 0x10, 0x05, 0x1d, 0xfe, 0x5a, 0xf0, 0xfe, 0x04, 0x1a, 0x20, 0xd5, 0xfe, + 0x26, 0x10, 0x05, 0x18, 0x87, 0x20, 0x8b, 0xe0, 0x05, 0x0b, 0x87, 0x20, 0xb1, 0xfe, 0x0e, 0x10, + 0x05, 0x06, 0x87, 0x20, 0x5e, 0xce, 0xb6, 0x03, 0x17, 0xfe, 0x09, 0x00, 0x01, 0x3b, 0x2f, 0xfe, + 0x34, 0x1a, 0x04, 0x76, 0xb7, 0x03, 0x1b, 0xfe, 0x54, 0x1a, 0xfe, 0x14, 0xf0, 0x0c, 0x2f, 0xfe, + 0x48, 0x1a, 0x1b, 0xfe, 0x54, 0x1a, 0xfe, 0x82, 0xf0, 0xfe, 0x4c, 0x1a, 0x03, 0xff, 0x15, 0x00, + 0x00, +}; + +u_int16_t adv_asc38C0800_mcode_size = sizeof(adv_asc38C0800_mcode); /* 0x14F1 */ + +/* + * This checksum is used to compare with that one that will be calculated + * at run time. + * This is performed to ensure the uCode is correctly loaded into the Lram. + */ +u_int32_t adv_asc38C0800_mcode_chksum = 0x053503A5; + diff --git a/sys/dev/ic/adwmcode.h b/sys/dev/ic/adwmcode.h index 0f9e2c2e15f..61f1d7c1bd0 100644 --- a/sys/dev/ic/adwmcode.h +++ b/sys/dev/ic/adwmcode.h @@ -1,11 +1,10 @@ -/* $OpenBSD: adwmcode.h,v 1.1 1998/11/17 06:14:58 downsj Exp $ */ -/* $NetBSD: adwmcode.h,v 1.1 1998/09/26 16:10:42 dante Exp $ */ +/* $NetBSD: adwmcode.h,v 1.2 2000/02/03 20:29:17 dante Exp $ */ /* * Generic driver definitions and exported functions for the Advanced * Systems Inc. SCSI controllers * - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * Author: Baldassare Dante Profeta <dante@mclink.it> @@ -42,8 +41,12 @@ #ifndef ADV_MCODE_H #define ADV_MCODE_H -extern u_int8_t adv_mcode[]; -extern u_int16_t adv_mcode_size; -extern u_int32_t adv_mcode_chksum; +extern u_int8_t adv_asc3550_mcode[]; +extern u_int16_t adv_asc3550_mcode_size; +extern u_int32_t adv_asc3550_mcode_chksum; + +extern u_int8_t adv_asc38C0800_mcode[]; +extern u_int16_t adv_asc38C0800_mcode_size; +extern u_int32_t adv_asc38C0800_mcode_chksum; #endif /* ADV_MCODE_H */ |