Commit 80e044ad authored by Justin T. Gibbs's avatar Justin T. Gibbs

Aic79XX Driver Update [Rev 1.3.5]

 o Clean up driver locking by making the locking semantics between
   2.4.X and 2.5.X almost identical.  Take advantage of SCSI_HAS_HOST_LOCK
   in certain RedHat kernels.
 o Clean up command line parsing.
 o Fix module unload/reload issues stemming from DV thread teardown
   and a missing deregistration of our reboot notifier (lost during
   PCI hot plug integration).
 o Correct precompensation value used for U320 transfers on
   rev A4 hardware.
 o Extract VPD information from the seeprom for potential use
   in sorting controller probes to match boot order.
 o Make LED activity more visible on Rev A4 hardware.
parent dfb4b108
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#86 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#88 $
*
* $FreeBSD$
*/
......@@ -322,7 +322,11 @@ typedef enum {
* glitches. This flag tells the firmware to tolerate
* early REQ assertions.
*/
AHD_EARLY_REQ_BUG = 0x400000
AHD_EARLY_REQ_BUG = 0x400000,
/*
* The LED does not stay on long enough in packetized modes.
*/
AHD_FAINT_LED_BUG = 0x800000
} ahd_bug;
/*
......@@ -332,10 +336,7 @@ typedef enum {
*/
typedef enum {
AHD_FNONE = 0x00000,
AHD_PRIMARY_CHANNEL = 0x00003,/*
* The channel that should
* be probed first.
*/
AHD_BOOT_CHANNEL = 0x00001,/* We were set as the boot channel. */
AHD_USEDEFAULTS = 0x00004,/*
* For cards without an seeprom
* or a BIOS to initialize the chip's
......@@ -900,6 +901,40 @@ struct seeprom_config {
uint16_t checksum; /* word 31 */
};
/*
* Vital Product Data used during POST and by the BIOS.
*/
struct vpd_config {
uint8_t bios_flags;
#define VPDMASTERBIOS 0x0001
#define VPDBOOTHOST 0x0002
uint8_t reserved_1[21];
uint8_t resource_type;
uint8_t resource_len[2];
uint8_t resource_data[8];
uint8_t vpd_tag;
uint16_t vpd_len;
uint8_t vpd_keyword[2];
uint8_t length;
uint8_t revision;
uint8_t device_flags;
uint8_t termnation_menus[2];
uint8_t fifo_threshold;
uint8_t end_tag;
uint8_t vpd_checksum;
uint16_t default_target_flags;
uint16_t default_bios_flags;
uint16_t default_ctrl_flags;
uint8_t default_irq;
uint8_t pci_lattime;
uint8_t max_target;
uint8_t boot_lun;
uint16_t signature;
uint8_t reserved_2;
uint8_t checksum;
uint8_t reserved_3[4];
};
/****************************** Flexport Logic ********************************/
#define FLXADDR_TERMCTL 0x0
#define FLX_TERMCTL_ENSECHIGH 0x8
......@@ -932,11 +967,12 @@ struct seeprom_config {
#define FLX_CSTAT_INVALID 0x3
int ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count);
u_int start_addr, u_int count, int bstream);
int ahd_write_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count);
int ahd_wait_seeprom(struct ahd_softc *ahd);
int ahd_verify_vpd_cksum(struct vpd_config *vpd);
int ahd_verify_cksum(struct seeprom_config *sc);
int ahd_acquire_seeprom(struct ahd_softc *ahd);
void ahd_release_seeprom(struct ahd_softc *ahd);
......@@ -1321,6 +1357,8 @@ int ahd_softc_init(struct ahd_softc *);
void ahd_controller_info(struct ahd_softc *ahd, char *buf);
int ahd_init(struct ahd_softc *ahd);
int ahd_default_config(struct ahd_softc *ahd);
int ahd_parse_vpddata(struct ahd_softc *ahd,
struct vpd_config *vpd);
int ahd_parse_cfgdata(struct ahd_softc *ahd,
struct seeprom_config *sc);
void ahd_intr_enable(struct ahd_softc *ahd, int enable);
......
......@@ -39,7 +39,7 @@
*
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#64 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $"
/*
* This file is processed by the aic7xxx_asm utility for use in assembling
......@@ -2545,10 +2545,10 @@ const AHD_PRECOMP_CUTBACK_37 0x07
const AHD_SLEWRATE_MASK 0x78
const AHD_SLEWRATE_SHIFT 3
/*
* Rev A has only a single bit of slew adjustment.
* Rev B has 4 bits.
* Rev A has only a single bit (high bit of field) of slew adjustment.
* Rev B has 4 bits. The current default happens to be the same for both.
*/
const AHD_SLEWRATE_DEF_REVA 0x01
const AHD_SLEWRATE_DEF_REVA 0x08
const AHD_SLEWRATE_DEF_REVB 0x08
/* Rev A does not have any amplitude setting. */
......
......@@ -40,7 +40,7 @@
* $FreeBSD$
*/
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#88 $"
VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $"
PATCH_ARG_LIST = "struct ahd_softc *ahd"
PREFIX = "ahd_"
......@@ -89,6 +89,13 @@ END_CRITICAL;
idle_loop_check_nonpackreq:
test SSTAT2, NONPACKREQ jz . + 2;
call unexpected_nonpkt_phase_find_ctxt;
if ((ahd->bugs & AHD_FAINT_LED_BUG) != 0) {
and A, FIFO0FREE|FIFO1FREE, DFFSTAT;
cmp A, FIFO0FREE|FIFO1FREE jne . + 3;
and SBLKCTL, ~DIAGLEDEN|DIAGLEDON;
jmp . + 2;
or SBLKCTL, DIAGLEDEN|DIAGLEDON;
}
call idle_loop_gsfifo_in_scsi_mode;
call idle_loop_service_fifos;
call idle_loop_cchan;
......
......@@ -37,7 +37,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#174 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.c#178 $
*
* $FreeBSD$
*/
......@@ -4832,9 +4832,6 @@ ahd_softc_insert(struct ahd_softc *ahd)
slave->flags &= ~AHD_BIOS_ENABLED;
slave->flags |=
master->flags & AHD_BIOS_ENABLED;
slave->flags &= ~AHD_PRIMARY_CHANNEL;
slave->flags |=
master->flags & AHD_PRIMARY_CHANNEL;
break;
}
}
......@@ -4846,7 +4843,7 @@ ahd_softc_insert(struct ahd_softc *ahd)
*/
list_ahd = TAILQ_FIRST(&ahd_tailq);
while (list_ahd != NULL
&& ahd_softc_comp(list_ahd, ahd) <= 0)
&& ahd_softc_comp(ahd, list_ahd) <= 0)
list_ahd = TAILQ_NEXT(list_ahd, links);
if (list_ahd != NULL)
TAILQ_INSERT_BEFORE(list_ahd, ahd, links);
......@@ -6535,6 +6532,22 @@ ahd_parse_cfgdata(struct ahd_softc *ahd, struct seeprom_config *sc)
return (0);
}
/*
* Parse device configuration information.
*/
int
ahd_parse_vpddata(struct ahd_softc *ahd, struct vpd_config *vpd)
{
int error;
error = ahd_verify_vpd_cksum(vpd);
if (error == 0)
return (EINVAL);
if ((vpd->bios_flags & VPDBOOTHOST) != 0)
ahd->flags |= AHD_BOOT_CHANNEL;
return (0);
}
void
ahd_intr_enable(struct ahd_softc *ahd, int enable)
{
......@@ -6815,7 +6828,6 @@ ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
/*
* Return the untagged transaction id for a given target/channel lun.
* Optionally, clear the entry.
*/
u_int
ahd_find_busy_tcl(struct ahd_softc *ahd, u_int tcl)
......@@ -7325,7 +7337,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
{
struct scb *scbp;
struct scb *scbp_next;
u_int active_scb;
u_int i, j;
u_int maxtarget;
u_int minlun;
......@@ -7333,11 +7344,10 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
int found;
ahd_mode_state saved_modes;
/* restore these when we're done */
active_scb = ahd_get_scbptr(ahd);
/* restore this when we're done */
saved_modes = ahd_save_modes(ahd);
ahd_set_modes(ahd, AHD_MODE_SCSI, AHD_MODE_SCSI);
found = ahd_search_qinfifo(ahd, target, channel, lun, SCB_LIST_NULL,
role, CAM_REQUEUE_REQ, SEARCH_COMPLETE);
......@@ -7411,7 +7421,6 @@ ahd_abort_scbs(struct ahd_softc *ahd, int target, char channel,
found++;
}
}
ahd_set_scbptr(ahd, active_scb);
ahd_restore_modes(ahd, saved_modes);
ahd_platform_abort_scbs(ahd, target, channel, lun, tag, role, status);
ahd->flags |= AHD_UPDATE_PEND_CMDS;
......@@ -8772,11 +8781,12 @@ ahd_dump_scbs(struct ahd_softc *ahd)
/*
* Read count 16bit words from 16bit word address start_addr from the
* SEEPROM attached to the controller, into buf, using the controller's
* SEEPROM reading state machine.
* SEEPROM reading state machine. Optionally treat the data as a byte
* stream in terms of byte order.
*/
int
ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
u_int start_addr, u_int count)
u_int start_addr, u_int count, int bytestream)
{
u_int cur_addr;
u_int end_addr;
......@@ -8790,13 +8800,26 @@ ahd_read_seeprom(struct ahd_softc *ahd, uint16_t *buf,
AHD_ASSERT_MODES(ahd, AHD_MODE_SCSI_MSK, AHD_MODE_SCSI_MSK);
end_addr = start_addr + count;
for (cur_addr = start_addr; cur_addr < end_addr; cur_addr++) {
ahd_outb(ahd, SEEADR, cur_addr);
ahd_outb(ahd, SEECTL, SEEOP_READ | SEESTART);
error = ahd_wait_seeprom(ahd);
if (error)
break;
*buf++ = ahd_inw(ahd, SEEDAT);
if (bytestream != 0) {
uint8_t *bytestream_ptr;
bytestream_ptr = (uint8_t *)buf;
*bytestream_ptr++ = ahd_inb(ahd, SEEDAT);
*bytestream_ptr = ahd_inb(ahd, SEEDAT+1);
} else {
/*
* ahd_inw() already handles machine byte order.
*/
*buf = ahd_inw(ahd, SEEDAT);
}
buf++;
}
return (error);
}
......@@ -8869,6 +8892,38 @@ ahd_wait_seeprom(struct ahd_softc *ahd)
return (0);
}
/*
* Validate the two checksums in the per_channel
* vital product data struct.
*/
int
ahd_verify_vpd_cksum(struct vpd_config *vpd)
{
int i;
int maxaddr;
uint32_t checksum;
uint8_t *vpdarray;
vpdarray = (uint8_t *)vpd;
maxaddr = offsetof(struct vpd_config, vpd_checksum);
checksum = 0;
for (i = offsetof(struct vpd_config, resource_type); i < maxaddr; i++)
checksum = checksum + vpdarray[i];
if (checksum == 0
|| (-checksum & 0xFF) != vpd->vpd_checksum)
return (0);
checksum = 0;
maxaddr = offsetof(struct vpd_config, checksum);
for (i = offsetof(struct vpd_config, default_target_flags);
i < maxaddr; i++)
checksum = checksum + vpdarray[i];
if (checksum == 0
|| (-checksum & 0xFF) != vpd->checksum)
return (0);
return (1);
}
int
ahd_verify_cksum(struct seeprom_config *sc)
{
......
/*
* Adaptec AIC79xx device driver for Linux.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#131 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#141 $
*
* --------------------------------------------------------------------------
* Copyright (c) 1994-2000 Justin T. Gibbs.
......@@ -460,12 +460,12 @@ MODULE_PARM_DESC(aic79xx,
" Set tag depth on Controller 2/Target 2 to 10 tags\n"
" Shorten the selection timeout to 128ms\n"
"\n"
" options aic79xx='\"verbose.tag_info:{{}.{}.{..10}}.seltime:1\"'\n"
" options aic79xx 'aic79xx=verbose.tag_info:{{}.{}.{..10}}.seltime:1'\n"
"\n"
" Sample /etc/modules.conf line:\n"
" Change Read Streaming for Controller's 2 and 3\n"
"\n"
" options aic79xx='\"rd_strm:{..0xFFF0.0xC0F0}\"'");
" options aic79xx 'aic79xx=rd_strm:{..0xFFF0.0xC0F0}'");
#endif
static void ahd_linux_handle_scsi_status(struct ahd_softc *,
......@@ -482,6 +482,7 @@ static void ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd);
static void ahd_linux_start_dv(struct ahd_softc *ahd);
static void ahd_linux_dv_timeout(struct scsi_cmnd *cmd);
static int ahd_linux_dv_thread(void *data);
static void ahd_linux_kill_dv_thread(struct ahd_softc *ahd);
static void ahd_linux_dv_target(struct ahd_softc *ahd, u_int target);
static void ahd_linux_dv_transition(struct ahd_softc *ahd,
struct scsi_cmnd *cmd,
......@@ -526,6 +527,7 @@ static void ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ);
static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo);
static u_int ahd_linux_user_dv_setting(struct ahd_softc *ahd);
static void ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd);
static void ahd_linux_device_queue_depth(struct ahd_softc *ahd,
struct ahd_linux_device *dev);
static struct ahd_linux_target* ahd_linux_alloc_target(struct ahd_softc*,
......@@ -539,11 +541,11 @@ static void ahd_linux_free_device(struct ahd_softc*,
struct ahd_linux_device*);
static void ahd_linux_run_device_queue(struct ahd_softc*,
struct ahd_linux_device*);
static void ahd_linux_setup_tag_info(char *p, char *end, char *s);
static void ahd_linux_setup_tag_info_global(char *p);
static void ahd_linux_setup_rd_strm_info(char *p, char *end, char *s);
static void ahd_linux_setup_dv(char *p, char *end, char *s);
static void ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index);
static aic_option_callback_t ahd_linux_setup_tag_info;
static aic_option_callback_t ahd_linux_setup_rd_strm_info;
static aic_option_callback_t ahd_linux_setup_dv;
static aic_option_callback_t ahd_linux_setup_iocell_info;
static int ahd_linux_next_unit(void);
static void ahd_runq_tasklet(unsigned long data);
static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf);
......@@ -599,6 +601,9 @@ ahd_schedule_completeq(struct ahd_softc *ahd, struct ahd_cmd *acmd)
}
}
/*
* Must be called with our lock held.
*/
static __inline void
ahd_schedule_runq(struct ahd_softc *ahd)
{
......@@ -662,8 +667,8 @@ ahd_linux_run_complete_queue(struct ahd_softc *ahd, struct ahd_cmd *acmd)
u_long done_flags;
int with_errors;
ahd_done_lock(ahd, &done_flags);
with_errors = 0;
ahd_done_lock(ahd, &done_flags);
while (acmd != NULL) {
Scsi_Cmnd *cmd;
......@@ -1102,7 +1107,7 @@ ahd_linux_select_queue_depth(struct Scsi_Host * host,
int scbnum;
ahd = *((struct ahd_softc **)host->hostdata);
ahd_midlayer_entrypoint_lock(ahd, &flags);
ahd_lock(ahd, &flags);
scbnum = 0;
for (device = scsi_devs; device != NULL; device = device->next) {
......@@ -1137,7 +1142,7 @@ ahd_linux_select_queue_depth(struct Scsi_Host * host,
}
}
}
ahd_midlayer_entrypoint_unlock(ahd, &flags);
ahd_unlock(ahd, &flags);
}
#endif
......@@ -1253,9 +1258,6 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
* by acquiring either the io_request_lock or our own
* lock, this *should* be safe.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irq(&io_request_lock);
#endif
ahd_midlayer_entrypoint_lock(ahd, &s);
/*
......@@ -1465,11 +1467,7 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
int ret;
pending_scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &s);
#else
spin_unlock_irq(ahd->platform_data->host->host_lock);
#endif
spin_unlock_irq(&ahd->platform_data->spin_lock);
init_timer(&timer);
timer.data = (u_long)pending_scb;
timer.expires = jiffies + (5 * HZ);
......@@ -1483,27 +1481,17 @@ ahd_linux_abort(Scsi_Cmnd *cmd)
printf("Timer Expired\n");
retval = FAILED;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, &s);
#else
spin_lock_irq(ahd->platform_data->host->host_lock);
#endif
spin_lock_irq(&ahd->platform_data->spin_lock);
}
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_schedule_runq(ahd);
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
ahd_midlayer_entrypoint_lock(ahd, &s);
if (acmd != NULL)
ahd_schedule_completeq(ahd, acmd);
ahd_midlayer_entrypoint_unlock(ahd, &s);
}
}
ahd_schedule_runq(ahd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_lock_irq(&io_request_lock);
#endif
ahd_midlayer_entrypoint_unlock(ahd, &s);
return (retval);
}
......@@ -1532,9 +1520,6 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
struct timer_list timer;
int retval;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irq(&io_request_lock);
#endif
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
recovery_cmd = malloc(sizeof(struct scsi_cmnd), M_DEVBUF, M_WAITOK);
memset(recovery_cmd, 0, sizeof(struct scsi_cmnd));
......@@ -1586,11 +1571,7 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
ahd_queue_scb(ahd, scb);
scb->platform_data->flags |= AHD_SCB_UP_EH_SEM;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &s);
#else
spin_unlock_irq(ahd->platform_data->host->host_lock);
#endif
spin_unlock_irq(&ahd->platform_data->spin_lock);
init_timer(&timer);
timer.data = (u_long)scb;
timer.expires = jiffies + (5 * HZ);
......@@ -1604,26 +1585,16 @@ ahd_linux_dev_reset(Scsi_Cmnd *cmd)
printf("Timer Expired\n");
retval = FAILED;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, &s);
#else
spin_lock_irq(ahd->platform_data->host->host_lock);
#endif
spin_lock_irq(&ahd->platform_data->spin_lock);
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
ahd_midlayer_entrypoint_unlock(ahd, &s);
ahd_schedule_runq(ahd);
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
ahd_midlayer_entrypoint_lock(ahd, &s);
if (acmd != NULL)
ahd_schedule_completeq(ahd, acmd);
ahd_midlayer_entrypoint_unlock(ahd, &s);
}
}
ahd_schedule_runq(ahd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_lock_irq(&io_request_lock);
#endif
ahd_midlayer_entrypoint_unlock(ahd, &s);
printf("%s: Device reset returning 0x%x\n", ahd_name(ahd), retval);
return (retval);
}
......@@ -1639,9 +1610,6 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
u_long s;
int found;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irq(&io_request_lock);
#endif
ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
#ifdef AHD_DEBUG
if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
......@@ -1653,23 +1621,18 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
/*initiate reset*/TRUE);
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
ahd_midlayer_entrypoint_unlock(ahd, &s);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "
"%d SCBs aborted.\n", ahd_name(ahd), found);
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
ahd_midlayer_entrypoint_lock(ahd, &s);
if (acmd != NULL)
ahd_schedule_completeq(ahd, acmd);
ahd_midlayer_entrypoint_unlock(ahd, &s);
}
}
ahd_midlayer_entrypoint_unlock(ahd, &s);
if (bootverbose)
printf("%s: SCSI bus reset delivered. "
"%d SCBs aborted.\n", ahd_name(ahd), found);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_lock_irq(&io_request_lock);
#endif
return (SUCCESS);
}
......@@ -1721,15 +1684,25 @@ Scsi_Host_Template aic79xx_driver_template = {
/**************************** Tasklet Handler *********************************/
/*
* In 2.4.X and above, this routine is called from a tasklet,
* so we must re-acquire our lock prior to executing this code.
* In all prior kernels, ahd_schedule_runq() calls this routine
* directly and ahd_schedule_runq() is called with our lock held.
*/
static void
ahd_runq_tasklet(unsigned long data)
{
struct ahd_softc* ahd;
struct ahd_linux_device *dev;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
u_long flags;
#endif
ahd = (struct ahd_softc *)data;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
ahd_lock(ahd, &flags);
#endif
while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) {
TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links);
......@@ -1739,7 +1712,9 @@ ahd_runq_tasklet(unsigned long data)
ahd_unlock(ahd, &flags);
ahd_lock(ahd, &flags);
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
ahd_unlock(ahd, &flags);
#endif
}
/************************ Shutdown/halt/reboot hook ***************************/
......@@ -1898,361 +1873,109 @@ ahd_dmamap_unload(struct ahd_softc *ahd, bus_dma_tag_t dmat, bus_dmamap_t map)
}
/********************* Platform Dependent Functions ***************************/
/*
* Compare "left hand" softc with "right hand" softc, returning:
* < 0 - lahd has a lower priority than rahd
* 0 - Softcs are equal
* > 0 - lahd has a higher priority than rahd
*/
int
ahd_softc_comp(struct ahd_softc *lahd, struct ahd_softc *rahd)
{
int value;
char primary_channel;
/*
* Under Linux, cards are ordered as follows:
* 1) PCI devices with BIOS enabled sorted by bus/slot/func.
* 2) All remaining PCI devices sorted by bus/slot/func.
* 1) PCI devices that are marked as the boot controller.
* 2) PCI devices with BIOS enabled sorted by bus/slot/func.
* 3) All remaining PCI devices sorted by bus/slot/func.
*/
#if 0
value = (lahd->flags & AHD_BOOT_CHANNEL)
- (rahd->flags & AHD_BOOT_CHANNEL);
if (value != 0)
/* Controllers set for boot have a *higher* priority */
return (value);
#endif
value = (lahd->flags & AHD_BIOS_ENABLED)
- (rahd->flags & AHD_BIOS_ENABLED);
if (value != 0)
/* Controllers with BIOS enabled have a *higher* priority */
return (-value);
return (value);
/* Still equal. Sort by bus/slot/func. */
if (aic79xx_reverse_scan != 0)
value = ahd_get_pci_bus(rahd->dev_softc)
- ahd_get_pci_bus(lahd->dev_softc);
else
value = ahd_get_pci_bus(lahd->dev_softc)
- ahd_get_pci_bus(rahd->dev_softc);
else
value = ahd_get_pci_bus(rahd->dev_softc)
- ahd_get_pci_bus(lahd->dev_softc);
if (value != 0)
return (value);
if (aic79xx_reverse_scan != 0)
value = ahd_get_pci_slot(rahd->dev_softc)
- ahd_get_pci_slot(lahd->dev_softc);
else
value = ahd_get_pci_slot(lahd->dev_softc)
- ahd_get_pci_slot(rahd->dev_softc);
else
value = ahd_get_pci_slot(rahd->dev_softc)
- ahd_get_pci_slot(lahd->dev_softc);
if (value != 0)
return (value);
/*
* On multi-function devices, the user can choose
* to have function 1 probed before function 0.
* Give whichever channel is the primary channel
* the lowest priority.
*/
primary_channel = (lahd->flags & AHD_PRIMARY_CHANNEL) + 'A';
value = 1;
if (lahd->channel == primary_channel)
value = -1;
value = rahd->channel - lahd->channel;
return (value);
}
static void
ahd_linux_setup_tag_info(char *p, char *end, char *s)
ahd_linux_setup_tag_info(void *arg, int instance, int targ, int32_t value)
{
char *base;
char *tok;
char *tok_end;
char *tok_end2;
int i;
int instance;
int targ;
int done;
char tok_list[] = {'.', ',', '{', '}', '\0'};
if (*p != ':')
return;
instance = -1;
targ = -1;
done = FALSE;
base = p;
/* Forward us just past the ':' */
tok = base + 1;
tok_end = strchr(tok, '\0');
if (tok_end < end)
*tok_end = ',';
while (!done) {
switch (*tok) {
case '{':
if (instance == -1)
instance = 0;
else if (targ == -1)
targ = 0;
tok++;
break;
case '}':
if (targ != -1)
targ = -1;
else if (instance != -1)
instance = -1;
tok++;
break;
case ',':
case '.':
if (instance == -1)
done = TRUE;
else if (targ >= 0)
targ++;
else if (instance >= 0)
instance++;
if ((targ >= AHD_NUM_TARGETS) ||
(instance >= NUM_ELEMENTS(aic79xx_tag_info)))
done = TRUE;
tok++;
if (!done) {
base = tok;
}
break;
case '\0':
done = TRUE;
break;
default:
done = TRUE;
tok_end = strchr(tok, '\0');
for (i = 0; tok_list[i]; i++) {
tok_end2 = strchr(tok, tok_list[i]);
if ((tok_end2) && (tok_end2 < tok_end)) {
tok_end = tok_end2;
done = FALSE;
}
}
if ((instance >= 0) && (targ >= 0)
&& (instance < NUM_ELEMENTS(aic79xx_tag_info))
&& (targ < AHD_NUM_TARGETS)) {
aic79xx_tag_info[instance].tag_commands[targ] =
simple_strtoul(tok, NULL, 0) & 0xff;
}
tok = tok_end;
break;
}
aic79xx_tag_info[instance].tag_commands[targ] = value & 0x1FF;
if (bootverbose)
printf("tag_info[%d:%d] = %d\n", instance, targ, value);
}
while ((p != base) && (p != NULL))
p = strsep(&s, ",.");
}
static void
ahd_linux_setup_rd_strm_info(char *p, char *end, char *s)
ahd_linux_setup_rd_strm_info(void *arg, int instance, int targ, int32_t value)
{
char *base;
char *tok;
char *tok_end;
char *tok_end2;
int i;
int instance;
int done;
char tok_list[] = {'.', ',', '{', '}', '\0'};
if (*p != ':')
return;
instance = -1;
done = FALSE;
base = p;
/* Forward us just past the ':' */
tok = base + 1;
tok_end = strchr(tok, '\0');
if (tok_end < end)
*tok_end = ',';
while (!done) {
switch (*tok) {
case '{':
if (instance == -1)
instance = 0;
tok++;
break;
case '}':
if (instance != -1)
instance = -1;
tok++;
break;
case ',':
case '.':
if (instance == -1)
done = TRUE;
else if (instance >= 0)
instance++;
if (instance >= NUM_ELEMENTS(aic79xx_rd_strm_info))
done = TRUE;
tok++;
if (!done) {
base = tok;
}
break;
case '\0':
done = TRUE;
break;
default:
done = TRUE;
tok_end = strchr(tok, '\0');
for (i = 0; tok_list[i]; i++) {
tok_end2 = strchr(tok, tok_list[i]);
if ((tok_end2) && (tok_end2 < tok_end)) {
tok_end = tok_end2;
done = FALSE;
}
}
if ((instance >= 0)
&& (instance < NUM_ELEMENTS(aic79xx_rd_strm_info))) {
aic79xx_rd_strm_info[instance] =
simple_strtoul(tok, NULL, 0) & 0xffff;
}
tok = tok_end;
break;
}
aic79xx_rd_strm_info[instance] = value * 0xFFFF;
if (bootverbose)
printf("rd_strm[%d] = 0x%x\n", instance, value);
}
while ((p != base) && (p != NULL))
p = strsep(&s, ",.");
}
static void
ahd_linux_setup_dv(char *p, char *end, char *s)
ahd_linux_setup_dv(void *arg, int instance, int targ, int32_t value)
{
char *base;
char *tok;
char *tok_end;
char *tok_end2;
int i;
int instance;
int done;
char tok_list[] = {'.', ',', '{', '}', '\0'};
if (*p != ':')
return;
instance = -1;
done = FALSE;
base = p;
/* Forward us just past the ':' */
tok = base + 1;
tok_end = strchr(tok, '\0');
if (tok_end < end)
*tok_end = ',';
while (!done) {
switch (*tok) {
case '{':
if (instance == -1)
instance = 0;
tok++;
break;
case '}':
if (instance != -1)
instance = -1;
tok++;
break;
case ',':
case '.':
if (instance == -1)
done = TRUE;
else if (instance >= 0)
instance++;
if (instance >= NUM_ELEMENTS(aic79xx_dv_settings))
done = TRUE;
tok++;
if (!done) {
base = tok;
}
break;
case '\0':
done = TRUE;
break;
default:
done = TRUE;
tok_end = strchr(tok, '\0');
for (i = 0; tok_list[i]; i++) {
tok_end2 = strchr(tok, tok_list[i]);
if ((tok_end2) && (tok_end2 < tok_end)) {
tok_end = tok_end2;
done = FALSE;
}
}
if ((instance >= 0)
&& (instance < NUM_ELEMENTS(aic79xx_dv_settings))) {
aic79xx_dv_settings[instance] =
simple_strtol(tok, NULL, 0);
}
tok = tok_end;
break;
}
aic79xx_dv_settings[instance] = value;
if (bootverbose)
printf("dv[%d] = %d\n", instance, value);
}
while ((p != base) && (p != NULL))
p = strsep(&s, ",.");
}
static void
ahd_linux_setup_iocell_info(char *p, char *end, char *s, int index)
ahd_linux_setup_iocell_info(void *arg, int instance, int targ, int32_t value)
{
char *base;
char *tok;
char *tok_end;
char *tok_end2;
uint8_t *iocell_info;
int i;
int instance;
int done;
char tok_list[] = {'.', ',', '{', '}', '\0'};
u_int index;
if (*p != ':')
return;
instance = -1;
done = FALSE;
base = p;
/* Forward us just past the ':' */
tok = base + 1;
tok_end = strchr(tok, '\0');
if (tok_end < end)
*tok_end = ',';
while (!done) {
switch (*tok) {
case '{':
if (instance == -1)
instance = 0;
tok++;
break;
case '}':
if (instance != -1)
instance = -1;
tok++;
break;
case ',':
case '.':
if (instance == -1)
done = TRUE;
else if (instance >= 0)
instance++;
if (instance >= NUM_ELEMENTS(aic79xx_iocell_info))
done = TRUE;
tok++;
if (!done) {
base = tok;
}
break;
case '\0':
done = TRUE;
break;
default:
done = TRUE;
tok_end = strchr(tok, '\0');
for (i = 0; tok_list[i]; i++) {
tok_end2 = strchr(tok, tok_list[i]);
if ((tok_end2) && (tok_end2 < tok_end)) {
tok_end = tok_end2;
done = FALSE;
}
}
index = (u_int)arg;
if ((instance >= 0)
&& (instance < NUM_ELEMENTS(aic79xx_iocell_info))) {
iocell_info =
(uint8_t*)&aic79xx_iocell_info[instance];
iocell_info[index] =
simple_strtoul(tok, NULL, 0) & 0xffff;
}
tok = tok_end;
break;
}
uint8_t *iocell_info;
iocell_info = (uint8_t*)&aic79xx_iocell_info[instance];
iocell_info[index] = value & 0xFFFF;
if (bootverbose)
printf("iocell[%d:%d] = %d\n", instance, index, value);
}
while ((p != base) && (p != NULL))
p = strsep(&s, ",.");
}
static void
......@@ -2308,42 +2031,55 @@ aic79xx_setup(char *s)
end = strchr(s, '\0');
/*
* XXX ia64 gcc isn't smart enough to know that NUM_ELEMENTS
* will never be 0 in this case.
*/
n = 0;
while ((p = strsep(&s, ",.")) != NULL) {
if (*p == '\0')
continue;
for (i = 0; i < NUM_ELEMENTS(options); i++) {
n = strlen(options[i].name);
if (strncmp(options[i].name, p, n) != 0)
n = strlen(options[i].name);
if (strncmp(options[i].name, p, n) == 0)
break;
}
if (i == NUM_ELEMENTS(options))
continue;
if (!strncmp(p, "global_tag_depth", n)) {
if (strncmp(p, "global_tag_depth", n) == 0) {
ahd_linux_setup_tag_info_global(p + n);
} else if (!strncmp(p, "tag_info", n)) {
ahd_linux_setup_tag_info(p + n, end, s);
} else if (strncmp(p, "tag_info", n) == 0) {
s = aic_parse_brace_option("tag_info", p + n, end,
2, ahd_linux_setup_tag_info, NULL);
} else if (strncmp(p, "rd_strm", n) == 0) {
ahd_linux_setup_rd_strm_info(p + n, end, s);
printf("Calling brace parse for %s\n", p);
s = aic_parse_brace_option("rd_strm", p + n, end,
1, ahd_linux_setup_rd_strm_info, NULL);
} else if (strncmp(p, "dv", n) == 0) {
ahd_linux_setup_dv(p + n, end, s);
s = aic_parse_brace_option("dv", p + n, end, 1,
ahd_linux_setup_dv, NULL);
} else if (strncmp(p, "slewrate", n) == 0) {
ahd_linux_setup_iocell_info(p + n, end, s,
AIC79XX_SLEWRATE_INDEX);
s = aic_parse_brace_option("slewrate",
p + n, end, 1, ahd_linux_setup_iocell_info,
(void *)AIC79XX_SLEWRATE_INDEX);
} else if (strncmp(p, "precomp", n) == 0) {
ahd_linux_setup_iocell_info(p + n, end, s,
AIC79XX_PRECOMP_INDEX);
s = aic_parse_brace_option("precomp",
p + n, end, 1, ahd_linux_setup_iocell_info,
(void *)AIC79XX_PRECOMP_INDEX);
} else if (strncmp(p, "amplitude", n) == 0) {
ahd_linux_setup_iocell_info(p + n, end, s,
AIC79XX_AMPLITUDE_INDEX);
s = aic_parse_brace_option("amplitude",
p + n, end, 1, ahd_linux_setup_iocell_info,
(void *)AIC79XX_AMPLITUDE_INDEX);
} else if (p[n] == ':') {
*(options[i].flag) =
simple_strtoul(p + n + 1, NULL, 0);
*(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0);
} else if (!strncmp(p, "verbose", n)) {
*(options[i].flag) = 1;
} else {
*(options[i].flag) = ~(*(options[i].flag));
}
break;
}
}
return 1;
}
......@@ -2372,6 +2108,8 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
ahd_lock(ahd, &s);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
scsi_assign_lock(host, &ahd->platform_data->spin_lock);
#elif AHD_SCSI_HAS_HOST_LOCK != 0
host->lock = &ahd->platform_data->spin_lock;
#endif
ahd->platform_data->host = host;
host->can_queue = AHD_MAX_QUEUE;
......@@ -2394,6 +2132,7 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
scsi_set_pci_device(host, ahd->dev_softc);
#endif
ahd_linux_setup_user_rd_strm_settings(ahd);
ahd_linux_initialize_scsi_bus(ahd);
ahd_unlock(ahd, &s);
ahd->platform_data->dv_pid = kernel_thread(ahd_linux_dv_thread, ahd, 0);
......@@ -2562,26 +2301,10 @@ ahd_platform_free(struct ahd_softc *ahd)
{
struct ahd_linux_target *targ;
struct ahd_linux_device *dev;
u_long s;
int i, j;
if (ahd->platform_data != NULL) {
/* Kill the DV kthread */
if (ahd->platform_data->dv_pid != 0) {
ahd_lock(ahd, &s);
ahd->platform_data->flags |= AHD_DV_SHUTDOWN;
ahd_unlock(ahd, &s);
up(&ahd->platform_data->dv_sem);
do {
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_DV) {
printf("%s: Waiting for DV thread to "
"exit\n", ahd_name(ahd));
}
#endif
} while (waitpid(ahd->platform_data->dv_pid, NULL,
__WCLONE) == -ERESTARTSYS);
}
ahd_linux_kill_dv_thread(ahd);
ahd_teardown_runq_tasklet(ahd);
if (ahd->platform_data->host != NULL) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
......@@ -2684,7 +2407,18 @@ ahd_platform_set_tags(struct ahd_softc *ahd, struct ahd_devinfo *devinfo,
if (dev == NULL)
return;
was_queuing = dev->flags & (AHD_DEV_Q_BASIC|AHD_DEV_Q_TAGGED);
now_queuing = alg != AHD_QUEUE_NONE;
switch (alg) {
default:
case AHD_QUEUE_NONE:
now_queuing = 0;
break;
case AHD_QUEUE_BASIC:
now_queuing = AHD_DEV_Q_BASIC;
break;
case AHD_QUEUE_TAGGED:
now_queuing = AHD_DEV_Q_TAGGED;
break;
}
if ((dev->flags & AHD_DEV_FREEZE_TIL_EMPTY) == 0
&& (was_queuing != now_queuing)
&& (dev->active != 0)) {
......@@ -2820,24 +2554,12 @@ ahd_linux_thread_run_complete_queue(struct ahd_softc *ahd)
ahd->platform_data->flags &= ~AHD_RUN_CMPLT_Q_TIMER;
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, &flags);
#endif
if (acmd != NULL)
ahd_schedule_completeq(ahd, acmd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
static void
......@@ -2904,7 +2626,7 @@ ahd_linux_dv_thread(void *data)
ahd_lock(ahd, &s);
if ((ahd->platform_data->flags & AHD_DV_SHUTDOWN) != 0) {
ahd_unlock(ahd, &s);
return (0);
break;
}
ahd_unlock(ahd, &s);
......@@ -2950,10 +2672,52 @@ ahd_linux_dv_thread(void *data)
*/
ahd_release_simq(ahd);
}
up(&ahd->platform_data->eh_sem);
return (0);
}
static void
ahd_linux_kill_dv_thread(struct ahd_softc *ahd)
{
u_long s;
ahd_lock(ahd, &s);
if (ahd->platform_data->dv_pid != 0) {
ahd->platform_data->flags |= AHD_DV_SHUTDOWN;
ahd_unlock(ahd, &s);
up(&ahd->platform_data->dv_sem);
/*
* Use the eh_sem as an indicator that the
* dv thread is exiting. Note that the dv
* thread must still return after performing
* the up on our semaphore before it has
* completely exited this module. Unfortunately,
* there seems to be no easy way to wait for the
* exit of a thread for which you are not the
* parent (dv threads are parented by init).
* Cross your fingers...
*/
down(&ahd->platform_data->eh_sem);
/*
* Mark the dv thread as already dead. This
* avoids attempting to kill it a second time.
* This is necessary because we must kill the
* DV thread before calling ahd_free() in the
* module shutdown case to avoid bogus locking
* in the SCSI mid-layer, but we ahd_free() is
* called without killing the DV thread in the
* instance detach case, so ahd_platform_free()
* calls us again to verify that the DV thread
* is dead.
*/
ahd->platform_data->dv_pid = 0;
} else {
ahd_unlock(ahd, &s);
}
}
#define AHD_LINUX_DV_INQ_SHORT_LEN 36
#define AHD_LINUX_DV_INQ_LEN 256
#define AHD_LINUX_DV_TIMEOUT (HZ / 4)
......@@ -3097,14 +2861,19 @@ ahd_linux_dv_target(struct ahd_softc *ahd, u_int target_offset)
/*
* In 2.5.X, it is assumed that all calls from the
* "midlayer" (which we are emulating) will have the
* ahd host lock held.
* ahd host lock held. For other kernels, the
* io_request_lock must be held.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#if AHD_SCSI_HAS_HOST_LOCK != 0
ahd_lock(ahd, &s);
#else
spin_lock_irqsave(&io_request_lock, s);
#endif
ahd_linux_queue(cmd, ahd_linux_dv_complete);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#if AHD_SCSI_HAS_HOST_LOCK != 0
ahd_unlock(ahd, &s);
#else
spin_unlock_irqrestore(&io_request_lock, s);
#endif
down_interruptible(&ahd->platform_data->dv_cmd_sem);
/*
......@@ -3992,7 +3761,6 @@ ahd_linux_dv_timeout(struct scsi_cmnd *cmd)
{
struct ahd_softc *ahd;
struct ahd_cmd *acmd;
struct ahd_linux_device *next_dev;
struct scb *scb;
u_long flags;
......@@ -4039,36 +3807,17 @@ ahd_linux_dv_timeout(struct scsi_cmnd *cmd)
ahd->platform_data->reset_timer.function =
(ahd_linux_callback_t *)ahd_release_simq;
add_timer(&ahd->platform_data->reset_timer);
/*
* In 2.5.X, the "done lock" is the ahd_lock.
* Instead of dropping and re-acquiring the same
* lock in the 2.5.X case, just hold our ahd_lock
* the whole time. ahd_done_lock() has been
* made a no-op for 2.5.X too.
*/
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
next_dev = ahd_linux_next_device_to_run(ahd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
if (next_dev)
if (ahd_linux_next_device_to_run(ahd) != NULL)
ahd_schedule_runq(ahd);
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, &flags);
#endif
ahd_schedule_completeq(ahd, acmd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
static void
......@@ -4157,17 +3906,17 @@ ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
tags = 0;
if ((ahd->user_discenable & devinfo->target_mask) != 0) {
if (warned_user == 0
&& ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) {
printf("aic79xx: WARNING, insufficient "
"tag_info instances for installed "
"controllers. Using defaults\n");
printf("aic79xx: Please update the "
"aic79xx_tag_info array in the "
"aic79xx.c source file.\n");
tags = AHD_MAX_QUEUE;
if (ahd->unit >= NUM_ELEMENTS(aic79xx_tag_info)) {
if (warned_user == 0) {
printf(KERN_WARNING
"aic79xx: WARNING: Insufficient tag_info instances\n"
"aic79xx: for installed controllers. Using defaults\n"
"aic79xx: Please update the aic79xx_tag_info array in\n"
"aic79xx: the aic79xx_osm.c source file.\n");
warned_user++;
}
tags = AHD_MAX_QUEUE;
} else {
adapter_tag_info_t *tag_info;
......@@ -4186,17 +3935,17 @@ ahd_linux_user_dv_setting(struct ahd_softc *ahd)
static int warned_user;
int dv;
if (warned_user == 0
&& ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) {
if (ahd->unit >= NUM_ELEMENTS(aic79xx_dv_settings)) {
printf("aic79xx: WARNING, insufficient "
"dv settings instances for installed "
"controllers. Using defaults\n");
printf("aic79xx: Please update the "
"aic79xx_dv_settings array in the "
"aic79xx.c source file.\n");
dv = -1;
if (warned_user == 0) {
printf(KERN_WARNING
"aic79xx: WARNING: Insufficient dv settings instances\n"
"aic79xx: for installed controllers. Using defaults\n"
"aic79xx: Please update the aic79xx_dv_settings array in"
"aic79xx: the aic79xx_osm.c source file.\n");
warned_user++;
}
dv = -1;
} else {
dv = aic79xx_dv_settings[ahd->unit];
......@@ -4213,6 +3962,48 @@ ahd_linux_user_dv_setting(struct ahd_softc *ahd)
return (dv);
}
static void
ahd_linux_setup_user_rd_strm_settings(struct ahd_softc *ahd)
{
static int warned_user;
u_int rd_strm_mask;
u_int target_id;
/*
* If we have specific read streaming info for this controller,
* apply it. Otherwise use the defaults.
*/
if (ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) {
if (warned_user == 0) {
printf(KERN_WARNING
"aic79xx: WARNING: Insufficient rd_strm instances\n"
"aic79xx: for installed controllers. Using defaults\n"
"aic79xx: Please update the aic79xx_rd_strm_info array\n"
"aic79xx: in the aic79xx_osm.c source file.\n");
warned_user++;
}
rd_strm_mask = AIC79XX_CONFIGED_RD_STRM;
} else {
rd_strm_mask = aic79xx_rd_strm_info[ahd->unit];
}
for (target_id = 0; target_id < 16; target_id++) {
struct ahd_devinfo devinfo;
struct ahd_initiator_tinfo *tinfo;
struct ahd_tmode_tstate *tstate;
tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
target_id, &tstate);
ahd_compile_devinfo(&devinfo, ahd->our_id, target_id,
CAM_LUN_WILDCARD, 'A', ROLE_INITIATOR);
tinfo->user.ppr_options &= ~MSG_EXT_PPR_RD_STRM;
if ((rd_strm_mask & devinfo.target_mask) != 0)
tinfo->user.ppr_options |= MSG_EXT_PPR_RD_STRM;
}
}
/*
* Determines the queue depth for a given device.
*/
......@@ -4416,41 +4207,21 @@ ahd_linux_isr(int irq, void *dev_id, struct pt_regs * regs)
struct ahd_softc *ahd;
struct ahd_cmd *acmd;
u_long flags;
struct ahd_linux_device *next_dev;
ahd = (struct ahd_softc *) dev_id;
ahd_lock(ahd, &flags);
ahd_intr(ahd);
acmd = TAILQ_FIRST(&ahd->platform_data->completeq);
TAILQ_INIT(&ahd->platform_data->completeq);
next_dev = ahd_linux_next_device_to_run(ahd);
/*
* In 2.5.X, the "done lock" is the ahd_lock.
* Instead of dropping and re-acquiring the same
* lock in the 2.5.X case, just hold our ahd_lock
* the whole time. ahd_done_lock() has been
* made a no-op for 2.5.X too.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
if (next_dev)
if (ahd_linux_next_device_to_run(ahd) != NULL)
ahd_schedule_runq(ahd);
if (acmd != NULL) {
acmd = ahd_linux_run_complete_queue(ahd, acmd);
if (acmd != NULL) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, &flags);
#endif
ahd_schedule_completeq(ahd, acmd);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, &flags);
#endif
}
void
......@@ -4897,7 +4668,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
*/
dev->openings = 0;
#ifdef AHD_DEBUG
if (ahd_debug & AHD_SHOW_QFULL) {
if ((ahd_debug & AHD_SHOW_QFULL) != 0) {
ahd_print_path(ahd, scb);
printf("Dropping tag count to %d\n",
dev->active);
......@@ -4927,7 +4698,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
}
ahd_set_transaction_status(scb, CAM_REQUEUE_REQ);
ahd_set_scsi_status(scb, SCSI_STATUS_OK);
ahd_set_tags(ahd, &devinfo,
ahd_platform_set_tags(ahd, &devinfo,
(dev->flags & AHD_DEV_Q_BASIC)
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
break;
......@@ -4937,7 +4708,7 @@ ahd_linux_handle_scsi_status(struct ahd_softc *ahd,
* as if the target returned BUSY SCSI status.
*/
dev->openings = 1;
ahd_set_tags(ahd, &devinfo,
ahd_platform_set_tags(ahd, &devinfo,
(dev->flags & AHD_DEV_Q_BASIC)
? AHD_QUEUE_BASIC : AHD_QUEUE_TAGGED);
ahd_set_scsi_status(scb, SCSI_STATUS_BUSY);
......@@ -5136,7 +4907,6 @@ ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
u_int ppr_options;
u_int trans_version;
u_int prot_version;
static int warned_user;
/*
* Determine if this lun actually exists. If so,
......@@ -5175,26 +4945,6 @@ ahd_linux_filter_inquiry(struct ahd_softc *ahd, struct ahd_devinfo *devinfo)
trans_version = user->transport_version;
prot_version = MIN(user->protocol_version, SID_ANSI_REV(sid));
/*
* If we have read streaming info for this controller,
* apply it to this target.
*/
if (warned_user == 0
&& ahd->unit >= NUM_ELEMENTS(aic79xx_rd_strm_info)) {
printf("aic79xx: WARNING, insufficient rd_strm instances "
"for installed controllers. Using defaults\n");
printf("aic79xx: Please update the aic79xx_rd_strm_info "
"array in the aic79xx_osm.c source file.\n");
warned_user++;
} else {
uint16_t rd_strm_mask;
rd_strm_mask = aic79xx_rd_strm_info[ahd->unit];
if ((rd_strm_mask & devinfo->target_mask) == 0)
ppr_options &= ~MSG_EXT_PPR_RD_STRM;
}
/*
* Only attempt SPI3/4 once we've verified that
* the device claims to support SPI3/4 features.
......@@ -5270,6 +5020,7 @@ ahd_release_simq(struct ahd_softc *ahd)
ahd->platform_data->flags &= ~AHD_DV_WAIT_SIMQ_RELEASE;
up(&ahd->platform_data->dv_sem);
}
ahd_schedule_runq(ahd);
ahd_unlock(ahd, &s);
/*
* There is still a race here. The mid-layer
......@@ -5279,8 +5030,6 @@ ahd_release_simq(struct ahd_softc *ahd)
*/
if (unblock_reqs)
scsi_unblock_requests(ahd->platform_data->host);
ahd_schedule_runq(ahd);
}
static void
......@@ -5370,6 +5119,21 @@ ahd_linux_init(void)
static void __exit
ahd_linux_exit(void)
{
struct ahd_softc *ahd;
u_long l;
/*
* Shutdown DV threads before going into the SCSI mid-layer.
* This avoids situations where the mid-layer locks the entire
* kernel so that waiting for our DV threads to exit leads
* to deadlock.
*/
ahd_list_lock(&l);
TAILQ_FOREACH(ahd, &ahd_tailq, links) {
ahd_linux_kill_dv_thread(ahd);
}
ahd_list_unlock(&l);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* In 2.4 we have to unregister from the PCI core _after_
......@@ -5379,6 +5143,8 @@ ahd_linux_exit(void)
scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template);
#endif
ahd_linux_pci_exit();
unregister_reboot_notifier(&ahd_linux_notifier);
}
module_init(ahd_linux_init);
......
......@@ -36,7 +36,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#118 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#121 $
*
*/
#ifndef _AIC79XX_LINUX_H_
......@@ -92,6 +92,7 @@
* Compile in debugging code, but do not enable any printfs.
*/
#define AHD_DEBUG 1
#define AHD_DEBUG_OPTS 0
#endif
/* No debugging code. */
#endif
......@@ -286,7 +287,13 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec)
#include <linux/smp.h>
#endif
#define AIC79XX_DRIVER_VERSION "1.3.4"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK))
#define AHD_SCSI_HAS_HOST_LOCK 1
#else
#define AHD_SCSI_HAS_HOST_LOCK 0
#endif
#define AIC79XX_DRIVER_VERSION "1.3.5"
/**************************** Front End Queues ********************************/
/*
......@@ -733,7 +740,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
}
......@@ -747,23 +753,24 @@ static __inline void
ahd_midlayer_entrypoint_lock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us, so avoid locking again.
* In 2.5.X and some 2.4.X versions, the midlayer takes our
* lock just before calling us, so we avoid locking again.
* For other kernel versions, the io_request_lock is taken
* just before our entry point is called. In this case, we
* trade the io_request_lock for our per-softc lock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_lock(ahd, flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
spin_lock(&ahd->platform_data->spin_lock);
#endif
}
static __inline void
ahd_midlayer_entrypoint_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
/*
* In 2.5.X, the midlayer takes our lock just before
* calling us and unlocks when we return, so let it do the unlock.
*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
ahd_unlock(ahd, flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&ahd->platform_data->spin_lock);
spin_lock(&io_request_lock);
#endif
}
......@@ -780,17 +787,16 @@ ahd_done_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_done_lock(struct ahd_softc *ahd, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
*flags = 0;
spin_lock_irqsave(&io_request_lock, *flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_lock(&io_request_lock);
#endif
}
static __inline void
ahd_done_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
spin_unlock_irqrestore(&io_request_lock, *flags);
#if AHD_SCSI_HAS_HOST_LOCK == 0
spin_unlock(&io_request_lock);
#endif
}
......@@ -803,7 +809,6 @@ ahd_list_lockinit()
static __inline void
ahd_list_lock(unsigned long *flags)
{
*flags = 0;
spin_lock_irqsave(&ahd_list_spinlock, *flags);
}
......@@ -822,7 +827,6 @@ ahd_lockinit(struct ahd_softc *ahd)
static __inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......@@ -860,7 +864,6 @@ ahd_list_lockinit()
static __inline void
ahd_list_lock(unsigned long *flags)
{
*flags = 0;
save_flags(*flags);
cli();
}
......
......@@ -38,7 +38,7 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#67 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx_pci.c#70 $
*
* $FreeBSD$
*/
......@@ -466,6 +466,7 @@ ahd_pci_test_register_access(struct ahd_softc *ahd)
static int
ahd_check_extport(struct ahd_softc *ahd)
{
struct vpd_config vpd;
struct seeprom_config *sc;
u_int adapter_control;
int have_seeprom;
......@@ -476,6 +477,27 @@ ahd_check_extport(struct ahd_softc *ahd)
if (have_seeprom) {
u_int start_addr;
/*
* Fetch VPD for this function and parse it.
*/
if (bootverbose)
printf("%s: Reading VPD from SEEPROM...",
ahd_name(ahd));
/* Address is always in units of 16bit words */
start_addr = ((2 * sizeof(*sc))
+ (sizeof(vpd) * (ahd->channel - 'A'))) / 2;
error = ahd_read_seeprom(ahd, (uint16_t *)&vpd,
start_addr, sizeof(vpd)/2,
/*bytestream*/TRUE);
if (error == 0)
error = ahd_parse_vpddata(ahd, &vpd);
if (bootverbose)
printf("%s: VPD parsing %s\n",
ahd_name(ahd),
error == 0 ? "successful" : "failed");
if (bootverbose)
printf("%s: Reading SEEPROM...", ahd_name(ahd));
......@@ -483,7 +505,8 @@ ahd_check_extport(struct ahd_softc *ahd)
start_addr = (sizeof(*sc) / 2) * (ahd->channel - 'A');
error = ahd_read_seeprom(ahd, (uint16_t *)sc,
start_addr, sizeof(*sc)/2);
start_addr, sizeof(*sc)/2,
/*bytestream*/FALSE);
if (error != 0) {
printf("Unable to read SEEPROM\n");
......@@ -803,7 +826,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
/* Clear latched errors. So our interrupt deasserts. */
ahd_outb(ahd, DCHSPLTSTAT0, split_status[i]);
ahd_outb(ahd, DCHSPLTSTAT1, split_status1[i]);
if (i != 0)
if (i > 1)
continue;
sg_split_status[i] = ahd_inb(ahd, SGSPLTSTAT0);
sg_split_status1[i] = ahd_inb(ahd, SGSPLTSTAT1);
......@@ -825,7 +848,7 @@ ahd_pci_split_intr(struct ahd_softc *ahd, u_int intstat)
split_status_source[i]);
}
if (i != 0)
if (i > 1)
continue;
if ((sg_split_status[i] & (0x1 << bit)) != 0) {
......@@ -887,7 +910,8 @@ ahd_aic7902_setup(struct ahd_softc *ahd)
| AHD_PKTIZED_STATUS_BUG|AHD_PKT_LUN_BUG
| AHD_MDFF_WSCBPTR_BUG|AHD_REG_SLOW_SETTLE_BUG
| AHD_SET_MODE_BUG|AHD_BUSFREEREV_BUG
| AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG;
| AHD_NONPACKFIFO_BUG|AHD_PACED_NEGTABLE_BUG
| AHD_FAINT_LED_BUG;
/*
* IO Cell paramter setup.
......
......@@ -37,7 +37,7 @@
* String handling code courtesy of Gerard Roudier's <groudier@club-internet.fr>
* sym driver.
*
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#13 $
* $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_proc.c#14 $
*/
#include "aic79xx_osm.h"
#include "aic79xx_inline.h"
......@@ -262,7 +262,8 @@ ahd_proc_write_seeprom(struct ahd_softc *ahd, char *buffer, int length)
ahd_write_seeprom(ahd, (u_int16_t *)buffer, start_addr,
sizeof(struct seeprom_config)/2);
ahd_read_seeprom(ahd, (uint16_t *)ahd->seep_config,
start_addr, sizeof(struct seeprom_config)/2);
start_addr, sizeof(struct seeprom_config)/2,
/*ByteStream*/FALSE);
ahd_release_seeprom(ahd);
written = length;
}
......
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#87 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/
typedef int (ahd_reg_print_t)(u_int, u_int *, u_int);
typedef struct ahd_reg_parse_entry {
......@@ -3720,7 +3720,7 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
#define AHD_AMPLITUDE_SHIFT 0x00
#define AHD_AMPLITUDE_MASK 0x07
#define AHD_ANNEXCOL_AMPLITUDE 0x06
#define AHD_SLEWRATE_DEF_REVA 0x01
#define AHD_SLEWRATE_DEF_REVA 0x08
#define AHD_SLEWRATE_SHIFT 0x03
#define AHD_SLEWRATE_MASK 0x78
#define AHD_PRECOMP_CUTBACK_29 0x06
......@@ -3775,5 +3775,5 @@ ahd_reg_print_t ahd_scb_disconnected_lists_print;
/* Exported Labels */
#define LABEL_seq_isr 0x268
#define LABEL_timer_isr 0x264
#define LABEL_seq_isr 0x26d
#define LABEL_timer_isr 0x269
......@@ -2,8 +2,8 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#87 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/
#include "aic79xx_osm.h"
......
......@@ -2,97 +2,102 @@
* DO NOT EDIT - This file is automatically generated
* from the following source files:
*
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#87 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#62 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.seq#89 $
* $Id: //depot/aic7xxx/aic7xxx/aic79xx.reg#65 $
*/
static uint8_t seqprog[] = {
0xff, 0x02, 0x06, 0x78,
0x00, 0xea, 0x46, 0x59,
0x00, 0xea, 0x50, 0x59,
0x01, 0xea, 0x04, 0x30,
0xff, 0x04, 0x0c, 0x78,
0x19, 0xea, 0x46, 0x59,
0x19, 0xea, 0x50, 0x59,
0x19, 0xea, 0x04, 0x00,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x60, 0x3a, 0x1a, 0x68,
0x04, 0x47, 0x1b, 0x68,
0xff, 0x21, 0x1b, 0x70,
0x40, 0x4b, 0x88, 0x69,
0x00, 0xe2, 0x4a, 0x59,
0x40, 0x4b, 0x88, 0x69,
0x20, 0x4b, 0x78, 0x69,
0x40, 0x4b, 0x92, 0x69,
0x00, 0xe2, 0x54, 0x59,
0x40, 0x4b, 0x92, 0x69,
0x20, 0x4b, 0x82, 0x69,
0xfc, 0x42, 0x24, 0x78,
0x10, 0x40, 0x24, 0x78,
0x00, 0xe2, 0xd6, 0x5d,
0x00, 0xe2, 0xe0, 0x5d,
0x20, 0x4d, 0x28, 0x78,
0x00, 0xe2, 0xd6, 0x5d,
0x00, 0xe2, 0x34, 0x58,
0x00, 0xe2, 0x66, 0x58,
0x00, 0xe2, 0x76, 0x58,
0x00, 0xe2, 0xe0, 0x5d,
0x30, 0x3f, 0xc0, 0x09,
0x30, 0xe0, 0x30, 0x60,
0x7f, 0x4a, 0x94, 0x08,
0x00, 0xe2, 0x32, 0x40,
0xc0, 0x4a, 0x94, 0x00,
0x00, 0xe2, 0x3e, 0x58,
0x00, 0xe2, 0x70, 0x58,
0x00, 0xe2, 0x80, 0x58,
0x00, 0xe2, 0x06, 0x40,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x01, 0x52, 0x8c, 0x7d,
0x01, 0x52, 0x96, 0x7d,
0x02, 0x58, 0x50, 0x31,
0xff, 0xea, 0x10, 0x0b,
0xff, 0x93, 0x45, 0x78,
0x50, 0x4b, 0x40, 0x68,
0xff, 0x93, 0x4f, 0x78,
0x50, 0x4b, 0x4a, 0x68,
0xbf, 0x3a, 0x74, 0x08,
0x14, 0xea, 0x46, 0x59,
0x14, 0xea, 0x50, 0x59,
0x14, 0xea, 0x04, 0x00,
0x08, 0xa8, 0x51, 0x03,
0x01, 0xa4, 0x4d, 0x78,
0x00, 0xe2, 0x42, 0x5b,
0x00, 0xe2, 0x34, 0x40,
0x01, 0xa4, 0x57, 0x78,
0x00, 0xe2, 0x4c, 0x5b,
0x00, 0xe2, 0x3e, 0x40,
0xff, 0xea, 0xd4, 0x19,
0x02, 0xa8, 0x84, 0x32,
0x00, 0xea, 0x3a, 0x59,
0x00, 0xea, 0x44, 0x59,
0x01, 0xea, 0x00, 0x30,
0x00, 0xe2, 0xc2, 0x5d,
0x00, 0xe2, 0x8c, 0x4d,
0x11, 0xea, 0x3a, 0x59,
0x00, 0xe2, 0xcc, 0x5d,
0x00, 0xe2, 0x96, 0x4d,
0x11, 0xea, 0x44, 0x59,
0x11, 0xea, 0x00, 0x00,
0x00, 0xe2, 0xc2, 0x5d,
0x00, 0xe2, 0x8c, 0x4d,
0x33, 0xea, 0x3a, 0x59,
0x00, 0xe2, 0xcc, 0x5d,
0x00, 0xe2, 0x96, 0x4d,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x00, 0xe2, 0x3a, 0x43,
0x00, 0xea, 0x3a, 0x59,
0x00, 0xe2, 0x44, 0x43,
0x00, 0xea, 0x44, 0x59,
0x01, 0xea, 0x00, 0x30,
0x80, 0xf9, 0x6e, 0x68,
0x00, 0xe2, 0x38, 0x59,
0x11, 0xea, 0x3a, 0x59,
0x80, 0xf9, 0x78, 0x68,
0x00, 0xe2, 0x42, 0x59,
0x11, 0xea, 0x44, 0x59,
0x11, 0xea, 0x00, 0x00,
0x80, 0xf9, 0x38, 0x79,
0x80, 0xf9, 0x42, 0x79,
0xff, 0xea, 0xd4, 0x0d,
0x22, 0xea, 0x3a, 0x59,
0x22, 0xea, 0x44, 0x59,
0x22, 0xea, 0x00, 0x00,
0x10, 0x16, 0x80, 0x78,
0x10, 0x16, 0x8a, 0x78,
0x01, 0x0b, 0xa2, 0x32,
0x10, 0x16, 0x2c, 0x00,
0x18, 0xad, 0xee, 0x78,
0x04, 0xad, 0xbc, 0x68,
0x80, 0xad, 0x8c, 0x7d,
0x10, 0xad, 0x8a, 0x78,
0x18, 0xad, 0xf8, 0x78,
0x04, 0xad, 0xc6, 0x68,
0x80, 0xad, 0x96, 0x7d,
0x10, 0xad, 0x94, 0x78,
0xe7, 0xad, 0x5a, 0x0d,
0xe7, 0xad, 0x5a, 0x09,
0x00, 0xe2, 0x98, 0x58,
0x00, 0xe2, 0xa2, 0x58,
0xff, 0xea, 0x56, 0x02,
0x04, 0x7c, 0x78, 0x32,
0x20, 0x16, 0x8c, 0x7d,
0x20, 0x16, 0x96, 0x7d,
0x04, 0x38, 0x79, 0x32,
0x80, 0x37, 0x6f, 0x16,
0xff, 0x2d, 0xa7, 0x60,
0xff, 0x29, 0xa7, 0x60,
0x40, 0x51, 0xb7, 0x78,
0xff, 0x4f, 0xa7, 0x68,
0xff, 0x2d, 0xb1, 0x60,
0xff, 0x29, 0xb1, 0x60,
0x40, 0x51, 0xc1, 0x78,
0xff, 0x4f, 0xb1, 0x68,
0xff, 0x4d, 0xc1, 0x19,
0x00, 0x4e, 0xd5, 0x19,
0x00, 0xe2, 0xb6, 0x50,
0x00, 0xe2, 0xc0, 0x50,
0x01, 0x4c, 0xc1, 0x31,
0x00, 0x50, 0xd5, 0x19,
0x00, 0xe2, 0xb6, 0x48,
0x80, 0x18, 0x8c, 0x7d,
0x00, 0xe2, 0xc0, 0x48,
0x80, 0x18, 0x96, 0x7d,
0x02, 0x4a, 0x1d, 0x30,
0x10, 0xea, 0x18, 0x00,
0x60, 0x18, 0x30, 0x00,
......@@ -100,7 +105,7 @@ static uint8_t seqprog[] = {
0x02, 0xea, 0x02, 0x00,
0xff, 0xea, 0xa0, 0x0a,
0x80, 0x18, 0x30, 0x04,
0x40, 0xad, 0x8c, 0x7d,
0x40, 0xad, 0x96, 0x7d,
0xe7, 0xad, 0x5a, 0x09,
0x02, 0xa8, 0x40, 0x31,
0xff, 0xea, 0xc0, 0x09,
......@@ -110,25 +115,25 @@ static uint8_t seqprog[] = {
0xff, 0xea, 0x2a, 0x03,
0xff, 0xea, 0x2e, 0x03,
0x01, 0x10, 0xd4, 0x31,
0x10, 0xa8, 0xe3, 0x68,
0x10, 0xa8, 0xed, 0x68,
0x3d, 0xa9, 0xc5, 0x29,
0xfe, 0xe2, 0xc4, 0x09,
0x01, 0xea, 0xc6, 0x01,
0x02, 0xe2, 0xc8, 0x31,
0x02, 0xec, 0x50, 0x31,
0x02, 0xa0, 0xda, 0x31,
0xff, 0xa9, 0xe2, 0x70,
0xff, 0xa9, 0xec, 0x70,
0x02, 0xa0, 0x28, 0x37,
0xff, 0x21, 0xeb, 0x70,
0xff, 0x21, 0xf5, 0x70,
0x02, 0x22, 0x51, 0x31,
0x02, 0xa0, 0x2c, 0x33,
0x02, 0xa0, 0x44, 0x36,
0x02, 0xa0, 0x40, 0x32,
0x02, 0xa0, 0x44, 0x36,
0x04, 0x47, 0xf3, 0x68,
0x40, 0x16, 0x1e, 0x69,
0xff, 0x2d, 0x23, 0x61,
0xff, 0x29, 0x8d, 0x75,
0x04, 0x47, 0xfd, 0x68,
0x40, 0x16, 0x28, 0x69,
0xff, 0x2d, 0x2d, 0x61,
0xff, 0x29, 0x97, 0x75,
0x01, 0x37, 0xc1, 0x31,
0x02, 0x28, 0x55, 0x32,
0x01, 0xea, 0x5a, 0x01,
......@@ -140,20 +145,20 @@ static uint8_t seqprog[] = {
0x01, 0x50, 0xa1, 0x1a,
0xff, 0x4e, 0x9d, 0x1a,
0xff, 0x4f, 0x9f, 0x22,
0xff, 0x8d, 0x17, 0x71,
0x80, 0xac, 0x16, 0x71,
0x20, 0x16, 0x16, 0x69,
0xff, 0x8d, 0x21, 0x71,
0x80, 0xac, 0x20, 0x71,
0x20, 0x16, 0x20, 0x69,
0x02, 0x8c, 0x51, 0x31,
0x00, 0xe2, 0x00, 0x41,
0x00, 0xe2, 0x0a, 0x41,
0x01, 0xac, 0x08, 0x31,
0x09, 0xea, 0x5a, 0x01,
0x02, 0x8c, 0x51, 0x32,
0xff, 0xea, 0x1a, 0x07,
0x04, 0x24, 0xf9, 0x30,
0x1d, 0xea, 0x2e, 0x41,
0x1d, 0xea, 0x38, 0x41,
0x02, 0x2c, 0x51, 0x31,
0x04, 0xac, 0xf9, 0x30,
0x19, 0xea, 0x2e, 0x59,
0x19, 0xea, 0x38, 0x59,
0x02, 0x8c, 0x59, 0x32,
0x02, 0x28, 0x19, 0x33,
0x02, 0xa8, 0x50, 0x36,
......@@ -175,23 +180,23 @@ static uint8_t seqprog[] = {
0x02, 0x20, 0xb9, 0x30,
0x02, 0x20, 0x51, 0x31,
0x4c, 0xa9, 0xd7, 0x28,
0x10, 0xa8, 0x59, 0x79,
0x10, 0xa8, 0x63, 0x79,
0x01, 0x6b, 0xc0, 0x30,
0x02, 0x64, 0xc8, 0x00,
0x40, 0x3a, 0x74, 0x04,
0x00, 0xe2, 0x66, 0x58,
0x33, 0xea, 0x3a, 0x59,
0x00, 0xe2, 0x70, 0x58,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x30, 0x3f, 0xc0, 0x09,
0x30, 0xe0, 0x5a, 0x61,
0x20, 0x3f, 0x70, 0x69,
0x10, 0x3f, 0x5a, 0x79,
0x30, 0xe0, 0x64, 0x61,
0x20, 0x3f, 0x7a, 0x69,
0x10, 0x3f, 0x64, 0x79,
0x02, 0xea, 0x7e, 0x00,
0x00, 0xea, 0x3a, 0x59,
0x00, 0xea, 0x44, 0x59,
0x01, 0xea, 0x00, 0x30,
0x02, 0x48, 0x51, 0x35,
0x01, 0xea, 0x7e, 0x00,
0x11, 0xea, 0x3a, 0x59,
0x11, 0xea, 0x44, 0x59,
0x11, 0xea, 0x00, 0x00,
0x02, 0x48, 0x51, 0x35,
0x08, 0xea, 0x98, 0x00,
......@@ -201,11 +206,11 @@ static uint8_t seqprog[] = {
0x0f, 0x67, 0xc0, 0x09,
0x00, 0x34, 0x69, 0x02,
0x20, 0xea, 0x96, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x40, 0x3a, 0xa4, 0x69,
0x00, 0xe2, 0xf8, 0x41,
0x40, 0x3a, 0xae, 0x69,
0x02, 0x55, 0x06, 0x68,
0x02, 0x56, 0xa4, 0x69,
0xff, 0x5b, 0xa4, 0x61,
0x02, 0x56, 0xae, 0x69,
0xff, 0x5b, 0xae, 0x61,
0x02, 0x20, 0x51, 0x31,
0x80, 0xea, 0xb2, 0x01,
0x44, 0xea, 0x00, 0x00,
......@@ -213,36 +218,36 @@ static uint8_t seqprog[] = {
0x33, 0xea, 0x00, 0x00,
0xff, 0xea, 0xb2, 0x09,
0xff, 0xe0, 0xc0, 0x19,
0xff, 0xe0, 0xa6, 0x79,
0xff, 0xe0, 0xb0, 0x79,
0x02, 0x94, 0x51, 0x31,
0x00, 0xe2, 0x9c, 0x41,
0x00, 0xe2, 0xa6, 0x41,
0x02, 0x5e, 0x50, 0x31,
0x02, 0xa8, 0xb8, 0x30,
0x02, 0x5c, 0x50, 0x31,
0xff, 0x95, 0xb7, 0x71,
0xff, 0x95, 0xc1, 0x71,
0x02, 0x94, 0x41, 0x31,
0x02, 0x22, 0x51, 0x31,
0x02, 0xa0, 0x2c, 0x33,
0x02, 0xa0, 0x44, 0x32,
0x00, 0xe2, 0xc0, 0x41,
0x10, 0xa8, 0xc1, 0x69,
0x00, 0xe2, 0xca, 0x41,
0x10, 0xa8, 0xcb, 0x69,
0x3d, 0xa9, 0xc9, 0x29,
0x01, 0xe4, 0xc8, 0x01,
0x01, 0xea, 0xca, 0x01,
0xff, 0xea, 0xda, 0x01,
0x02, 0x20, 0x51, 0x31,
0x02, 0x96, 0x41, 0x32,
0xff, 0x21, 0xc9, 0x61,
0xff, 0x21, 0xd3, 0x61,
0xff, 0xea, 0x46, 0x02,
0x02, 0x5c, 0x50, 0x31,
0x40, 0xea, 0x96, 0x00,
0x02, 0x56, 0xde, 0x6d,
0x01, 0x55, 0xde, 0x6d,
0x10, 0xa8, 0xd5, 0x79,
0x10, 0x40, 0xde, 0x69,
0x01, 0x56, 0xde, 0x79,
0x02, 0x56, 0xe8, 0x6d,
0x01, 0x55, 0xe8, 0x6d,
0x10, 0xa8, 0xdf, 0x79,
0x10, 0x40, 0xe8, 0x69,
0x01, 0x56, 0xe8, 0x79,
0xff, 0x93, 0x07, 0x78,
0x13, 0xea, 0x46, 0x59,
0x13, 0xea, 0x50, 0x59,
0x13, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x06, 0x40,
0xbf, 0x3a, 0x74, 0x08,
......@@ -253,104 +258,104 @@ static uint8_t seqprog[] = {
0x40, 0xea, 0x66, 0x02,
0x08, 0x3c, 0x78, 0x00,
0x80, 0xea, 0x62, 0x02,
0x00, 0xe2, 0xa2, 0x5b,
0x00, 0xe2, 0xac, 0x5b,
0x01, 0x36, 0xc1, 0x31,
0x9f, 0xe0, 0x44, 0x7c,
0x80, 0xe0, 0x02, 0x72,
0xa0, 0xe0, 0x3a, 0x72,
0xc0, 0xe0, 0x30, 0x72,
0xe0, 0xe0, 0x6a, 0x72,
0x01, 0xea, 0x46, 0x59,
0x9f, 0xe0, 0x4e, 0x7c,
0x80, 0xe0, 0x0c, 0x72,
0xa0, 0xe0, 0x44, 0x72,
0xc0, 0xe0, 0x3a, 0x72,
0xe0, 0xe0, 0x74, 0x72,
0x01, 0xea, 0x50, 0x59,
0x01, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x80, 0x33, 0x09, 0x7a,
0x03, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xf8, 0x41,
0x80, 0x33, 0x13, 0x7a,
0x03, 0xea, 0x50, 0x59,
0x03, 0xea, 0x04, 0x00,
0xee, 0x00, 0x10, 0x6a,
0xee, 0x00, 0x1a, 0x6a,
0x05, 0xea, 0xb4, 0x00,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x02, 0xa8, 0x90, 0x32,
0x00, 0xe2, 0x60, 0x59,
0x00, 0xe2, 0x6a, 0x59,
0xef, 0x92, 0xd5, 0x19,
0x00, 0xe2, 0x20, 0x52,
0x00, 0xe2, 0x2a, 0x52,
0x09, 0x80, 0xe1, 0x30,
0x02, 0xea, 0x36, 0x00,
0xa8, 0xea, 0x32, 0x00,
0x00, 0xe2, 0x26, 0x42,
0x00, 0xe2, 0x30, 0x42,
0x01, 0x92, 0xd1, 0x30,
0x10, 0x80, 0x89, 0x31,
0x20, 0xea, 0x32, 0x00,
0xbf, 0x33, 0x67, 0x0a,
0x20, 0x19, 0x28, 0x6a,
0x02, 0x4d, 0xee, 0x69,
0x20, 0x19, 0x32, 0x6a,
0x02, 0x4d, 0xf8, 0x69,
0x40, 0x33, 0x67, 0x02,
0x00, 0xe2, 0xee, 0x41,
0x80, 0x33, 0xa7, 0x6a,
0x00, 0xe2, 0xf8, 0x41,
0x80, 0x33, 0xb1, 0x6a,
0x01, 0x44, 0x10, 0x33,
0x08, 0xa8, 0x51, 0x03,
0x00, 0xe2, 0xee, 0x41,
0x00, 0xe2, 0xf8, 0x41,
0x10, 0xea, 0x80, 0x00,
0x01, 0x31, 0xc5, 0x31,
0x80, 0xe2, 0x56, 0x62,
0x10, 0xa8, 0x7b, 0x6a,
0x80, 0xe2, 0x60, 0x62,
0x10, 0xa8, 0x85, 0x6a,
0xc0, 0xaa, 0xc5, 0x01,
0x40, 0xa8, 0x47, 0x6a,
0x40, 0xa8, 0x51, 0x6a,
0xbf, 0xe2, 0xc4, 0x09,
0x20, 0xa8, 0x5b, 0x7a,
0x20, 0xa8, 0x65, 0x7a,
0x01, 0xe2, 0x88, 0x30,
0x00, 0xe2, 0xa2, 0x5b,
0xa0, 0x36, 0x63, 0x62,
0x00, 0xe2, 0xac, 0x5b,
0xa0, 0x36, 0x6d, 0x62,
0x23, 0xa8, 0x89, 0x08,
0x00, 0xe2, 0xa2, 0x5b,
0xa0, 0x36, 0x63, 0x62,
0x00, 0xa8, 0x5a, 0x42,
0xff, 0xe2, 0x5a, 0x62,
0x00, 0xe2, 0x7a, 0x42,
0x00, 0xe2, 0xac, 0x5b,
0xa0, 0x36, 0x6d, 0x62,
0x00, 0xa8, 0x64, 0x42,
0xff, 0xe2, 0x64, 0x62,
0x00, 0xe2, 0x84, 0x42,
0x40, 0xea, 0x98, 0x00,
0x01, 0xe2, 0x88, 0x30,
0x00, 0xe2, 0xa2, 0x5b,
0xa0, 0x36, 0x39, 0x72,
0x00, 0xe2, 0xac, 0x5b,
0xa0, 0x36, 0x43, 0x72,
0x40, 0xea, 0x98, 0x00,
0x01, 0x31, 0x89, 0x32,
0x08, 0xea, 0x62, 0x02,
0x00, 0xe2, 0xee, 0x41,
0xe0, 0xea, 0xbe, 0x5b,
0x80, 0xe0, 0xb2, 0x6a,
0x04, 0xe0, 0x50, 0x73,
0x02, 0xe0, 0x80, 0x73,
0x00, 0xea, 0x10, 0x73,
0x03, 0xe0, 0x90, 0x73,
0x23, 0xe0, 0x8c, 0x72,
0x08, 0xe0, 0xae, 0x72,
0x00, 0xe2, 0xa2, 0x5b,
0x07, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xf8, 0x41,
0xe0, 0xea, 0xc8, 0x5b,
0x80, 0xe0, 0xbc, 0x6a,
0x04, 0xe0, 0x5a, 0x73,
0x02, 0xe0, 0x8a, 0x73,
0x00, 0xea, 0x1a, 0x73,
0x03, 0xe0, 0x9a, 0x73,
0x23, 0xe0, 0x96, 0x72,
0x08, 0xe0, 0xb8, 0x72,
0x00, 0xe2, 0xac, 0x5b,
0x07, 0xea, 0x50, 0x59,
0x07, 0xea, 0x04, 0x00,
0x08, 0x42, 0xef, 0x71,
0x04, 0x42, 0x89, 0x62,
0x08, 0x42, 0xf9, 0x71,
0x04, 0x42, 0x93, 0x62,
0x01, 0x43, 0x89, 0x30,
0x00, 0xe2, 0x7a, 0x42,
0x00, 0xe2, 0x84, 0x42,
0x01, 0x44, 0xd4, 0x31,
0x00, 0xe2, 0x7a, 0x42,
0x00, 0xe2, 0x84, 0x42,
0x01, 0x00, 0x60, 0x32,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x4c, 0x34, 0xc1, 0x28,
0x01, 0x64, 0xc0, 0x31,
0x00, 0x30, 0x3b, 0x59,
0x00, 0x30, 0x45, 0x59,
0x01, 0x30, 0x01, 0x30,
0x01, 0xe0, 0xac, 0x7a,
0xa0, 0xea, 0xb4, 0x5b,
0x01, 0xa0, 0xac, 0x62,
0x01, 0x84, 0xa5, 0x7a,
0x01, 0xa7, 0xae, 0x7a,
0x00, 0xe2, 0xae, 0x42,
0x03, 0xea, 0x46, 0x59,
0x01, 0xe0, 0xb6, 0x7a,
0xa0, 0xea, 0xbe, 0x5b,
0x01, 0xa0, 0xb6, 0x62,
0x01, 0x84, 0xaf, 0x7a,
0x01, 0xa7, 0xb8, 0x7a,
0x00, 0xe2, 0xb8, 0x42,
0x03, 0xea, 0x50, 0x59,
0x03, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xae, 0x42,
0x07, 0xea, 0xc6, 0x5b,
0x00, 0xe2, 0xb8, 0x42,
0x07, 0xea, 0xd0, 0x5b,
0x01, 0x44, 0xd4, 0x31,
0x00, 0xe2, 0xee, 0x41,
0x00, 0xe2, 0xf8, 0x41,
0x3f, 0xe0, 0x6a, 0x0a,
0xc0, 0x34, 0xc1, 0x09,
0x00, 0x35, 0x51, 0x01,
......@@ -361,54 +366,54 @@ static uint8_t seqprog[] = {
0x01, 0xea, 0xc6, 0x01,
0x02, 0xe2, 0xc8, 0x31,
0x02, 0xec, 0x40, 0x31,
0xff, 0xa1, 0xce, 0x72,
0xff, 0xa1, 0xd8, 0x72,
0x02, 0xe8, 0xda, 0x31,
0x02, 0xa0, 0x50, 0x31,
0x00, 0xe2, 0xf0, 0x42,
0x00, 0xe2, 0xfa, 0x42,
0x80, 0x33, 0x67, 0x02,
0x01, 0x44, 0xd4, 0x31,
0x00, 0xe2, 0xa2, 0x5b,
0x00, 0xe2, 0xac, 0x5b,
0x01, 0x33, 0x67, 0x02,
0xe0, 0x36, 0x0b, 0x63,
0xe0, 0x36, 0x15, 0x63,
0x02, 0x33, 0x67, 0x02,
0x20, 0x46, 0x04, 0x63,
0x20, 0x46, 0x0e, 0x63,
0xff, 0xea, 0x52, 0x09,
0xa8, 0xea, 0xb4, 0x5b,
0x04, 0xa8, 0xeb, 0x7a,
0xa8, 0xea, 0xbe, 0x5b,
0x04, 0xa8, 0xf5, 0x7a,
0x01, 0x34, 0xc1, 0x31,
0x00, 0xa9, 0xeb, 0x62,
0x00, 0xa9, 0xf5, 0x62,
0x01, 0x35, 0xc1, 0x31,
0x00, 0xaa, 0xf5, 0x72,
0x00, 0xaa, 0xff, 0x72,
0x01, 0xa9, 0x52, 0x11,
0xff, 0xa9, 0xe0, 0x6a,
0x00, 0xe2, 0x04, 0x43,
0xff, 0xa9, 0xea, 0x6a,
0x00, 0xe2, 0x0e, 0x43,
0x10, 0x33, 0x67, 0x02,
0x04, 0xa8, 0x05, 0x7b,
0x04, 0xa8, 0x0f, 0x7b,
0xfb, 0xa8, 0x51, 0x0b,
0xff, 0xea, 0x66, 0x0a,
0x01, 0xa4, 0xff, 0x6a,
0x01, 0xa4, 0x09, 0x6b,
0x02, 0xa8, 0x90, 0x32,
0x00, 0xe2, 0x60, 0x59,
0x10, 0xa8, 0xaf, 0x7a,
0xff, 0xea, 0xc6, 0x5b,
0x00, 0xe2, 0xae, 0x42,
0x04, 0xea, 0x46, 0x59,
0x00, 0xe2, 0x6a, 0x59,
0x10, 0xa8, 0xb9, 0x7a,
0xff, 0xea, 0xd0, 0x5b,
0x00, 0xe2, 0xb8, 0x42,
0x04, 0xea, 0x50, 0x59,
0x04, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xae, 0x42,
0x04, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xb8, 0x42,
0x04, 0xea, 0x50, 0x59,
0x04, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x08, 0xa8, 0xa7, 0x7a,
0xc0, 0x33, 0x1b, 0x7b,
0x80, 0x33, 0xa7, 0x6a,
0xff, 0x88, 0x1b, 0x6b,
0x40, 0x33, 0xa7, 0x6a,
0x10, 0xa8, 0x21, 0x7b,
0x0a, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xf8, 0x41,
0x08, 0xa8, 0xb1, 0x7a,
0xc0, 0x33, 0x25, 0x7b,
0x80, 0x33, 0xb1, 0x6a,
0xff, 0x88, 0x25, 0x6b,
0x40, 0x33, 0xb1, 0x6a,
0x10, 0xa8, 0x2b, 0x7b,
0x0a, 0xea, 0x50, 0x59,
0x0a, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x3a, 0x5b,
0x00, 0xe2, 0x6c, 0x43,
0x50, 0x4b, 0x28, 0x6b,
0x00, 0xe2, 0x44, 0x5b,
0x00, 0xe2, 0x76, 0x43,
0x50, 0x4b, 0x32, 0x6b,
0xbf, 0x3a, 0x74, 0x08,
0x01, 0xe0, 0xf8, 0x31,
0xff, 0xea, 0xc0, 0x09,
......@@ -416,23 +421,23 @@ static uint8_t seqprog[] = {
0x00, 0x2f, 0x5f, 0x22,
0x04, 0x47, 0x8f, 0x02,
0x01, 0xfc, 0xc0, 0x35,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x02, 0x42, 0x51, 0x31,
0xff, 0x88, 0x47, 0x6b,
0x01, 0xa4, 0x43, 0x6b,
0x02, 0xa4, 0x4b, 0x6b,
0x01, 0x84, 0x4b, 0x7b,
0xff, 0x88, 0x51, 0x6b,
0x01, 0xa4, 0x4d, 0x6b,
0x02, 0xa4, 0x55, 0x6b,
0x01, 0x84, 0x55, 0x7b,
0x02, 0x28, 0x19, 0x33,
0x02, 0xa8, 0x50, 0x36,
0xff, 0x88, 0x4b, 0x73,
0x00, 0xe2, 0x24, 0x5b,
0xff, 0x88, 0x55, 0x73,
0x00, 0xe2, 0x2e, 0x5b,
0x02, 0x2c, 0x19, 0x33,
0x02, 0xa8, 0x58, 0x32,
0x04, 0xa4, 0x49, 0x07,
0xc0, 0x33, 0xa7, 0x6a,
0xc0, 0x33, 0xb1, 0x6a,
0x04, 0xa8, 0x51, 0x03,
0x20, 0xa8, 0x6d, 0x6b,
0x20, 0xa8, 0x77, 0x6b,
0x02, 0xa8, 0x40, 0x31,
0xc0, 0x34, 0xc1, 0x09,
0x00, 0x35, 0x51, 0x01,
......@@ -447,73 +452,73 @@ static uint8_t seqprog[] = {
0xf7, 0x57, 0xae, 0x08,
0x08, 0xea, 0x98, 0x00,
0x01, 0x44, 0xd4, 0x31,
0xee, 0x00, 0x76, 0x6b,
0xee, 0x00, 0x80, 0x6b,
0x02, 0xea, 0xb4, 0x00,
0x00, 0xe2, 0x9e, 0x5b,
0x09, 0x4c, 0x78, 0x7b,
0x00, 0xe2, 0xa8, 0x5b,
0x09, 0x4c, 0x82, 0x7b,
0x08, 0x4c, 0x06, 0x68,
0x0b, 0xea, 0x46, 0x59,
0x0b, 0xea, 0x50, 0x59,
0x0b, 0xea, 0x04, 0x00,
0x01, 0x44, 0xd4, 0x31,
0x20, 0x33, 0xef, 0x79,
0x00, 0xe2, 0x88, 0x5b,
0x00, 0xe2, 0xee, 0x41,
0x01, 0x84, 0x8d, 0x7b,
0x20, 0x33, 0xf9, 0x79,
0x00, 0xe2, 0x92, 0x5b,
0x00, 0xe2, 0xf8, 0x41,
0x01, 0x84, 0x97, 0x7b,
0x01, 0xa4, 0x49, 0x07,
0x08, 0x60, 0x30, 0x33,
0x08, 0x80, 0x41, 0x37,
0xdf, 0x33, 0x67, 0x0a,
0xee, 0x00, 0x9a, 0x6b,
0xee, 0x00, 0xa4, 0x6b,
0x05, 0xea, 0xb4, 0x00,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x00, 0xe2, 0x60, 0x59,
0x00, 0xe2, 0xae, 0x42,
0x00, 0xe2, 0x6a, 0x59,
0x00, 0xe2, 0xb8, 0x42,
0x01, 0xea, 0x6c, 0x02,
0xc0, 0xea, 0x66, 0x06,
0xff, 0x42, 0xae, 0x6b,
0x01, 0x41, 0xa2, 0x6b,
0x02, 0x41, 0xa2, 0x7b,
0xff, 0x42, 0xae, 0x6b,
0x01, 0x41, 0xa2, 0x6b,
0x02, 0x41, 0xa2, 0x7b,
0xff, 0x42, 0xae, 0x7b,
0x04, 0x4c, 0xa2, 0x6b,
0xff, 0x42, 0xb8, 0x6b,
0x01, 0x41, 0xac, 0x6b,
0x02, 0x41, 0xac, 0x7b,
0xff, 0x42, 0xb8, 0x6b,
0x01, 0x41, 0xac, 0x6b,
0x02, 0x41, 0xac, 0x7b,
0xff, 0x42, 0xb8, 0x7b,
0x04, 0x4c, 0xac, 0x6b,
0xe0, 0x41, 0x6c, 0x0e,
0x01, 0x44, 0xd4, 0x31,
0xff, 0x42, 0xb6, 0x7b,
0x04, 0x4c, 0xb6, 0x6b,
0xff, 0x42, 0xc0, 0x7b,
0x04, 0x4c, 0xc0, 0x6b,
0xe0, 0x41, 0x6c, 0x0a,
0xe0, 0x36, 0xef, 0x61,
0xe0, 0x36, 0xf9, 0x61,
0xff, 0xea, 0xca, 0x09,
0x01, 0xe2, 0xc8, 0x31,
0x01, 0x46, 0xda, 0x35,
0x01, 0x44, 0xd4, 0x35,
0x10, 0xea, 0x80, 0x00,
0x01, 0xe2, 0x62, 0x36,
0x04, 0xa6, 0xce, 0x7b,
0x04, 0xa6, 0xd8, 0x7b,
0xff, 0xea, 0x5a, 0x09,
0xff, 0xea, 0x4c, 0x0d,
0x01, 0xa6, 0xec, 0x6b,
0x10, 0xad, 0x8c, 0x7d,
0x80, 0xad, 0xe4, 0x6b,
0x08, 0xad, 0x8c, 0x6d,
0x01, 0xa6, 0xf6, 0x6b,
0x10, 0xad, 0x96, 0x7d,
0x80, 0xad, 0xee, 0x6b,
0x08, 0xad, 0x96, 0x6d,
0x04, 0x84, 0xf9, 0x30,
0x00, 0xea, 0x08, 0x81,
0xff, 0xea, 0xd4, 0x09,
0x02, 0x84, 0xf9, 0x88,
0x0d, 0xea, 0x5a, 0x01,
0x04, 0xa6, 0x4c, 0x05,
0x04, 0xa6, 0x8c, 0x7d,
0x04, 0xa6, 0x96, 0x7d,
0xff, 0xea, 0x5a, 0x09,
0x03, 0x84, 0x59, 0x89,
0x03, 0xea, 0x4c, 0x01,
0x80, 0x1a, 0x8c, 0x7d,
0x08, 0x19, 0x8c, 0x7d,
0x80, 0x1a, 0x96, 0x7d,
0x08, 0x19, 0x96, 0x7d,
0x08, 0xb0, 0xe0, 0x30,
0x04, 0xb0, 0xe0, 0x30,
0x03, 0xb0, 0xf0, 0x30,
0x01, 0x78, 0xfa, 0x7b,
0x01, 0x78, 0x04, 0x7c,
0x01, 0xa7, 0x4e, 0x11,
0x01, 0xb0, 0x06, 0x33,
0x7f, 0x83, 0xe9, 0x08,
......@@ -524,266 +529,266 @@ static uint8_t seqprog[] = {
0x00, 0x86, 0x0d, 0x23,
0x00, 0x87, 0x0f, 0x23,
0x01, 0x84, 0xc5, 0x31,
0x01, 0xa7, 0x10, 0x7c,
0x01, 0xa7, 0x1a, 0x7c,
0x04, 0xe2, 0xc4, 0x01,
0x80, 0x83, 0x17, 0x7c,
0x80, 0x83, 0x21, 0x7c,
0x02, 0xe2, 0xc4, 0x01,
0xff, 0xea, 0x4c, 0x09,
0x01, 0xe2, 0x36, 0x30,
0xc8, 0x19, 0x32, 0x00,
0x88, 0x19, 0x32, 0x00,
0x01, 0xac, 0xd4, 0x99,
0x00, 0xe2, 0x8c, 0x55,
0x00, 0xe2, 0x96, 0x55,
0xfe, 0xa6, 0x4c, 0x0d,
0x0b, 0x98, 0xe1, 0x30,
0x01, 0xa0, 0x4f, 0x09,
0xfd, 0xa4, 0x49, 0x09,
0x80, 0xa3, 0x2d, 0x7c,
0x80, 0xa3, 0x37, 0x7c,
0x02, 0xa4, 0x48, 0x01,
0x01, 0xa7, 0x30, 0x7c,
0x01, 0xa7, 0x3a, 0x7c,
0x04, 0xa4, 0x48, 0x01,
0x01, 0xa4, 0x36, 0x30,
0xa8, 0xea, 0x32, 0x00,
0xfd, 0xa4, 0x49, 0x0b,
0x05, 0xa3, 0x07, 0x33,
0x80, 0x83, 0x3d, 0x6c,
0x80, 0x83, 0x47, 0x6c,
0x02, 0xea, 0x4c, 0x05,
0xff, 0xea, 0x4c, 0x0d,
0x00, 0xe2, 0x32, 0x59,
0x02, 0xa6, 0xd0, 0x6b,
0x00, 0xe2, 0x3c, 0x59,
0x02, 0xa6, 0xda, 0x6b,
0x80, 0xf9, 0xf2, 0x05,
0xc0, 0x33, 0x4b, 0x7c,
0x03, 0xea, 0x46, 0x59,
0xc0, 0x33, 0x55, 0x7c,
0x03, 0xea, 0x50, 0x59,
0x03, 0xea, 0x04, 0x00,
0x20, 0x33, 0x6f, 0x7c,
0x01, 0x84, 0x55, 0x6c,
0x06, 0xea, 0x46, 0x59,
0x20, 0x33, 0x79, 0x7c,
0x01, 0x84, 0x5f, 0x6c,
0x06, 0xea, 0x50, 0x59,
0x06, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x72, 0x44,
0x00, 0xe2, 0x7c, 0x44,
0x01, 0x00, 0x60, 0x32,
0xee, 0x00, 0x5e, 0x6c,
0xee, 0x00, 0x68, 0x6c,
0x05, 0xea, 0xb4, 0x00,
0x33, 0xea, 0x3a, 0x59,
0x33, 0xea, 0x44, 0x59,
0x33, 0xea, 0x00, 0x00,
0x80, 0x3d, 0x7a, 0x00,
0xfc, 0x42, 0x60, 0x7c,
0xfc, 0x42, 0x6a, 0x7c,
0x7f, 0x3d, 0x7a, 0x08,
0x00, 0x30, 0x3b, 0x59,
0x00, 0x30, 0x45, 0x59,
0x01, 0x30, 0x01, 0x30,
0x09, 0xea, 0x46, 0x59,
0x09, 0xea, 0x50, 0x59,
0x09, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x01, 0xa4, 0x55, 0x6c,
0x00, 0xe2, 0x22, 0x5c,
0x00, 0xe2, 0xf8, 0x41,
0x01, 0xa4, 0x5f, 0x6c,
0x00, 0xe2, 0x2c, 0x5c,
0x20, 0x33, 0x67, 0x02,
0x01, 0x00, 0x60, 0x32,
0x02, 0xa6, 0x7a, 0x7c,
0x00, 0xe2, 0x3e, 0x5c,
0x00, 0xe2, 0x66, 0x58,
0x00, 0xe2, 0x76, 0x58,
0x00, 0xe2, 0x30, 0x58,
0x00, 0x30, 0x3b, 0x59,
0x02, 0xa6, 0x84, 0x7c,
0x00, 0xe2, 0x48, 0x5c,
0x00, 0xe2, 0x70, 0x58,
0x00, 0xe2, 0x80, 0x58,
0x00, 0xe2, 0x3a, 0x58,
0x00, 0x30, 0x45, 0x59,
0x01, 0x30, 0x01, 0x30,
0x20, 0x19, 0x7a, 0x6c,
0x00, 0xe2, 0xaa, 0x5c,
0x04, 0x19, 0x94, 0x6c,
0x20, 0x19, 0x84, 0x6c,
0x00, 0xe2, 0xb4, 0x5c,
0x04, 0x19, 0x9e, 0x6c,
0x02, 0x19, 0x32, 0x00,
0x01, 0x84, 0x95, 0x7c,
0x01, 0x1b, 0x8e, 0x7c,
0x01, 0x1a, 0x94, 0x6c,
0x00, 0xe2, 0x44, 0x44,
0x80, 0x4b, 0x9a, 0x6c,
0x01, 0x4c, 0x96, 0x7c,
0x03, 0x42, 0x44, 0x6c,
0x00, 0xe2, 0xca, 0x5b,
0x01, 0x84, 0x9f, 0x7c,
0x01, 0x1b, 0x98, 0x7c,
0x01, 0x1a, 0x9e, 0x6c,
0x00, 0xe2, 0x4e, 0x44,
0x80, 0x4b, 0xa4, 0x6c,
0x01, 0x4c, 0xa0, 0x7c,
0x03, 0x42, 0x4e, 0x6c,
0x00, 0xe2, 0xd4, 0x5b,
0x80, 0xf9, 0xf2, 0x01,
0x04, 0x33, 0xef, 0x79,
0x00, 0xe2, 0xee, 0x41,
0x08, 0x5d, 0xb2, 0x6c,
0x00, 0xe2, 0x66, 0x58,
0x00, 0x30, 0x3b, 0x59,
0x04, 0x33, 0xf9, 0x79,
0x00, 0xe2, 0xf8, 0x41,
0x08, 0x5d, 0xbc, 0x6c,
0x00, 0xe2, 0x70, 0x58,
0x00, 0x30, 0x45, 0x59,
0x01, 0x30, 0x01, 0x30,
0x02, 0x1b, 0xa2, 0x7c,
0x08, 0x5d, 0xb0, 0x7c,
0x02, 0x1b, 0xac, 0x7c,
0x08, 0x5d, 0xba, 0x7c,
0x03, 0x68, 0x00, 0x37,
0x01, 0x84, 0x09, 0x07,
0x80, 0x1b, 0xbc, 0x7c,
0x80, 0x84, 0xbd, 0x6c,
0x80, 0x1b, 0xc6, 0x7c,
0x80, 0x84, 0xc7, 0x6c,
0xff, 0x85, 0x0b, 0x1b,
0xff, 0x86, 0x0d, 0x23,
0xff, 0x87, 0x0f, 0x23,
0xf8, 0x1b, 0x08, 0x0b,
0xff, 0xea, 0x4e, 0x09,
0x04, 0x1b, 0xc4, 0x7c,
0x04, 0x1b, 0xce, 0x7c,
0x01, 0xa7, 0x4e, 0x01,
0xff, 0xea, 0x06, 0x0b,
0x03, 0x68, 0x00, 0x37,
0x00, 0xe2, 0xb6, 0x58,
0x00, 0xe2, 0xc0, 0x58,
0x10, 0xea, 0x18, 0x00,
0xf9, 0xd9, 0xb2, 0x0d,
0x01, 0xd9, 0xb2, 0x05,
0x01, 0x52, 0x48, 0x31,
0x20, 0xa4, 0xe8, 0x7c,
0x20, 0x5b, 0xe8, 0x7c,
0x80, 0xf9, 0xf6, 0x7c,
0x20, 0xa4, 0xf2, 0x7c,
0x20, 0x5b, 0xf2, 0x7c,
0x80, 0xf9, 0x00, 0x7d,
0x11, 0x00, 0x00, 0x10,
0x04, 0x19, 0xe2, 0x7c,
0x04, 0x19, 0xec, 0x7c,
0xdf, 0x19, 0x32, 0x08,
0x01, 0x4c, 0xde, 0x7c,
0x01, 0x4c, 0xe8, 0x7c,
0x20, 0x19, 0x32, 0x00,
0x11, 0x00, 0x00, 0x10,
0x02, 0xea, 0xb4, 0x00,
0x01, 0xd9, 0xb2, 0x05,
0x10, 0x5b, 0xfa, 0x6c,
0x08, 0x5b, 0x02, 0x6d,
0x20, 0x5b, 0xf4, 0x6c,
0x02, 0x5b, 0x22, 0x6d,
0x0e, 0xea, 0x46, 0x59,
0x10, 0x5b, 0x04, 0x6d,
0x08, 0x5b, 0x0c, 0x6d,
0x20, 0x5b, 0xfe, 0x6c,
0x02, 0x5b, 0x2c, 0x6d,
0x0e, 0xea, 0x50, 0x59,
0x0e, 0xea, 0x04, 0x00,
0x80, 0xf9, 0xe4, 0x6c,
0x80, 0xf9, 0xee, 0x6c,
0xdf, 0x5c, 0xb8, 0x08,
0x01, 0xd9, 0xb2, 0x05,
0x01, 0xa4, 0xf5, 0x6d,
0x00, 0xe2, 0x22, 0x5c,
0x00, 0xe2, 0x2c, 0x5d,
0x01, 0xa4, 0xff, 0x6d,
0x00, 0xe2, 0x2c, 0x5c,
0x00, 0xe2, 0x36, 0x5d,
0x01, 0xd9, 0xb2, 0x05,
0x00, 0xe2, 0x24, 0x5b,
0x00, 0xe2, 0x2e, 0x5b,
0xf3, 0x92, 0xd5, 0x19,
0x00, 0xe2, 0x10, 0x55,
0x80, 0x92, 0x11, 0x6d,
0x0f, 0xea, 0x46, 0x59,
0x00, 0xe2, 0x1a, 0x55,
0x80, 0x92, 0x1b, 0x6d,
0x0f, 0xea, 0x50, 0x59,
0x0f, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x18, 0x45,
0x00, 0xe2, 0x22, 0x45,
0x04, 0x8c, 0xe1, 0x30,
0x01, 0xea, 0xf2, 0x00,
0x02, 0xea, 0x36, 0x00,
0xa8, 0xea, 0x32, 0x00,
0xff, 0x93, 0x1f, 0x7d,
0x14, 0xea, 0x46, 0x59,
0xff, 0x93, 0x29, 0x7d,
0x14, 0xea, 0x50, 0x59,
0x14, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xa6, 0x5d,
0x00, 0xe2, 0xb0, 0x5d,
0x01, 0xd9, 0xb2, 0x05,
0x09, 0x80, 0xe1, 0x30,
0x02, 0xea, 0x36, 0x00,
0xa8, 0xea, 0x32, 0x00,
0x00, 0xe2, 0xce, 0x5d,
0x00, 0xe2, 0xd8, 0x5d,
0x01, 0xd9, 0xb2, 0x05,
0x02, 0xa8, 0xf4, 0x31,
0x02, 0xa6, 0x3e, 0x7d,
0x00, 0xe2, 0x34, 0x59,
0x20, 0x5b, 0x4c, 0x6d,
0xfc, 0x42, 0x38, 0x7d,
0x10, 0x40, 0x3a, 0x6d,
0x20, 0x4d, 0x3c, 0x7d,
0x08, 0x5d, 0x4c, 0x6d,
0x02, 0xa6, 0xd0, 0x6b,
0x00, 0xe2, 0x34, 0x59,
0x20, 0x5b, 0x4c, 0x6d,
0x01, 0x1b, 0x6c, 0x6d,
0xfc, 0x42, 0x48, 0x7d,
0x10, 0x40, 0x4a, 0x6d,
0x20, 0x4d, 0x8c, 0x7d,
0x08, 0x5d, 0x8c, 0x7d,
0x02, 0xa6, 0x48, 0x7d,
0x00, 0xe2, 0x3e, 0x59,
0x20, 0x5b, 0x56, 0x6d,
0xfc, 0x42, 0x42, 0x7d,
0x10, 0x40, 0x44, 0x6d,
0x20, 0x4d, 0x46, 0x7d,
0x08, 0x5d, 0x56, 0x6d,
0x02, 0xa6, 0xda, 0x6b,
0x00, 0xe2, 0x3e, 0x59,
0x20, 0x5b, 0x56, 0x6d,
0x01, 0x1b, 0x76, 0x6d,
0xfc, 0x42, 0x52, 0x7d,
0x10, 0x40, 0x54, 0x6d,
0x20, 0x4d, 0x96, 0x7d,
0x08, 0x5d, 0x96, 0x7d,
0x02, 0x19, 0x32, 0x00,
0x01, 0x5b, 0x40, 0x31,
0x00, 0xe2, 0xaa, 0x5c,
0x00, 0xe2, 0x88, 0x5b,
0x00, 0xe2, 0xb4, 0x5c,
0x00, 0xe2, 0x92, 0x5b,
0x20, 0xea, 0xb6, 0x00,
0x00, 0xe2, 0xca, 0x5b,
0x00, 0xe2, 0xd4, 0x5b,
0x20, 0x5c, 0xb8, 0x00,
0x04, 0x19, 0x62, 0x6d,
0x01, 0x1a, 0x62, 0x6d,
0x00, 0xe2, 0x34, 0x59,
0x01, 0x1a, 0x8c, 0x7d,
0x04, 0x19, 0x6c, 0x6d,
0x01, 0x1a, 0x6c, 0x6d,
0x00, 0xe2, 0x3e, 0x59,
0x01, 0x1a, 0x96, 0x7d,
0x80, 0xf9, 0xf2, 0x01,
0x20, 0xa0, 0xde, 0x7d,
0x08, 0xa8, 0x6b, 0x7d,
0x00, 0xe2, 0x7e, 0x45,
0x20, 0xa0, 0xe8, 0x7d,
0x08, 0xa8, 0x75, 0x7d,
0x00, 0xe2, 0x88, 0x45,
0x02, 0xea, 0xb4, 0x04,
0x02, 0x19, 0x32, 0x00,
0x08, 0xa8, 0x8f, 0x7d,
0x04, 0x5d, 0xf4, 0x7d,
0x01, 0x1a, 0xf4, 0x7d,
0x08, 0xa8, 0x99, 0x7d,
0x04, 0x5d, 0xfe, 0x7d,
0x01, 0x1a, 0xfe, 0x7d,
0x01, 0xa4, 0x49, 0x03,
0x80, 0xf9, 0xf2, 0x01,
0x02, 0xa8, 0x84, 0x32,
0x02, 0xea, 0xb4, 0x00,
0x00, 0xe2, 0x34, 0x43,
0x00, 0xe2, 0x3e, 0x43,
0x02, 0xa8, 0x84, 0x32,
0x02, 0xea, 0xb4, 0x00,
0xff, 0xea, 0xd4, 0x19,
0x00, 0xe2, 0x40, 0x59,
0x00, 0xe2, 0x4a, 0x59,
0x11, 0x00, 0x00, 0x10,
0x00, 0xe2, 0xc2, 0x5d,
0x00, 0xe2, 0x34, 0x53,
0x00, 0xe2, 0xcc, 0x5d,
0x00, 0xe2, 0x3e, 0x53,
0xff, 0xea, 0xd4, 0x0d,
0x00, 0xe2, 0x34, 0x59,
0x40, 0x5b, 0x9a, 0x6d,
0x04, 0x5d, 0xf4, 0x7d,
0x01, 0x1a, 0xf4, 0x7d,
0x20, 0x4d, 0x8c, 0x7d,
0x40, 0x5b, 0xde, 0x7d,
0x04, 0x5d, 0xf4, 0x7d,
0x01, 0x1a, 0xf4, 0x7d,
0x00, 0xe2, 0x3e, 0x59,
0x40, 0x5b, 0xa4, 0x6d,
0x04, 0x5d, 0xfe, 0x7d,
0x01, 0x1a, 0xfe, 0x7d,
0x20, 0x4d, 0x96, 0x7d,
0x40, 0x5b, 0xe8, 0x7d,
0x04, 0x5d, 0xfe, 0x7d,
0x01, 0x1a, 0xfe, 0x7d,
0x80, 0xf9, 0xf2, 0x01,
0x01, 0xa4, 0x49, 0x03,
0x08, 0xa8, 0x7f, 0x6d,
0x08, 0xa8, 0x89, 0x6d,
0x02, 0xea, 0xb4, 0x04,
0x00, 0xe2, 0x32, 0x59,
0x01, 0x1b, 0xb6, 0x7d,
0x40, 0x5b, 0x8c, 0x7d,
0x00, 0xe2, 0x3c, 0x59,
0x01, 0x1b, 0xc0, 0x7d,
0x40, 0x5b, 0x96, 0x7d,
0x02, 0x19, 0x32, 0x00,
0x80, 0xf9, 0xf2, 0x01,
0xff, 0xea, 0x10, 0x03,
0x08, 0xa8, 0x51, 0x03,
0x00, 0xe2, 0x7e, 0x45,
0xff, 0x6a, 0xbc, 0x6d,
0x40, 0x5b, 0x8c, 0x7d,
0xff, 0x6a, 0xac, 0x7d,
0x10, 0xea, 0x46, 0x59,
0x00, 0xe2, 0x88, 0x45,
0xff, 0x6a, 0xc6, 0x6d,
0x40, 0x5b, 0x96, 0x7d,
0xff, 0x6a, 0xb6, 0x7d,
0x10, 0xea, 0x50, 0x59,
0x10, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xac, 0x45,
0x80, 0xf9, 0x8c, 0x6d,
0x00, 0xe2, 0xb6, 0x45,
0x80, 0xf9, 0x96, 0x6d,
0x01, 0x43, 0xc1, 0x31,
0x00, 0xfb, 0x8c, 0x65,
0x00, 0xfb, 0x96, 0x65,
0x01, 0x42, 0xc1, 0x31,
0x00, 0xfa, 0x8c, 0x65,
0x00, 0xfa, 0x96, 0x65,
0x01, 0xe8, 0xd4, 0x1d,
0x00, 0xe2, 0x32, 0x59,
0x01, 0x1b, 0x8c, 0x7d,
0x00, 0xe2, 0x3c, 0x59,
0x01, 0x1b, 0x96, 0x7d,
0x80, 0xf9, 0xf2, 0x01,
0x02, 0xea, 0xb4, 0x04,
0x30, 0x3f, 0xc0, 0x09,
0x30, 0xe0, 0x8c, 0x65,
0x40, 0x4b, 0x8c, 0x6d,
0x30, 0xe0, 0x96, 0x65,
0x40, 0x4b, 0x96, 0x6d,
0xff, 0xea, 0x52, 0x01,
0xee, 0x00, 0xe4, 0x6d,
0xee, 0x00, 0xee, 0x6d,
0x80, 0xf9, 0xf2, 0x01,
0x02, 0xea, 0xb4, 0x00,
0x20, 0xea, 0x9a, 0x00,
0xf3, 0x42, 0xee, 0x6d,
0x12, 0xea, 0x46, 0x59,
0xf3, 0x42, 0xf8, 0x6d,
0x12, 0xea, 0x50, 0x59,
0x12, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x0d, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xf8, 0x41,
0x0d, 0xea, 0x50, 0x59,
0x0d, 0xea, 0x04, 0x00,
0x00, 0xe2, 0xee, 0x41,
0x11, 0xea, 0x46, 0x59,
0x00, 0xe2, 0xf8, 0x41,
0x11, 0xea, 0x50, 0x59,
0x11, 0xea, 0x04, 0x00,
0x00, 0xe2, 0x24, 0x5b,
0x00, 0xe2, 0x2e, 0x5b,
0x08, 0x5a, 0xb4, 0x00,
0x00, 0xe2, 0x18, 0x5e,
0x00, 0xe2, 0x22, 0x5e,
0xa8, 0xea, 0x32, 0x00,
0x00, 0xe2, 0x34, 0x59,
0x80, 0x1a, 0x08, 0x7e,
0x00, 0xe2, 0x18, 0x5e,
0x00, 0xe2, 0x3e, 0x59,
0x80, 0x1a, 0x12, 0x7e,
0x00, 0xe2, 0x22, 0x5e,
0x80, 0x19, 0x32, 0x00,
0x40, 0x5b, 0x0e, 0x6e,
0x08, 0x5a, 0x0e, 0x7e,
0x20, 0x4d, 0x8c, 0x7d,
0x40, 0x5b, 0x18, 0x6e,
0x08, 0x5a, 0x18, 0x7e,
0x20, 0x4d, 0x96, 0x7d,
0x02, 0x84, 0x09, 0x03,
0x40, 0x5b, 0xde, 0x7d,
0x08, 0xa8, 0x77, 0x6d,
0x40, 0x5b, 0xe8, 0x7d,
0x08, 0xa8, 0x81, 0x6d,
0x80, 0xf9, 0xf2, 0x01,
0x02, 0xea, 0xb4, 0x04,
0x01, 0x38, 0xe1, 0x30,
......@@ -800,12 +805,20 @@ static uint8_t seqprog[] = {
};
typedef int ahd_patch_func_t (struct ahd_softc *ahd);
static ahd_patch_func_t ahd_patch21_func;
static int
ahd_patch21_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
}
static ahd_patch_func_t ahd_patch20_func;
static int
ahd_patch20_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) != 0);
return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
}
static ahd_patch_func_t ahd_patch19_func;
......@@ -813,7 +826,7 @@ static ahd_patch_func_t ahd_patch19_func;
static int
ahd_patch19_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_PKT_BITBUCKET_BUG) == 0);
return ((ahd->features & AHD_RTI) == 0);
}
static ahd_patch_func_t ahd_patch18_func;
......@@ -821,7 +834,7 @@ static ahd_patch_func_t ahd_patch18_func;
static int
ahd_patch18_func(struct ahd_softc *ahd)
{
return ((ahd->features & AHD_RTI) == 0);
return ((ahd->flags & AHD_INITIATORROLE) != 0);
}
static ahd_patch_func_t ahd_patch17_func;
......@@ -829,7 +842,7 @@ static ahd_patch_func_t ahd_patch17_func;
static int
ahd_patch17_func(struct ahd_softc *ahd)
{
return ((ahd->flags & AHD_INITIATORROLE) != 0);
return ((ahd->flags & AHD_TARGETROLE) != 0);
}
static ahd_patch_func_t ahd_patch16_func;
......@@ -837,7 +850,7 @@ static ahd_patch_func_t ahd_patch16_func;
static int
ahd_patch16_func(struct ahd_softc *ahd)
{
return ((ahd->flags & AHD_TARGETROLE) != 0);
return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
}
static ahd_patch_func_t ahd_patch15_func;
......@@ -845,7 +858,7 @@ static ahd_patch_func_t ahd_patch15_func;
static int
ahd_patch15_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_AUTOFLUSH_BUG) != 0);
return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
}
static ahd_patch_func_t ahd_patch14_func;
......@@ -853,7 +866,7 @@ static ahd_patch_func_t ahd_patch14_func;
static int
ahd_patch14_func(struct ahd_softc *ahd)
{
return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) != 0);
return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
}
static ahd_patch_func_t ahd_patch13_func;
......@@ -861,7 +874,7 @@ static ahd_patch_func_t ahd_patch13_func;
static int
ahd_patch13_func(struct ahd_softc *ahd)
{
return ((ahd->flags & AHD_39BIT_ADDRESSING) != 0);
return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
}
static ahd_patch_func_t ahd_patch12_func;
......@@ -869,7 +882,7 @@ static ahd_patch_func_t ahd_patch12_func;
static int
ahd_patch12_func(struct ahd_softc *ahd)
{
return ((ahd->flags & AHD_64BIT_ADDRESSING) != 0);
return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
}
static ahd_patch_func_t ahd_patch11_func;
......@@ -877,7 +890,7 @@ static ahd_patch_func_t ahd_patch11_func;
static int
ahd_patch11_func(struct ahd_softc *ahd)
{
return ((ahd->features & AHD_NEW_DFCNTRL_OPTS) == 0);
return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
}
static ahd_patch_func_t ahd_patch10_func;
......@@ -885,7 +898,7 @@ static ahd_patch_func_t ahd_patch10_func;
static int
ahd_patch10_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_REG_SLOW_SETTLE_BUG) != 0);
return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
}
static ahd_patch_func_t ahd_patch9_func;
......@@ -893,7 +906,7 @@ static ahd_patch_func_t ahd_patch9_func;
static int
ahd_patch9_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_EARLY_REQ_BUG) != 0);
return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
}
static ahd_patch_func_t ahd_patch8_func;
......@@ -901,7 +914,7 @@ static ahd_patch_func_t ahd_patch8_func;
static int
ahd_patch8_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_BUSFREEREV_BUG) == 0);
return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
}
static ahd_patch_func_t ahd_patch7_func;
......@@ -909,7 +922,7 @@ static ahd_patch_func_t ahd_patch7_func;
static int
ahd_patch7_func(struct ahd_softc *ahd)
{
return ((ahd->flags & AHD_SEQUENCER_DEBUG) != 0);
return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0);
}
static ahd_patch_func_t ahd_patch6_func;
......@@ -917,7 +930,7 @@ static ahd_patch_func_t ahd_patch6_func;
static int
ahd_patch6_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_LQO_ATNO_BUG) != 0);
return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0);
}
static ahd_patch_func_t ahd_patch5_func;
......@@ -925,7 +938,7 @@ static ahd_patch_func_t ahd_patch5_func;
static int
ahd_patch5_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_BUSFREEREV_BUG) != 0);
return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0);
}
static ahd_patch_func_t ahd_patch4_func;
......@@ -933,7 +946,7 @@ static ahd_patch_func_t ahd_patch4_func;
static int
ahd_patch4_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_NONPACKFIFO_BUG) != 0);
return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0);
}
static ahd_patch_func_t ahd_patch3_func;
......@@ -941,7 +954,7 @@ static ahd_patch_func_t ahd_patch3_func;
static int
ahd_patch3_func(struct ahd_softc *ahd)
{
return ((ahd->bugs & AHD_SENT_SCB_UPDATE_BUG) != 0);
return ((ahd->bugs & AHD_FAINT_LED_BUG) != 0);
}
static ahd_patch_func_t ahd_patch2_func;
......@@ -982,128 +995,129 @@ static struct patch {
{ ahd_patch0_func, 5, 1, 1 },
{ ahd_patch2_func, 6, 1, 2 },
{ ahd_patch0_func, 7, 1, 1 },
{ ahd_patch2_func, 24, 1, 2 },
{ ahd_patch0_func, 25, 1, 1 },
{ ahd_patch1_func, 32, 1, 2 },
{ ahd_patch0_func, 33, 1, 1 },
{ ahd_patch2_func, 40, 1, 2 },
{ ahd_patch0_func, 41, 1, 1 },
{ ahd_patch2_func, 44, 1, 2 },
{ ahd_patch0_func, 45, 1, 1 },
{ ahd_patch2_func, 48, 1, 2 },
{ ahd_patch0_func, 49, 1, 1 },
{ ahd_patch2_func, 51, 1, 2 },
{ ahd_patch0_func, 52, 1, 1 },
{ ahd_patch2_func, 55, 1, 2 },
{ ahd_patch0_func, 56, 1, 1 },
{ ahd_patch2_func, 59, 1, 2 },
{ ahd_patch0_func, 60, 1, 1 },
{ ahd_patch2_func, 157, 6, 1 },
{ ahd_patch1_func, 163, 2, 1 },
{ ahd_patch3_func, 165, 1, 1 },
{ ahd_patch2_func, 174, 1, 2 },
{ ahd_patch0_func, 175, 1, 1 },
{ ahd_patch4_func, 176, 2, 2 },
{ ahd_patch0_func, 178, 6, 3 },
{ ahd_patch2_func, 181, 1, 2 },
{ ahd_patch0_func, 182, 1, 1 },
{ ahd_patch2_func, 185, 1, 2 },
{ ahd_patch0_func, 186, 1, 1 },
{ ahd_patch5_func, 188, 2, 1 },
{ ahd_patch3_func, 196, 16, 2 },
{ ahd_patch0_func, 212, 1, 1 },
{ ahd_patch6_func, 232, 2, 1 },
{ ahd_patch1_func, 236, 1, 2 },
{ ahd_patch0_func, 237, 1, 1 },
{ ahd_patch5_func, 240, 2, 1 },
{ ahd_patch1_func, 254, 1, 2 },
{ ahd_patch0_func, 255, 1, 1 },
{ ahd_patch1_func, 258, 1, 2 },
{ ahd_patch0_func, 259, 1, 1 },
{ ahd_patch2_func, 262, 1, 2 },
{ ahd_patch0_func, 263, 1, 1 },
{ ahd_patch1_func, 318, 1, 2 },
{ ahd_patch0_func, 319, 1, 1 },
{ ahd_patch2_func, 327, 1, 2 },
{ ahd_patch0_func, 328, 1, 1 },
{ ahd_patch2_func, 331, 1, 2 },
{ ahd_patch0_func, 332, 1, 1 },
{ ahd_patch1_func, 339, 1, 2 },
{ ahd_patch0_func, 340, 1, 1 },
{ ahd_patch7_func, 359, 1, 1 },
{ ahd_patch7_func, 362, 1, 1 },
{ ahd_patch7_func, 364, 1, 1 },
{ ahd_patch7_func, 376, 1, 1 },
{ ahd_patch1_func, 386, 1, 2 },
{ ahd_patch0_func, 387, 1, 1 },
{ ahd_patch1_func, 389, 1, 2 },
{ ahd_patch0_func, 390, 1, 1 },
{ ahd_patch1_func, 398, 1, 2 },
{ ahd_patch0_func, 399, 1, 1 },
{ ahd_patch2_func, 410, 1, 2 },
{ ahd_patch0_func, 411, 1, 1 },
{ ahd_patch8_func, 439, 1, 1 },
{ ahd_patch1_func, 446, 1, 2 },
{ ahd_patch0_func, 447, 1, 1 },
{ ahd_patch2_func, 459, 1, 2 },
{ ahd_patch0_func, 460, 1, 1 },
{ ahd_patch9_func, 465, 6, 2 },
{ ahd_patch0_func, 471, 1, 1 },
{ ahd_patch10_func, 494, 1, 1 },
{ ahd_patch11_func, 503, 1, 1 },
{ ahd_patch12_func, 504, 1, 2 },
{ ahd_patch0_func, 505, 1, 1 },
{ ahd_patch13_func, 510, 1, 1 },
{ ahd_patch12_func, 511, 1, 1 },
{ ahd_patch14_func, 524, 1, 2 },
{ ahd_patch0_func, 525, 1, 1 },
{ ahd_patch1_func, 547, 1, 2 },
{ ahd_patch0_func, 548, 1, 1 },
{ ahd_patch1_func, 551, 1, 2 },
{ ahd_patch0_func, 552, 1, 1 },
{ ahd_patch2_func, 557, 1, 2 },
{ ahd_patch0_func, 558, 1, 1 },
{ ahd_patch3_func, 20, 5, 1 },
{ ahd_patch2_func, 29, 1, 2 },
{ ahd_patch0_func, 30, 1, 1 },
{ ahd_patch1_func, 37, 1, 2 },
{ ahd_patch0_func, 38, 1, 1 },
{ ahd_patch2_func, 45, 1, 2 },
{ ahd_patch0_func, 46, 1, 1 },
{ ahd_patch2_func, 49, 1, 2 },
{ ahd_patch0_func, 50, 1, 1 },
{ ahd_patch2_func, 53, 1, 2 },
{ ahd_patch0_func, 54, 1, 1 },
{ ahd_patch2_func, 56, 1, 2 },
{ ahd_patch0_func, 57, 1, 1 },
{ ahd_patch2_func, 60, 1, 2 },
{ ahd_patch0_func, 61, 1, 1 },
{ ahd_patch2_func, 64, 1, 2 },
{ ahd_patch0_func, 65, 1, 1 },
{ ahd_patch2_func, 162, 6, 1 },
{ ahd_patch1_func, 168, 2, 1 },
{ ahd_patch4_func, 170, 1, 1 },
{ ahd_patch2_func, 179, 1, 2 },
{ ahd_patch0_func, 180, 1, 1 },
{ ahd_patch5_func, 181, 2, 2 },
{ ahd_patch0_func, 183, 6, 3 },
{ ahd_patch2_func, 186, 1, 2 },
{ ahd_patch0_func, 187, 1, 1 },
{ ahd_patch2_func, 190, 1, 2 },
{ ahd_patch0_func, 191, 1, 1 },
{ ahd_patch6_func, 193, 2, 1 },
{ ahd_patch4_func, 201, 16, 2 },
{ ahd_patch0_func, 217, 1, 1 },
{ ahd_patch7_func, 237, 2, 1 },
{ ahd_patch1_func, 241, 1, 2 },
{ ahd_patch0_func, 242, 1, 1 },
{ ahd_patch6_func, 245, 2, 1 },
{ ahd_patch1_func, 259, 1, 2 },
{ ahd_patch0_func, 260, 1, 1 },
{ ahd_patch1_func, 263, 1, 2 },
{ ahd_patch0_func, 264, 1, 1 },
{ ahd_patch2_func, 267, 1, 2 },
{ ahd_patch0_func, 268, 1, 1 },
{ ahd_patch1_func, 323, 1, 2 },
{ ahd_patch0_func, 324, 1, 1 },
{ ahd_patch2_func, 332, 1, 2 },
{ ahd_patch0_func, 333, 1, 1 },
{ ahd_patch2_func, 336, 1, 2 },
{ ahd_patch0_func, 337, 1, 1 },
{ ahd_patch1_func, 344, 1, 2 },
{ ahd_patch0_func, 345, 1, 1 },
{ ahd_patch8_func, 364, 1, 1 },
{ ahd_patch8_func, 367, 1, 1 },
{ ahd_patch8_func, 369, 1, 1 },
{ ahd_patch8_func, 381, 1, 1 },
{ ahd_patch1_func, 391, 1, 2 },
{ ahd_patch0_func, 392, 1, 1 },
{ ahd_patch1_func, 394, 1, 2 },
{ ahd_patch0_func, 395, 1, 1 },
{ ahd_patch1_func, 403, 1, 2 },
{ ahd_patch0_func, 404, 1, 1 },
{ ahd_patch2_func, 415, 1, 2 },
{ ahd_patch0_func, 416, 1, 1 },
{ ahd_patch9_func, 444, 1, 1 },
{ ahd_patch1_func, 451, 1, 2 },
{ ahd_patch0_func, 452, 1, 1 },
{ ahd_patch2_func, 464, 1, 2 },
{ ahd_patch0_func, 465, 1, 1 },
{ ahd_patch10_func, 470, 6, 2 },
{ ahd_patch0_func, 476, 1, 1 },
{ ahd_patch11_func, 499, 1, 1 },
{ ahd_patch12_func, 508, 1, 1 },
{ ahd_patch13_func, 509, 1, 2 },
{ ahd_patch0_func, 510, 1, 1 },
{ ahd_patch14_func, 515, 1, 1 },
{ ahd_patch13_func, 516, 1, 1 },
{ ahd_patch15_func, 529, 1, 2 },
{ ahd_patch0_func, 530, 1, 1 },
{ ahd_patch1_func, 552, 1, 2 },
{ ahd_patch0_func, 553, 1, 1 },
{ ahd_patch1_func, 556, 1, 2 },
{ ahd_patch0_func, 557, 1, 1 },
{ ahd_patch2_func, 562, 1, 2 },
{ ahd_patch0_func, 563, 1, 1 },
{ ahd_patch1_func, 564, 1, 2 },
{ ahd_patch0_func, 565, 1, 1 },
{ ahd_patch2_func, 576, 1, 2 },
{ ahd_patch0_func, 577, 1, 1 },
{ ahd_patch15_func, 581, 1, 1 },
{ ahd_patch2_func, 567, 1, 2 },
{ ahd_patch0_func, 568, 1, 1 },
{ ahd_patch1_func, 569, 1, 2 },
{ ahd_patch0_func, 570, 1, 1 },
{ ahd_patch2_func, 581, 1, 2 },
{ ahd_patch0_func, 582, 1, 1 },
{ ahd_patch16_func, 586, 1, 1 },
{ ahd_patch17_func, 587, 2, 1 },
{ ahd_patch16_func, 591, 1, 2 },
{ ahd_patch0_func, 592, 1, 1 },
{ ahd_patch2_func, 595, 1, 2 },
{ ahd_patch0_func, 596, 1, 1 },
{ ahd_patch2_func, 614, 1, 2 },
{ ahd_patch0_func, 615, 1, 1 },
{ ahd_patch18_func, 616, 12, 1 },
{ ahd_patch1_func, 632, 1, 2 },
{ ahd_patch0_func, 633, 1, 1 },
{ ahd_patch18_func, 634, 1, 1 },
{ ahd_patch1_func, 645, 1, 2 },
{ ahd_patch0_func, 646, 1, 1 },
{ ahd_patch1_func, 653, 1, 2 },
{ ahd_patch0_func, 654, 1, 1 },
{ ahd_patch15_func, 678, 1, 1 },
{ ahd_patch15_func, 694, 1, 1 },
{ ahd_patch2_func, 706, 1, 2 },
{ ahd_patch0_func, 707, 1, 1 },
{ ahd_patch15_func, 726, 1, 1 },
{ ahd_patch1_func, 734, 1, 2 },
{ ahd_patch0_func, 735, 1, 1 },
{ ahd_patch1_func, 756, 1, 2 },
{ ahd_patch0_func, 757, 1, 1 },
{ ahd_patch1_func, 759, 1, 2 },
{ ahd_patch0_func, 760, 1, 1 },
{ ahd_patch1_func, 762, 1, 2 },
{ ahd_patch0_func, 763, 1, 1 },
{ ahd_patch19_func, 765, 1, 2 },
{ ahd_patch0_func, 766, 2, 1 },
{ ahd_patch20_func, 769, 4, 2 },
{ ahd_patch0_func, 773, 1, 1 },
{ ahd_patch20_func, 780, 11, 1 }
{ ahd_patch17_func, 591, 1, 1 },
{ ahd_patch18_func, 592, 2, 1 },
{ ahd_patch17_func, 596, 1, 2 },
{ ahd_patch0_func, 597, 1, 1 },
{ ahd_patch2_func, 600, 1, 2 },
{ ahd_patch0_func, 601, 1, 1 },
{ ahd_patch2_func, 619, 1, 2 },
{ ahd_patch0_func, 620, 1, 1 },
{ ahd_patch19_func, 621, 12, 1 },
{ ahd_patch1_func, 637, 1, 2 },
{ ahd_patch0_func, 638, 1, 1 },
{ ahd_patch19_func, 639, 1, 1 },
{ ahd_patch1_func, 650, 1, 2 },
{ ahd_patch0_func, 651, 1, 1 },
{ ahd_patch1_func, 658, 1, 2 },
{ ahd_patch0_func, 659, 1, 1 },
{ ahd_patch16_func, 683, 1, 1 },
{ ahd_patch16_func, 699, 1, 1 },
{ ahd_patch2_func, 711, 1, 2 },
{ ahd_patch0_func, 712, 1, 1 },
{ ahd_patch16_func, 731, 1, 1 },
{ ahd_patch1_func, 739, 1, 2 },
{ ahd_patch0_func, 740, 1, 1 },
{ ahd_patch1_func, 761, 1, 2 },
{ ahd_patch0_func, 762, 1, 1 },
{ ahd_patch1_func, 764, 1, 2 },
{ ahd_patch0_func, 765, 1, 1 },
{ ahd_patch1_func, 767, 1, 2 },
{ ahd_patch0_func, 768, 1, 1 },
{ ahd_patch20_func, 770, 1, 2 },
{ ahd_patch0_func, 771, 2, 1 },
{ ahd_patch21_func, 774, 4, 2 },
{ ahd_patch0_func, 778, 1, 1 },
{ ahd_patch21_func, 785, 11, 1 }
};
static struct cs {
......@@ -1112,19 +1126,19 @@ static struct cs {
} critical_sections[] = {
{ 11, 12 },
{ 13, 14 },
{ 24, 37 },
{ 38, 51 },
{ 64, 67 },
{ 94, 119 },
{ 120, 151 },
{ 153, 157 },
{ 165, 173 },
{ 196, 245 },
{ 678, 694 },
{ 694, 712 },
{ 717, 723 },
{ 726, 731 },
{ 737, 743 }
{ 29, 42 },
{ 43, 56 },
{ 69, 72 },
{ 99, 124 },
{ 125, 156 },
{ 158, 162 },
{ 170, 178 },
{ 201, 250 },
{ 683, 699 },
{ 699, 717 },
{ 722, 728 },
{ 731, 736 },
{ 742, 748 }
};
static const int num_critical_sections = sizeof(critical_sections)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment