diff options
Diffstat (limited to 'drivers/scsi')
163 files changed, 2879 insertions, 5530 deletions
diff --git a/drivers/scsi/53c7xx.c b/drivers/scsi/53c7xx.c index 7a33c70..9cb5dd4 100644 --- a/drivers/scsi/53c7xx.c +++ b/drivers/scsi/53c7xx.c @@ -343,7 +343,7 @@ static void NCR53c7x0_soft_reset (struct Scsi_Host *host); /* Size of event list (per host adapter) */ static int track_events = 0; static struct Scsi_Host *first_host = NULL; /* Head of list of NCR boards */ -static Scsi_Host_Template *the_template = NULL; +static struct scsi_host_template *the_template = NULL; /* NCR53c710 script handling code */ @@ -1103,7 +1103,7 @@ NCR53c7x0_init (struct Scsi_Host *host) { } /* - * Function : int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, + * Function : int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip, * unsigned long base, int io_port, int irq, int dma, long long options, * int clock); * @@ -1118,7 +1118,7 @@ NCR53c7x0_init (struct Scsi_Host *host) { */ int -ncr53c7xx_init (Scsi_Host_Template *tpnt, int board, int chip, +ncr53c7xx_init (struct scsi_host_template *tpnt, int board, int chip, unsigned long base, int io_port, int irq, int dma, long long options, int clock) { diff --git a/drivers/scsi/53c7xx.h b/drivers/scsi/53c7xx.h index d9098bd..218f3b9 100644 --- a/drivers/scsi/53c7xx.h +++ b/drivers/scsi/53c7xx.h @@ -1600,7 +1600,7 @@ struct NCR53c7x0_hostdata { /* Paranoid people could use panic() here. */ #define FATAL(host) shutdown((host)); -extern int ncr53c7xx_init(Scsi_Host_Template *tpnt, int board, int chip, +extern int ncr53c7xx_init(struct scsi_host_template *tpnt, int board, int chip, unsigned long base, int io_port, int irq, int dma, long long options, int clock); diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index afeca32..20dd85a 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -497,7 +497,7 @@ config SCSI_ATA_PIIX If unsure, say N. config SCSI_SATA_MV - tristate "Marvell SATA support" + tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)" depends on SCSI_SATA && PCI && EXPERIMENTAL help This option enables support for the Marvell Serial ATA family. @@ -1295,27 +1295,6 @@ config SCSI_QLOGIC_FAS To compile this driver as a module, choose M here: the module will be called qlogicfas. -config SCSI_QLOGIC_ISP - tristate "Qlogic ISP SCSI support (old driver)" - depends on PCI && SCSI && BROKEN - ---help--- - This driver works for all QLogic PCI SCSI host adapters (IQ-PCI, - IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card. (This latter - card is supported by the "AM53/79C974 PCI SCSI" driver.) - - If you say Y here, make sure to choose "BIOS" at the question "PCI - access mode". - - Please read the file <file:Documentation/scsi/qlogicisp.txt>. You - should also read the SCSI-HOWTO, available from - <http://www.tldp.org/docs.html#howto>. - - To compile this driver as a module, choose M here: the - module will be called qlogicisp. - - These days the hardware is also supported by the more modern qla1280 - driver. In doubt use that one instead of qlogicisp. - config SCSI_QLOGIC_FC tristate "Qlogic ISP FC SCSI support" depends on PCI && SCSI @@ -1342,14 +1321,6 @@ config SCSI_QLOGIC_1280 To compile this driver as a module, choose M here: the module will be called qla1280. -config SCSI_QLOGIC_1280_1040 - bool "Qlogic QLA 1020/1040 SCSI support" - depends on SCSI_QLOGIC_1280 && SCSI_QLOGIC_ISP!=y - help - Say Y here if you have a QLogic ISP1020/1040 SCSI host adapter and - do not want to use the old driver. This option enables support in - the qla1280 driver for those host adapters. - config SCSI_QLOGICPTI tristate "PTI Qlogic, ISP Driver" depends on SBUS && SCSI diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index b88b8c4..f062ea0 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -78,7 +78,6 @@ obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o -obj-$(CONFIG_SCSI_QLOGIC_ISP) += qlogicisp.o obj-$(CONFIG_SCSI_QLOGIC_FC) += qlogicfc.o obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o obj-$(CONFIG_SCSI_QLA2XXX) += qla2xxx/ diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 26146a4..640590b 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -529,7 +529,7 @@ void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs) /* Allocate structure and insert basic data such as SCSI chip frequency * data and a pointer to the device */ -struct NCR_ESP* esp_allocate(Scsi_Host_Template *tpnt, void *esp_dev) +struct NCR_ESP* esp_allocate(struct scsi_host_template *tpnt, void *esp_dev) { struct NCR_ESP *esp, *elink; struct Scsi_Host *esp_host; @@ -1006,7 +1006,7 @@ static void esp_exec_cmd(struct NCR_ESP *esp) struct ESP_regs *eregs = esp->eregs; struct esp_device *esp_dev; Scsi_Cmnd *SCptr; - Scsi_Device *SDptr; + struct scsi_device *SDptr; volatile unchar *cmdp = esp->esp_command; unsigned char the_esp_command; int lun, target; @@ -1687,7 +1687,7 @@ static inline int reconnect_lun(struct NCR_ESP *esp, struct ESP_regs *eregs) static inline void esp_connect(struct NCR_ESP *esp, struct ESP_regs *eregs, Scsi_Cmnd *sp) { - Scsi_Device *dp = sp->device; + struct scsi_device *dp = sp->device; struct esp_device *esp_dev = dp->hostdata; if(esp->prev_soff != esp_dev->sync_max_offset || @@ -3605,7 +3605,7 @@ out: } #endif -int esp_slave_alloc(Scsi_Device *SDptr) +int esp_slave_alloc(struct scsi_device *SDptr) { struct esp_device *esp_dev = kmalloc(sizeof(struct esp_device), GFP_ATOMIC); @@ -3617,7 +3617,7 @@ int esp_slave_alloc(Scsi_Device *SDptr) return 0; } -void esp_slave_destroy(Scsi_Device *SDptr) +void esp_slave_destroy(struct scsi_device *SDptr) { struct NCR_ESP *esp = (struct NCR_ESP *) SDptr->host->hostdata; diff --git a/drivers/scsi/NCR53C9x.h b/drivers/scsi/NCR53C9x.h index 06e7edf..65a9b37 100644 --- a/drivers/scsi/NCR53C9x.h +++ b/drivers/scsi/NCR53C9x.h @@ -653,7 +653,7 @@ extern int nesps, esps_in_use, esps_running; /* External functions */ extern void esp_bootup_reset(struct NCR_ESP *esp, struct ESP_regs *eregs); -extern struct NCR_ESP *esp_allocate(Scsi_Host_Template *, void *); +extern struct NCR_ESP *esp_allocate(struct scsi_host_template *, void *); extern void esp_deallocate(struct NCR_ESP *); extern void esp_release(void); extern void esp_initialize(struct NCR_ESP *); @@ -664,6 +664,6 @@ extern int esp_abort(Scsi_Cmnd *); extern int esp_reset(Scsi_Cmnd *); extern int esp_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout); -extern int esp_slave_alloc(Scsi_Device *); -extern void esp_slave_destroy(Scsi_Device *); +extern int esp_slave_alloc(struct scsi_device *); +extern void esp_slave_destroy(struct scsi_device *); #endif /* !(NCR53C9X_H) */ diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c index 1353769..ae37d3a 100644 --- a/drivers/scsi/NCR53c406a.c +++ b/drivers/scsi/NCR53c406a.c @@ -447,7 +447,7 @@ static __inline__ int NCR53c406a_pio_write(unsigned char *request, unsigned int } #endif /* USE_PIO */ -static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt) +static int __init NCR53c406a_detect(struct scsi_host_template * tpnt) { int present = 0; struct Scsi_Host *shpnt = NULL; @@ -1057,7 +1057,7 @@ MODULE_LICENSE("GPL"); * Use SG_NONE if DMA mode is enabled! */ -static Scsi_Host_Template driver_template = +static struct scsi_host_template driver_template = { .proc_name = "NCR53c406a" /* proc_name */, .name = "NCR53c406a" /* name */, diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 30a14ba..54996ea 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -172,7 +172,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, } } -int __init a2091_detect(Scsi_Host_Template *tpnt) +int __init a2091_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; struct Scsi_Host *instance; @@ -233,7 +233,7 @@ static int a2091_bus_reset(Scsi_Cmnd *cmd) #define HOSTS_C -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "A2901", .name = "Commodore A2091/A590 SCSI", .detect = a2091_detect, diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h index 5499397..22d6a13 100644 --- a/drivers/scsi/a2091.h +++ b/drivers/scsi/a2091.h @@ -11,7 +11,7 @@ #include <linux/types.h> -int a2091_detect(Scsi_Host_Template *); +int a2091_detect(struct scsi_host_template *); int a2091_release(struct Scsi_Host *); const char *wd33c93_info(void); int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index 306caf5..f425d42 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -168,7 +168,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, } } -int __init a3000_detect(Scsi_Host_Template *tpnt) +int __init a3000_detect(struct scsi_host_template *tpnt) { wd33c93_regs regs; @@ -221,7 +221,7 @@ static int a3000_bus_reset(Scsi_Cmnd *cmd) #define HOSTS_C -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "A3000", .name = "Amiga 3000 built-in SCSI", .detect = a3000_detect, diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h index b1eda73..5535a65 100644 --- a/drivers/scsi/a3000.h +++ b/drivers/scsi/a3000.h @@ -11,7 +11,7 @@ #include <linux/types.h> -int a3000_detect(Scsi_Host_Template *); +int a3000_detect(struct scsi_host_template *); int a3000_release(struct Scsi_Host *); const char *wd33c93_info(void); int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 2a128a1..7139659 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -1579,18 +1579,10 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) break; { u64 capacity; - char cp[12]; - unsigned int offset = 0; + char cp[13]; dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n")); capacity = fsa_dev_ptr[cid].size - 1; - if (scsicmd->cmnd[13] > 12) { - offset = scsicmd->cmnd[13] - 12; - if (offset > sizeof(cp)) - break; - memset(cp, 0, offset); - aac_internal_transfer(scsicmd, cp, 0, offset); - } cp[0] = (capacity >> 56) & 0xff; cp[1] = (capacity >> 48) & 0xff; cp[2] = (capacity >> 40) & 0xff; @@ -1603,7 +1595,18 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) cp[9] = 0; cp[10] = 2; cp[11] = 0; - aac_internal_transfer(scsicmd, cp, offset, sizeof(cp)); + cp[12] = 0; + aac_internal_transfer(scsicmd, cp, 0, + min((unsigned int)scsicmd->cmnd[13], sizeof(cp))); + if (sizeof(cp) < scsicmd->cmnd[13]) { + unsigned int len, offset = sizeof(cp); + + memset(cp, 0, offset); + do { + len = min(scsicmd->cmnd[13]-offset, sizeof(cp)); + aac_internal_transfer(scsicmd, cp, offset, len); + } while ((offset += len) < scsicmd->cmnd[13]); + } /* Do not cache partition table for arrays */ scsicmd->device->removable = 1; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 723c0ce..38d6d00 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -820,7 +820,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) break; /* - * Find the Scsi_Device associated with the SCSI + * Find the scsi_device associated with the SCSI * address. Make sure we have the right array, and if * so set the flag to initiate a new re-config once we * see an AifEnConfigChange AIF come through. @@ -987,7 +987,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr) /* - * Find the Scsi_Device associated with the SCSI address, + * Find the scsi_device associated with the SCSI address, * and mark it as changed, invalidating the cache. This deals * with changes to existing device IDs. */ diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index ab383d1..3cb68af 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -325,6 +325,8 @@ static int aac_biosparm(struct scsi_device *sdev, struct block_device *bdev, * translations ( 64/32, 128/32, 255/63 ). */ buf = scsi_bios_ptable(bdev); + if (!buf) + return 0; if(*(__le16 *)(buf + 0x40) == cpu_to_le16(0xaa55)) { struct partition *first = (struct partition * )buf; struct partition *entry = first; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index f4cfb8f..28b9305 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -114,7 +114,7 @@ #include "advansys.h" #endif - and after "static Scsi_Host_Template builtin_scsi_hosts[] =": + and after "static struct scsi_host_template builtin_scsi_hosts[] =": #ifdef CONFIG_SCSI_ADVANSYS ADVANSYS, @@ -160,7 +160,7 @@ --- Driver Structures --- Driver Data --- Driver Function Prototypes - --- Linux 'Scsi_Host_Template' and advansys_setup() Functions + --- Linux 'struct scsi_host_template' and advansys_setup() Functions --- Loadable Driver Support --- Miscellaneous Driver Functions --- Functions Required by the Asc Library @@ -4068,7 +4068,7 @@ STATIC void asc_prt_hex(char *f, uchar *, int); /* - * --- Linux 'Scsi_Host_Template' and advansys_setup() Functions + * --- Linux 'struct scsi_host_template' and advansys_setup() Functions */ #ifdef CONFIG_PROC_FS diff --git a/drivers/scsi/advansys.h b/drivers/scsi/advansys.h index 3f4bde0..8ee7fb1 100644 --- a/drivers/scsi/advansys.h +++ b/drivers/scsi/advansys.h @@ -19,7 +19,7 @@ #define _ADVANSYS_H /* - * Scsi_Host_Template function prototypes. + * struct scsi_host_template function prototypes. */ int advansys_detect(struct scsi_host_template *); int advansys_release(struct Scsi_Host *); diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index 9b7caf5..9df23b6 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -424,7 +424,7 @@ MODULE_DEVICE_TABLE(isapnp, id_table); static int registered_count=0; static struct Scsi_Host *aha152x_host[2]; -static Scsi_Host_Template aha152x_driver_template; +static struct scsi_host_template aha152x_driver_template; /* * internal states of the host @@ -3464,7 +3464,7 @@ static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start return thislength < length ? thislength : length; } -static Scsi_Host_Template aha152x_driver_template = { +static struct scsi_host_template aha152x_driver_template = { .module = THIS_MODULE, .name = AHA152X_REVID, .proc_name = "aha152x", diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 1b1adfb..51bad7a 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -1021,7 +1021,7 @@ __setup("aha1542=",do_setup); #endif /* return non-zero on detection */ -static int __init aha1542_detect(Scsi_Host_Template * tpnt) +static int __init aha1542_detect(struct scsi_host_template * tpnt) { unsigned char dma_chan; unsigned char irq_level; @@ -1789,7 +1789,7 @@ static int aha1542_biosparam(struct scsi_device *sdev, MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "aha1542", .name = "Adaptec 1542", .detect = aha1542_detect, diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h index 3821ee1..1db5385 100644 --- a/drivers/scsi/aha1542.h +++ b/drivers/scsi/aha1542.h @@ -131,7 +131,7 @@ struct ccb { /* Command Control Block 5.3 */ /* REQUEST SENSE */ }; -static int aha1542_detect(Scsi_Host_Template *); +static int aha1542_detect(struct scsi_host_template *); static int aha1542_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int aha1542_bus_reset(Scsi_Cmnd * SCpnt); static int aha1542_dev_reset(Scsi_Cmnd * SCpnt); diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index 8f85dcc..4b8c6a5 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -570,7 +570,7 @@ static int aha1740_eh_abort_handler (Scsi_Cmnd *dummy) return 0; } -static Scsi_Host_Template aha1740_template = { +static struct scsi_host_template aha1740_template = { .module = THIS_MODULE, .proc_name = "aha1740", .proc_info = aha1740_proc_info, diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 10c470e..83467a0 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -48,7 +48,7 @@ #include <asm/io.h> #define DRV_NAME "ahci" -#define DRV_VERSION "1.01" +#define DRV_VERSION "1.2" enum { @@ -134,6 +134,7 @@ enum { PORT_IRQ_D2H_REG_FIS, /* PORT_CMD bits */ + PORT_CMD_ATAPI = (1 << 24), /* Device is ATAPI */ PORT_CMD_LIST_ON = (1 << 15), /* cmd list DMA engine running */ PORT_CMD_FIS_ON = (1 << 14), /* FIS DMA engine running */ PORT_CMD_FIS_RX = (1 << 4), /* Enable FIS receive DMA engine */ @@ -255,7 +256,7 @@ static struct ata_port_info ahci_port_info[] = { }, }; -static struct pci_device_id ahci_pci_tbl[] = { +static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VENDOR_ID_INTEL, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* ICH6 */ { PCI_VENDOR_ID_INTEL, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, @@ -441,7 +442,7 @@ static void ahci_phy_reset(struct ata_port *ap) void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; struct ata_taskfile tf; struct ata_device *dev = &ap->device[0]; - u32 tmp; + u32 new_tmp, tmp; __sata_phy_reset(ap); @@ -455,8 +456,21 @@ static void ahci_phy_reset(struct ata_port *ap) tf.nsect = (tmp) & 0xff; dev->class = ata_dev_classify(&tf); - if (!ata_dev_present(dev)) + if (!ata_dev_present(dev)) { ata_port_disable(ap); + return; + } + + /* Make sure port's ATAPI bit is set appropriately */ + new_tmp = tmp = readl(port_mmio + PORT_CMD); + if (dev->class == ATA_DEV_ATAPI) + new_tmp |= PORT_CMD_ATAPI; + else + new_tmp &= ~PORT_CMD_ATAPI; + if (new_tmp != tmp) { + writel(new_tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ + } } static u8 ahci_check_status(struct ata_port *ap) @@ -474,11 +488,12 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf) ata_tf_from_fis(d2h_fis, tf); } -static void ahci_fill_sg(struct ata_queued_cmd *qc) +static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc) { struct ahci_port_priv *pp = qc->ap->private_data; struct scatterlist *sg; struct ahci_sg *ahci_sg; + unsigned int n_sg = 0; VPRINTK("ENTER\n"); @@ -493,8 +508,12 @@ static void ahci_fill_sg(struct ata_queued_cmd *qc) ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); ahci_sg->flags_size = cpu_to_le32(sg_len - 1); + ahci_sg++; + n_sg++; } + + return n_sg; } static void ahci_qc_prep(struct ata_queued_cmd *qc) @@ -503,13 +522,14 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) struct ahci_port_priv *pp = ap->private_data; u32 opts; const u32 cmd_fis_len = 5; /* five dwords */ + unsigned int n_elem; /* * Fill in command slot information (currently only one slot, * slot 0, is currently since we don't do queueing) */ - opts = (qc->n_elem << 16) | cmd_fis_len; + opts = cmd_fis_len; if (qc->tf.flags & ATA_TFLAG_WRITE) opts |= AHCI_CMD_WRITE; if (is_atapi_taskfile(&qc->tf)) @@ -533,16 +553,31 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc) if (!(qc->flags & ATA_QCFLAG_DMAMAP)) return; - ahci_fill_sg(qc); + n_elem = ahci_fill_sg(qc); + + pp->cmd_slot[0].opts |= cpu_to_le32(n_elem << 16); } -static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) +static void ahci_restart_port(struct ata_port *ap, u32 irq_stat) { void __iomem *mmio = ap->host_set->mmio_base; void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); u32 tmp; int work; + if ((ap->device[0].class != ATA_DEV_ATAPI) || + ((irq_stat & PORT_IRQ_TF_ERR) == 0)) + printk(KERN_WARNING "ata%u: port reset, " + "p_is %x is %x pis %x cmd %x tf %x ss %x se %x\n", + ap->id, + irq_stat, + readl(mmio + HOST_IRQ_STAT), + readl(port_mmio + PORT_IRQ_STAT), + readl(port_mmio + PORT_CMD), + readl(port_mmio + PORT_TFDATA), + readl(port_mmio + PORT_SCR_STAT), + readl(port_mmio + PORT_SCR_ERR)); + /* stop DMA */ tmp = readl(port_mmio + PORT_CMD); tmp &= ~PORT_CMD_START; @@ -580,8 +615,6 @@ static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) tmp |= PORT_CMD_START; writel(tmp, port_mmio + PORT_CMD); readl(port_mmio + PORT_CMD); /* flush */ - - printk(KERN_WARNING "ata%u: error occurred, port reset\n", ap->id); } static void ahci_eng_timeout(struct ata_port *ap) @@ -592,17 +625,17 @@ static void ahci_eng_timeout(struct ata_port *ap) struct ata_queued_cmd *qc; unsigned long flags; - DPRINTK("ENTER\n"); + printk(KERN_WARNING "ata%u: handling error/timeout\n", ap->id); spin_lock_irqsave(&host_set->lock, flags); - ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); - qc = ata_qc_from_tag(ap, ap->active_tag); if (!qc) { printk(KERN_ERR "ata%u: BUG: timeout without command\n", ap->id); } else { + ahci_restart_port(ap, readl(port_mmio + PORT_IRQ_STAT)); + /* hack alert! We cannot use the supplied completion * function from inside the ->eh_strategy_handler() thread. * libata is the only user of ->eh_strategy_handler() in @@ -637,9 +670,19 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) } if (status & PORT_IRQ_FATAL) { - ahci_intr_error(ap, status); + unsigned int err_mask; + if (status & PORT_IRQ_TF_ERR) + err_mask = AC_ERR_DEV; + else if (status & PORT_IRQ_IF_ERR) + err_mask = AC_ERR_ATA_BUS; + else + err_mask = AC_ERR_HOST_BUS; + + /* command processing has stopped due to error; restart */ + ahci_restart_port(ap, status); + if (qc) - ata_qc_complete(qc, AC_ERR_OTHER); + ata_qc_complete(qc, err_mask); } return 1; diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index cfb46c2..6aab9da 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -436,29 +436,20 @@ ahd_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) { struct ahd_softc *ahd; struct ahd_linux_device *dev = scsi_transport_device_data(cmd->device); + int rtn = SCSI_MLQUEUE_HOST_BUSY; + unsigned long flags; ahd = *(struct ahd_softc **)cmd->device->host->hostdata; - /* - * Close the race of a command that was in the process of - * being queued to us just as our simq was frozen. Let - * DV commands through so long as we are only frozen to - * perform DV. - */ - if (ahd->platform_data->qfrozen != 0) { - printf("%s: queue frozen\n", ahd_name(ahd)); + ahd_lock(ahd, &flags); + if (ahd->platform_data->qfrozen == 0) { + cmd->scsi_done = scsi_done; + cmd->result = CAM_REQ_INPROG << 16; + rtn = ahd_linux_run_command(ahd, dev, cmd); - return SCSI_MLQUEUE_HOST_BUSY; } - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - cmd->result = CAM_REQ_INPROG << 16; - - return ahd_linux_run_command(ahd, dev, cmd); + ahd_unlock(ahd, &flags); + return rtn; } static inline struct scsi_target ** @@ -1081,7 +1072,6 @@ ahd_linux_register_host(struct ahd_softc *ahd, struct scsi_host_template *templa *((struct ahd_softc **)host->hostdata) = ahd; ahd_lock(ahd, &s); - scsi_assign_lock(host, &ahd->platform_data->spin_lock); ahd->platform_data->host = host; host->can_queue = AHD_MAX_QUEUE; host->cmd_per_lun = 2; @@ -2062,6 +2052,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) int wait; int disconnected; ahd_mode_state saved_modes; + unsigned long flags; pending_scb = NULL; paused = FALSE; @@ -2077,7 +2068,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) printf(" 0x%x", cmd->cmnd[cdb_byte]); printf("\n"); - spin_lock_irq(&ahd->platform_data->spin_lock); + ahd_lock(ahd, &flags); /* * First determine if we currently own this command. @@ -2114,7 +2105,7 @@ ahd_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) scmd_id(cmd), scmd_channel(cmd) + 'A', CAM_LUN_WILDCARD, - SCB_LIST_NULL, ROLE_INITIATOR) == 0) + SCB_LIST_NULL, ROLE_INITIATOR)) break; } } @@ -2291,7 +2282,8 @@ done: int ret; ahd->platform_data->flags |= AHD_SCB_UP_EH_SEM; - spin_unlock_irq(&ahd->platform_data->spin_lock); + ahd_unlock(ahd, &flags); + init_timer(&timer); timer.data = (u_long)ahd; timer.expires = jiffies + (5 * HZ); @@ -2305,9 +2297,8 @@ done: printf("Timer Expired\n"); retval = FAILED; } - spin_lock_irq(&ahd->platform_data->spin_lock); } - spin_unlock_irq(&ahd->platform_data->spin_lock); + ahd_unlock(ahd, &flags); return (retval); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 1861407..d866213 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -476,26 +476,20 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) { struct ahc_softc *ahc; struct ahc_linux_device *dev = scsi_transport_device_data(cmd->device); + int rtn = SCSI_MLQUEUE_HOST_BUSY; + unsigned long flags; ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - /* - * Close the race of a command that was in the process of - * being queued to us just as our simq was frozen. Let - * DV commands through so long as we are only frozen to - * perform DV. - */ - if (ahc->platform_data->qfrozen != 0) - return SCSI_MLQUEUE_HOST_BUSY; - - cmd->result = CAM_REQ_INPROG << 16; + ahc_lock(ahc, &flags); + if (ahc->platform_data->qfrozen == 0) { + cmd->scsi_done = scsi_done; + cmd->result = CAM_REQ_INPROG << 16; + rtn = ahc_linux_run_command(ahc, dev, cmd); + } + ahc_unlock(ahc, &flags); - return ahc_linux_run_command(ahc, dev, cmd); + return rtn; } static inline struct scsi_target ** @@ -1079,7 +1073,6 @@ ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *templa *((struct ahc_softc **)host->hostdata) = ahc; ahc_lock(ahc, &s); - scsi_assign_lock(host, &ahc->platform_data->spin_lock); ahc->platform_data->host = host; host->can_queue = AHC_MAX_QUEUE; host->cmd_per_lun = 2; @@ -2111,6 +2104,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) int paused; int wait; int disconnected; + unsigned long flags; pending_scb = NULL; paused = FALSE; @@ -2125,7 +2119,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) printf(" 0x%x", cmd->cmnd[cdb_byte]); printf("\n"); - spin_lock_irq(&ahc->platform_data->spin_lock); + ahc_lock(ahc, &flags); /* * First determine if we currently own this command. @@ -2175,7 +2169,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd), scmd_channel(cmd) + 'A', CAM_LUN_WILDCARD, - SCB_LIST_NULL, ROLE_INITIATOR) == 0) + SCB_LIST_NULL, ROLE_INITIATOR)) break; } } @@ -2357,7 +2351,8 @@ done: int ret; ahc->platform_data->flags |= AHC_UP_EH_SEMAPHORE; - spin_unlock_irq(&ahc->platform_data->spin_lock); + ahc_unlock(ahc, &flags); + init_timer(&timer); timer.data = (u_long)ahc; timer.expires = jiffies + (5 * HZ); @@ -2371,10 +2366,8 @@ done: printf("Timer Expired\n"); retval = FAILED; } - spin_lock_irq(&ahc->platform_data->spin_lock); - } - - spin_unlock_irq(&ahc->platform_data->spin_lock); + } else + ahc_unlock(ahc, &flags); return (retval); } diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 880e2d9..33d56c3 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c @@ -6514,7 +6514,7 @@ do_aic7xxx_isr(int irq, void *dev_id, struct pt_regs *regs) static void aic7xxx_init_transinfo(struct aic7xxx_host *p, struct aic_dev_data *aic_dev) { - Scsi_Device *sdpnt = aic_dev->SDptr; + struct scsi_device *sdpnt = aic_dev->SDptr; unsigned char tindex; tindex = sdpnt->id | (sdpnt->channel << 3); @@ -6581,7 +6581,7 @@ aic7xxx_init_transinfo(struct aic7xxx_host *p, struct aic_dev_data *aic_dev) * Set up the initial aic_dev struct pointers *-F*************************************************************************/ static int -aic7xxx_slave_alloc(Scsi_Device *SDptr) +aic7xxx_slave_alloc(struct scsi_device *SDptr) { struct aic7xxx_host *p = (struct aic7xxx_host *)SDptr->host->hostdata; struct aic_dev_data *aic_dev; @@ -6644,7 +6644,7 @@ aic7xxx_slave_alloc(Scsi_Device *SDptr) * queueing to be [en|dis]abled for a specific adapter. *-F*************************************************************************/ static void -aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) +aic7xxx_device_queue_depth(struct aic7xxx_host *p, struct scsi_device *device) { int tag_enabled = FALSE; struct aic_dev_data *aic_dev = device->hostdata; @@ -6734,7 +6734,7 @@ aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device) * prepare for this device to go away *-F*************************************************************************/ static void -aic7xxx_slave_destroy(Scsi_Device *SDptr) +aic7xxx_slave_destroy(struct scsi_device *SDptr) { struct aic_dev_data *aic_dev = SDptr->hostdata; @@ -6754,7 +6754,7 @@ aic7xxx_slave_destroy(Scsi_Device *SDptr) * depths, allocate command structs, etc. *-F*************************************************************************/ static int -aic7xxx_slave_configure(Scsi_Device *SDptr) +aic7xxx_slave_configure(struct scsi_device *SDptr) { struct aic7xxx_host *p = (struct aic7xxx_host *) SDptr->host->hostdata; struct aic_dev_data *aic_dev; @@ -7865,7 +7865,7 @@ detect_maxscb(struct aic7xxx_host *p) * Register a Adaptec aic7xxx chip SCSI controller with the kernel. *-F*************************************************************************/ static int -aic7xxx_register(Scsi_Host_Template *template, struct aic7xxx_host *p, +aic7xxx_register(struct scsi_host_template *template, struct aic7xxx_host *p, int reset_delay) { int i, result; @@ -8412,7 +8412,7 @@ aic7xxx_chip_reset(struct aic7xxx_host *p) * and a pointer to a aic7xxx_host struct upon success. *-F*************************************************************************/ static struct aic7xxx_host * -aic7xxx_alloc(Scsi_Host_Template *sht, struct aic7xxx_host *temp) +aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp) { struct aic7xxx_host *p = NULL; struct Scsi_Host *host; @@ -8991,7 +8991,7 @@ aic7xxx_configure_bugs(struct aic7xxx_host *p) * mid-level SCSI code is overhauled. *-F*************************************************************************/ static int -aic7xxx_detect(Scsi_Host_Template *template) +aic7xxx_detect(struct scsi_host_template *template) { struct aic7xxx_host *temp_p = NULL; struct aic7xxx_host *current_p = NULL; @@ -11161,7 +11161,7 @@ MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(AIC7XXX_H_VERSION); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_info = aic7xxx_proc_info, .detect = aic7xxx_detect, .release = aic7xxx_release, diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c index dea8446..c0844fa 100644 --- a/drivers/scsi/amiga7xx.c +++ b/drivers/scsi/amiga7xx.c @@ -29,7 +29,7 @@ #include "amiga7xx.h" -static int amiga7xx_register_one(Scsi_Host_Template *tpnt, +static int amiga7xx_register_one(struct scsi_host_template *tpnt, unsigned long address) { long long options; @@ -65,7 +65,7 @@ static struct { { 0 } }; -static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt) +static int __init amiga7xx_zorro_detect(struct scsi_host_template *tpnt) { int num = 0, i; struct zorro_dev *z = NULL; @@ -89,7 +89,7 @@ static int __init amiga7xx_zorro_detect(Scsi_Host_Template *tpnt) #endif /* CONFIG_ZORRO */ -int __init amiga7xx_detect(Scsi_Host_Template *tpnt) +int __init amiga7xx_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; int num = 0; @@ -122,7 +122,7 @@ static int amiga7xx_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "Amiga NCR53c710 SCSI", .detect = amiga7xx_detect, .release = amiga7xx_release, diff --git a/drivers/scsi/amiga7xx.h b/drivers/scsi/amiga7xx.h index 8cc54a5..1b63759 100644 --- a/drivers/scsi/amiga7xx.h +++ b/drivers/scsi/amiga7xx.h @@ -2,7 +2,7 @@ #include <linux/types.h> -int amiga7xx_detect(Scsi_Host_Template *); +int amiga7xx_detect(struct scsi_host_template *); const char *NCR53c7x0_info(void); int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); diff --git a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c index be2caec..b7b20c6 100644 --- a/drivers/scsi/arm/acornscsi.c +++ b/drivers/scsi/arm/acornscsi.c @@ -896,7 +896,7 @@ void acornscsi_done(AS_Host *host, Scsi_Cmnd **SCpntp, unsigned int result) * Notes : this will only be one SG entry or less */ static -void acornscsi_data_updateptr(AS_Host *host, Scsi_Pointer *SCp, unsigned int length) +void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length) { SCp->ptr += length; SCp->this_residual -= length; @@ -2862,7 +2862,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, int length, int inout) { int pos, begin = 0, devidx; - Scsi_Device *scd; + struct scsi_device *scd; AS_Host *host; char *p = buffer; @@ -2971,7 +2971,7 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start, return pos; } -static Scsi_Host_Template acornscsi_template = { +static struct scsi_host_template acornscsi_template = { .module = THIS_MODULE, .proc_info = acornscsi_proc_info, .name = "AcornSCSI", diff --git a/drivers/scsi/arm/acornscsi.h b/drivers/scsi/arm/acornscsi.h index 03881f0..2142290 100644 --- a/drivers/scsi/arm/acornscsi.h +++ b/drivers/scsi/arm/acornscsi.h @@ -292,7 +292,7 @@ typedef struct acornscsi_hostdata { unsigned char tag; /* reconnected tag */ } reconnected; - Scsi_Pointer SCp; /* current commands data pointer */ + struct scsi_pointer SCp; /* current commands data pointer */ MsgQueue_t msgs; diff --git a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c index 29811f5..804125e 100644 --- a/drivers/scsi/arm/arxescsi.c +++ b/drivers/scsi/arm/arxescsi.c @@ -65,7 +65,7 @@ struct arxescsi_info { * Returns : 0 if we should not set CMD_WITHDMA for transfer info command */ static fasdmatype_t -arxescsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +arxescsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { /* @@ -111,7 +111,7 @@ static void arxescsi_pseudo_dma_write(unsigned char *addr, void __iomem *base) * transfer - minimum number of bytes we expect to transfer */ static void -arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +arxescsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer) { struct arxescsi_info *info = (struct arxescsi_info *)host->hostdata; @@ -197,7 +197,7 @@ arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * Params : host - host * SCpnt - command */ -static void arxescsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +static void arxescsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { /* * no DMA to stop @@ -261,7 +261,7 @@ arxescsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t off return pos; } -static Scsi_Host_Template arxescsi_template = { +static struct scsi_host_template arxescsi_template = { .proc_info = arxescsi_proc_info, .name = "ARXE SCSI card", .info = arxescsi_info, diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c index 26498553..81e266b 100644 --- a/drivers/scsi/arm/cumana_1.c +++ b/drivers/scsi/arm/cumana_1.c @@ -238,7 +238,7 @@ static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value) #include "../NCR5380.c" -static Scsi_Host_Template cumanascsi_template = { +static struct scsi_host_template cumanascsi_template = { .module = THIS_MODULE, .name = "Cumana 16-bit SCSI", .info = cumanascsi_info, diff --git a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c index 0ef0644..3a7a46b 100644 --- a/drivers/scsi/arm/cumana_2.c +++ b/drivers/scsi/arm/cumana_2.c @@ -157,7 +157,7 @@ cumanascsi_2_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +cumanascsi_2_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; @@ -209,7 +209,7 @@ cumanascsi_2_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, * transfer - minimum number of bytes we expect to transfer */ static void -cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +cumanascsi_2_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; @@ -283,7 +283,7 @@ cumanascsi_2_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -cumanascsi_2_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +cumanascsi_2_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct cumanascsi2_info *info = (struct cumanascsi2_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) { @@ -381,7 +381,7 @@ int cumanascsi_2_proc_info (struct Scsi_Host *host, char *buffer, char **start, return pos; } -static Scsi_Host_Template cumanascsi2_template = { +static struct scsi_host_template cumanascsi2_template = { .module = THIS_MODULE, .proc_info = cumanascsi_2_proc_info, .name = "Cumana SCSI II", diff --git a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c index f8a7fdd..6adcccb 100644 --- a/drivers/scsi/arm/ecoscsi.c +++ b/drivers/scsi/arm/ecoscsi.c @@ -155,7 +155,7 @@ printk("reading %p len %d\n",addr, len); #include "../NCR5380.c" -static Scsi_Host_Template ecoscsi_template = { +static struct scsi_host_template ecoscsi_template = { .module = THIS_MODULE, .name = "Serial Port EcoSCSI NCR5380", .proc_name = "ecoscsi", diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index ce711f1..4d1e8f5 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -158,7 +158,7 @@ eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; @@ -353,7 +353,7 @@ static void eesoxscsi_buffer_out(void *buf, int length, void __iomem *base) } static void -eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t dir, int transfer_size) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; @@ -370,7 +370,7 @@ eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +eesoxscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) @@ -499,7 +499,7 @@ static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, eesoxscsi_show_term, eesoxscsi_store_term); -static Scsi_Host_Template eesox_template = { +static struct scsi_host_template eesox_template = { .module = THIS_MODULE, .proc_info = eesoxscsi_proc_info, .name = "EESOX SCSI", diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 4772fb3..3e1053f 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -173,7 +173,7 @@ static void fas216_dumpstate(FAS216_Info *info) fas216_readb(info, REG_CTCH)); } -static void print_SCp(Scsi_Pointer *SCp, const char *prefix, const char *suffix) +static void print_SCp(struct scsi_pointer *SCp, const char *prefix, const char *suffix) { printk("%sptr %p this_residual 0x%x buffer %p buffers_residual 0x%x%s", prefix, SCp->ptr, SCp->this_residual, SCp->buffer, @@ -628,7 +628,7 @@ static void fas216_handlesync(FAS216_Info *info, char *msg) */ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) { - Scsi_Pointer *SCp = &info->scsi.SCp; + struct scsi_pointer *SCp = &info->scsi.SCp; fas216_checkmagic(info); @@ -668,7 +668,7 @@ static void fas216_updateptrs(FAS216_Info *info, int bytes_transferred) */ static void fas216_pio(FAS216_Info *info, fasdmadir_t direction) { - Scsi_Pointer *SCp = &info->scsi.SCp; + struct scsi_pointer *SCp = &info->scsi.SCp; fas216_checkmagic(info); @@ -2559,7 +2559,7 @@ int fas216_eh_bus_reset(Scsi_Cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; unsigned long flags; - Scsi_Device *SDpnt; + struct scsi_device *SDpnt; fas216_checkmagic(info); fas216_log(info, LOG_ERROR, "resetting bus"); @@ -3000,7 +3000,7 @@ int fas216_print_stats(FAS216_Info *info, char *buffer) int fas216_print_devices(FAS216_Info *info, char *buffer) { struct fas216_device *dev; - Scsi_Device *scd; + struct scsi_device *scd; char *p = buffer; p += sprintf(p, "Device/Lun TaggedQ Parity Sync\n"); diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h index 60a2a12..540914d 100644 --- a/drivers/scsi/arm/fas216.h +++ b/drivers/scsi/arm/fas216.h @@ -243,7 +243,7 @@ typedef struct { unsigned int irq; /* interrupt */ int dma; /* dma channel */ - Scsi_Pointer SCp; /* current commands data pointer */ + struct scsi_pointer SCp; /* current commands data pointer */ MsgQueue_t msgs; /* message queue for connected device */ @@ -304,9 +304,9 @@ typedef struct { /* dma */ struct { fasdmatype_t transfer_type; /* current type of DMA transfer */ - fasdmatype_t (*setup) (struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma); - void (*pseudo)(struct Scsi_Host *host, Scsi_Pointer *SCp, fasdmadir_t direction, int transfer); - void (*stop) (struct Scsi_Host *host, Scsi_Pointer *SCp); + fasdmatype_t (*setup) (struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_dma); + void (*pseudo)(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, int transfer); + void (*stop) (struct Scsi_Host *host, struct scsi_pointer *SCp); } dma; /* miscellaneous */ diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c index de24bb9..d806b02 100644 --- a/drivers/scsi/arm/oak.c +++ b/drivers/scsi/arm/oak.c @@ -111,7 +111,7 @@ printk("reading %p len %d\n", addr, len); #include "../NCR5380.c" -static Scsi_Host_Template oakscsi_template = { +static struct scsi_host_template oakscsi_template = { .module = THIS_MODULE, .proc_info = oakscsi_proc_info, .name = "Oak 16-bit SCSI", diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index abda216..3333d7b 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -132,7 +132,7 @@ powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct powertec_info *info = (struct powertec_info *)host->hostdata; @@ -174,7 +174,7 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -powertecscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +powertecscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { struct powertec_info *info = (struct powertec_info *)host->hostdata; if (info->info.scsi.dma != NO_DMA) @@ -293,7 +293,7 @@ powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, powertecscsi_show_term, powertecscsi_store_term); -static Scsi_Host_Template powertecscsi_template = { +static struct scsi_host_template powertecscsi_template = { .module = THIS_MODULE, .proc_info = powertecscsi_proc_info, .name = "PowerTec SCSI", diff --git a/drivers/scsi/arm/scsi.h b/drivers/scsi/arm/scsi.h index 1993764..6dd544a 100644 --- a/drivers/scsi/arm/scsi.h +++ b/drivers/scsi/arm/scsi.h @@ -18,7 +18,7 @@ * The scatter-gather list handling. This contains all * the yucky stuff that needs to be fixed properly. */ -static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int max) +static inline int copy_SCp_to_sg(struct scatterlist *sg, struct scsi_pointer *SCp, int max) { int bufs = SCp->buffers_residual; @@ -32,7 +32,7 @@ static inline int copy_SCp_to_sg(struct scatterlist *sg, Scsi_Pointer *SCp, int return bufs + 1; } -static inline int next_SCp(Scsi_Pointer *SCp) +static inline int next_SCp(struct scsi_pointer *SCp) { int ret = SCp->buffers_residual; if (ret) { @@ -49,7 +49,7 @@ static inline int next_SCp(Scsi_Pointer *SCp) return ret; } -static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp) +static inline unsigned char get_next_SCp_byte(struct scsi_pointer *SCp) { char c = *SCp->ptr; @@ -59,7 +59,7 @@ static inline unsigned char get_next_SCp_byte(Scsi_Pointer *SCp) return c; } -static inline void put_next_SCp_byte(Scsi_Pointer *SCp, unsigned char c) +static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c) { *SCp->ptr = c; SCp->ptr += 1; diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index a1bd8d9..333d69d 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -50,7 +50,7 @@ #include <linux/libata.h> #define DRV_NAME "ata_piix" -#define DRV_VERSION "1.04" +#define DRV_VERSION "1.05" enum { PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ @@ -95,7 +95,7 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev); static unsigned int in_module_init = 1; -static struct pci_device_id piix_pci_tbl[] = { +static const struct pci_device_id piix_pci_tbl[] = { #ifdef ATA_ENABLE_PATA { 0x8086, 0x7111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, piix4_pata }, { 0x8086, 0x24db, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_pata }, diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 2c12be7..2ae31ce 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -255,7 +255,7 @@ */ static struct Scsi_Host *first_instance = NULL; -static Scsi_Host_Template *the_template = NULL; +static struct scsi_host_template *the_template = NULL; /* Macros ease life... :-) */ #define SETUP_HOSTDATA(in) \ diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index af8adb6..f4c1ca7 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c @@ -600,7 +600,7 @@ int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) #endif -int atari_scsi_detect (Scsi_Host_Template *host) +int atari_scsi_detect (struct scsi_host_template *host) { static int called = 0; struct Scsi_Host *instance; @@ -1141,7 +1141,7 @@ static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value #include "atari_NCR5380.c" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_info = atari_scsi_proc_info, .name = "Atari native SCSI", .detect = atari_scsi_detect, diff --git a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h index cc12569..f917bdd 100644 --- a/drivers/scsi/atari_scsi.h +++ b/drivers/scsi/atari_scsi.h @@ -18,7 +18,7 @@ /* (I_HAVE_OVERRUNS stuff removed) */ #ifndef ASM -int atari_scsi_detect (Scsi_Host_Template *); +int atari_scsi_detect (struct scsi_host_template *); const char *atari_scsi_info (struct Scsi_Host *); int atari_scsi_reset (Scsi_Cmnd *, unsigned int); #ifdef MODULE diff --git a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c index 4cd9fcf..763e409 100644 --- a/drivers/scsi/blz1230.c +++ b/drivers/scsi/blz1230.c @@ -94,7 +94,7 @@ static volatile unsigned char cmd_buffer[16]; */ /***************************************************************** Detection */ -int __init blz1230_esp_detect(Scsi_Host_Template *tpnt) +int __init blz1230_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -328,7 +328,7 @@ int blz1230_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-blz1230", .proc_info = esp_proc_info, .name = "Blizzard1230 SCSI IV", diff --git a/drivers/scsi/blz2060.c b/drivers/scsi/blz2060.c index c5221d0..d72d05f 100644 --- a/drivers/scsi/blz2060.c +++ b/drivers/scsi/blz2060.c @@ -90,7 +90,7 @@ static volatile unsigned char cmd_buffer[16]; */ /***************************************************************** Detection */ -int __init blz2060_esp_detect(Scsi_Host_Template *tpnt) +int __init blz2060_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -282,7 +282,7 @@ int blz2060_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-blz2060", .proc_info = esp_proc_info, .name = "Blizzard2060 SCSI", diff --git a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c index 130f30f5..2958b8c 100644 --- a/drivers/scsi/bvme6000.c +++ b/drivers/scsi/bvme6000.c @@ -23,7 +23,7 @@ #include<linux/stat.h> -int bvme6000_scsi_detect(Scsi_Host_Template *tpnt) +int bvme6000_scsi_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; int clock; @@ -59,7 +59,7 @@ static int bvme6000_scsi_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "BVME6000 NCR53c710 SCSI", .detect = bvme6000_scsi_detect, .release = bvme6000_scsi_release, diff --git a/drivers/scsi/bvme6000.h b/drivers/scsi/bvme6000.h index 49b6bbb..7c9c036 100644 --- a/drivers/scsi/bvme6000.h +++ b/drivers/scsi/bvme6000.h @@ -3,7 +3,7 @@ #include <linux/types.h> -int bvme6000_scsi_detect(Scsi_Host_Template *); +int bvme6000_scsi_detect(struct scsi_host_template *); const char *NCR53c7x0_info(void); int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); diff --git a/drivers/scsi/cyberstorm.c b/drivers/scsi/cyberstorm.c index bdbca85d..f9b940e 100644 --- a/drivers/scsi/cyberstorm.c +++ b/drivers/scsi/cyberstorm.c @@ -104,7 +104,7 @@ static volatile unsigned char cmd_buffer[16]; */ /***************************************************************** Detection */ -int __init cyber_esp_detect(Scsi_Host_Template *tpnt) +int __init cyber_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -353,7 +353,7 @@ int cyber_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-cyberstorm", .proc_info = esp_proc_info, .name = "CyberStorm SCSI", diff --git a/drivers/scsi/cyberstormII.c b/drivers/scsi/cyberstormII.c index 845d925..a3caabf 100644 --- a/drivers/scsi/cyberstormII.c +++ b/drivers/scsi/cyberstormII.c @@ -81,7 +81,7 @@ static volatile unsigned char cmd_buffer[16]; */ /***************************************************************** Detection */ -int __init cyberII_esp_detect(Scsi_Host_Template *tpnt) +int __init cyberII_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -290,7 +290,7 @@ int cyberII_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-cyberstormII", .proc_info = esp_proc_info, .name = "CyberStorm Mk II SCSI", diff --git a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c index 256d6ba..a35ee43 100644 --- a/drivers/scsi/dec_esp.c +++ b/drivers/scsi/dec_esp.c @@ -133,7 +133,7 @@ static struct scsi_host_template driver_template = { #include "scsi_module.c" /***************************************************************** Detection */ -static int dec_esp_detect(Scsi_Host_Template * tpnt) +static int dec_esp_detect(struct scsi_host_template * tpnt) { struct NCR_ESP *esp; struct ConfigDev *esp_dev; diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index c28e3ae..6252b9d 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c @@ -660,7 +660,12 @@ static int adpt_abort(struct scsi_cmnd * cmd) msg[2] = 0; msg[3]= 0; msg[4] = (u32)cmd; - if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){ + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); + rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER); + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { if(rcode == -EOPNOTSUPP ){ printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name); return FAILED; @@ -697,10 +702,15 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) msg[2] = 0; msg[3] = 0; + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); old_state = d->state; d->state |= DPTI_DEV_RESET; - if( (rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER)) ){ - d->state = old_state; + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); + d->state = old_state; + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { if(rcode == -EOPNOTSUPP ){ printk(KERN_INFO"%s: Device reset not supported\n",pHba->name); return FAILED; @@ -708,7 +718,6 @@ static int adpt_device_reset(struct scsi_cmnd* cmd) printk(KERN_INFO"%s: Device reset failed\n",pHba->name); return FAILED; } else { - d->state = old_state; printk(KERN_INFO"%s: Device reset successful\n",pHba->name); return SUCCESS; } @@ -721,6 +730,7 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) { adpt_hba* pHba; u32 msg[4]; + u32 rcode; pHba = (adpt_hba*)cmd->device->host->hostdata[0]; memset(msg, 0, sizeof(msg)); @@ -729,7 +739,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd) msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid); msg[2] = 0; msg[3] = 0; - if(adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER) ){ + if (pHba->host) + spin_lock_irq(pHba->host->host_lock); + rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER); + if (pHba->host) + spin_unlock_irq(pHba->host->host_lock); + if (rcode != 0) { printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name); return FAILED; } else { @@ -816,7 +831,7 @@ static int adpt_hba_reset(adpt_hba* pHba) static void adpt_i2o_sys_shutdown(void) { adpt_hba *pHba, *pNext; - struct adpt_i2o_post_wait_data *p1, *p2; + struct adpt_i2o_post_wait_data *p1, *old; printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n"); printk(KERN_INFO" This could take a few minutes if there are many devices attached\n"); @@ -830,13 +845,14 @@ static void adpt_i2o_sys_shutdown(void) } /* Remove any timedout entries from the wait queue. */ - p2 = NULL; // spin_lock_irqsave(&adpt_post_wait_lock, flags); /* Nothing should be outstanding at this point so just * free them */ - for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) { - kfree(p1); + for(p1 = adpt_post_wait_queue; p1;) { + old = p1; + p1 = p1->next; + kfree(old); } // spin_unlock_irqrestore(&adpt_post_wait_lock, flags); adpt_post_wait_queue = NULL; diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index 489194a..2ad2a89 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h @@ -44,7 +44,7 @@ static int adpt_device_reset(struct scsi_cmnd* cmd); /* - * Scsi_Host_Template (see hosts.h) + * struct scsi_host_template (see hosts.h) */ #define DPT_DRIVER_NAME "Adaptec I2O RAID" diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 897743b..310d2f4 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c @@ -199,7 +199,7 @@ static void __init dtc_setup(char *str, int *ints) #endif /* - * Function : int dtc_detect(Scsi_Host_Template * tpnt) + * Function : int dtc_detect(struct scsi_host_template * tpnt) * * Purpose : detects and initializes DTC 3180/3280 controllers * that were autoprobed, overridden on the LILO command line, @@ -211,7 +211,7 @@ static void __init dtc_setup(char *str, int *ints) * */ -static int __init dtc_detect(Scsi_Host_Template * tpnt) +static int __init dtc_detect(struct scsi_host_template * tpnt) { static int current_override = 0, current_base = 0; struct Scsi_Host *instance; @@ -471,7 +471,7 @@ static int dtc_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "DTC 3180/3280 ", .detect = dtc_detect, .release = dtc_release, diff --git a/drivers/scsi/dtc.h b/drivers/scsi/dtc.h index 277cd01..0b205f8 100644 --- a/drivers/scsi/dtc.h +++ b/drivers/scsi/dtc.h @@ -35,7 +35,7 @@ static int dtc_abort(Scsi_Cmnd *); static int dtc_biosparam(struct scsi_device *, struct block_device *, sector_t, int*); -static int dtc_detect(Scsi_Host_Template *); +static int dtc_detect(struct scsi_host_template *); static int dtc_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int dtc_bus_reset(Scsi_Cmnd *); diff --git a/drivers/scsi/fastlane.c b/drivers/scsi/fastlane.c index ae47612..ccee68b 100644 --- a/drivers/scsi/fastlane.c +++ b/drivers/scsi/fastlane.c @@ -125,7 +125,7 @@ static inline void dma_clear(struct NCR_ESP *esp) } /***************************************************************** Detection */ -int __init fastlane_esp_detect(Scsi_Host_Template *tpnt) +int __init fastlane_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -398,7 +398,7 @@ int fastlane_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-fastlane", .proc_info = esp_proc_info, .name = "Fastlane SCSI", diff --git a/drivers/scsi/fcal.c b/drivers/scsi/fcal.c index a6f120d..0341654 100644 --- a/drivers/scsi/fcal.c +++ b/drivers/scsi/fcal.c @@ -70,7 +70,7 @@ static unsigned char target2alpa[] = { static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmnd *fcmd); -int fcal_slave_configure(Scsi_Device *device) +int fcal_slave_configure(struct scsi_device *device) { int depth_to_use; @@ -89,7 +89,7 @@ int fcal_slave_configure(Scsi_Device *device) /* Detect all FC Arbitrated Loops attached to the machine. fc4 module has done all the work for us... */ -int __init fcal_detect(Scsi_Host_Template *tpnt) +int __init fcal_detect(struct scsi_host_template *tpnt) { int nfcals = 0; fc_channel *fc; @@ -244,7 +244,7 @@ int fcal_proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t of SPRINTF (" [AL-PA: %02x, Port WWN: %08x%08x, Node WWN: %08x%08x] Not responded to PRLI\n", alpa, u1[0], u1[1], u2[0], u2[1]); } else { - Scsi_Device *scd; + struct scsi_device *scd; shost_for_each_device(scd, host) if (scd->id == target) { SPRINTF (" [AL-PA: %02x, Id: %02d, Port WWN: %08x%08x, Node WWN: %08x%08x] ", @@ -297,7 +297,7 @@ static int fcal_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cmn return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "Fibre Channel Arbitrated Loop", .detect = fcal_detect, .release = fcal_release, diff --git a/drivers/scsi/fcal.h b/drivers/scsi/fcal.h index 21aa32e..7ff2c349 100644 --- a/drivers/scsi/fcal.h +++ b/drivers/scsi/fcal.h @@ -20,8 +20,8 @@ struct fcal { for a particular channel */ #define FCAL_CAN_QUEUE 512 -int fcal_detect(Scsi_Host_Template *); +int fcal_detect(struct scsi_host_template *); int fcal_release(struct Scsi_Host *); -int fcal_slave_configure(Scsi_Device *); +int fcal_slave_configure(struct scsi_device *); #endif /* !(_FCAL_H) */ diff --git a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c index 6d44602..cca485a 100644 --- a/drivers/scsi/fd_mcs.c +++ b/drivers/scsi/fd_mcs.c @@ -343,7 +343,7 @@ static void fd_mcs_make_bus_idle(struct Scsi_Host *shpnt) outb(0x01 | PARITY_MASK, TMC_Cntl_port); } -static int fd_mcs_detect(Scsi_Host_Template * tpnt) +static int fd_mcs_detect(struct scsi_host_template * tpnt) { int loop; struct Scsi_Host *shpnt; @@ -1343,7 +1343,7 @@ static int fd_mcs_biosparam(struct scsi_device * disk, struct block_device *bdev return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "fd_mcs", .proc_info = fd_mcs_proc_info, .detect = fd_mcs_detect, diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index a3aa729..45756fa 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c @@ -285,7 +285,7 @@ static int __init do_DTC3181E_setup(char *str) * Locks: none */ -int __init generic_NCR5380_detect(Scsi_Host_Template * tpnt) +int __init generic_NCR5380_detect(struct scsi_host_template * tpnt) { static int current_override = 0; int count, i; @@ -798,7 +798,7 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c Scsi_Cmnd *ptr; struct NCR5380_hostdata *hostdata; #ifdef NCR5380_STATS - Scsi_Device *dev; + struct scsi_device *dev; extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; #endif @@ -899,7 +899,7 @@ static int generic_NCR5380_proc_info(struct Scsi_Host *scsi_ptr, char *buffer, c #undef PRINTP #undef ANDP -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_info = generic_NCR5380_proc_info, .name = "Generic NCR5380/NCR53C400 Scsi Driver", .detect = generic_NCR5380_detect, diff --git a/drivers/scsi/g_NCR5380.h b/drivers/scsi/g_NCR5380.h index c8adc5a..656fbe2 100644 --- a/drivers/scsi/g_NCR5380.h +++ b/drivers/scsi/g_NCR5380.h @@ -45,7 +45,7 @@ #ifndef ASM static int generic_NCR5380_abort(Scsi_Cmnd *); -static int generic_NCR5380_detect(Scsi_Host_Template *); +static int generic_NCR5380_detect(struct scsi_host_template *); static int generic_NCR5380_release_resources(struct Scsi_Host *); static int generic_NCR5380_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int generic_NCR5380_bus_reset(Scsi_Cmnd *); diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index af68230..a6deb01 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c @@ -94,7 +94,7 @@ * Bugfix free_irq() * * Revision 1.56 2001/08/09 11:19:39 achim - * Scsi_Host_Template changes + * struct scsi_host_template changes * * Revision 1.55 2001/08/09 10:11:28 achim * Command HOST_UNFREEZE_IO before cache service init. @@ -4153,7 +4153,7 @@ int __init option_setup(char *str) return 1; } -static int __init gdth_detect(Scsi_Host_Template *shtp) +static int __init gdth_detect(struct scsi_host_template *shtp) { struct Scsi_Host *shp; gdth_pci_str pcistr[MAXHA]; @@ -5562,7 +5562,7 @@ static void gdth_flush(int hanum) #else Scsi_Cmnd *scp; #endif - Scsi_Device *sdev; + struct scsi_device *sdev; char cmnd[MAX_COMMAND_SIZE]; memset(cmnd, 0xff, MAX_COMMAND_SIZE); @@ -5624,10 +5624,10 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) gdth_cmd_str gdtcmd; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *srp; - Scsi_Device *sdev; + struct scsi_device *sdev; #else Scsi_Cmnd *scp; - Scsi_Device *sdev; + struct scsi_device *sdev; #endif char cmnd[MAX_COMMAND_SIZE]; #endif @@ -5683,7 +5683,7 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) return NOTIFY_OK; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "gdth", .proc_info = gdth_proc_info, .name = "GDT SCSI Disk Array Controller", diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index c0f1e34..cc4882f 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h @@ -944,9 +944,9 @@ typedef struct { ulong dma32_cnt, dma64_cnt; /* statistics: DMA buffer */ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) - Scsi_Device *sdev; + struct scsi_device *sdev; #else - Scsi_Device sdev; + struct scsi_device sdev; #endif } gdth_ha_str; diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 1bd02f8..5e8657f 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c @@ -54,10 +54,10 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, int ret_val = -EINVAL; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *scp; - Scsi_Device *sdev; + struct scsi_device *sdev; #else Scsi_Cmnd *scp; - Scsi_Device *sdev; + struct scsi_device *sdev; #endif TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); @@ -232,10 +232,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, gdth_evt_str *estr; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) Scsi_Request *scp; - Scsi_Device *sdev; + struct scsi_device *sdev; #else Scsi_Cmnd *scp; - Scsi_Device *sdev; + struct scsi_device *sdev; #endif char hrec[161]; struct timeval tv; @@ -275,7 +275,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, scp->cmd_len = 12; scp->use_sg = 0; #else - memset(&sdev,0,sizeof(Scsi_Device)); + memset(&sdev,0,sizeof(struct scsi_device)); memset(&scp, 0,sizeof(Scsi_Cmnd)); sdev.host = scp.host = host; sdev.id = scp.target = sdev.host->this_id; diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index ab22387..5b15449 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -169,7 +169,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, #define CHECK_WD33C93 -int __init gvp11_detect(Scsi_Host_Template *tpnt) +int __init gvp11_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; struct Scsi_Host *instance; @@ -361,7 +361,7 @@ static int gvp11_bus_reset(Scsi_Cmnd *cmd) #include "gvp11.h" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "GVP11", .name = "GVP Series II SCSI", .detect = gvp11_detect, diff --git a/drivers/scsi/gvp11.h b/drivers/scsi/gvp11.h index 5148d9f..575d219d 100644 --- a/drivers/scsi/gvp11.h +++ b/drivers/scsi/gvp11.h @@ -11,7 +11,7 @@ #include <linux/types.h> -int gvp11_detect(Scsi_Host_Template *); +int gvp11_detect(struct scsi_host_template *); int gvp11_release(struct Scsi_Host *); const char *wd33c93_info(void); int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 8d97999..b60c1b9 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c @@ -492,7 +492,7 @@ static char *ibmrate(unsigned int, int); static int probe_display(int); static int probe_bus_mode(int); static int device_exists(int, int, int *, int *); -static struct Scsi_Host *ibmmca_register(Scsi_Host_Template *, int, int, int, char *); +static struct Scsi_Host *ibmmca_register(struct scsi_host_template *, int, int, int, char *); static int option_setup(char *); /* local functions needed for proc_info */ static int ldn_access_load(int, int); @@ -1483,7 +1483,7 @@ static int ibmmca_getinfo(char *buf, int slot, void *dev_id) return len; } -int ibmmca_detect(Scsi_Host_Template * scsi_template) +int ibmmca_detect(struct scsi_host_template * scsi_template) { struct Scsi_Host *shpnt; int port, id, i, j, k, list_size, slot; @@ -1736,7 +1736,7 @@ int ibmmca_detect(Scsi_Host_Template * scsi_template) return found; /* return the number of found SCSI hosts. Should be 1 or 0. */ } -static struct Scsi_Host *ibmmca_register(Scsi_Host_Template * scsi_template, int port, int id, int adaptertype, char *hostname) +static struct Scsi_Host *ibmmca_register(struct scsi_host_template * scsi_template, int port, int id, int adaptertype, char *hostname) { struct Scsi_Host *shpnt; int i, j; @@ -2494,7 +2494,7 @@ static int option_setup(char *str) __setup("ibmmcascsi=", option_setup); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "ibmmca", .proc_info = ibmmca_proc_info, .name = "IBM SCSI-Subsystem", diff --git a/drivers/scsi/ibmmca.h b/drivers/scsi/ibmmca.h index 6d68f60..017ee2f 100644 --- a/drivers/scsi/ibmmca.h +++ b/drivers/scsi/ibmmca.h @@ -11,7 +11,7 @@ /* Common forward declarations for all Linux-versions: */ /* Interfaces to the midlevel Linux SCSI driver */ -static int ibmmca_detect (Scsi_Host_Template *); +static int ibmmca_detect (struct scsi_host_template *); static int ibmmca_release (struct Scsi_Host *); static int ibmmca_queuecommand (Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); static int ibmmca_abort (Scsi_Cmnd *); diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index 8bec043..5b0edd1 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h @@ -100,7 +100,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, void ibmvscsi_release_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata, int max_requests); -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata); void ibmvscsi_handle_crq(struct viosrp_crq *crq, diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 1045872..ce15d9e 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -117,9 +117,10 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, * * no-op for iSeries */ -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { + return 0; } /** diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 8bf5652..75db2f5 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -230,6 +230,11 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, rc = plpar_hcall_norets(H_REG_CRQ, vdev->unit_address, queue->msg_token, PAGE_SIZE); + if (rc == H_Resource) + /* maybe kexecing and resource is busy. try a reset */ + rc = ibmvscsi_reset_crq_queue(queue, + hostdata); + if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); @@ -281,7 +286,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, * @hostdata: ibmvscsi_host_data of host * */ -void ibmvscsi_reset_crq_queue(struct crq_queue *queue, +int ibmvscsi_reset_crq_queue(struct crq_queue *queue, struct ibmvscsi_host_data *hostdata) { int rc; @@ -309,4 +314,5 @@ void ibmvscsi_reset_crq_queue(struct crq_queue *queue, printk(KERN_WARNING "ibmvscsi: couldn't register crq--rc 0x%x\n", rc); } + return rc; } diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 3553da0..4cb1f3e 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -784,8 +784,8 @@ static ide_proc_entry_t idescsi_proc[] = { #endif static ide_driver_t idescsi_driver = { - .owner = THIS_MODULE, .gen_driver = { + .owner = THIS_MODULE, .name = "ide-scsi", .bus = &ide_bus_type, .probe = ide_scsi_probe, @@ -882,7 +882,7 @@ static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd) struct gendisk *disk = cmd->request->rq_disk; if (disk) { - struct Scsi_Device_Template **p = disk->private_data; + struct struct scsi_device_Template **p = disk->private_data; if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0) return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); } diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index fe387b5..34daa3e 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c @@ -1899,7 +1899,7 @@ static int int_tab[] in2000__INITDATA = { }; -static int __init in2000_detect(Scsi_Host_Template * tpnt) +static int __init in2000_detect(struct scsi_host_template * tpnt) { struct Scsi_Host *instance; struct IN2000_hostdata *hostdata; @@ -2305,7 +2305,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "in2000", .proc_info = in2000_proc_info, .name = "Always IN2000", diff --git a/drivers/scsi/in2000.h b/drivers/scsi/in2000.h index a240b52..0fb8b06 100644 --- a/drivers/scsi/in2000.h +++ b/drivers/scsi/in2000.h @@ -395,7 +395,7 @@ struct IN2000_hostdata { # define CLISPIN_UNLOCK(host,flags) spin_unlock_irqrestore(host->host_lock, \ flags) -static int in2000_detect(Scsi_Host_Template *) in2000__INIT; +static int in2000_detect(struct scsi_host_template *) in2000__INIT; static int in2000_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int in2000_abort(Scsi_Cmnd *); static void in2000_setup(char *, int *) in2000__INIT; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e0039df..fa2cb358 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -91,11 +91,14 @@ static unsigned int ipr_max_speed = 1; static int ipr_testmode = 0; static unsigned int ipr_fastfail = 0; static unsigned int ipr_transop_timeout = IPR_OPERATIONAL_TIMEOUT; +static unsigned int ipr_enable_cache = 1; +static unsigned int ipr_debug = 0; +static int ipr_auto_create = 1; static DEFINE_SPINLOCK(ipr_driver_lock); /* This table describes the differences between DMA controller chips */ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { - { /* Gemstone and Citrine */ + { /* Gemstone, Citrine, and Obsidian */ .mailbox = 0x0042C, .cache_line_size = 0x20, { @@ -130,6 +133,8 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = { static const struct ipr_chip_t ipr_chip[] = { { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, &ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, &ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, &ipr_chip_cfg[1] }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, &ipr_chip_cfg[1] } }; @@ -150,6 +155,12 @@ module_param_named(fastfail, ipr_fastfail, int, 0); MODULE_PARM_DESC(fastfail, "Reduce timeouts and retries"); module_param_named(transop_timeout, ipr_transop_timeout, int, 0); MODULE_PARM_DESC(transop_timeout, "Time in seconds to wait for adapter to come operational (default: 300)"); +module_param_named(enable_cache, ipr_enable_cache, int, 0); +MODULE_PARM_DESC(enable_cache, "Enable adapter's non-volatile write cache (default: 1)"); +module_param_named(debug, ipr_debug, int, 0); +MODULE_PARM_DESC(debug, "Enable device driver debugging logging. Set to 1 to enable. (default: 0)"); +module_param_named(auto_create, ipr_auto_create, int, 0); +MODULE_PARM_DESC(auto_create, "Auto-create single device RAID 0 arrays when initialized (default: 1)"); MODULE_LICENSE("GPL"); MODULE_VERSION(IPR_DRIVER_VERSION); @@ -285,12 +296,18 @@ struct ipr_error_table_t ipr_error_table[] = { "3110: Device bus error, message or command phase"}, {0x04670400, 0, 1, "9091: Incorrect hardware configuration change has been detected"}, + {0x04678000, 0, 1, + "9073: Invalid multi-adapter configuration"}, {0x046E0000, 0, 1, "FFF4: Command to logical unit failed"}, {0x05240000, 1, 0, "Illegal request, invalid request type or request packet"}, {0x05250000, 0, 0, "Illegal request, invalid resource handle"}, + {0x05258000, 0, 0, + "Illegal request, commands not allowed to this device"}, + {0x05258100, 0, 0, + "Illegal request, command not allowed to a secondary adapter"}, {0x05260000, 0, 0, "Illegal request, invalid field in parameter list"}, {0x05260100, 0, 0, @@ -299,6 +316,8 @@ struct ipr_error_table_t ipr_error_table[] = { "Illegal request, parameter value invalid"}, {0x052C0000, 0, 0, "Illegal request, command sequence error"}, + {0x052C8000, 1, 0, + "Illegal request, dual adapter support not enabled"}, {0x06040500, 0, 1, "9031: Array protection temporarily suspended, protection resuming"}, {0x06040600, 0, 1, @@ -315,18 +334,26 @@ struct ipr_error_table_t ipr_error_table[] = { "3029: A device replacement has occurred"}, {0x064C8000, 0, 1, "9051: IOA cache data exists for a missing or failed device"}, + {0x064C8100, 0, 1, + "9055: Auxiliary cache IOA contains cache data needed by the primary IOA"}, {0x06670100, 0, 1, "9025: Disk unit is not supported at its physical location"}, {0x06670600, 0, 1, "3020: IOA detected a SCSI bus configuration error"}, {0x06678000, 0, 1, "3150: SCSI bus configuration error"}, + {0x06678100, 0, 1, + "9074: Asymmetric advanced function disk configuration"}, {0x06690200, 0, 1, "9041: Array protection temporarily suspended"}, {0x06698200, 0, 1, "9042: Corrupt array parity detected on specified device"}, {0x066B0200, 0, 1, "9030: Array no longer protected due to missing or failed disk unit"}, + {0x066B8000, 0, 1, + "9071: Link operational transition"}, + {0x066B8100, 0, 1, + "9072: Link not operational transition"}, {0x066B8200, 0, 1, "9032: Array exposed but still protected"}, {0x07270000, 0, 0, @@ -789,7 +816,7 @@ static void ipr_send_hcam(struct ipr_ioa_cfg *ioa_cfg, u8 type, **/ static void ipr_init_res_entry(struct ipr_resource_entry *res) { - res->needs_sync_complete = 1; + res->needs_sync_complete = 0; res->in_erp = 0; res->add_to_ml = 0; res->del_from_ml = 0; @@ -889,29 +916,74 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd) /** * ipr_log_vpd - Log the passed VPD to the error log. - * @vpids: vendor/product id struct - * @serial_num: serial number string + * @vpd: vendor/product id/sn struct * * Return value: * none **/ -static void ipr_log_vpd(struct ipr_std_inq_vpids *vpids, u8 *serial_num) +static void ipr_log_vpd(struct ipr_vpd *vpd) { char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN]; - memcpy(buffer, vpids->vendor_id, IPR_VENDOR_ID_LEN); - memcpy(buffer + IPR_VENDOR_ID_LEN, vpids->product_id, + memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN); + memcpy(buffer + IPR_VENDOR_ID_LEN, vpd->vpids.product_id, IPR_PROD_ID_LEN); buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN] = '\0'; ipr_err("Vendor/Product ID: %s\n", buffer); - memcpy(buffer, serial_num, IPR_SERIAL_NUM_LEN); + memcpy(buffer, vpd->sn, IPR_SERIAL_NUM_LEN); buffer[IPR_SERIAL_NUM_LEN] = '\0'; ipr_err(" Serial Number: %s\n", buffer); } /** + * ipr_log_ext_vpd - Log the passed extended VPD to the error log. + * @vpd: vendor/product id/sn/wwn struct + * + * Return value: + * none + **/ +static void ipr_log_ext_vpd(struct ipr_ext_vpd *vpd) +{ + ipr_log_vpd(&vpd->vpd); + ipr_err(" WWN: %08X%08X\n", be32_to_cpu(vpd->wwid[0]), + be32_to_cpu(vpd->wwid[1])); +} + +/** + * ipr_log_enhanced_cache_error - Log a cache error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_enhanced_cache_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + struct ipr_hostrcb_type_12_error *error = + &hostrcb->hcam.u.error.u.type_12_error; + + ipr_err("-----Current Configuration-----\n"); + ipr_err("Cache Directory Card Information:\n"); + ipr_log_ext_vpd(&error->ioa_vpd); + ipr_err("Adapter Card Information:\n"); + ipr_log_ext_vpd(&error->cfc_vpd); + + ipr_err("-----Expected Configuration-----\n"); + ipr_err("Cache Directory Card Information:\n"); + ipr_log_ext_vpd(&error->ioa_last_attached_to_cfc_vpd); + ipr_err("Adapter Card Information:\n"); + ipr_log_ext_vpd(&error->cfc_last_attached_to_ioa_vpd); + + ipr_err("Additional IOA Data: %08X %08X %08X\n", + be32_to_cpu(error->ioa_data[0]), + be32_to_cpu(error->ioa_data[1]), + be32_to_cpu(error->ioa_data[2])); +} + +/** * ipr_log_cache_error - Log a cache error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -927,17 +999,15 @@ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg, ipr_err("-----Current Configuration-----\n"); ipr_err("Cache Directory Card Information:\n"); - ipr_log_vpd(&error->ioa_vpids, error->ioa_sn); + ipr_log_vpd(&error->ioa_vpd); ipr_err("Adapter Card Information:\n"); - ipr_log_vpd(&error->cfc_vpids, error->cfc_sn); + ipr_log_vpd(&error->cfc_vpd); ipr_err("-----Expected Configuration-----\n"); ipr_err("Cache Directory Card Information:\n"); - ipr_log_vpd(&error->ioa_last_attached_to_cfc_vpids, - error->ioa_last_attached_to_cfc_sn); + ipr_log_vpd(&error->ioa_last_attached_to_cfc_vpd); ipr_err("Adapter Card Information:\n"); - ipr_log_vpd(&error->cfc_last_attached_to_ioa_vpids, - error->cfc_last_attached_to_ioa_sn); + ipr_log_vpd(&error->cfc_last_attached_to_ioa_vpd); ipr_err("Additional IOA Data: %08X %08X %08X\n", be32_to_cpu(error->ioa_data[0]), @@ -946,6 +1016,46 @@ static void ipr_log_cache_error(struct ipr_ioa_cfg *ioa_cfg, } /** + * ipr_log_enhanced_config_error - Log a configuration error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_enhanced_config_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + int errors_logged, i; + struct ipr_hostrcb_device_data_entry_enhanced *dev_entry; + struct ipr_hostrcb_type_13_error *error; + + error = &hostrcb->hcam.u.error.u.type_13_error; + errors_logged = be32_to_cpu(error->errors_logged); + + ipr_err("Device Errors Detected/Logged: %d/%d\n", + be32_to_cpu(error->errors_detected), errors_logged); + + dev_entry = error->dev; + + for (i = 0; i < errors_logged; i++, dev_entry++) { + ipr_err_separator; + + ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1); + ipr_log_ext_vpd(&dev_entry->vpd); + + ipr_err("-----New Device Information-----\n"); + ipr_log_ext_vpd(&dev_entry->new_vpd); + + ipr_err("Cache Directory Card Information:\n"); + ipr_log_ext_vpd(&dev_entry->ioa_last_with_dev_vpd); + + ipr_err("Adapter Card Information:\n"); + ipr_log_ext_vpd(&dev_entry->cfc_last_with_dev_vpd); + } +} + +/** * ipr_log_config_error - Log a configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -966,30 +1076,22 @@ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg, ipr_err("Device Errors Detected/Logged: %d/%d\n", be32_to_cpu(error->errors_detected), errors_logged); - dev_entry = error->dev_entry; + dev_entry = error->dev; for (i = 0; i < errors_logged; i++, dev_entry++) { ipr_err_separator; - if (dev_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) { - ipr_err("Device %d: missing\n", i + 1); - } else { - ipr_err("Device %d: %d:%d:%d:%d\n", i + 1, - ioa_cfg->host->host_no, dev_entry->dev_res_addr.bus, - dev_entry->dev_res_addr.target, dev_entry->dev_res_addr.lun); - } - ipr_log_vpd(&dev_entry->dev_vpids, dev_entry->dev_sn); + ipr_phys_res_err(ioa_cfg, dev_entry->dev_res_addr, "Device %d", i + 1); + ipr_log_vpd(&dev_entry->vpd); ipr_err("-----New Device Information-----\n"); - ipr_log_vpd(&dev_entry->new_dev_vpids, dev_entry->new_dev_sn); + ipr_log_vpd(&dev_entry->new_vpd); ipr_err("Cache Directory Card Information:\n"); - ipr_log_vpd(&dev_entry->ioa_last_with_dev_vpids, - dev_entry->ioa_last_with_dev_sn); + ipr_log_vpd(&dev_entry->ioa_last_with_dev_vpd); ipr_err("Adapter Card Information:\n"); - ipr_log_vpd(&dev_entry->cfc_last_with_dev_vpids, - dev_entry->cfc_last_with_dev_sn); + ipr_log_vpd(&dev_entry->cfc_last_with_dev_vpd); ipr_err("Additional IOA Data: %08X %08X %08X %08X %08X\n", be32_to_cpu(dev_entry->ioa_data[0]), @@ -1001,6 +1103,57 @@ static void ipr_log_config_error(struct ipr_ioa_cfg *ioa_cfg, } /** + * ipr_log_enhanced_array_error - Log an array configuration error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_enhanced_array_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + int i, num_entries; + struct ipr_hostrcb_type_14_error *error; + struct ipr_hostrcb_array_data_entry_enhanced *array_entry; + const u8 zero_sn[IPR_SERIAL_NUM_LEN] = { [0 ... IPR_SERIAL_NUM_LEN-1] = '0' }; + + error = &hostrcb->hcam.u.error.u.type_14_error; + + ipr_err_separator; + + ipr_err("RAID %s Array Configuration: %d:%d:%d:%d\n", + error->protection_level, + ioa_cfg->host->host_no, + error->last_func_vset_res_addr.bus, + error->last_func_vset_res_addr.target, + error->last_func_vset_res_addr.lun); + + ipr_err_separator; + + array_entry = error->array_member; + num_entries = min_t(u32, be32_to_cpu(error->num_entries), + sizeof(error->array_member)); + + for (i = 0; i < num_entries; i++, array_entry++) { + if (!memcmp(array_entry->vpd.vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) + continue; + + if (be32_to_cpu(error->exposed_mode_adn) == i) + ipr_err("Exposed Array Member %d:\n", i); + else + ipr_err("Array Member %d:\n", i); + + ipr_log_ext_vpd(&array_entry->vpd); + ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location"); + ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr, + "Expected Location"); + + ipr_err_separator; + } +} + +/** * ipr_log_array_error - Log an array configuration error. * @ioa_cfg: ioa config struct * @hostrcb: hostrcb struct @@ -1032,36 +1185,19 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, array_entry = error->array_member; for (i = 0; i < 18; i++) { - if (!memcmp(array_entry->serial_num, zero_sn, IPR_SERIAL_NUM_LEN)) + if (!memcmp(array_entry->vpd.sn, zero_sn, IPR_SERIAL_NUM_LEN)) continue; - if (be32_to_cpu(error->exposed_mode_adn) == i) { + if (be32_to_cpu(error->exposed_mode_adn) == i) ipr_err("Exposed Array Member %d:\n", i); - } else { + else ipr_err("Array Member %d:\n", i); - } - ipr_log_vpd(&array_entry->vpids, array_entry->serial_num); - - if (array_entry->dev_res_addr.bus >= IPR_MAX_NUM_BUSES) { - ipr_err("Current Location: unknown\n"); - } else { - ipr_err("Current Location: %d:%d:%d:%d\n", - ioa_cfg->host->host_no, - array_entry->dev_res_addr.bus, - array_entry->dev_res_addr.target, - array_entry->dev_res_addr.lun); - } + ipr_log_vpd(&array_entry->vpd); - if (array_entry->expected_dev_res_addr.bus >= IPR_MAX_NUM_BUSES) { - ipr_err("Expected Location: unknown\n"); - } else { - ipr_err("Expected Location: %d:%d:%d:%d\n", - ioa_cfg->host->host_no, - array_entry->expected_dev_res_addr.bus, - array_entry->expected_dev_res_addr.target, - array_entry->expected_dev_res_addr.lun); - } + ipr_phys_res_err(ioa_cfg, array_entry->dev_res_addr, "Current Location"); + ipr_phys_res_err(ioa_cfg, array_entry->expected_dev_res_addr, + "Expected Location"); ipr_err_separator; @@ -1073,35 +1209,95 @@ static void ipr_log_array_error(struct ipr_ioa_cfg *ioa_cfg, } /** - * ipr_log_generic_error - Log an adapter error. - * @ioa_cfg: ioa config struct - * @hostrcb: hostrcb struct + * ipr_log_hex_data - Log additional hex IOA error data. + * @data: IOA error data + * @len: data length * * Return value: * none **/ -static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, - struct ipr_hostrcb *hostrcb) +static void ipr_log_hex_data(u32 *data, int len) { int i; - int ioa_data_len = be32_to_cpu(hostrcb->hcam.length); - if (ioa_data_len == 0) + if (len == 0) return; - ipr_err("IOA Error Data:\n"); - ipr_err("Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); - - for (i = 0; i < ioa_data_len / 4; i += 4) { + for (i = 0; i < len / 4; i += 4) { ipr_err("%08X: %08X %08X %08X %08X\n", i*4, - be32_to_cpu(hostrcb->hcam.u.raw.data[i]), - be32_to_cpu(hostrcb->hcam.u.raw.data[i+1]), - be32_to_cpu(hostrcb->hcam.u.raw.data[i+2]), - be32_to_cpu(hostrcb->hcam.u.raw.data[i+3])); + be32_to_cpu(data[i]), + be32_to_cpu(data[i+1]), + be32_to_cpu(data[i+2]), + be32_to_cpu(data[i+3])); } } /** + * ipr_log_enhanced_dual_ioa_error - Log an enhanced dual adapter error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_enhanced_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + struct ipr_hostrcb_type_17_error *error; + + error = &hostrcb->hcam.u.error.u.type_17_error; + error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; + + ipr_err("%s\n", error->failure_reason); + ipr_err("Remote Adapter VPD:\n"); + ipr_log_ext_vpd(&error->vpd); + ipr_log_hex_data(error->data, + be32_to_cpu(hostrcb->hcam.length) - + (offsetof(struct ipr_hostrcb_error, u) + + offsetof(struct ipr_hostrcb_type_17_error, data))); +} + +/** + * ipr_log_dual_ioa_error - Log a dual adapter error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_dual_ioa_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + struct ipr_hostrcb_type_07_error *error; + + error = &hostrcb->hcam.u.error.u.type_07_error; + error->failure_reason[sizeof(error->failure_reason) - 1] = '\0'; + + ipr_err("%s\n", error->failure_reason); + ipr_err("Remote Adapter VPD:\n"); + ipr_log_vpd(&error->vpd); + ipr_log_hex_data(error->data, + be32_to_cpu(hostrcb->hcam.length) - + (offsetof(struct ipr_hostrcb_error, u) + + offsetof(struct ipr_hostrcb_type_07_error, data))); +} + +/** + * ipr_log_generic_error - Log an adapter error. + * @ioa_cfg: ioa config struct + * @hostrcb: hostrcb struct + * + * Return value: + * none + **/ +static void ipr_log_generic_error(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_hostrcb *hostrcb) +{ + ipr_log_hex_data(hostrcb->hcam.u.raw.data, + be32_to_cpu(hostrcb->hcam.length)); +} + +/** * ipr_get_error - Find the specfied IOASC in the ipr_error_table. * @ioasc: IOASC * @@ -1172,11 +1368,10 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, if (ioa_cfg->log_level < IPR_DEFAULT_LOG_LEVEL) return; + if (be32_to_cpu(hostrcb->hcam.length) > sizeof(hostrcb->hcam.u.raw)) + hostrcb->hcam.length = cpu_to_be32(sizeof(hostrcb->hcam.u.raw)); switch (hostrcb->hcam.overlay_id) { - case IPR_HOST_RCB_OVERLAY_ID_1: - ipr_log_generic_error(ioa_cfg, hostrcb); - break; case IPR_HOST_RCB_OVERLAY_ID_2: ipr_log_cache_error(ioa_cfg, hostrcb); break; @@ -1187,13 +1382,26 @@ static void ipr_handle_log_data(struct ipr_ioa_cfg *ioa_cfg, case IPR_HOST_RCB_OVERLAY_ID_6: ipr_log_array_error(ioa_cfg, hostrcb); break; - case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: - ipr_log_generic_error(ioa_cfg, hostrcb); + case IPR_HOST_RCB_OVERLAY_ID_7: + ipr_log_dual_ioa_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_12: + ipr_log_enhanced_cache_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_13: + ipr_log_enhanced_config_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_14: + case IPR_HOST_RCB_OVERLAY_ID_16: + ipr_log_enhanced_array_error(ioa_cfg, hostrcb); break; + case IPR_HOST_RCB_OVERLAY_ID_17: + ipr_log_enhanced_dual_ioa_error(ioa_cfg, hostrcb); + break; + case IPR_HOST_RCB_OVERLAY_ID_1: + case IPR_HOST_RCB_OVERLAY_ID_DEFAULT: default: - dev_err(&ioa_cfg->pdev->dev, - "Unknown error received. Overlay ID: %d\n", - hostrcb->hcam.overlay_id); + ipr_log_generic_error(ioa_cfg, hostrcb); break; } } @@ -1972,6 +2180,103 @@ static struct bin_attribute ipr_trace_attr = { }; #endif +static const struct { + enum ipr_cache_state state; + char *name; +} cache_state [] = { + { CACHE_NONE, "none" }, + { CACHE_DISABLED, "disabled" }, + { CACHE_ENABLED, "enabled" } +}; + +/** + * ipr_show_write_caching - Show the write caching attribute + * @class_dev: class device struct + * @buf: buffer + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ipr_show_write_caching(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; + unsigned long lock_flags = 0; + int i, len = 0; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + for (i = 0; i < ARRAY_SIZE(cache_state); i++) { + if (cache_state[i].state == ioa_cfg->cache_state) { + len = snprintf(buf, PAGE_SIZE, "%s\n", cache_state[i].name); + break; + } + } + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return len; +} + + +/** + * ipr_store_write_caching - Enable/disable adapter write cache + * @class_dev: class_device struct + * @buf: buffer + * @count: buffer size + * + * This function will enable/disable adapter write cache. + * + * Return value: + * count on success / other on failure + **/ +static ssize_t ipr_store_write_caching(struct class_device *class_dev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; + unsigned long lock_flags = 0; + enum ipr_cache_state new_state = CACHE_INVALID; + int i; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (ioa_cfg->cache_state == CACHE_NONE) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(cache_state); i++) { + if (!strncmp(cache_state[i].name, buf, strlen(cache_state[i].name))) { + new_state = cache_state[i].state; + break; + } + } + + if (new_state != CACHE_DISABLED && new_state != CACHE_ENABLED) + return -EINVAL; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + if (ioa_cfg->cache_state == new_state) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return count; + } + + ioa_cfg->cache_state = new_state; + dev_info(&ioa_cfg->pdev->dev, "%s adapter write cache.\n", + new_state == CACHE_ENABLED ? "Enabling" : "Disabling"); + if (!ioa_cfg->in_reset_reload) + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + + return count; +} + +static struct class_device_attribute ipr_ioa_cache_attr = { + .attr = { + .name = "write_cache", + .mode = S_IRUGO | S_IWUSR, + }, + .show = ipr_show_write_caching, + .store = ipr_store_write_caching +}; + /** * ipr_show_fw_version - Show the firmware version * @class_dev: class device struct @@ -2112,6 +2417,74 @@ static struct class_device_attribute ipr_diagnostics_attr = { }; /** + * ipr_show_adapter_state - Show the adapter's state + * @class_dev: class device struct + * @buf: buffer + * + * Return value: + * number of bytes printed to buffer + **/ +static ssize_t ipr_show_adapter_state(struct class_device *class_dev, char *buf) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; + unsigned long lock_flags = 0; + int len; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + if (ioa_cfg->ioa_is_dead) + len = snprintf(buf, PAGE_SIZE, "offline\n"); + else + len = snprintf(buf, PAGE_SIZE, "online\n"); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + return len; +} + +/** + * ipr_store_adapter_state - Change adapter state + * @class_dev: class_device struct + * @buf: buffer + * @count: buffer size + * + * This function will change the adapter's state. + * + * Return value: + * count on success / other on failure + **/ +static ssize_t ipr_store_adapter_state(struct class_device *class_dev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = class_to_shost(class_dev); + struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; + unsigned long lock_flags; + int result = count; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + if (ioa_cfg->ioa_is_dead && !strncmp(buf, "online", 6)) { + ioa_cfg->ioa_is_dead = 0; + ioa_cfg->reset_retries = 0; + ioa_cfg->in_ioa_bringdown = 0; + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); + } + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + + return result; +} + +static struct class_device_attribute ipr_ioa_state_attr = { + .attr = { + .name = "state", + .mode = S_IRUGO | S_IWUSR, + }, + .show = ipr_show_adapter_state, + .store = ipr_store_adapter_state +}; + +/** * ipr_store_reset_adapter - Reset the adapter * @class_dev: class_device struct * @buf: buffer @@ -2183,7 +2556,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) num_elem = buf_len / bsize_elem; /* Allocate a scatter/gather list for the DMA */ - sglist = kmalloc(sizeof(struct ipr_sglist) + + sglist = kzalloc(sizeof(struct ipr_sglist) + (sizeof(struct scatterlist) * (num_elem - 1)), GFP_KERNEL); @@ -2192,9 +2565,6 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) return NULL; } - memset(sglist, 0, sizeof(struct ipr_sglist) + - (sizeof(struct scatterlist) * (num_elem - 1))); - scatterlist = sglist->scatterlist; sglist->order = order; @@ -2289,31 +2659,24 @@ static int ipr_copy_ucode_buffer(struct ipr_sglist *sglist, } /** - * ipr_map_ucode_buffer - Map a microcode download buffer + * ipr_build_ucode_ioadl - Build a microcode download IOADL * @ipr_cmd: ipr command struct * @sglist: scatter/gather list - * @len: total length of download buffer * - * Maps a microcode download scatter/gather list for DMA and - * builds the IOADL. + * Builds a microcode download IOA data list (IOADL). * - * Return value: - * 0 on success / -EIO on failure **/ -static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd, - struct ipr_sglist *sglist, int len) +static void ipr_build_ucode_ioadl(struct ipr_cmnd *ipr_cmd, + struct ipr_sglist *sglist) { - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; struct scatterlist *scatterlist = sglist->scatterlist; int i; - ipr_cmd->dma_use_sg = pci_map_sg(ioa_cfg->pdev, scatterlist, - sglist->num_sg, DMA_TO_DEVICE); - + ipr_cmd->dma_use_sg = sglist->num_dma_sg; ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_WRITE_NOT_READ; - ioarcb->write_data_transfer_length = cpu_to_be32(len); + ioarcb->write_data_transfer_length = cpu_to_be32(sglist->buffer_len); ioarcb->write_ioadl_len = cpu_to_be32(sizeof(struct ipr_ioadl_desc) * ipr_cmd->dma_use_sg); @@ -2324,15 +2687,52 @@ static int ipr_map_ucode_buffer(struct ipr_cmnd *ipr_cmd, cpu_to_be32(sg_dma_address(&scatterlist[i])); } - if (likely(ipr_cmd->dma_use_sg)) { - ioadl[i-1].flags_and_data_len |= - cpu_to_be32(IPR_IOADL_FLAGS_LAST); + ioadl[i-1].flags_and_data_len |= + cpu_to_be32(IPR_IOADL_FLAGS_LAST); +} + +/** + * ipr_update_ioa_ucode - Update IOA's microcode + * @ioa_cfg: ioa config struct + * @sglist: scatter/gather list + * + * Initiate an adapter reset to update the IOA's microcode + * + * Return value: + * 0 on success / -EIO on failure + **/ +static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, + struct ipr_sglist *sglist) +{ + unsigned long lock_flags; + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + + if (ioa_cfg->ucode_sglist) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + dev_err(&ioa_cfg->pdev->dev, + "Microcode download already in progress\n"); + return -EIO; } - else { - dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n"); + + sglist->num_dma_sg = pci_map_sg(ioa_cfg->pdev, sglist->scatterlist, + sglist->num_sg, DMA_TO_DEVICE); + + if (!sglist->num_dma_sg) { + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + dev_err(&ioa_cfg->pdev->dev, + "Failed to map microcode download buffer!\n"); return -EIO; } + ioa_cfg->ucode_sglist = sglist; + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); + + spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + ioa_cfg->ucode_sglist = NULL; + spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); return 0; } @@ -2355,7 +2755,6 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev, struct ipr_ucode_image_header *image_hdr; const struct firmware *fw_entry; struct ipr_sglist *sglist; - unsigned long lock_flags; char fname[100]; char *src; int len, result, dnld_size; @@ -2396,35 +2795,17 @@ static ssize_t ipr_store_update_fw(struct class_device *class_dev, if (result) { dev_err(&ioa_cfg->pdev->dev, "Microcode buffer copy to DMA buffer failed\n"); - ipr_free_ucode_buffer(sglist); - release_firmware(fw_entry); - return result; - } - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - - if (ioa_cfg->ucode_sglist) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - dev_err(&ioa_cfg->pdev->dev, - "Microcode download already in progress\n"); - ipr_free_ucode_buffer(sglist); - release_firmware(fw_entry); - return -EIO; + goto out; } - ioa_cfg->ucode_sglist = sglist; - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); - ioa_cfg->ucode_sglist = NULL; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + result = ipr_update_ioa_ucode(ioa_cfg, sglist); + if (!result) + result = count; +out: ipr_free_ucode_buffer(sglist); release_firmware(fw_entry); - - return count; + return result; } static struct class_device_attribute ipr_update_fw_attr = { @@ -2439,8 +2820,10 @@ static struct class_device_attribute *ipr_ioa_attrs[] = { &ipr_fw_version_attr, &ipr_log_level_attr, &ipr_diagnostics_attr, + &ipr_ioa_state_attr, &ipr_ioa_reset_attr, &ipr_update_fw_attr, + &ipr_ioa_cache_attr, NULL, }; @@ -2548,14 +2931,13 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) unsigned long lock_flags = 0; ENTER; - dump = kmalloc(sizeof(struct ipr_dump), GFP_KERNEL); + dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL); if (!dump) { ipr_err("Dump memory allocation failed\n"); return -ENOMEM; } - memset(dump, 0, sizeof(struct ipr_dump)); kref_init(&dump->kref); dump->ioa_cfg = ioa_cfg; @@ -2824,8 +3206,10 @@ static int ipr_slave_configure(struct scsi_device *sdev) if (res) { if (ipr_is_af_dasd_device(res)) sdev->type = TYPE_RAID; - if (ipr_is_af_dasd_device(res) || ipr_is_ioa_resource(res)) + if (ipr_is_af_dasd_device(res) || ipr_is_ioa_resource(res)) { sdev->scsi_level = 4; + sdev->no_uld_attach = 1; + } if (ipr_is_vset_device(res)) { sdev->timeout = IPR_VSET_RW_TIMEOUT; blk_queue_max_sectors(sdev->request_queue, IPR_VSET_MAX_SECTORS); @@ -2848,13 +3232,14 @@ static int ipr_slave_configure(struct scsi_device *sdev) * handling new commands. * * Return value: - * 0 on success + * 0 on success / -ENXIO if device does not exist **/ static int ipr_slave_alloc(struct scsi_device *sdev) { struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata; struct ipr_resource_entry *res; unsigned long lock_flags; + int rc = -ENXIO; sdev->hostdata = NULL; @@ -2868,14 +3253,16 @@ static int ipr_slave_alloc(struct scsi_device *sdev) res->add_to_ml = 0; res->in_erp = 0; sdev->hostdata = res; - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; + rc = 0; break; } } spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); - return 0; + return rc; } /** @@ -2939,7 +3326,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd) ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; res = scsi_cmd->device->hostdata; - if (!res || (!ipr_is_gscsi(res) && !ipr_is_vset_device(res))) + if (!res) return FAILED; /* @@ -3131,7 +3518,8 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd) } list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; LEAVE; return (IPR_IOASC_SENSE_KEY(ioasc) ? FAILED : SUCCESS); @@ -3435,7 +3823,8 @@ static void ipr_erp_done(struct ipr_cmnd *ipr_cmd) } if (res) { - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; res->in_erp = 0; } ipr_unmap_sglist(ioa_cfg, ipr_cmd); @@ -3705,6 +4094,30 @@ static void ipr_gen_sense(struct ipr_cmnd *ipr_cmd) } /** + * ipr_get_autosense - Copy autosense data to sense buffer + * @ipr_cmd: ipr command struct + * + * This function copies the autosense buffer to the buffer + * in the scsi_cmd, if there is autosense available. + * + * Return value: + * 1 if autosense was available / 0 if not + **/ +static int ipr_get_autosense(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioasa *ioasa = &ipr_cmd->ioasa; + + if ((be32_to_cpu(ioasa->ioasc_specific) & + (IPR_ADDITIONAL_STATUS_FMT | IPR_AUTOSENSE_VALID)) == 0) + return 0; + + memcpy(ipr_cmd->scsi_cmd->sense_buffer, ioasa->auto_sense.data, + min_t(u16, be16_to_cpu(ioasa->auto_sense.auto_sense_len), + SCSI_SENSE_BUFFERSIZE)); + return 1; +} + +/** * ipr_erp_start - Process an error response for a SCSI op * @ioa_cfg: ioa config struct * @ipr_cmd: ipr command struct @@ -3734,14 +4147,19 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, switch (ioasc & IPR_IOASC_IOASC_MASK) { case IPR_IOASC_ABORTED_CMD_TERM_BY_HOST: - scsi_cmd->result |= (DID_IMM_RETRY << 16); + if (ipr_is_naca_model(res)) + scsi_cmd->result |= (DID_ABORT << 16); + else + scsi_cmd->result |= (DID_IMM_RETRY << 16); break; case IPR_IOASC_IR_RESOURCE_HANDLE: + case IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA: scsi_cmd->result |= (DID_NO_CONNECT << 16); break; case IPR_IOASC_HW_SEL_TIMEOUT: scsi_cmd->result |= (DID_NO_CONNECT << 16); - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; break; case IPR_IOASC_SYNC_REQUIRED: if (!res->in_erp) @@ -3749,6 +4167,7 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, scsi_cmd->result |= (DID_IMM_RETRY << 16); break; case IPR_IOASC_MED_DO_NOT_REALLOC: /* prevent retries */ + case IPR_IOASA_IR_DUAL_IOA_DISABLED: scsi_cmd->result |= (DID_PASSTHROUGH << 16); break; case IPR_IOASC_BUS_WAS_RESET: @@ -3760,21 +4179,27 @@ static void ipr_erp_start(struct ipr_ioa_cfg *ioa_cfg, if (!res->resetting_device) scsi_report_bus_reset(ioa_cfg->host, scsi_cmd->device->channel); scsi_cmd->result |= (DID_ERROR << 16); - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; break; case IPR_IOASC_HW_DEV_BUS_STATUS: scsi_cmd->result |= IPR_IOASC_SENSE_STATUS(ioasc); if (IPR_IOASC_SENSE_STATUS(ioasc) == SAM_STAT_CHECK_CONDITION) { - ipr_erp_cancel_all(ipr_cmd); - return; + if (!ipr_get_autosense(ipr_cmd)) { + if (!ipr_is_naca_model(res)) { + ipr_erp_cancel_all(ipr_cmd); + return; + } + } } - res->needs_sync_complete = 1; + if (!ipr_is_naca_model(res)) + res->needs_sync_complete = 1; break; case IPR_IOASC_NR_INIT_CMD_REQUIRED: break; default: scsi_cmd->result |= (DID_ERROR << 16); - if (!ipr_is_vset_device(res)) + if (!ipr_is_vset_device(res) && !ipr_is_naca_model(res)) res->needs_sync_complete = 1; break; } @@ -4073,6 +4498,7 @@ static int ipr_ioa_reset_done(struct ipr_cmnd *ipr_cmd) ioa_cfg->in_reset_reload = 0; ioa_cfg->allow_cmds = 1; ioa_cfg->reset_cmd = NULL; + ioa_cfg->doorbell |= IPR_RUNTIME_RESET; list_for_each_entry(res, &ioa_cfg->used_res_q, queue) { if (ioa_cfg->allow_ml_add_del && (res->add_to_ml || res->del_from_ml)) { @@ -4146,7 +4572,7 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) ipr_cmd->job_step = ipr_ioa_reset_done; list_for_each_entry_continue(res, &ioa_cfg->used_res_q, queue) { - if (!ipr_is_af_dasd_device(res)) + if (!IPR_IS_DASD_DEVICE(res->cfgte.std_inq_data)) continue; ipr_cmd->u.res = res; @@ -4179,6 +4605,36 @@ static int ipr_set_supported_devs(struct ipr_cmnd *ipr_cmd) } /** + * ipr_setup_write_cache - Disable write cache if needed + * @ipr_cmd: ipr command struct + * + * This function sets up adapters write cache to desired setting + * + * Return value: + * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN + **/ +static int ipr_setup_write_cache(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + + ipr_cmd->job_step = ipr_set_supported_devs; + ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, + struct ipr_resource_entry, queue); + + if (ioa_cfg->cache_state != CACHE_DISABLED) + return IPR_RC_JOB_CONTINUE; + + ipr_cmd->ioarcb.res_handle = cpu_to_be32(IPR_IOA_RES_HANDLE); + ipr_cmd->ioarcb.cmd_pkt.request_type = IPR_RQTYPE_IOACMD; + ipr_cmd->ioarcb.cmd_pkt.cdb[0] = IPR_IOA_SHUTDOWN; + ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; + + ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); + + return IPR_RC_JOB_RETURN; +} + +/** * ipr_get_mode_page - Locate specified mode page * @mode_pages: mode page buffer * @page_code: page code to find @@ -4389,10 +4845,7 @@ static int ipr_ioafp_mode_select_page28(struct ipr_cmnd *ipr_cmd) ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, mode_pages), length); - ipr_cmd->job_step = ipr_set_supported_devs; - ipr_cmd->u.res = list_entry(ioa_cfg->used_res_q.next, - struct ipr_resource_entry, queue); - + ipr_cmd->job_step = ipr_setup_write_cache; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); LEAVE; @@ -4431,6 +4884,51 @@ static void ipr_build_mode_sense(struct ipr_cmnd *ipr_cmd, } /** + * ipr_reset_cmd_failed - Handle failure of IOA reset command + * @ipr_cmd: ipr command struct + * + * This function handles the failure of an IOA bringup command. + * + * Return value: + * IPR_RC_JOB_RETURN + **/ +static int ipr_reset_cmd_failed(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + + dev_err(&ioa_cfg->pdev->dev, + "0x%02X failed with IOASC: 0x%08X\n", + ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc); + + ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); + list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); + return IPR_RC_JOB_RETURN; +} + +/** + * ipr_reset_mode_sense_failed - Handle failure of IOAFP mode sense + * @ipr_cmd: ipr command struct + * + * This function handles the failure of a Mode Sense to the IOAFP. + * Some adapters do not handle all mode pages. + * + * Return value: + * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN + **/ +static int ipr_reset_mode_sense_failed(struct ipr_cmnd *ipr_cmd) +{ + u32 ioasc = be32_to_cpu(ipr_cmd->ioasa.ioasc); + + if (ioasc == IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT) { + ipr_cmd->job_step = ipr_setup_write_cache; + return IPR_RC_JOB_CONTINUE; + } + + return ipr_reset_cmd_failed(ipr_cmd); +} + +/** * ipr_ioafp_mode_sense_page28 - Issue Mode Sense Page 28 to IOA * @ipr_cmd: ipr command struct * @@ -4451,6 +4949,7 @@ static int ipr_ioafp_mode_sense_page28(struct ipr_cmnd *ipr_cmd) sizeof(struct ipr_mode_pages)); ipr_cmd->job_step = ipr_ioafp_mode_select_page28; + ipr_cmd->job_step_failed = ipr_reset_mode_sense_failed; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, IPR_INTERNAL_TIMEOUT); @@ -4612,6 +5111,27 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, } /** + * ipr_inquiry_page_supported - Is the given inquiry page supported + * @page0: inquiry page 0 buffer + * @page: page code. + * + * This function determines if the specified inquiry page is supported. + * + * Return value: + * 1 if page is supported / 0 if not + **/ +static int ipr_inquiry_page_supported(struct ipr_inquiry_page0 *page0, u8 page) +{ + int i; + + for (i = 0; i < min_t(u8, page0->len, IPR_INQUIRY_PAGE0_ENTRIES); i++) + if (page0->page[i] == page) + return 1; + + return 0; +} + +/** * ipr_ioafp_page3_inquiry - Send a Page 3 Inquiry to the adapter. * @ipr_cmd: ipr command struct * @@ -4624,6 +5144,36 @@ static void ipr_ioafp_inquiry(struct ipr_cmnd *ipr_cmd, u8 flags, u8 page, static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; + struct ipr_inquiry_page0 *page0 = &ioa_cfg->vpd_cbs->page0_data; + + ENTER; + + if (!ipr_inquiry_page_supported(page0, 1)) + ioa_cfg->cache_state = CACHE_NONE; + + ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; + + ipr_ioafp_inquiry(ipr_cmd, 1, 3, + ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data), + sizeof(struct ipr_inquiry_page3)); + + LEAVE; + return IPR_RC_JOB_RETURN; +} + +/** + * ipr_ioafp_page0_inquiry - Send a Page 0 Inquiry to the adapter. + * @ipr_cmd: ipr command struct + * + * This function sends a Page 0 inquiry to the adapter + * to retrieve supported inquiry pages. + * + * Return value: + * IPR_RC_JOB_CONTINUE / IPR_RC_JOB_RETURN + **/ +static int ipr_ioafp_page0_inquiry(struct ipr_cmnd *ipr_cmd) +{ + struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; char type[5]; ENTER; @@ -4633,11 +5183,11 @@ static int ipr_ioafp_page3_inquiry(struct ipr_cmnd *ipr_cmd) type[4] = '\0'; ioa_cfg->type = simple_strtoul((char *)type, NULL, 16); - ipr_cmd->job_step = ipr_ioafp_query_ioa_cfg; + ipr_cmd->job_step = ipr_ioafp_page3_inquiry; - ipr_ioafp_inquiry(ipr_cmd, 1, 3, - ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page3_data), - sizeof(struct ipr_inquiry_page3)); + ipr_ioafp_inquiry(ipr_cmd, 1, 0, + ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, page0_data), + sizeof(struct ipr_inquiry_page0)); LEAVE; return IPR_RC_JOB_RETURN; @@ -4657,7 +5207,7 @@ static int ipr_ioafp_std_inquiry(struct ipr_cmnd *ipr_cmd) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ENTER; - ipr_cmd->job_step = ipr_ioafp_page3_inquiry; + ipr_cmd->job_step = ipr_ioafp_page0_inquiry; ipr_ioafp_inquiry(ipr_cmd, 0, 0, ioa_cfg->vpd_cbs_dma + offsetof(struct ipr_misc_cbs, ioa_vpd), @@ -4815,7 +5365,7 @@ static int ipr_reset_enable_ioa(struct ipr_cmnd *ipr_cmd) } /* Enable destructive diagnostics on IOA */ - writel(IPR_DOORBELL, ioa_cfg->regs.set_uproc_interrupt_reg); + writel(ioa_cfg->doorbell, ioa_cfg->regs.set_uproc_interrupt_reg); writel(IPR_PCII_OPER_INTERRUPTS, ioa_cfg->regs.clr_interrupt_mask_reg); int_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg); @@ -5147,12 +5697,7 @@ static int ipr_reset_ucode_download(struct ipr_cmnd *ipr_cmd) ipr_cmd->ioarcb.cmd_pkt.cdb[7] = (sglist->buffer_len & 0x00ff00) >> 8; ipr_cmd->ioarcb.cmd_pkt.cdb[8] = sglist->buffer_len & 0x0000ff; - if (ipr_map_ucode_buffer(ipr_cmd, sglist, sglist->buffer_len)) { - dev_err(&ioa_cfg->pdev->dev, - "Failed to map microcode download buffer\n"); - return IPR_RC_JOB_CONTINUE; - } - + ipr_build_ucode_ioadl(ipr_cmd, sglist); ipr_cmd->job_step = ipr_reset_ucode_download_done; ipr_do_req(ipr_cmd, ipr_reset_ioa_job, ipr_timeout, @@ -5217,7 +5762,6 @@ static int ipr_reset_shutdown_ioa(struct ipr_cmnd *ipr_cmd) static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) { u32 rc, ioasc; - unsigned long scratch = ipr_cmd->u.scratch; struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; do { @@ -5233,17 +5777,13 @@ static void ipr_reset_ioa_job(struct ipr_cmnd *ipr_cmd) } if (IPR_IOASC_SENSE_KEY(ioasc)) { - dev_err(&ioa_cfg->pdev->dev, - "0x%02X failed with IOASC: 0x%08X\n", - ipr_cmd->ioarcb.cmd_pkt.cdb[0], ioasc); - - ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q); - return; + rc = ipr_cmd->job_step_failed(ipr_cmd); + if (rc == IPR_RC_JOB_RETURN) + return; } ipr_reinit_ipr_cmnd(ipr_cmd); - ipr_cmd->u.scratch = scratch; + ipr_cmd->job_step_failed = ipr_reset_cmd_failed; rc = ipr_cmd->job_step(ipr_cmd); } while(rc == IPR_RC_JOB_CONTINUE); } @@ -5517,15 +6057,12 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) int i, rc = -ENOMEM; ENTER; - ioa_cfg->res_entries = kmalloc(sizeof(struct ipr_resource_entry) * + ioa_cfg->res_entries = kzalloc(sizeof(struct ipr_resource_entry) * IPR_MAX_PHYSICAL_DEVS, GFP_KERNEL); if (!ioa_cfg->res_entries) goto out; - memset(ioa_cfg->res_entries, 0, - sizeof(struct ipr_resource_entry) * IPR_MAX_PHYSICAL_DEVS); - for (i = 0; i < IPR_MAX_PHYSICAL_DEVS; i++) list_add_tail(&ioa_cfg->res_entries[i].queue, &ioa_cfg->free_res_q); @@ -5566,15 +6103,12 @@ static int __devinit ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); } - ioa_cfg->trace = kmalloc(sizeof(struct ipr_trace_entry) * + ioa_cfg->trace = kzalloc(sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES, GFP_KERNEL); if (!ioa_cfg->trace) goto out_free_hostrcb_dma; - memset(ioa_cfg->trace, 0, - sizeof(struct ipr_trace_entry) * IPR_NUM_TRACE_ENTRIES); - rc = 0; out: LEAVE; @@ -5642,6 +6176,9 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->host = host; ioa_cfg->pdev = pdev; ioa_cfg->log_level = ipr_log_level; + ioa_cfg->doorbell = IPR_DOORBELL; + if (!ipr_auto_create) + ioa_cfg->doorbell |= IPR_RUNTIME_RESET; sprintf(ioa_cfg->eye_catcher, IPR_EYECATCHER); sprintf(ioa_cfg->trace_start, IPR_TRACE_START_LABEL); sprintf(ioa_cfg->ipr_free_label, IPR_FREEQ_LABEL); @@ -5660,6 +6197,10 @@ static void __devinit ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread, ioa_cfg); init_waitqueue_head(&ioa_cfg->reset_wait_q); ioa_cfg->sdt_state = INACTIVE; + if (ipr_enable_cache) + ioa_cfg->cache_state = CACHE_ENABLED; + else + ioa_cfg->cache_state = CACHE_DISABLED; ipr_initialize_bus_attr(ioa_cfg); @@ -6008,6 +6549,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev, ipr_scan_vsets(ioa_cfg); scsi_add_device(ioa_cfg->host, IPR_IOA_BUS, IPR_IOA_TARGET, IPR_IOA_LUN); ioa_cfg->allow_ml_add_del = 1; + ioa_cfg->host->max_channel = IPR_VSET_BUS; schedule_work(&ioa_cfg->work_q); return 0; } @@ -6055,12 +6597,30 @@ static struct pci_device_id ipr_pci_table[] __devinitdata = { { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571A, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_575B, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572A, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, + { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_572B, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[0] }, { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_2780, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571E, 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, + { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, + PCI_VENDOR_ID_IBM, IPR_SUBS_DEV_ID_571F, + 0, 0, (kernel_ulong_t)&ipr_chip_cfg[1] }, { } }; MODULE_DEVICE_TABLE(pci, ipr_pci_table); diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index 8cf9671..6bec673 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h @@ -36,23 +36,8 @@ /* * Literals */ -#define IPR_DRIVER_VERSION "2.0.14" -#define IPR_DRIVER_DATE "(May 2, 2005)" - -/* - * IPR_DBG_TRACE: Setting this to 1 will turn on some general function tracing - * resulting in a bunch of extra debugging printks to the console - * - * IPR_DEBUG: Setting this to 1 will turn on some error path tracing. - * Enables the ipr_trace macro. - */ -#ifdef IPR_DEBUG_ALL -#define IPR_DEBUG 1 -#define IPR_DBG_TRACE 1 -#else -#define IPR_DEBUG 0 -#define IPR_DBG_TRACE 0 -#endif +#define IPR_DRIVER_VERSION "2.1.0" +#define IPR_DRIVER_DATE "(October 31, 2005)" /* * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding @@ -76,6 +61,10 @@ #define IPR_SUBS_DEV_ID_571A 0x02C0 #define IPR_SUBS_DEV_ID_571B 0x02BE #define IPR_SUBS_DEV_ID_571E 0x02BF +#define IPR_SUBS_DEV_ID_571F 0x02D5 +#define IPR_SUBS_DEV_ID_572A 0x02C1 +#define IPR_SUBS_DEV_ID_572B 0x02C2 +#define IPR_SUBS_DEV_ID_575B 0x030D #define IPR_NAME "ipr" @@ -95,7 +84,10 @@ #define IPR_IOASC_HW_DEV_BUS_STATUS 0x04448500 #define IPR_IOASC_IOASC_MASK 0xFFFFFF00 #define IPR_IOASC_SCSI_STATUS_MASK 0x000000FF +#define IPR_IOASC_IR_INVALID_REQ_TYPE_OR_PKT 0x05240000 #define IPR_IOASC_IR_RESOURCE_HANDLE 0x05250000 +#define IPR_IOASC_IR_NO_CMDS_TO_2ND_IOA 0x05258100 +#define IPR_IOASA_IR_DUAL_IOA_DISABLED 0x052C8000 #define IPR_IOASC_BUS_WAS_RESET 0x06290000 #define IPR_IOASC_BUS_WAS_RESET_BY_OTHER 0x06298000 #define IPR_IOASC_ABORTED_CMD_TERM_BY_HOST 0x0B5A0000 @@ -107,14 +99,14 @@ #define IPR_NUM_LOG_HCAMS 2 #define IPR_NUM_CFG_CHG_HCAMS 2 #define IPR_NUM_HCAMS (IPR_NUM_LOG_HCAMS + IPR_NUM_CFG_CHG_HCAMS) -#define IPR_MAX_NUM_TARGETS_PER_BUS 0x10 +#define IPR_MAX_NUM_TARGETS_PER_BUS 256 #define IPR_MAX_NUM_LUNS_PER_TARGET 256 #define IPR_MAX_NUM_VSET_LUNS_PER_TARGET 8 #define IPR_VSET_BUS 0xff #define IPR_IOA_BUS 0xff #define IPR_IOA_TARGET 0xff #define IPR_IOA_LUN 0xff -#define IPR_MAX_NUM_BUSES 4 +#define IPR_MAX_NUM_BUSES 8 #define IPR_MAX_BUS_TO_SCAN IPR_MAX_NUM_BUSES #define IPR_NUM_RESET_RELOAD_RETRIES 3 @@ -205,6 +197,7 @@ #define IPR_SDT_FMT2_EXP_ROM_SEL 0x8 #define IPR_FMT2_SDT_READY_TO_USE 0xC4D4E3F2 #define IPR_DOORBELL 0x82800000 +#define IPR_RUNTIME_RESET 0x40000000 #define IPR_PCII_IOA_TRANS_TO_OPER (0x80000000 >> 0) #define IPR_PCII_IOARCB_XFER_FAILED (0x80000000 >> 3) @@ -261,6 +254,16 @@ struct ipr_std_inq_vpids { u8 product_id[IPR_PROD_ID_LEN]; }__attribute__((packed)); +struct ipr_vpd { + struct ipr_std_inq_vpids vpids; + u8 sn[IPR_SERIAL_NUM_LEN]; +}__attribute__((packed)); + +struct ipr_ext_vpd { + struct ipr_vpd vpd; + __be32 wwid[2]; +}__attribute__((packed)); + struct ipr_std_inq_data { u8 peri_qual_dev_type; #define IPR_STD_INQ_PERI_QUAL(peri) ((peri) >> 5) @@ -304,6 +307,10 @@ struct ipr_config_table_entry { #define IPR_SUBTYPE_GENERIC_SCSI 1 #define IPR_SUBTYPE_VOLUME_SET 2 +#define IPR_QUEUEING_MODEL(res) ((((res)->cfgte.flags) & 0x70) >> 4) +#define IPR_QUEUE_FROZEN_MODEL 0 +#define IPR_QUEUE_NACA_MODEL 1 + struct ipr_res_addr res_addr; __be32 res_handle; __be32 reserved4[2]; @@ -410,23 +417,26 @@ struct ipr_ioadl_desc { struct ipr_ioasa_vset { __be32 failing_lba_hi; __be32 failing_lba_lo; - __be32 ioa_data[22]; + __be32 reserved; }__attribute__((packed, aligned (4))); struct ipr_ioasa_af_dasd { __be32 failing_lba; + __be32 reserved[2]; }__attribute__((packed, aligned (4))); struct ipr_ioasa_gpdd { u8 end_state; u8 bus_phase; __be16 reserved; - __be32 ioa_data[23]; + __be32 ioa_data[2]; }__attribute__((packed, aligned (4))); -struct ipr_ioasa_raw { - __be32 ioa_data[24]; -}__attribute__((packed, aligned (4))); +struct ipr_auto_sense { + __be16 auto_sense_len; + __be16 ioa_data_len; + __be32 data[SCSI_SENSE_BUFFERSIZE/sizeof(__be32)]; +}; struct ipr_ioasa { __be32 ioasc; @@ -453,6 +463,8 @@ struct ipr_ioasa { __be32 fd_res_handle; __be32 ioasc_specific; /* status code specific field */ +#define IPR_ADDITIONAL_STATUS_FMT 0x80000000 +#define IPR_AUTOSENSE_VALID 0x40000000 #define IPR_IOASC_SPECIFIC_MASK 0x00ffffff #define IPR_FIELD_POINTER_VALID (0x80000000 >> 8) #define IPR_FIELD_POINTER_MASK 0x0000ffff @@ -461,8 +473,9 @@ struct ipr_ioasa { struct ipr_ioasa_vset vset; struct ipr_ioasa_af_dasd dasd; struct ipr_ioasa_gpdd gpdd; - struct ipr_ioasa_raw raw; } u; + + struct ipr_auto_sense auto_sense; }__attribute__((packed, aligned (4))); struct ipr_mode_parm_hdr { @@ -536,28 +549,49 @@ struct ipr_inquiry_page3 { u8 patch_number[4]; }__attribute__((packed)); +#define IPR_INQUIRY_PAGE0_ENTRIES 20 +struct ipr_inquiry_page0 { + u8 peri_qual_dev_type; + u8 page_code; + u8 reserved1; + u8 len; + u8 page[IPR_INQUIRY_PAGE0_ENTRIES]; +}__attribute__((packed)); + struct ipr_hostrcb_device_data_entry { - struct ipr_std_inq_vpids dev_vpids; - u8 dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd vpd; struct ipr_res_addr dev_res_addr; - struct ipr_std_inq_vpids new_dev_vpids; - u8 new_dev_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids ioa_last_with_dev_vpids; - u8 ioa_last_with_dev_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_last_with_dev_vpids; - u8 cfc_last_with_dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd new_vpd; + struct ipr_vpd ioa_last_with_dev_vpd; + struct ipr_vpd cfc_last_with_dev_vpd; __be32 ioa_data[5]; }__attribute__((packed, aligned (4))); +struct ipr_hostrcb_device_data_entry_enhanced { + struct ipr_ext_vpd vpd; + u8 ccin[4]; + struct ipr_res_addr dev_res_addr; + struct ipr_ext_vpd new_vpd; + u8 new_ccin[4]; + struct ipr_ext_vpd ioa_last_with_dev_vpd; + struct ipr_ext_vpd cfc_last_with_dev_vpd; +}__attribute__((packed, aligned (4))); + struct ipr_hostrcb_array_data_entry { - struct ipr_std_inq_vpids vpids; - u8 serial_num[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd vpd; + struct ipr_res_addr expected_dev_res_addr; + struct ipr_res_addr dev_res_addr; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_array_data_entry_enhanced { + struct ipr_ext_vpd vpd; + u8 ccin[4]; struct ipr_res_addr expected_dev_res_addr; struct ipr_res_addr dev_res_addr; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_ff_error { - __be32 ioa_data[246]; + __be32 ioa_data[502]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_01_error { @@ -568,47 +602,75 @@ struct ipr_hostrcb_type_01_error { }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_02_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids ioa_last_attached_to_cfc_vpids; - u8 ioa_last_attached_to_cfc_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_last_attached_to_ioa_vpids; - u8 cfc_last_attached_to_ioa_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; + struct ipr_vpd ioa_last_attached_to_cfc_vpd; + struct ipr_vpd cfc_last_attached_to_ioa_vpd; + __be32 ioa_data[3]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_12_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + struct ipr_ext_vpd ioa_last_attached_to_cfc_vpd; + struct ipr_ext_vpd cfc_last_attached_to_ioa_vpd; __be32 ioa_data[3]; - u8 reserved[844]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_03_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; __be32 errors_detected; __be32 errors_logged; u8 ioa_data[12]; - struct ipr_hostrcb_device_data_entry dev_entry[3]; - u8 reserved[444]; + struct ipr_hostrcb_device_data_entry dev[3]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_13_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + __be32 errors_detected; + __be32 errors_logged; + struct ipr_hostrcb_device_data_entry_enhanced dev[3]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_type_04_error { - struct ipr_std_inq_vpids ioa_vpids; - u8 ioa_sn[IPR_SERIAL_NUM_LEN]; - struct ipr_std_inq_vpids cfc_vpids; - u8 cfc_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd ioa_vpd; + struct ipr_vpd cfc_vpd; u8 ioa_data[12]; struct ipr_hostrcb_array_data_entry array_member[10]; __be32 exposed_mode_adn; __be32 array_id; - struct ipr_std_inq_vpids incomp_dev_vpids; - u8 incomp_dev_sn[IPR_SERIAL_NUM_LEN]; + struct ipr_vpd incomp_dev_vpd; __be32 ioa_data2; struct ipr_hostrcb_array_data_entry array_member2[8]; struct ipr_res_addr last_func_vset_res_addr; u8 vset_serial_num[IPR_SERIAL_NUM_LEN]; u8 protection_level[8]; - u8 reserved[124]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_14_error { + struct ipr_ext_vpd ioa_vpd; + struct ipr_ext_vpd cfc_vpd; + __be32 exposed_mode_adn; + __be32 array_id; + struct ipr_res_addr last_func_vset_res_addr; + u8 vset_serial_num[IPR_SERIAL_NUM_LEN]; + u8 protection_level[8]; + __be32 num_entries; + struct ipr_hostrcb_array_data_entry_enhanced array_member[18]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_07_error { + u8 failure_reason[64]; + struct ipr_vpd vpd; + u32 data[222]; +}__attribute__((packed, aligned (4))); + +struct ipr_hostrcb_type_17_error { + u8 failure_reason[64]; + struct ipr_ext_vpd vpd; + u32 data[476]; }__attribute__((packed, aligned (4))); struct ipr_hostrcb_error { @@ -622,6 +684,11 @@ struct ipr_hostrcb_error { struct ipr_hostrcb_type_02_error type_02_error; struct ipr_hostrcb_type_03_error type_03_error; struct ipr_hostrcb_type_04_error type_04_error; + struct ipr_hostrcb_type_07_error type_07_error; + struct ipr_hostrcb_type_12_error type_12_error; + struct ipr_hostrcb_type_13_error type_13_error; + struct ipr_hostrcb_type_14_error type_14_error; + struct ipr_hostrcb_type_17_error type_17_error; } u; }__attribute__((packed, aligned (4))); @@ -655,6 +722,12 @@ struct ipr_hcam { #define IPR_HOST_RCB_OVERLAY_ID_3 0x03 #define IPR_HOST_RCB_OVERLAY_ID_4 0x04 #define IPR_HOST_RCB_OVERLAY_ID_6 0x06 +#define IPR_HOST_RCB_OVERLAY_ID_7 0x07 +#define IPR_HOST_RCB_OVERLAY_ID_12 0x12 +#define IPR_HOST_RCB_OVERLAY_ID_13 0x13 +#define IPR_HOST_RCB_OVERLAY_ID_14 0x14 +#define IPR_HOST_RCB_OVERLAY_ID_16 0x16 +#define IPR_HOST_RCB_OVERLAY_ID_17 0x17 #define IPR_HOST_RCB_OVERLAY_ID_DEFAULT 0xFF u8 reserved1[3]; @@ -743,6 +816,7 @@ struct ipr_resource_table { struct ipr_misc_cbs { struct ipr_ioa_vpd ioa_vpd; + struct ipr_inquiry_page0 page0_data; struct ipr_inquiry_page3 page3_data; struct ipr_mode_pages mode_pages; struct ipr_supported_device supp_dev; @@ -813,6 +887,7 @@ struct ipr_trace_entry { struct ipr_sglist { u32 order; u32 num_sg; + u32 num_dma_sg; u32 buffer_len; struct scatterlist scatterlist[1]; }; @@ -825,6 +900,13 @@ enum ipr_sdt_state { DUMP_OBTAINED }; +enum ipr_cache_state { + CACHE_NONE, + CACHE_DISABLED, + CACHE_ENABLED, + CACHE_INVALID +}; + /* Per-controller data */ struct ipr_ioa_cfg { char eye_catcher[8]; @@ -841,6 +923,7 @@ struct ipr_ioa_cfg { u8 allow_cmds:1; u8 allow_ml_add_del:1; + enum ipr_cache_state cache_state; u16 type; /* CCIN of the card */ u8 log_level; @@ -911,6 +994,7 @@ struct ipr_ioa_cfg { u16 reset_retries; u32 errors_logged; + u32 doorbell; struct Scsi_Host *host; struct pci_dev *pdev; @@ -948,6 +1032,7 @@ struct ipr_cmnd { struct timer_list timer; void (*done) (struct ipr_cmnd *); int (*job_step) (struct ipr_cmnd *); + int (*job_step_failed) (struct ipr_cmnd *); u16 cmd_index; u8 sense_buffer[SCSI_SENSE_BUFFERSIZE]; dma_addr_t sense_buffer_dma; @@ -1083,11 +1168,7 @@ struct ipr_ucode_image_header { /* * Macros */ -#if IPR_DEBUG -#define IPR_DBG_CMD(CMD) do { CMD; } while (0) -#else -#define IPR_DBG_CMD(CMD) -#endif +#define IPR_DBG_CMD(CMD) if (ipr_debug) { CMD; } #ifdef CONFIG_SCSI_IPR_TRACE #define ipr_create_trace_file(kobj, attr) sysfs_create_bin_file(kobj, attr) @@ -1135,16 +1216,22 @@ struct ipr_ucode_image_header { #define ipr_res_dbg(ioa_cfg, res, fmt, ...) \ IPR_DBG_CMD(ipr_res_printk(KERN_INFO, ioa_cfg, res, fmt, ##__VA_ARGS__)) +#define ipr_phys_res_err(ioa_cfg, res, fmt, ...) \ +{ \ + if ((res).bus >= IPR_MAX_NUM_BUSES) { \ + ipr_err(fmt": unknown\n", ##__VA_ARGS__); \ + } else { \ + ipr_err(fmt": %d:%d:%d:%d\n", \ + ##__VA_ARGS__, (ioa_cfg)->host->host_no, \ + (res).bus, (res).target, (res).lun); \ + } \ +} + #define ipr_trace ipr_dbg("%s: %s: Line: %d\n",\ __FILE__, __FUNCTION__, __LINE__) -#if IPR_DBG_TRACE -#define ENTER printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__) -#define LEAVE printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__) -#else -#define ENTER -#define LEAVE -#endif +#define ENTER IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Entering %s\n", __FUNCTION__)) +#define LEAVE IPR_DBG_CMD(printk(KERN_INFO IPR_NAME": Leaving %s\n", __FUNCTION__)) #define ipr_err_separator \ ipr_err("----------------------------------------------------------\n") @@ -1217,6 +1304,20 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) } /** + * ipr_is_naca_model - Determine if a resource is using NACA queueing model + * @res: resource entry struct + * + * Return value: + * 1 if NACA queueing model / 0 if not NACA queueing model + **/ +static inline int ipr_is_naca_model(struct ipr_resource_entry *res) +{ + if (ipr_is_gscsi(res) && IPR_QUEUEING_MODEL(res) == IPR_QUEUE_NACA_MODEL) + return 1; + return 0; +} + +/** * ipr_is_device - Determine if resource address is that of a device * @res_addr: resource address struct * @@ -1226,7 +1327,7 @@ static inline int ipr_is_gscsi(struct ipr_resource_entry *res) static inline int ipr_is_device(struct ipr_res_addr *res_addr) { if ((res_addr->bus < IPR_MAX_NUM_BUSES) && - (res_addr->target < IPR_MAX_NUM_TARGETS_PER_BUS)) + (res_addr->target < (IPR_MAX_NUM_TARGETS_PER_BUS - 1))) return 1; return 0; diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index cd9b95d..3882d48 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -139,6 +139,7 @@ /* - Remove 3 unused "inline" functions */ /* 7.12.xx - Use STATIC functions whereever possible */ /* - Clean up deprecated MODULE_PARM calls */ +/* 7.12.05 - Remove Version Matching per IBM request */ /*****************************************************************************/ /* @@ -210,7 +211,7 @@ module_param(ips, charp, 0); * DRIVER_VER */ #define IPS_VERSION_HIGH "7.12" -#define IPS_VERSION_LOW ".02 " +#define IPS_VERSION_LOW ".05 " #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" @@ -247,7 +248,7 @@ module_param(ips, charp, 0); /* * Function prototypes */ -static int ips_detect(Scsi_Host_Template *); +static int ips_detect(struct scsi_host_template *); static int ips_release(struct Scsi_Host *); static int ips_eh_abort(Scsi_Cmnd *); static int ips_eh_reset(Scsi_Cmnd *); @@ -347,8 +348,6 @@ static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_host_info(ips_ha_t *, char *, off_t, int); static void copy_mem_info(IPS_INFOSTR *, char *, int); static int copy_info(IPS_INFOSTR *, char *, ...); -static int ips_get_version_info(ips_ha_t * ha, dma_addr_t, int intr); -static void ips_version_check(ips_ha_t * ha, int intr); static int ips_abort_init(ips_ha_t * ha, int index); static int ips_init_phase2(int index); @@ -378,7 +377,7 @@ static char *ips_FlashData = NULL; /* CD Boot - Flash Data Buffer */ static dma_addr_t ips_flashbusaddr; static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ -static Scsi_Host_Template ips_driver_template = { +static struct scsi_host_template ips_driver_template = { .detect = ips_detect, .release = ips_release, .info = ips_info, @@ -406,8 +405,6 @@ static Scsi_Host_Template ips_driver_template = { #endif }; -static IPS_DEFINE_COMPAT_TABLE( Compatable ); /* Version Compatability Table */ - /* This table describes all ServeRAID Adapters */ static struct pci_device_id ips_pci_table[] = { @@ -590,7 +587,7 @@ __setup("ips=", ips_setup); /* */ /****************************************************************************/ static int -ips_detect(Scsi_Host_Template * SHT) +ips_detect(struct scsi_host_template * SHT) { int i; @@ -1265,9 +1262,9 @@ ips_proc24_info(char *buffer, char **start, off_t offset, int length, /* */ /****************************************************************************/ static void -ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs) +ips_select_queue_depth(struct Scsi_Host *host, struct scsi_device * scsi_devs) { - Scsi_Device *device; + struct scsi_device *device; ips_ha_t *ha; int count = 0; int min; @@ -1310,7 +1307,7 @@ ips_select_queue_depth(struct Scsi_Host *host, Scsi_Device * scsi_devs) /* */ /****************************************************************************/ static int -ips_slave_configure(Scsi_Device * SDptr) +ips_slave_configure(struct scsi_device * SDptr) { ips_ha_t *ha; int min; @@ -5930,7 +5927,7 @@ ips_write_driver_status(ips_ha_t * ha, int intr) strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4); strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4); - ips_version_check(ha, intr); /* Check BIOS/FW/Driver Versions */ + ha->nvram->versioning = 0; /* Indicate the Driver Does Not Support Versioning */ /* now update the page */ if (!ips_readwrite_page5(ha, TRUE, intr)) { @@ -6847,135 +6844,6 @@ ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize, return (0); } -/*---------------------------------------------------------------------------*/ -/* Routine Name: ips_version_check */ -/* */ -/* Dependencies: */ -/* Assumes that ips_read_adapter_status() is called first filling in */ -/* the data for SubSystem Parameters. */ -/* Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */ -/* Data is available. */ -/* */ -/*---------------------------------------------------------------------------*/ -static void -ips_version_check(ips_ha_t * ha, int intr) -{ - IPS_VERSION_DATA *VersionInfo; - uint8_t FirmwareVersion[IPS_COMPAT_ID_LENGTH + 1]; - uint8_t BiosVersion[IPS_COMPAT_ID_LENGTH + 1]; - int MatchError; - int rc; - char BiosString[10]; - char FirmwareString[10]; - - METHOD_TRACE("ips_version_check", 1); - - VersionInfo = ( IPS_VERSION_DATA * ) ha->ioctl_data; - - memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1); - - /* Get the Compatible BIOS Version from NVRAM Page 5 */ - memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, - IPS_COMPAT_ID_LENGTH); - - rc = IPS_FAILURE; - if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT) { /* If Versioning is Supported */ - /* Get the Version Info with a Get Version Command */ - memset( VersionInfo, 0, sizeof (IPS_VERSION_DATA)); - rc = ips_get_version_info(ha, ha->ioctl_busaddr, intr); - if (rc == IPS_SUCCESS) - memcpy(FirmwareVersion, VersionInfo->compatibilityId, - IPS_COMPAT_ID_LENGTH); - } - - if (rc != IPS_SUCCESS) { /* If Data Not Obtainable from a GetVersion Command */ - /* Get the Firmware Version from Enquiry Data */ - memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, - IPS_COMPAT_ID_LENGTH); - } - - /* printk(KERN_WARNING "Adapter's BIOS Version = %s\n", BiosVersion); */ - /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS); */ - /* printk(KERN_WARNING "Adapter's Firmware Version = %s\n", FirmwareVersion); */ - /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */ - - MatchError = 0; - - if (strncmp - (FirmwareVersion, Compatable[ha->nvram->adapter_type], - IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - if (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0) - MatchError = 1; - - ha->nvram->versioning = 1; /* Indicate the Driver Supports Versioning */ - - if (MatchError) { - ha->nvram->version_mismatch = 1; - if (ips_cd_boot == 0) { - strncpy(&BiosString[0], ha->nvram->bios_high, 4); - strncpy(&BiosString[4], ha->nvram->bios_low, 4); - BiosString[8] = 0; - - strncpy(&FirmwareString[0], ha->enq->CodeBlkVersion, 8); - FirmwareString[8] = 0; - - IPS_PRINTK(KERN_WARNING, ha->pcidev, - "Warning ! ! ! ServeRAID Version Mismatch\n"); - IPS_PRINTK(KERN_WARNING, ha->pcidev, - "Bios = %s, Firmware = %s, Device Driver = %s%s\n", - BiosString, FirmwareString, IPS_VERSION_HIGH, - IPS_VERSION_LOW); - IPS_PRINTK(KERN_WARNING, ha->pcidev, - "These levels should match to avoid possible compatibility problems.\n"); - } - } else { - ha->nvram->version_mismatch = 0; - } - - return; -} - -/*---------------------------------------------------------------------------*/ -/* Routine Name: ips_get_version_info */ -/* */ -/* Routine Description: */ -/* Issue an internal GETVERSION Command */ -/* */ -/* Return Value: */ -/* 0 if Successful, else non-zero */ -/*---------------------------------------------------------------------------*/ -static int -ips_get_version_info(ips_ha_t * ha, dma_addr_t Buffer, int intr) -{ - ips_scb_t *scb; - int rc; - - METHOD_TRACE("ips_get_version_info", 1); - - scb = &ha->scbs[ha->max_cmds - 1]; - - ips_init_scb(ha, scb); - - scb->timeout = ips_cmd_timeout; - scb->cdb[0] = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO; - scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb); - scb->cmd.version_info.reserved = 0; - scb->cmd.version_info.count = sizeof (IPS_VERSION_DATA); - scb->cmd.version_info.reserved2 = 0; - scb->data_len = sizeof (IPS_VERSION_DATA); - scb->data_busaddr = Buffer; - scb->cmd.version_info.buffer_addr = Buffer; - scb->flags = 0; - - /* issue command */ - rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr); - return (rc); -} - /****************************************************************************/ /* */ /* Routine Name: ips_abort_init */ diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index adc6eab..f46c382 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h @@ -450,13 +450,13 @@ */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) static int ips_proc24_info(char *, char **, off_t, int, int, int); - static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *); + static void ips_select_queue_depth(struct Scsi_Host *, struct scsi_device *); static int ips_biosparam(Disk *disk, kdev_t dev, int geom[]); #else static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); - static int ips_slave_configure(Scsi_Device *SDptr); + static int ips_slave_configure(struct scsi_device *SDptr); #endif /* diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index 4fea3e4..3d8009f 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -3368,7 +3368,7 @@ iscsi_conn_set_param(iscsi_connh_t connh, enum iscsi_param param, switch(param) { case ISCSI_PARAM_MAX_RECV_DLENGTH: { char *saveptr = conn->data; - int flags = GFP_KERNEL; + gfp_t flags = GFP_KERNEL; if (conn->data_size >= value) { conn->max_recv_dlength = value; diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index a642f73..23728d1 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c @@ -52,7 +52,7 @@ static volatile unsigned char cmd_buffer[16]; * via PIO. */ -int jazz_esp_detect(Scsi_Host_Template *tpnt); +int jazz_esp_detect(struct scsi_host_template *tpnt); static int jazz_esp_release(struct Scsi_Host *shost) { if (shost->irq) @@ -65,7 +65,7 @@ static int jazz_esp_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "jazz_esp", .proc_info = &esp_proc_info, .name = "ESP 100/100a/200", diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index a74b407..d0a0fdb 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -532,8 +532,7 @@ void ata_tf_to_fis(const struct ata_taskfile *tf, u8 *fis, u8 pmp) * @fis: Buffer from which data will be input * @tf: Taskfile to output * - * Converts a standard ATA taskfile to a Serial ATA - * FIS structure (Register - Host to Device). + * Converts a serial ATA FIS structure to a standard ATA taskfile. * * LOCKING: * Inherited from caller. @@ -1047,6 +1046,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev) return modes; } +static int ata_qc_wait_err(struct ata_queued_cmd *qc, + struct completion *wait) +{ + int rc = 0; + + if (wait_for_completion_timeout(wait, 30 * HZ) < 1) { + /* timeout handling */ + unsigned int err_mask = ac_err_mask(ata_chk_status(qc->ap)); + + if (!err_mask) { + printk(KERN_WARNING "ata%u: slow completion (cmd %x)\n", + qc->ap->id, qc->tf.command); + } else { + printk(KERN_WARNING "ata%u: qc timeout (cmd %x)\n", + qc->ap->id, qc->tf.command); + rc = -EIO; + } + + ata_qc_complete(qc, err_mask); + } + + return rc; +} + /** * ata_dev_identify - obtain IDENTIFY x DEVICE page * @ap: port on which device we wish to probe resides @@ -1126,7 +1149,7 @@ retry: if (rc) goto err_out; else - wait_for_completion(&wait); + ata_qc_wait_err(qc, &wait); spin_lock_irqsave(&ap->host_set->lock, flags); ap->ops->tf_read(ap, &qc->tf); @@ -1264,7 +1287,7 @@ retry: } /* ATAPI-specific feature tests */ - else { + else if (dev->class == ATA_DEV_ATAPI) { if (ata_id_is_ata(dev->id)) /* sanity check */ goto err_out_nosup; @@ -1571,11 +1594,13 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, /* * Find the mode. - */ + */ if (!(s = ata_timing_find_mode(speed))) return -EINVAL; + memcpy(t, s, sizeof(*s)); + /* * If the drive is an EIDE drive, it can tell us it needs extended * PIO/MW_DMA cycle timing. @@ -1596,7 +1621,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed, * Convert the timing to bus clock counts. */ - ata_timing_quantize(s, t, T, UT); + ata_timing_quantize(t, t, T, UT); /* * Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T @@ -2268,7 +2293,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) if (rc) ata_port_disable(ap); else - wait_for_completion(&wait); + ata_qc_wait_err(qc, &wait); DPRINTK("EXIT\n"); } @@ -2316,7 +2341,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev) if (rc) goto err_out; - wait_for_completion(&wait); + ata_qc_wait_err(qc, &wait); swap_buf_le16(dev->id, ATA_ID_WORDS); @@ -2372,7 +2397,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev) if (rc) ata_port_disable(ap); else - wait_for_completion(&wait); + ata_qc_wait_err(qc, &wait); DPRINTK("EXIT\n"); } @@ -2400,7 +2425,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) if (qc->flags & ATA_QCFLAG_SINGLE) assert(qc->n_elem == 1); - DPRINTK("unmapping %u sg elements\n", qc->n_elem); + VPRINTK("unmapping %u sg elements\n", qc->n_elem); /* if we padded the buffer out to 32-bit bound, and data * xfer direction is from-device, we must copy from the @@ -2410,18 +2435,21 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) pad_buf = ap->pad + (qc->tag * ATA_DMA_PAD_SZ); if (qc->flags & ATA_QCFLAG_SG) { - dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); + if (qc->n_elem) + dma_unmap_sg(ap->host_set->dev, sg, qc->n_elem, dir); /* restore last sg */ sg[qc->orig_n_elem - 1].length += qc->pad_len; if (pad_buf) { struct scatterlist *psg = &qc->pad_sgent; void *addr = kmap_atomic(psg->page, KM_IRQ0); memcpy(addr + psg->offset, pad_buf, qc->pad_len); - kunmap_atomic(psg->page, KM_IRQ0); + kunmap_atomic(addr, KM_IRQ0); } } else { - dma_unmap_single(ap->host_set->dev, sg_dma_address(&sg[0]), - sg_dma_len(&sg[0]), dir); + if (sg_dma_len(&sg[0]) > 0) + dma_unmap_single(ap->host_set->dev, + sg_dma_address(&sg[0]), sg_dma_len(&sg[0]), + dir); /* restore sg */ sg->length += qc->pad_len; if (pad_buf) @@ -2620,6 +2648,11 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) sg->length, qc->pad_len); } + if (!sg->length) { + sg_dma_address(sg) = 0; + goto skip_map; + } + dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, sg->length, dir); if (dma_mapping_error(dma_address)) { @@ -2629,6 +2662,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) } sg_dma_address(sg) = dma_address; +skip_map: sg_dma_len(sg) = sg->length; DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), @@ -2656,7 +2690,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) struct ata_port *ap = qc->ap; struct scatterlist *sg = qc->__sg; struct scatterlist *lsg = &sg[qc->n_elem - 1]; - int n_elem, dir; + int n_elem, pre_n_elem, dir, trim_sg = 0; VPRINTK("ENTER, ata%u\n", ap->id); assert(qc->flags & ATA_QCFLAG_SG); @@ -2683,20 +2717,31 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) if (qc->tf.flags & ATA_TFLAG_WRITE) { void *addr = kmap_atomic(psg->page, KM_IRQ0); memcpy(pad_buf, addr + psg->offset, qc->pad_len); - kunmap_atomic(psg->page, KM_IRQ0); + kunmap_atomic(addr, KM_IRQ0); } sg_dma_address(psg) = ap->pad_dma + (qc->tag * ATA_DMA_PAD_SZ); sg_dma_len(psg) = ATA_DMA_PAD_SZ; /* trim last sg */ lsg->length -= qc->pad_len; + if (lsg->length == 0) + trim_sg = 1; DPRINTK("padding done, sg[%d].length=%u pad_len=%u\n", qc->n_elem - 1, lsg->length, qc->pad_len); } + pre_n_elem = qc->n_elem; + if (trim_sg && pre_n_elem) + pre_n_elem--; + + if (!pre_n_elem) { + n_elem = 0; + goto skip_map; + } + dir = qc->dma_dir; - n_elem = dma_map_sg(ap->host_set->dev, sg, qc->n_elem, dir); + n_elem = dma_map_sg(ap->host_set->dev, sg, pre_n_elem, dir); if (n_elem < 1) { /* restore last sg */ lsg->length += qc->pad_len; @@ -2705,6 +2750,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) DPRINTK("%d sg elements mapped\n", n_elem); +skip_map: qc->n_elem = n_elem; return 0; @@ -3264,32 +3310,11 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct ata_host_set *host_set = ap->host_set; - struct ata_device *dev = qc->dev; u8 host_stat = 0, drv_stat; unsigned long flags; DPRINTK("ENTER\n"); - /* FIXME: doesn't this conflict with timeout handling? */ - if (qc->dev->class == ATA_DEV_ATAPI && qc->scsicmd) { - struct scsi_cmnd *cmd = qc->scsicmd; - - if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { - - /* finish completing original command */ - spin_lock_irqsave(&host_set->lock, flags); - __ata_qc_complete(qc); - spin_unlock_irqrestore(&host_set->lock, flags); - - atapi_request_sense(ap, dev, cmd); - - cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); - scsi_finish_command(cmd); - - goto out; - } - } - spin_lock_irqsave(&host_set->lock, flags); /* hack alert! We cannot use the supplied completion @@ -3328,7 +3353,6 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) spin_unlock_irqrestore(&host_set->lock, flags); -out: DPRINTK("EXIT\n"); } @@ -3412,16 +3436,11 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, qc = ata_qc_new(ap); if (qc) { - qc->__sg = NULL; - qc->flags = 0; qc->scsicmd = NULL; qc->ap = ap; qc->dev = dev; - qc->cursect = qc->cursg = qc->cursg_ofs = 0; - qc->nsect = 0; - qc->nbytes = qc->curbytes = 0; - ata_tf_init(ap, &qc->tf, dev->devno); + ata_qc_reinit(qc); } return qc; @@ -4563,6 +4582,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int probe_ent->irq = pdev->irq; probe_ent->irq_flags = SA_SHIRQ; + probe_ent->private_data = port[0]->private_data; if (ports & ATA_PORT_PRIMARY) { probe_ent->port[p].cmd_addr = pci_resource_start(pdev, 0); @@ -4599,6 +4619,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, stru probe_ent->legacy_mode = 1; probe_ent->n_ports = 1; probe_ent->hard_port_no = port_num; + probe_ent->private_data = port->private_data; switch(port_num) { diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index bb30fcd..2282c04 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c @@ -38,6 +38,7 @@ #include <linux/spinlock.h> #include <scsi/scsi.h> #include <scsi/scsi_host.h> +#include <scsi/scsi_eh.h> #include <scsi/scsi_device.h> #include <scsi/scsi_request.h> #include <linux/libata.h> @@ -147,7 +148,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) u8 scsi_cmd[MAX_COMMAND_SIZE]; u8 args[4], *argbuf = NULL; int argsize = 0; - struct scsi_request *sreq; + struct scsi_sense_hdr sshdr; + enum dma_data_direction data_dir; if (NULL == (void *)arg) return -EINVAL; @@ -155,10 +157,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) if (copy_from_user(args, arg, sizeof(args))) return -EFAULT; - sreq = scsi_allocate_request(scsidev, GFP_KERNEL); - if (!sreq) - return -EINTR; - memset(scsi_cmd, 0, sizeof(scsi_cmd)); if (args[3]) { @@ -172,11 +170,11 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[1] = (4 << 1); /* PIO Data-in */ scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, block count in sector count field */ - sreq->sr_data_direction = DMA_FROM_DEVICE; + data_dir = DMA_FROM_DEVICE; } else { scsi_cmd[1] = (3 << 1); /* Non-data */ /* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */ - sreq->sr_data_direction = DMA_NONE; + data_dir = DMA_NONE; } scsi_cmd[0] = ATA_16; @@ -194,9 +192,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) /* Good values for timeout and retries? Values below from scsi_ioctl_send_command() for default case... */ - scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5); - - if (sreq->sr_result) { + if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize, + &sshdr, (10*HZ), 5)) { rc = -EIO; goto error; } @@ -207,8 +204,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) && copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize)) rc = -EFAULT; error: - scsi_release_request(sreq); - if (argbuf) kfree(argbuf); @@ -231,7 +226,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) int rc = 0; u8 scsi_cmd[MAX_COMMAND_SIZE]; u8 args[7]; - struct scsi_request *sreq; + struct scsi_sense_hdr sshdr; if (NULL == (void *)arg) return -EINVAL; @@ -250,26 +245,13 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) scsi_cmd[12] = args[5]; scsi_cmd[14] = args[0]; - sreq = scsi_allocate_request(scsidev, GFP_KERNEL); - if (!sreq) { - rc = -EINTR; - goto error; - } - - sreq->sr_data_direction = DMA_NONE; /* Good values for timeout and retries? Values below - from scsi_ioctl_send_command() for default case... */ - scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5); - - if (sreq->sr_result) { + from scsi_ioctl_send_command() for default case... */ + if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr, + (10*HZ), 5)) rc = -EIO; - goto error; - } /* Need code to retrieve data from check condition? */ - -error: - scsi_release_request(sreq); return rc; } @@ -1129,6 +1111,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm * length 0 means transfer 0 block of data. * However, for ATA R/W commands, sector count 0 means * 256 or 65536 sectors, not 0 sectors as in SCSI. + * + * WARNING: one or two older ATA drives treat 0 as 0... */ goto nothing_to_do; @@ -1971,22 +1955,44 @@ void ata_scsi_badcmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), u8 done(cmd); } -void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd) +static int atapi_sense_complete(struct ata_queued_cmd *qc,unsigned int err_mask) { - DECLARE_COMPLETION(wait); - struct ata_queued_cmd *qc; - unsigned long flags; - int rc; + if (err_mask && ((err_mask & AC_ERR_DEV) == 0)) + /* FIXME: not quite right; we don't want the + * translation of taskfile registers into + * a sense descriptors, since that's only + * correct for ATA, not ATAPI + */ + ata_gen_ata_desc_sense(qc); - DPRINTK("ATAPI request sense\n"); + qc->scsidone(qc->scsicmd); + return 0; +} - qc = ata_qc_new_init(ap, dev); - BUG_ON(qc == NULL); +/* is it pointless to prefer PIO for "safety reasons"? */ +static inline int ata_pio_use_silly(struct ata_port *ap) +{ + return (ap->flags & ATA_FLAG_PIO_DMA); +} + +static void atapi_request_sense(struct ata_queued_cmd *qc) +{ + struct ata_port *ap = qc->ap; + struct scsi_cmnd *cmd = qc->scsicmd; + + DPRINTK("ATAPI request sense\n"); /* FIXME: is this needed? */ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); + ap->ops->tf_read(ap, &qc->tf); + + /* fill these in, for the case where they are -not- overwritten */ + cmd->sense_buffer[0] = 0x70; + cmd->sense_buffer[2] = qc->tf.feature >> 4; + + ata_qc_reinit(qc); + ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); qc->dma_dir = DMA_FROM_DEVICE; @@ -1997,22 +2003,20 @@ void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; qc->tf.command = ATA_CMD_PACKET; - qc->tf.protocol = ATA_PROT_ATAPI; - qc->tf.lbam = (8 * 1024) & 0xff; - qc->tf.lbah = (8 * 1024) >> 8; + if (ata_pio_use_silly(ap)) { + qc->tf.protocol = ATA_PROT_ATAPI_DMA; + qc->tf.feature |= ATAPI_PKT_DMA; + } else { + qc->tf.protocol = ATA_PROT_ATAPI; + qc->tf.lbam = (8 * 1024) & 0xff; + qc->tf.lbah = (8 * 1024) >> 8; + } qc->nbytes = SCSI_SENSE_BUFFERSIZE; - qc->waiting = &wait; - qc->complete_fn = ata_qc_complete_noop; - - spin_lock_irqsave(&ap->host_set->lock, flags); - rc = ata_qc_issue(qc); - spin_unlock_irqrestore(&ap->host_set->lock, flags); + qc->complete_fn = atapi_sense_complete; - if (rc) - ata_port_disable(ap); - else - wait_for_completion(&wait); + if (ata_qc_issue(qc)) + ata_qc_complete(qc, AC_ERR_OTHER); DPRINTK("EXIT\n"); } @@ -2024,19 +2028,8 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) VPRINTK("ENTER, err_mask 0x%X\n", err_mask); if (unlikely(err_mask & AC_ERR_DEV)) { - DPRINTK("request check condition\n"); - - /* FIXME: command completion with check condition - * but no sense causes the error handler to run, - * which then issues REQUEST SENSE, fills in the sense - * buffer, and completes the command (for the second - * time). We need to issue REQUEST SENSE some other - * way, to avoid completing the command twice. - */ cmd->result = SAM_STAT_CHECK_CONDITION; - - qc->scsidone(cmd); - + atapi_request_sense(qc); return 1; } @@ -2051,7 +2044,7 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) else { u8 *scsicmd = cmd->cmnd; - if (scsicmd[0] == INQUIRY) { + if ((scsicmd[0] == INQUIRY) && ((scsicmd[1] & 0x03) == 0)) { u8 *buf = NULL; unsigned int buflen; @@ -2065,9 +2058,6 @@ static int atapi_qc_complete(struct ata_queued_cmd *qc, unsigned int err_mask) * device. 2) Ensure response data format / ATAPI information * are always correct. */ - /* FIXME: do we ever override EVPD pages and the like, with - * this code? - */ if (buf[2] == 0) { buf[2] = 0x5; buf[3] = 0x32; @@ -2180,9 +2170,12 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) if (unlikely(!ata_dev_present(dev))) return NULL; - if (!atapi_enabled) { - if (unlikely(dev->class == ATA_DEV_ATAPI)) + if (!atapi_enabled || (ap->flags & ATA_FLAG_NO_ATAPI)) { + if (unlikely(dev->class == ATA_DEV_ATAPI)) { + printk(KERN_WARNING "ata%u(%u): WARNING: ATAPI is %s, device ignored.\n", + ap->id, dev->devno, atapi_enabled ? "not supported with this driver" : "disabled"); return NULL; + } } return dev; @@ -2246,7 +2239,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) struct scsi_cmnd *cmd = qc->scsicmd; if ((tf->protocol = ata_scsi_map_proto(scsicmd[1])) == ATA_PROT_UNKNOWN) - return 1; + goto invalid_fld; /* * 12 and 16 byte CDBs use different offsets to @@ -2292,6 +2285,12 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) tf->device = scsicmd[8]; tf->command = scsicmd[9]; } + /* + * If slave is possible, enforce correct master/slave bit + */ + if (qc->ap->flags & ATA_FLAG_SLAVE_POSS) + tf->device = qc->dev->devno ? + tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; /* * Filter SET_FEATURES - XFER MODE command -- otherwise, @@ -2302,7 +2301,7 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) */ if ((tf->command == ATA_CMD_SET_FEATURES) && (tf->feature == SETFEATURES_XFER)) - return 1; + goto invalid_fld; /* * Set flags so that all registers will be written, @@ -2323,6 +2322,11 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd) qc->nsect = cmd->bufflen / ATA_SECT_SIZE; return 0; + + invalid_fld: + ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x00); + /* "Invalid field in cdb" */ + return 1; } /** diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index fad051c..8ebaa69 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -29,7 +29,7 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "1.12" /* must be exactly four chars */ +#define DRV_VERSION "1.20" /* must be exactly four chars */ struct ata_scsi_args { u16 *id; @@ -54,8 +54,6 @@ extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); /* libata-scsi.c */ -extern void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd); extern void ata_scsi_scan_host(struct ata_port *ap); extern int ata_scsi_error(struct Scsi_Host *host); extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index c907238..0749811 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -1704,7 +1704,6 @@ MODULE_DEVICE_TABLE(pci, lpfc_id_table); static struct pci_driver lpfc_driver = { .name = LPFC_DRIVER_NAME, - .owner = THIS_MODULE, .id_table = lpfc_id_table, .probe = lpfc_pci_probe_one, .remove = __devexit_p(lpfc_pci_remove_one), diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index c94c8db..e31fadd6 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -300,7 +300,7 @@ unsigned long get_base(int chip_num) * Model dependent ESP setup */ -int mac_esp_detect(Scsi_Host_Template * tpnt) +int mac_esp_detect(struct scsi_host_template * tpnt) { int quick = 0; int chipnum, chipspresent = 0; @@ -730,7 +730,7 @@ static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int wri #endif } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "mac_esp", .name = "Mac 53C9x SCSI", .detect = mac_esp_detect, diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c index 92d2c83..777f9bc 100644 --- a/drivers/scsi/mac_scsi.c +++ b/drivers/scsi/mac_scsi.c @@ -222,7 +222,7 @@ static struct Scsi_Host *default_instance; #endif /* - * Function : int macscsi_detect(Scsi_Host_Template * tpnt) + * Function : int macscsi_detect(struct scsi_host_template * tpnt) * * Purpose : initializes mac NCR5380 driver based on the * command line / compile time port and irq definitions. @@ -233,7 +233,7 @@ static struct Scsi_Host *default_instance; * */ -int macscsi_detect(Scsi_Host_Template * tpnt) +int macscsi_detect(struct scsi_host_template * tpnt) { static int called = 0; int flags = 0; @@ -581,7 +581,7 @@ static int macscsi_pwrite (struct Scsi_Host *instance, #include "NCR5380.c" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "Mac5380", .proc_info = macscsi_proc_info, .name = "Macintosh NCR5380 SCSI", diff --git a/drivers/scsi/mca_53c9x.c b/drivers/scsi/mca_53c9x.c index 194c754..998a8bb 100644 --- a/drivers/scsi/mca_53c9x.c +++ b/drivers/scsi/mca_53c9x.c @@ -103,7 +103,7 @@ static volatile unsigned char cmd_buffer[16]; static struct ESP_regs eregs; /***************************************************************** Detection */ -static int mca_esp_detect(Scsi_Host_Template *tpnt) +static int mca_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; static int io_port_by_pos[] = MCA_53C9X_IO_PORTS; @@ -444,7 +444,7 @@ static void dma_led_off(struct NCR_ESP *esp) outb(inb(PS2_SYS_CTR) & 0x3f, PS2_SYS_CTR); } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "mca_53c9x", .name = "NCR 53c9x SCSI", .detect = mca_esp_detect, diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 61a6fd8..578143e 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -362,6 +362,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) adapter_t *adapter; scb_t *scb; int busy=0; + unsigned long flags; adapter = (adapter_t *)scmd->device->host->hostdata; @@ -377,23 +378,25 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) * return 0 in that case. */ + spin_lock_irqsave(&adapter->lock, flags); scb = mega_build_cmd(adapter, scmd, &busy); + if (!scb) + goto out; - if(scb) { - scb->state |= SCB_PENDQ; - list_add_tail(&scb->list, &adapter->pending_list); + scb->state |= SCB_PENDQ; + list_add_tail(&scb->list, &adapter->pending_list); - /* - * Check if the HBA is in quiescent state, e.g., during a - * delete logical drive opertion. If it is, don't run - * the pending_list. - */ - if(atomic_read(&adapter->quiescent) == 0) { - mega_runpendq(adapter); - } - return 0; - } + /* + * Check if the HBA is in quiescent state, e.g., during a + * delete logical drive opertion. If it is, don't run + * the pending_list. + */ + if (atomic_read(&adapter->quiescent) == 0) + mega_runpendq(adapter); + busy = 0; + out: + spin_unlock_irqrestore(&adapter->lock, flags); return busy; } @@ -661,7 +664,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) sg->offset; } else buf = cmd->request_buffer; - memset(cmd->request_buffer, 0, cmd->cmnd[4]); + memset(buf, 0, cmd->cmnd[4]); if (cmd->use_sg) { struct scatterlist *sg; @@ -1683,7 +1686,7 @@ mega_rundoneq (adapter_t *adapter) list_for_each(pos, &adapter->completed_list) { - Scsi_Pointer* spos = (Scsi_Pointer *)pos; + struct scsi_pointer* spos = (struct scsi_pointer *)pos; cmd = list_entry(spos, Scsi_Cmnd, SCp); cmd->scsi_done(cmd); @@ -1981,7 +1984,7 @@ megaraid_reset(struct scsi_cmnd *cmd) mc.cmd = MEGA_CLUSTER_CMD; mc.opcode = MEGA_RESET_RESERVATIONS; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { + if( mega_internal_command(adapter, &mc, NULL) != 0 ) { printk(KERN_WARNING "megaraid: reservation reset failed.\n"); } @@ -3011,7 +3014,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) mc.cmd = FC_NEW_CONFIG; mc.opcode = OP_DCMD_READ_CONFIG; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { + if( mega_internal_command(adapter, &mc, NULL) ) { len = sprintf(page, "40LD read config failed.\n"); @@ -3029,11 +3032,11 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) else { mc.cmd = NEW_READ_CONFIG_8LD; - if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { + if( mega_internal_command(adapter, &mc, NULL) ) { mc.cmd = READ_CONFIG_8LD; - if( mega_internal_command(adapter, LOCK_INT, &mc, + if( mega_internal_command(adapter, &mc, NULL) ){ len = sprintf(page, @@ -3632,7 +3635,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, /* * Issue the command */ - mega_internal_command(adapter, LOCK_INT, &mc, pthru); + mega_internal_command(adapter, &mc, pthru); rval = mega_n_to_m((void __user *)arg, &mc); @@ -3715,7 +3718,7 @@ freemem_and_return: /* * Issue the command */ - mega_internal_command(adapter, LOCK_INT, &mc, NULL); + mega_internal_command(adapter, &mc, NULL); rval = mega_n_to_m((void __user *)arg, &mc); @@ -4234,7 +4237,7 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv) mc.opcode = OP_DEL_LOGDRV; mc.subopcode = logdrv; - rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL); + rval = mega_internal_command(adapter, &mc, NULL); /* log this event */ if(rval) { @@ -4367,7 +4370,7 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle) mc.xferaddr = (u32)dma_handle; - if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { + if ( mega_internal_command(adapter, &mc, NULL) != 0 ) { return -1; } @@ -4435,7 +4438,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, mc.cmd = MEGA_MBOXCMD_PASSTHRU; mc.xferaddr = (u32)pthru_dma_handle; - rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru); + rval = mega_internal_command(adapter, &mc, pthru); pci_free_consistent(pdev, sizeof(mega_passthru), pthru, pthru_dma_handle); @@ -4449,7 +4452,6 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, /** * mega_internal_command() * @adapter - pointer to our soft state - * @ls - the scope of the exclusion lock. * @mc - the mailbox command * @pthru - Passthru structure for DCDB commands * @@ -4463,8 +4465,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, * Note: parameter 'pthru' is null for non-passthru commands. */ static int -mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, - mega_passthru *pthru ) +mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) { Scsi_Cmnd *scmd; struct scsi_device *sdev; @@ -4508,15 +4509,8 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, scb->idx = CMDID_INT_CMDS; - /* - * Get the lock only if the caller has not acquired it already - */ - if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags); - megaraid_queue(scmd, mega_internal_done); - if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags); - wait_for_completion(&adapter->int_waitq); rval = scmd->result; @@ -4683,7 +4677,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) adapter->flag = flag; spin_lock_init(&adapter->lock); - scsi_assign_lock(host, &adapter->lock); host->cmd_per_lun = max_cmd_per_lun; host->max_sectors = max_sectors_per_io; diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 4facf55..6f90780 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -926,13 +926,6 @@ struct mega_hbas { #define MEGA_SGLIST 0x0002 /* - * lockscope definitions, callers can specify the lock scope with this data - * type. LOCK_INT would mean the caller has not acquired the lock before - * making the call and LOCK_EXT would mean otherwise. - */ -typedef enum { LOCK_INT, LOCK_EXT } lockscope_t; - -/* * Parameters for the io-mapped controllers */ @@ -1062,8 +1055,7 @@ static int mega_support_random_del(adapter_t *); static int mega_del_logdrv(adapter_t *, int); static int mega_do_del_logdrv(adapter_t *, int); static void mega_get_max_sgl(adapter_t *); -static int mega_internal_command(adapter_t *, lockscope_t, megacmd_t *, - mega_passthru *); +static int mega_internal_command(adapter_t *, megacmd_t *, mega_passthru *); static void mega_internal_done(Scsi_Cmnd *); static int mega_support_cluster(adapter_t *); #endif diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h index 8e54713..4675343 100644 --- a/drivers/scsi/megaraid/mega_common.h +++ b/drivers/scsi/megaraid/mega_common.h @@ -96,7 +96,6 @@ typedef struct { * @param dpc_h : tasklet handle * @param pdev : pci configuration pointer for kernel * @param host : pointer to host structure of mid-layer - * @param host_lock : pointer to appropriate lock * @param lock : synchronization lock for mid-layer and driver * @param quiescent : driver is quiescent for now. * @param outstanding_cmds : number of commands pending in the driver @@ -151,7 +150,6 @@ typedef struct { struct tasklet_struct dpc_h; struct pci_dev *pdev; struct Scsi_Host *host; - spinlock_t *host_lock; spinlock_t lock; uint8_t quiescent; int outstanding_cmds; diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index 1a3d195..4b5d420 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -533,8 +533,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) // Initialize the synchronization lock for kernel and LLD spin_lock_init(&adapter->lock); - adapter->host_lock = &adapter->lock; - // Initialize the command queues: the list of free SCBs and the list // of pending SCBs. @@ -715,9 +713,6 @@ megaraid_io_attach(adapter_t *adapter) SCSIHOST2ADAP(host) = (caddr_t)adapter; adapter->host = host; - // export the parameters required by the mid-layer - scsi_assign_lock(host, adapter->host_lock); - host->irq = adapter->irq; host->unique_id = adapter->unique_id; host->can_queue = adapter->max_cmds; @@ -1560,10 +1555,6 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *)) scp->scsi_done = done; scp->result = 0; - assert_spin_locked(adapter->host_lock); - - spin_unlock(adapter->host_lock); - /* * Allocate and build a SCB request * if_busy flag will be set if megaraid_mbox_build_cmd() command could @@ -1573,23 +1564,16 @@ megaraid_queue_command(struct scsi_cmnd *scp, void (* done)(struct scsi_cmnd *)) * return 0 in that case, and we would do the callback right away. */ if_busy = 0; - scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy); - - if (scb) { - megaraid_mbox_runpendq(adapter, scb); - } - - spin_lock(adapter->host_lock); - + scb = megaraid_mbox_build_cmd(adapter, scp, &if_busy); if (!scb) { // command already completed done(scp); return 0; } + megaraid_mbox_runpendq(adapter, scb); return if_busy; } - /** * megaraid_mbox_build_cmd - transform the mid-layer scsi command to megaraid * firmware lingua @@ -2546,9 +2530,7 @@ megaraid_mbox_dpc(unsigned long devp) megaraid_dealloc_scb(adapter, scb); // send the scsi packet back to kernel - spin_lock(adapter->host_lock); scp->scsi_done(scp); - spin_unlock(adapter->host_lock); } return; @@ -2563,7 +2545,7 @@ megaraid_mbox_dpc(unsigned long devp) * aborted. All the commands issued to the F/W must complete. **/ static int -__megaraid_abort_handler(struct scsi_cmnd *scp) +megaraid_abort_handler(struct scsi_cmnd *scp) { adapter_t *adapter; mraid_device_t *raid_dev; @@ -2577,8 +2559,6 @@ __megaraid_abort_handler(struct scsi_cmnd *scp) adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); - assert_spin_locked(adapter->host_lock); - con_log(CL_ANN, (KERN_WARNING "megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n", scp->serial_number, scp->cmnd[0], SCP2CHANNEL(scp), @@ -2658,6 +2638,7 @@ __megaraid_abort_handler(struct scsi_cmnd *scp) // traverse through the list of all SCB, since driver does not // maintain these SCBs on any list found = 0; + spin_lock_irq(&adapter->lock); for (i = 0; i < MBOX_MAX_SCSI_CMDS; i++) { scb = adapter->kscb_list + i; @@ -2680,6 +2661,7 @@ __megaraid_abort_handler(struct scsi_cmnd *scp) } } } + spin_unlock_irq(&adapter->lock); if (!found) { con_log(CL_ANN, (KERN_WARNING @@ -2696,22 +2678,6 @@ __megaraid_abort_handler(struct scsi_cmnd *scp) return FAILED; } -static int -megaraid_abort_handler(struct scsi_cmnd *scp) -{ - adapter_t *adapter; - int rc; - - adapter = SCP2ADAPTER(scp); - - spin_lock_irq(adapter->host_lock); - rc = __megaraid_abort_handler(scp); - spin_unlock_irq(adapter->host_lock); - - return rc; -} - - /** * megaraid_reset_handler - device reset hadler for mailbox based driver * @scp : reference command @@ -2723,7 +2689,7 @@ megaraid_abort_handler(struct scsi_cmnd *scp) * host **/ static int -__megaraid_reset_handler(struct scsi_cmnd *scp) +megaraid_reset_handler(struct scsi_cmnd *scp) { adapter_t *adapter; scb_t *scb; @@ -2739,10 +2705,6 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) adapter = SCP2ADAPTER(scp); raid_dev = ADAP2RAIDDEV(adapter); - assert_spin_locked(adapter->host_lock); - - con_log(CL_ANN, (KERN_WARNING "megaraid: reseting the host...\n")); - // return failure if adapter is not responding if (raid_dev->hw_error) { con_log(CL_ANN, (KERN_NOTICE @@ -2779,8 +2741,6 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) adapter->outstanding_cmds, MBOX_RESET_WAIT)); } - spin_unlock(adapter->host_lock); - recovery_window = MBOX_RESET_WAIT + MBOX_RESET_EXT_WAIT; recovering = adapter->outstanding_cmds; @@ -2806,7 +2766,7 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) msleep(1000); } - spin_lock(adapter->host_lock); + spin_lock(&adapter->lock); // If still outstanding commands, bail out if (adapter->outstanding_cmds) { @@ -2815,7 +2775,8 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) raid_dev->hw_error = 1; - return FAILED; + rval = FAILED; + goto out; } else { con_log(CL_ANN, (KERN_NOTICE @@ -2824,7 +2785,10 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) // If the controller supports clustering, reset reservations - if (!adapter->ha) return SUCCESS; + if (!adapter->ha) { + rval = SUCCESS; + goto out; + } // clear reservations if any raw_mbox[0] = CLUSTER_CMD; @@ -2841,22 +2805,11 @@ __megaraid_reset_handler(struct scsi_cmnd *scp) "megaraid: reservation reset failed\n")); } + out: + spin_unlock_irq(&adapter->lock); return rval; } -static int -megaraid_reset_handler(struct scsi_cmnd *cmd) -{ - int rc; - - spin_lock_irq(cmd->device->host->host_lock); - rc = __megaraid_reset_handler(cmd); - spin_unlock_irq(cmd->device->host->host_lock); - - return rc; -} - - /* * START: internal commands library * @@ -3776,9 +3729,9 @@ wait_till_fw_empty(adapter_t *adapter) /* * Set the quiescent flag to stop issuing cmds to FW. */ - spin_lock_irqsave(adapter->host_lock, flags); + spin_lock_irqsave(&adapter->lock, flags); adapter->quiescent++; - spin_unlock_irqrestore(adapter->host_lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); /* * Wait till there are no more cmds outstanding at FW. Try for at most diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 801a63b..3c32e69 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c @@ -766,17 +766,12 @@ static int megasas_generic_reset(struct scsi_cmnd *scmd) return FAILED; } - spin_unlock(scmd->device->host->host_lock); - ret_val = megasas_wait_for_outstanding(instance); - if (ret_val == SUCCESS) printk(KERN_NOTICE "megasas: reset successful \n"); else printk(KERN_ERR "megasas: failed to do reset\n"); - spin_lock(scmd->device->host->host_lock); - return ret_val; } diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index 33380ce..cb367c2 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c @@ -63,7 +63,7 @@ static void dma_stop (struct Scsi_Host *instance, Scsi_Cmnd *SCpnt, m147_pcc->dma_cntrl = 0; } -int mvme147_detect(Scsi_Host_Template *tpnt) +int mvme147_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; wd33c93_regs regs; @@ -130,7 +130,7 @@ static int mvme147_bus_reset(Scsi_Cmnd *cmd) #include "mvme147.h" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "MVME147", .name = "MVME147 built-in SCSI", .detect = mvme147_detect, diff --git a/drivers/scsi/mvme147.h b/drivers/scsi/mvme147.h index d8903f0..2f56d69 100644 --- a/drivers/scsi/mvme147.h +++ b/drivers/scsi/mvme147.h @@ -10,7 +10,7 @@ #include <linux/types.h> -int mvme147_detect(Scsi_Host_Template *); +int mvme147_detect(struct scsi_host_template *); int mvme147_release(struct Scsi_Host *); const char *wd33c93_info(void); int wd33c93_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c index 29ec699..890e9e2 100644 --- a/drivers/scsi/mvme16x.c +++ b/drivers/scsi/mvme16x.c @@ -21,7 +21,7 @@ #include<linux/stat.h> -int mvme16x_scsi_detect(Scsi_Host_Template *tpnt) +int mvme16x_scsi_detect(struct scsi_host_template *tpnt) { static unsigned char called = 0; int clock; @@ -61,7 +61,7 @@ static int mvme16x_scsi_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "MVME16x NCR53c710 SCSI", .detect = mvme16x_scsi_detect, .release = mvme16x_scsi_release, diff --git a/drivers/scsi/mvme16x.h b/drivers/scsi/mvme16x.h index 25173c8..c7a1253 100644 --- a/drivers/scsi/mvme16x.h +++ b/drivers/scsi/mvme16x.h @@ -3,7 +3,7 @@ #include <linux/types.h> -int mvme16x_scsi_detect(Scsi_Host_Template *); +int mvme16x_scsi_detect(struct scsi_host_template *); const char *NCR53c7x0_info(void); int NCR53c7xx_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); int NCR53c7xx_abort(Scsi_Cmnd *); diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index e4ff4f0..a279ebb 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -198,7 +198,7 @@ static void __devexit nsp32_remove(struct pci_dev *); static int __init init_nsp32 (void); static void __exit exit_nsp32 (void); -/* struct Scsi_Host_Template */ +/* struct struct scsi_host_template */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) static int nsp32_proc_info (struct Scsi_Host *, char *, char **, off_t, int, int); #else @@ -208,7 +208,7 @@ static int nsp32_proc_info (char *, char **, off_t, int, int, int); #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) static int nsp32_detect (struct pci_dev *pdev); #else -static int nsp32_detect (Scsi_Host_Template *); +static int nsp32_detect (struct scsi_host_template *); #endif static int nsp32_queuecommand(struct scsi_cmnd *, void (*done)(struct scsi_cmnd *)); @@ -2683,7 +2683,7 @@ static int nsp32_detect(struct pci_dev *pdev) #define DETECT_OK 1 #define DETECT_NG 0 #define PCIDEV (data->Pci) -static int nsp32_detect(Scsi_Host_Template *sht) +static int nsp32_detect(struct scsi_host_template *sht) #endif { struct Scsi_Host *host; /* registered host structure */ diff --git a/drivers/scsi/oktagon_esp.c b/drivers/scsi/oktagon_esp.c index 573d7ef..5d9c9ad 100644 --- a/drivers/scsi/oktagon_esp.c +++ b/drivers/scsi/oktagon_esp.c @@ -114,7 +114,7 @@ static volatile unsigned char cmd_buffer[16]; */ /***************************************************************** Detection */ -int oktagon_esp_detect(Scsi_Host_Template *tpnt) +int oktagon_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct zorro_dev *z = NULL; @@ -585,7 +585,7 @@ int oktagon_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "esp-oktagon", .proc_info = &esp_proc_info, .name = "BSC Oktagon SCSI", diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c index 72bc947..f09e94a 100644 --- a/drivers/scsi/pas16.c +++ b/drivers/scsi/pas16.c @@ -369,7 +369,7 @@ void __init pas16_setup(char *str, int *ints) } /* - * Function : int pas16_detect(Scsi_Host_Template * tpnt) + * Function : int pas16_detect(struct scsi_host_template * tpnt) * * Purpose : detects and initializes PAS16 controllers * that were autoprobed, overridden on the LILO command line, @@ -381,7 +381,7 @@ void __init pas16_setup(char *str, int *ints) * */ -int __init pas16_detect(Scsi_Host_Template * tpnt) +int __init pas16_detect(struct scsi_host_template * tpnt) { static int current_override = 0; static unsigned short current_base = 0; @@ -615,7 +615,7 @@ static int pas16_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "Pro Audio Spectrum-16 SCSI", .detect = pas16_detect, .release = pas16_release, diff --git a/drivers/scsi/pas16.h b/drivers/scsi/pas16.h index 65ce1cc..8dc5b1a 100644 --- a/drivers/scsi/pas16.h +++ b/drivers/scsi/pas16.h @@ -117,7 +117,7 @@ static int pas16_abort(Scsi_Cmnd *); static int pas16_biosparam(struct scsi_device *, struct block_device *, sector_t, int*); -static int pas16_detect(Scsi_Host_Template *); +static int pas16_detect(struct scsi_host_template *); static int pas16_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int pas16_bus_reset(Scsi_Cmnd *); diff --git a/drivers/scsi/pci2000.h b/drivers/scsi/pci2000.h index 6c962d7..0ebd8ce 100644 --- a/drivers/scsi/pci2000.h +++ b/drivers/scsi/pci2000.h @@ -184,7 +184,7 @@ typedef struct _INQUIRYDATA #endif // function prototypes -int Pci2000_Detect (Scsi_Host_Template *tpnt); +int Pci2000_Detect (struct scsi_host_template *tpnt); int Pci2000_Command (Scsi_Cmnd *SCpnt); int Pci2000_QueueCommand (Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)); int Pci2000_Abort (Scsi_Cmnd *SCpnt); diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 3d2f710..050ea13 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -81,7 +81,7 @@ module_param(free_ports, bool, 0); MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))"); /* /usr/src/linux/drivers/scsi/hosts.h */ -static Scsi_Host_Template nsp_driver_template = { +static struct scsi_host_template nsp_driver_template = { .proc_name = "nsp_cs", .proc_info = nsp_proc_info, .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", @@ -1310,7 +1310,7 @@ timer_out: /*----------------------------------------------------------------*/ /* look for ninja3 card and init if found */ /*----------------------------------------------------------------*/ -static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht) +static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht) { struct Scsi_Host *host; /* registered host structure */ nsp_hw_data *data_b = &nsp_data_base, *data; @@ -1358,7 +1358,7 @@ static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht) } #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int nsp_detect_old(Scsi_Host_Template *sht) +static int nsp_detect_old(struct scsi_host_template *sht) { if (nsp_detect(sht) == NULL) { return 0; @@ -1717,7 +1717,7 @@ static void nsp_cs_config(dev_link_t *link) struct Scsi_Host *host; nsp_hw_data *data = &nsp_data_base; #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) - Scsi_Device *dev; + struct scsi_device *dev; dev_node_t **tail, *node; #endif diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index c201b52..f8b9430 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -303,9 +303,9 @@ static void nsp_cs_config (dev_link_t *link); static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args); /* Linux SCSI subsystem specific functions */ -static struct Scsi_Host *nsp_detect (Scsi_Host_Template *sht); +static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -static int nsp_detect_old (Scsi_Host_Template *sht); +static int nsp_detect_old (struct scsi_host_template *sht); static int nsp_release_old(struct Scsi_Host *shpnt); #endif static const char *nsp_info (struct Scsi_Host *shpnt); @@ -345,7 +345,7 @@ static int nsp_expect_signal (Scsi_Cmnd *SCpnt, unsigned char current_phase, static int nsp_xfer (Scsi_Cmnd *SCpnt, int phase); static int nsp_dataphase_bypass (Scsi_Cmnd *SCpnt); static int nsp_reselected (Scsi_Cmnd *SCpnt); -static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht); +static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht); /* Interrupt handler */ //static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 7a516f35..bb091a4 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -72,7 +72,7 @@ static char *version = "qlogic_cs.c 1.79-ac 2002/10/26 (David Hinds)"; #define DEBUG(n, args...) #endif -static Scsi_Host_Template qlogicfas_driver_template = { +static struct scsi_host_template qlogicfas_driver_template = { .module = THIS_MODULE, .name = qlogic_name, .proc_name = qlogic_name, @@ -108,7 +108,7 @@ static dev_link_t *dev_list = NULL; static dev_info_t dev_info = "qlogic_cs"; -static struct Scsi_Host *qlogic_detect(Scsi_Host_Template *host, +static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, dev_link_t *link, int qbase, int qlirq) { int qltyp; /* type of chip */ diff --git a/drivers/scsi/pdc_adma.c b/drivers/scsi/pdc_adma.c index 78b4ff1..f557f17 100644 --- a/drivers/scsi/pdc_adma.c +++ b/drivers/scsi/pdc_adma.c @@ -190,7 +190,7 @@ static struct ata_port_info adma_port_info[] = { }, }; -static struct pci_device_id adma_ata_pci_tbl[] = { +static const struct pci_device_id adma_ata_pci_tbl[] = { { PCI_VENDOR_ID_PDC, 0x1841, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_1841_idx }, diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index c89da7d..46624ab 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c @@ -71,7 +71,7 @@ static void __init pluto_detect_scsi_done(Scsi_Cmnd *SCpnt) up(&fc_sem); } -int pluto_slave_configure(Scsi_Device *device) +int pluto_slave_configure(struct scsi_device *device) { int depth_to_use; @@ -90,11 +90,11 @@ int pluto_slave_configure(Scsi_Device *device) /* Detect all SSAs attached to the machine. To be fast, do it on all online FC channels at the same time. */ -int __init pluto_detect(Scsi_Host_Template *tpnt) +int __init pluto_detect(struct scsi_host_template *tpnt) { int i, retry, nplutos; fc_channel *fc; - Scsi_Device dev; + struct scsi_device dev; DEFINE_TIMER(fc_timer, pluto_detect_timeout, 0, 0); tpnt->proc_name = "pluto"; @@ -339,7 +339,7 @@ static int pluto_encode_addr(Scsi_Cmnd *SCpnt, u16 *addr, fc_channel *fc, fcp_cm return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "Sparc Storage Array 100/200", .detect = pluto_detect, .release = pluto_release, diff --git a/drivers/scsi/pluto.h b/drivers/scsi/pluto.h index beb844a..5da2061 100644 --- a/drivers/scsi/pluto.h +++ b/drivers/scsi/pluto.h @@ -38,10 +38,10 @@ struct pluto_inquiry { /* This is the max number of outstanding SCSI commands per pluto */ #define PLUTO_CAN_QUEUE 254 -int pluto_detect(Scsi_Host_Template *); +int pluto_detect(struct scsi_host_template *); int pluto_release(struct Scsi_Host *); const char * pluto_info(struct Scsi_Host *); -int pluto_slave_configure(Scsi_Device *); +int pluto_slave_configure(struct scsi_device *); #endif /* !(_PLUTO_H) */ diff --git a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c index 4322c95..5c2cdf5 100644 --- a/drivers/scsi/psi240i.c +++ b/drivers/scsi/psi240i.c @@ -538,7 +538,7 @@ static void ReadChipMemory (void *pdata, USHORT base, USHORT length, USHORT port * Returns: Number of adapters found. * ****************************************************************/ -static int Psi240i_Detect (Scsi_Host_Template *tpnt) +static int Psi240i_Detect (struct scsi_host_template *tpnt) { int board; int count = 0; @@ -669,7 +669,7 @@ static int Psi240i_BiosParam (struct scsi_device *sdev, struct block_device *dev MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "psi240i", .name = "PSI-240I EIDE Disk Controller", .detect = Psi240i_Detect, diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 637fb65..0878f95 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -465,7 +465,7 @@ scsi_adjust_queue_depth(struct scsi_device *device, int tag, int depth) } device->queue_depth = depth; } -static inline struct Scsi_Host *scsi_host_alloc(Scsi_Host_Template *t, size_t s) +static inline struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *t, size_t s) { return scsi_register(t, s); } @@ -639,10 +639,8 @@ struct qla_boards { static struct pci_device_id qla1280_pci_tbl[] = { {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP12160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -#ifdef CONFIG_SCSI_QLOGIC_1280_1040 {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, -#endif {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240, @@ -1177,7 +1175,7 @@ qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev, #if LINUX_VERSION_CODE < 0x020600 static int -qla1280_detect(Scsi_Host_Template *template) +qla1280_detect(struct scsi_host_template *template) { struct pci_device_id *id = &qla1280_pci_tbl[0]; struct pci_dev *pdev = NULL; @@ -4507,7 +4505,7 @@ static struct scsi_host_template qla1280_driver_template = { .use_clustering = ENABLE_CLUSTERING, }; #else -static Scsi_Host_Template qla1280_driver_template = { +static struct scsi_host_template qla1280_driver_template = { .proc_name = "qla1280", .name = "Qlogic ISP 1280/12160", .detect = qla1280_detect, diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 89793c1..5c5d231 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -970,7 +970,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) int rval; uint32_t cnt, timer; uint32_t risc_address; - uint16_t mb[4]; + uint16_t mb[4], wd; uint32_t stat; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; @@ -1514,10 +1514,10 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) WRT_REG_DWORD(®->ctrl_status, CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - RD_REG_DWORD(®->ctrl_status); + pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); + udelay(100); /* Wait for firmware to complete NVRAM accesses. */ - udelay(5); mb[0] = (uint32_t) RD_REG_WORD(®->mailbox0); for (cnt = 10000 ; cnt && mb[0]; cnt--) { udelay(5); @@ -1525,7 +1525,7 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) barrier(); } - udelay(20); + /* Wait for soft-reset to complete. */ for (cnt = 0; cnt < 30000; cnt++) { if ((RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET) == 0) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7096945..7b3efd5 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2476,17 +2476,9 @@ typedef struct scsi_qla_host { */ #define LOOP_TRANSITION(ha) \ (test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) - -#define LOOP_NOT_READY(ha) \ - ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) || \ - test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ - test_bit(LOOP_RESYNC_ACTIVE, &ha->dpc_flags)) || \ + test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ atomic_read(&ha->loop_state) == LOOP_DOWN) -#define LOOP_RDY(ha) (!LOOP_NOT_READY(ha)) - #define TGT_Q(ha, t) (ha->otgt[t]) #define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 72d9090..c46d246 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -147,8 +147,8 @@ check_fw_ready_again: * LIP to complete */ - if (atomic_read(&ha->loop_state) == - LOOP_DOWN && retry--) { + if (atomic_read(&ha->loop_state) != + LOOP_READY && retry--) { goto check_fw_ready_again; } wait_time--; @@ -567,6 +567,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) unsigned long flags = 0; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; uint32_t cnt, d2; + uint16_t wd; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -581,10 +582,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) WRT_REG_DWORD(®->ctrl_status, CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); - RD_REG_DWORD(®->ctrl_status); + pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); + udelay(100); /* Wait for firmware to complete NVRAM accesses. */ - udelay(5); d2 = (uint32_t) RD_REG_WORD(®->mailbox0); for (cnt = 10000 ; cnt && d2; cnt--) { udelay(5); @@ -592,7 +593,7 @@ qla24xx_reset_risc(scsi_qla_host_t *ha) barrier(); } - udelay(20); + /* Wait for soft-reset to complete. */ d2 = RD_REG_DWORD(®->ctrl_status); for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) { udelay(5); @@ -1258,9 +1259,15 @@ qla2x00_configure_hba(scsi_qla_host_t *ha) rval = qla2x00_get_adapter_id(ha, &loop_id, &al_pa, &area, &domain, &topo); if (rval != QLA_SUCCESS) { - qla_printk(KERN_WARNING, ha, - "ERROR -- Unable to get host loop ID.\n"); - set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + if (LOOP_TRANSITION(ha) || atomic_read(&ha->loop_down_timer) || + (rval == QLA_COMMAND_ERROR && loop_id == 0x7)) { + DEBUG2(printk("%s(%ld) Loop is in a transition state\n", + __func__, ha->host_no)); + } else { + qla_printk(KERN_WARNING, ha, + "ERROR -- Unable to get host loop ID.\n"); + set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); + } return (rval); } @@ -1789,7 +1796,7 @@ qla2x00_configure_loop(scsi_qla_host_t *ha) } if (rval == QLA_SUCCESS && test_bit(RSCN_UPDATE, &flags)) { - if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) { + if (LOOP_TRANSITION(ha)) { rval = QLA_FUNCTION_FAILED; } else { rval = qla2x00_configure_fabric(ha); @@ -2362,8 +2369,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) if (qla2x00_is_reserved_id(ha, loop_id)) continue; - if (atomic_read(&ha->loop_down_timer) || - test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) + if (atomic_read(&ha->loop_down_timer) || LOOP_TRANSITION(ha)) break; if (swl != NULL) { diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 09afc0f..5181d96 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -909,6 +909,21 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) resid = resid_len; cp->resid = resid; CMD_RESID_LEN(cp) = resid; + + if (!lscsi_status && + ((unsigned)(cp->request_bufflen - resid) < + cp->underflow)) { + qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Mid-layer underflow " + "detected (%x of %x bytes)...returning " + "error status.\n", ha->host_no, + cp->device->channel, cp->device->id, + cp->device->lun, resid, + cp->request_bufflen); + + cp->result = DID_ERROR << 16; + break; + } } cp->result = DID_OK << 16 | lscsi_status; diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index ad3cacb..9746cd1 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -868,10 +868,6 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) fcport = sp->fcport; - if (atomic_read(&ha->loop_state) == LOOP_DOWN || - atomic_read(&fcport->state) == FCS_DEVICE_LOST) { - return 1; - } spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { @@ -1008,6 +1004,8 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, mcp->tov = 30; mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); + if (mcp->mb[0] == MBS_COMMAND_ERROR) + rval = QLA_COMMAND_ERROR; /* Return data. */ *id = mcp->mb[1]; @@ -2179,10 +2177,6 @@ qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) fcport = sp->fcport; - if (atomic_read(&ha->loop_state) == LOOP_DOWN || - atomic_read(&fcport->state) == FCS_DEVICE_LOST) { - return QLA_FUNCTION_FAILED; - } spin_lock_irqsave(&ha->hardware_lock, flags); for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index 4bec0b4..d54d2a9 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c @@ -126,6 +126,7 @@ qla2x00_write_nvram_word(scsi_qla_host_t *ha, uint32_t addr, uint16_t data) /* Wait for NVRAM to become ready */ WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); /* PCI Posting. */ do { NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); @@ -178,6 +179,7 @@ qla2x00_write_nvram_word_tmo(scsi_qla_host_t *ha, uint32_t addr, uint16_t data, /* Wait for NVRAM to become ready */ WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); /* PCI Posting. */ do { NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); @@ -235,6 +237,7 @@ qla2x00_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd) /* Read data from NVRAM. */ for (cnt = 0; cnt < 16; cnt++) { WRT_REG_WORD(®->nvram, NVR_SELECT | NVR_CLOCK); + RD_REG_WORD(®->nvram); /* PCI Posting. */ NVRAM_DELAY(); data <<= 1; reg_data = RD_REG_WORD(®->nvram); @@ -337,6 +340,7 @@ qla2x00_clear_nvram_protection(scsi_qla_host_t *ha) /* Wait for NVRAM to become ready. */ WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); /* PCI Posting. */ do { NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); @@ -388,6 +392,7 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat) /* Wait for NVRAM to become ready. */ WRT_REG_WORD(®->nvram, NVR_SELECT); + RD_REG_WORD(®->nvram); /* PCI Posting. */ do { NVRAM_DELAY(); word = RD_REG_WORD(®->nvram); diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 0d5472f..f7937f7 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h @@ -7,9 +7,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.01.00-k" +#define QLA2XXX_VERSION "8.01.03-k" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 1 -#define QLA_DRIVER_PATCH_VER 0 +#define QLA_DRIVER_PATCH_VER 3 #define QLA_DRIVER_BETA_VER 0 diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index 55e698b..94baca8 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c @@ -47,7 +47,7 @@ static char qlogicfas_name[] = "qlogicfas"; * Look for qlogic card and init if found */ -static struct Scsi_Host *__qlogicfas_detect(Scsi_Host_Template *host, +static struct Scsi_Host *__qlogicfas_detect(struct scsi_host_template *host, int qbase, int qlirq) { @@ -142,7 +142,7 @@ module_param_array(irq, int, NULL, 0); MODULE_PARM_DESC(iobase, "I/O address"); MODULE_PARM_DESC(irq, "IRQ"); -static int __devinit qlogicfas_detect(Scsi_Host_Template *sht) +static int __devinit qlogicfas_detect(struct scsi_host_template *sht) { struct Scsi_Host *shost; struct qlogicfas408_priv *priv; @@ -183,7 +183,7 @@ static int qlogicfas_release(struct Scsi_Host *shost) /* * The driver template is also needed for PCMCIA */ -static Scsi_Host_Template qlogicfas_driver_template = { +static struct scsi_host_template qlogicfas_driver_template = { .module = THIS_MODULE, .name = qlogicfas_name, .proc_name = qlogicfas_name, diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c index a4b3b3f..94ef3f0 100644 --- a/drivers/scsi/qlogicfc.c +++ b/drivers/scsi/qlogicfc.c @@ -711,7 +711,7 @@ static inline void isp2x00_disable_irqs(struct Scsi_Host *host) } -static int isp2x00_detect(Scsi_Host_Template * tmpt) +static int isp2x00_detect(struct scsi_host_template * tmpt) { int hosts = 0; unsigned long wait_time; @@ -2210,7 +2210,7 @@ void isp2x00_print_scsi_cmd(Scsi_Cmnd * cmd) MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .detect = isp2x00_detect, .release = isp2x00_release, .info = isp2x00_info, diff --git a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c deleted file mode 100644 index 6c9266b..0000000 --- a/drivers/scsi/qlogicisp.c +++ /dev/null @@ -1,1934 +0,0 @@ -/* - * QLogic ISP1020 Intelligent SCSI Processor Driver (PCI) - * Written by Erik H. Moe, ehm@cris.com - * Copyright 1995, Erik H. Moe - * Copyright 1996, 1997 Michael A. Griffith <grif@acm.org> - * Copyright 2000, Jayson C. Vantuyl <vantuyl@csc.smsu.edu> - * and Bryon W. Roche <bryon@csc.smsu.edu> - * - * 64-bit addressing added by Kanoj Sarcar <kanoj@sgi.com> - * and Leo Dagum <dagum@sgi.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include <linux/blkdev.h> -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/unistd.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/byteorder.h> -#include "scsi.h" -#include <scsi/scsi_host.h> - -/* - * With the qlogic interface, every queue slot can hold a SCSI - * command with up to 4 scatter/gather entries. If we need more - * than 4 entries, continuation entries can be used that hold - * another 7 entries each. Unlike for other drivers, this means - * that the maximum number of scatter/gather entries we can - * support at any given time is a function of the number of queue - * slots available. That is, host->can_queue and host->sg_tablesize - * are dynamic and _not_ independent. This all works fine because - * requests are queued serially and the scatter/gather limit is - * determined for each queue request anew. - */ -#define QLOGICISP_REQ_QUEUE_LEN 63 /* must be power of two - 1 */ -#define QLOGICISP_MAX_SG(ql) (4 + ((ql) > 0) ? 7*((ql) - 1) : 0) - -/* Configuration section *****************************************************/ - -/* Set the following macro to 1 to reload the ISP1020's firmware. This is - the latest firmware provided by QLogic. This may be an earlier/later - revision than supplied by your board. */ - -#define RELOAD_FIRMWARE 1 - -/* Set the following macro to 1 to reload the ISP1020's defaults from nvram. - If you are not sure of your settings, leave this alone, the driver will - use a set of 'safe' defaults */ - -#define USE_NVRAM_DEFAULTS 0 - -/* Macros used for debugging */ - -#define DEBUG_ISP1020 0 -#define DEBUG_ISP1020_INTR 0 -#define DEBUG_ISP1020_SETUP 0 -#define TRACE_ISP 0 - -#define DEFAULT_LOOP_COUNT 1000000 - -/* End Configuration section *************************************************/ - -#include <linux/module.h> - -#if TRACE_ISP - -# define TRACE_BUF_LEN (32*1024) - -struct { - u_long next; - struct { - u_long time; - u_int index; - u_int addr; - u_char * name; - } buf[TRACE_BUF_LEN]; -} trace; - -#define TRACE(w, i, a) \ -{ \ - unsigned long flags; \ - \ - trace.buf[trace.next].name = (w); \ - trace.buf[trace.next].time = jiffies; \ - trace.buf[trace.next].index = (i); \ - trace.buf[trace.next].addr = (long) (a); \ - trace.next = (trace.next + 1) & (TRACE_BUF_LEN - 1); \ -} - -#else -# define TRACE(w, i, a) -#endif - -#if DEBUG_ISP1020 -#define ENTER(x) printk("isp1020 : entering %s()\n", x); -#define LEAVE(x) printk("isp1020 : leaving %s()\n", x); -#define DEBUG(x) x -#else -#define ENTER(x) -#define LEAVE(x) -#define DEBUG(x) -#endif /* DEBUG_ISP1020 */ - -#if DEBUG_ISP1020_INTR -#define ENTER_INTR(x) printk("isp1020 : entering %s()\n", x); -#define LEAVE_INTR(x) printk("isp1020 : leaving %s()\n", x); -#define DEBUG_INTR(x) x -#else -#define ENTER_INTR(x) -#define LEAVE_INTR(x) -#define DEBUG_INTR(x) -#endif /* DEBUG ISP1020_INTR */ - -#define ISP1020_REV_ID 1 - -#define MAX_TARGETS 16 -#define MAX_LUNS 8 - -/* host configuration and control registers */ -#define HOST_HCCR 0xc0 /* host command and control */ - -/* pci bus interface registers */ -#define PCI_ID_LOW 0x00 /* vendor id */ -#define PCI_ID_HIGH 0x02 /* device id */ -#define ISP_CFG0 0x04 /* configuration register #0 */ -#define ISP_CFG0_HWMSK 0x000f /* Hardware revision mask */ -#define ISP_CFG0_1020 0x0001 /* ISP1020 */ -#define ISP_CFG0_1020A 0x0002 /* ISP1020A */ -#define ISP_CFG0_1040 0x0003 /* ISP1040 */ -#define ISP_CFG0_1040A 0x0004 /* ISP1040A */ -#define ISP_CFG0_1040B 0x0005 /* ISP1040B */ -#define ISP_CFG0_1040C 0x0006 /* ISP1040C */ -#define ISP_CFG1 0x06 /* configuration register #1 */ -#define ISP_CFG1_F128 0x0040 /* 128-byte FIFO threshold */ -#define ISP_CFG1_F64 0x0030 /* 128-byte FIFO threshold */ -#define ISP_CFG1_F32 0x0020 /* 128-byte FIFO threshold */ -#define ISP_CFG1_F16 0x0010 /* 128-byte FIFO threshold */ -#define ISP_CFG1_BENAB 0x0004 /* Global Bus burst enable */ -#define ISP_CFG1_SXP 0x0001 /* SXP register select */ -#define PCI_INTF_CTL 0x08 /* pci interface control */ -#define PCI_INTF_STS 0x0a /* pci interface status */ -#define PCI_SEMAPHORE 0x0c /* pci semaphore */ -#define PCI_NVRAM 0x0e /* pci nvram interface */ -#define CDMA_CONF 0x20 /* Command DMA Config */ -#define DDMA_CONF 0x40 /* Data DMA Config */ -#define DMA_CONF_SENAB 0x0008 /* SXP to DMA Data enable */ -#define DMA_CONF_RIRQ 0x0004 /* RISC interrupt enable */ -#define DMA_CONF_BENAB 0x0002 /* Bus burst enable */ -#define DMA_CONF_DIR 0x0001 /* DMA direction (0=fifo->host 1=host->fifo) */ - -/* mailbox registers */ -#define MBOX0 0x70 /* mailbox 0 */ -#define MBOX1 0x72 /* mailbox 1 */ -#define MBOX2 0x74 /* mailbox 2 */ -#define MBOX3 0x76 /* mailbox 3 */ -#define MBOX4 0x78 /* mailbox 4 */ -#define MBOX5 0x7a /* mailbox 5 */ -#define MBOX6 0x7c /* mailbox 6 */ -#define MBOX7 0x7e /* mailbox 7 */ - -/* mailbox command complete status codes */ -#define MBOX_COMMAND_COMPLETE 0x4000 -#define INVALID_COMMAND 0x4001 -#define HOST_INTERFACE_ERROR 0x4002 -#define TEST_FAILED 0x4003 -#define COMMAND_ERROR 0x4005 -#define COMMAND_PARAM_ERROR 0x4006 - -/* async event status codes */ -#define ASYNC_SCSI_BUS_RESET 0x8001 -#define SYSTEM_ERROR 0x8002 -#define REQUEST_TRANSFER_ERROR 0x8003 -#define RESPONSE_TRANSFER_ERROR 0x8004 -#define REQUEST_QUEUE_WAKEUP 0x8005 -#define EXECUTION_TIMEOUT_RESET 0x8006 - -#ifdef CONFIG_QL_ISP_A64 -#define IOCB_SEGS 2 -#define CONTINUATION_SEGS 5 -#define MAX_CONTINUATION_ENTRIES 254 -#else -#define IOCB_SEGS 4 -#define CONTINUATION_SEGS 7 -#endif /* CONFIG_QL_ISP_A64 */ - -struct Entry_header { - u_char entry_type; - u_char entry_cnt; - u_char sys_def_1; - u_char flags; -}; - -/* entry header type commands */ -#ifdef CONFIG_QL_ISP_A64 -#define ENTRY_COMMAND 9 -#define ENTRY_CONTINUATION 0xa -#else -#define ENTRY_COMMAND 1 -#define ENTRY_CONTINUATION 2 -#endif /* CONFIG_QL_ISP_A64 */ - -#define ENTRY_STATUS 3 -#define ENTRY_MARKER 4 -#define ENTRY_EXTENDED_COMMAND 5 - -/* entry header flag definitions */ -#define EFLAG_CONTINUATION 1 -#define EFLAG_BUSY 2 -#define EFLAG_BAD_HEADER 4 -#define EFLAG_BAD_PAYLOAD 8 - -struct dataseg { - u_int d_base; -#ifdef CONFIG_QL_ISP_A64 - u_int d_base_hi; -#endif - u_int d_count; -}; - -struct Command_Entry { - struct Entry_header hdr; - u_int handle; - u_char target_lun; - u_char target_id; - u_short cdb_length; - u_short control_flags; - u_short rsvd; - u_short time_out; - u_short segment_cnt; - u_char cdb[12]; -#ifdef CONFIG_QL_ISP_A64 - u_int rsvd1; - u_int rsvd2; -#endif - struct dataseg dataseg[IOCB_SEGS]; -}; - -/* command entry control flag definitions */ -#define CFLAG_NODISC 0x01 -#define CFLAG_HEAD_TAG 0x02 -#define CFLAG_ORDERED_TAG 0x04 -#define CFLAG_SIMPLE_TAG 0x08 -#define CFLAG_TAR_RTN 0x10 -#define CFLAG_READ 0x20 -#define CFLAG_WRITE 0x40 - -struct Ext_Command_Entry { - struct Entry_header hdr; - u_int handle; - u_char target_lun; - u_char target_id; - u_short cdb_length; - u_short control_flags; - u_short rsvd; - u_short time_out; - u_short segment_cnt; - u_char cdb[44]; -}; - -struct Continuation_Entry { - struct Entry_header hdr; -#ifndef CONFIG_QL_ISP_A64 - u_int reserved; -#endif - struct dataseg dataseg[CONTINUATION_SEGS]; -}; - -struct Marker_Entry { - struct Entry_header hdr; - u_int reserved; - u_char target_lun; - u_char target_id; - u_char modifier; - u_char rsvd; - u_char rsvds[52]; -}; - -/* marker entry modifier definitions */ -#define SYNC_DEVICE 0 -#define SYNC_TARGET 1 -#define SYNC_ALL 2 - -struct Status_Entry { - struct Entry_header hdr; - u_int handle; - u_short scsi_status; - u_short completion_status; - u_short state_flags; - u_short status_flags; - u_short time; - u_short req_sense_len; - u_int residual; - u_char rsvd[8]; - u_char req_sense_data[32]; -}; - -/* status entry completion status definitions */ -#define CS_COMPLETE 0x0000 -#define CS_INCOMPLETE 0x0001 -#define CS_DMA_ERROR 0x0002 -#define CS_TRANSPORT_ERROR 0x0003 -#define CS_RESET_OCCURRED 0x0004 -#define CS_ABORTED 0x0005 -#define CS_TIMEOUT 0x0006 -#define CS_DATA_OVERRUN 0x0007 -#define CS_COMMAND_OVERRUN 0x0008 -#define CS_STATUS_OVERRUN 0x0009 -#define CS_BAD_MESSAGE 0x000a -#define CS_NO_MESSAGE_OUT 0x000b -#define CS_EXT_ID_FAILED 0x000c -#define CS_IDE_MSG_FAILED 0x000d -#define CS_ABORT_MSG_FAILED 0x000e -#define CS_REJECT_MSG_FAILED 0x000f -#define CS_NOP_MSG_FAILED 0x0010 -#define CS_PARITY_ERROR_MSG_FAILED 0x0011 -#define CS_DEVICE_RESET_MSG_FAILED 0x0012 -#define CS_ID_MSG_FAILED 0x0013 -#define CS_UNEXP_BUS_FREE 0x0014 -#define CS_DATA_UNDERRUN 0x0015 - -/* status entry state flag definitions */ -#define SF_GOT_BUS 0x0100 -#define SF_GOT_TARGET 0x0200 -#define SF_SENT_CDB 0x0400 -#define SF_TRANSFERRED_DATA 0x0800 -#define SF_GOT_STATUS 0x1000 -#define SF_GOT_SENSE 0x2000 - -/* status entry status flag definitions */ -#define STF_DISCONNECT 0x0001 -#define STF_SYNCHRONOUS 0x0002 -#define STF_PARITY_ERROR 0x0004 -#define STF_BUS_RESET 0x0008 -#define STF_DEVICE_RESET 0x0010 -#define STF_ABORTED 0x0020 -#define STF_TIMEOUT 0x0040 -#define STF_NEGOTIATION 0x0080 - -/* interface control commands */ -#define ISP_RESET 0x0001 -#define ISP_EN_INT 0x0002 -#define ISP_EN_RISC 0x0004 - -/* host control commands */ -#define HCCR_NOP 0x0000 -#define HCCR_RESET 0x1000 -#define HCCR_PAUSE 0x2000 -#define HCCR_RELEASE 0x3000 -#define HCCR_SINGLE_STEP 0x4000 -#define HCCR_SET_HOST_INTR 0x5000 -#define HCCR_CLEAR_HOST_INTR 0x6000 -#define HCCR_CLEAR_RISC_INTR 0x7000 -#define HCCR_BP_ENABLE 0x8000 -#define HCCR_BIOS_DISABLE 0x9000 -#define HCCR_TEST_MODE 0xf000 - -#define RISC_BUSY 0x0004 - -/* mailbox commands */ -#define MBOX_NO_OP 0x0000 -#define MBOX_LOAD_RAM 0x0001 -#define MBOX_EXEC_FIRMWARE 0x0002 -#define MBOX_DUMP_RAM 0x0003 -#define MBOX_WRITE_RAM_WORD 0x0004 -#define MBOX_READ_RAM_WORD 0x0005 -#define MBOX_MAILBOX_REG_TEST 0x0006 -#define MBOX_VERIFY_CHECKSUM 0x0007 -#define MBOX_ABOUT_FIRMWARE 0x0008 -#define MBOX_CHECK_FIRMWARE 0x000e -#define MBOX_INIT_REQ_QUEUE 0x0010 -#define MBOX_INIT_RES_QUEUE 0x0011 -#define MBOX_EXECUTE_IOCB 0x0012 -#define MBOX_WAKE_UP 0x0013 -#define MBOX_STOP_FIRMWARE 0x0014 -#define MBOX_ABORT 0x0015 -#define MBOX_ABORT_DEVICE 0x0016 -#define MBOX_ABORT_TARGET 0x0017 -#define MBOX_BUS_RESET 0x0018 -#define MBOX_STOP_QUEUE 0x0019 -#define MBOX_START_QUEUE 0x001a -#define MBOX_SINGLE_STEP_QUEUE 0x001b -#define MBOX_ABORT_QUEUE 0x001c -#define MBOX_GET_DEV_QUEUE_STATUS 0x001d -#define MBOX_GET_FIRMWARE_STATUS 0x001f -#define MBOX_GET_INIT_SCSI_ID 0x0020 -#define MBOX_GET_SELECT_TIMEOUT 0x0021 -#define MBOX_GET_RETRY_COUNT 0x0022 -#define MBOX_GET_TAG_AGE_LIMIT 0x0023 -#define MBOX_GET_CLOCK_RATE 0x0024 -#define MBOX_GET_ACT_NEG_STATE 0x0025 -#define MBOX_GET_ASYNC_DATA_SETUP_TIME 0x0026 -#define MBOX_GET_PCI_PARAMS 0x0027 -#define MBOX_GET_TARGET_PARAMS 0x0028 -#define MBOX_GET_DEV_QUEUE_PARAMS 0x0029 -#define MBOX_SET_INIT_SCSI_ID 0x0030 -#define MBOX_SET_SELECT_TIMEOUT 0x0031 -#define MBOX_SET_RETRY_COUNT 0x0032 -#define MBOX_SET_TAG_AGE_LIMIT 0x0033 -#define MBOX_SET_CLOCK_RATE 0x0034 -#define MBOX_SET_ACTIVE_NEG_STATE 0x0035 -#define MBOX_SET_ASYNC_DATA_SETUP_TIME 0x0036 -#define MBOX_SET_PCI_CONTROL_PARAMS 0x0037 -#define MBOX_SET_TARGET_PARAMS 0x0038 -#define MBOX_SET_DEV_QUEUE_PARAMS 0x0039 -#define MBOX_RETURN_BIOS_BLOCK_ADDR 0x0040 -#define MBOX_WRITE_FOUR_RAM_WORDS 0x0041 -#define MBOX_EXEC_BIOS_IOCB 0x0042 - -#ifdef CONFIG_QL_ISP_A64 -#define MBOX_CMD_INIT_REQUEST_QUEUE_64 0x0052 -#define MBOX_CMD_INIT_RESPONSE_QUEUE_64 0x0053 -#endif /* CONFIG_QL_ISP_A64 */ - -#include "qlogicisp_asm.c" - -#define PACKB(a, b) (((a)<<4)|(b)) - -static const u_char mbox_param[] = { - PACKB(1, 1), /* MBOX_NO_OP */ - PACKB(5, 5), /* MBOX_LOAD_RAM */ - PACKB(2, 0), /* MBOX_EXEC_FIRMWARE */ - PACKB(5, 5), /* MBOX_DUMP_RAM */ - PACKB(3, 3), /* MBOX_WRITE_RAM_WORD */ - PACKB(2, 3), /* MBOX_READ_RAM_WORD */ - PACKB(6, 6), /* MBOX_MAILBOX_REG_TEST */ - PACKB(2, 3), /* MBOX_VERIFY_CHECKSUM */ - PACKB(1, 3), /* MBOX_ABOUT_FIRMWARE */ - PACKB(0, 0), /* 0x0009 */ - PACKB(0, 0), /* 0x000a */ - PACKB(0, 0), /* 0x000b */ - PACKB(0, 0), /* 0x000c */ - PACKB(0, 0), /* 0x000d */ - PACKB(1, 2), /* MBOX_CHECK_FIRMWARE */ - PACKB(0, 0), /* 0x000f */ - PACKB(5, 5), /* MBOX_INIT_REQ_QUEUE */ - PACKB(6, 6), /* MBOX_INIT_RES_QUEUE */ - PACKB(4, 4), /* MBOX_EXECUTE_IOCB */ - PACKB(2, 2), /* MBOX_WAKE_UP */ - PACKB(1, 6), /* MBOX_STOP_FIRMWARE */ - PACKB(4, 4), /* MBOX_ABORT */ - PACKB(2, 2), /* MBOX_ABORT_DEVICE */ - PACKB(3, 3), /* MBOX_ABORT_TARGET */ - PACKB(2, 2), /* MBOX_BUS_RESET */ - PACKB(2, 3), /* MBOX_STOP_QUEUE */ - PACKB(2, 3), /* MBOX_START_QUEUE */ - PACKB(2, 3), /* MBOX_SINGLE_STEP_QUEUE */ - PACKB(2, 3), /* MBOX_ABORT_QUEUE */ - PACKB(2, 4), /* MBOX_GET_DEV_QUEUE_STATUS */ - PACKB(0, 0), /* 0x001e */ - PACKB(1, 3), /* MBOX_GET_FIRMWARE_STATUS */ - PACKB(1, 2), /* MBOX_GET_INIT_SCSI_ID */ - PACKB(1, 2), /* MBOX_GET_SELECT_TIMEOUT */ - PACKB(1, 3), /* MBOX_GET_RETRY_COUNT */ - PACKB(1, 2), /* MBOX_GET_TAG_AGE_LIMIT */ - PACKB(1, 2), /* MBOX_GET_CLOCK_RATE */ - PACKB(1, 2), /* MBOX_GET_ACT_NEG_STATE */ - PACKB(1, 2), /* MBOX_GET_ASYNC_DATA_SETUP_TIME */ - PACKB(1, 3), /* MBOX_GET_PCI_PARAMS */ - PACKB(2, 4), /* MBOX_GET_TARGET_PARAMS */ - PACKB(2, 4), /* MBOX_GET_DEV_QUEUE_PARAMS */ - PACKB(0, 0), /* 0x002a */ - PACKB(0, 0), /* 0x002b */ - PACKB(0, 0), /* 0x002c */ - PACKB(0, 0), /* 0x002d */ - PACKB(0, 0), /* 0x002e */ - PACKB(0, 0), /* 0x002f */ - PACKB(2, 2), /* MBOX_SET_INIT_SCSI_ID */ - PACKB(2, 2), /* MBOX_SET_SELECT_TIMEOUT */ - PACKB(3, 3), /* MBOX_SET_RETRY_COUNT */ - PACKB(2, 2), /* MBOX_SET_TAG_AGE_LIMIT */ - PACKB(2, 2), /* MBOX_SET_CLOCK_RATE */ - PACKB(2, 2), /* MBOX_SET_ACTIVE_NEG_STATE */ - PACKB(2, 2), /* MBOX_SET_ASYNC_DATA_SETUP_TIME */ - PACKB(3, 3), /* MBOX_SET_PCI_CONTROL_PARAMS */ - PACKB(4, 4), /* MBOX_SET_TARGET_PARAMS */ - PACKB(4, 4), /* MBOX_SET_DEV_QUEUE_PARAMS */ - PACKB(0, 0), /* 0x003a */ - PACKB(0, 0), /* 0x003b */ - PACKB(0, 0), /* 0x003c */ - PACKB(0, 0), /* 0x003d */ - PACKB(0, 0), /* 0x003e */ - PACKB(0, 0), /* 0x003f */ - PACKB(1, 2), /* MBOX_RETURN_BIOS_BLOCK_ADDR */ - PACKB(6, 1), /* MBOX_WRITE_FOUR_RAM_WORDS */ - PACKB(2, 3) /* MBOX_EXEC_BIOS_IOCB */ -#ifdef CONFIG_QL_ISP_A64 - ,PACKB(0, 0), /* 0x0043 */ - PACKB(0, 0), /* 0x0044 */ - PACKB(0, 0), /* 0x0045 */ - PACKB(0, 0), /* 0x0046 */ - PACKB(0, 0), /* 0x0047 */ - PACKB(0, 0), /* 0x0048 */ - PACKB(0, 0), /* 0x0049 */ - PACKB(0, 0), /* 0x004a */ - PACKB(0, 0), /* 0x004b */ - PACKB(0, 0), /* 0x004c */ - PACKB(0, 0), /* 0x004d */ - PACKB(0, 0), /* 0x004e */ - PACKB(0, 0), /* 0x004f */ - PACKB(0, 0), /* 0x0050 */ - PACKB(0, 0), /* 0x0051 */ - PACKB(8, 8), /* MBOX_CMD_INIT_REQUEST_QUEUE_64 (0x0052) */ - PACKB(8, 8) /* MBOX_CMD_INIT_RESPONSE_QUEUE_64 (0x0053) */ -#endif /* CONFIG_QL_ISP_A64 */ -}; - -#define MAX_MBOX_COMMAND (sizeof(mbox_param)/sizeof(u_short)) - -struct host_param { - u_short fifo_threshold; - u_short host_adapter_enable; - u_short initiator_scsi_id; - u_short bus_reset_delay; - u_short retry_count; - u_short retry_delay; - u_short async_data_setup_time; - u_short req_ack_active_negation; - u_short data_line_active_negation; - u_short data_dma_burst_enable; - u_short command_dma_burst_enable; - u_short tag_aging; - u_short selection_timeout; - u_short max_queue_depth; -}; - -/* - * Device Flags: - * - * Bit Name - * --------- - * 7 Disconnect Privilege - * 6 Parity Checking - * 5 Wide Data Transfers - * 4 Synchronous Data Transfers - * 3 Tagged Queuing - * 2 Automatic Request Sense - * 1 Stop Queue on Check Condition - * 0 Renegotiate on Error - */ - -struct dev_param { - u_short device_flags; - u_short execution_throttle; - u_short synchronous_period; - u_short synchronous_offset; - u_short device_enable; - u_short reserved; /* pad */ -}; - -/* - * The result queue can be quite a bit smaller since continuation entries - * do not show up there: - */ -#define RES_QUEUE_LEN ((QLOGICISP_REQ_QUEUE_LEN + 1) / 8 - 1) -#define QUEUE_ENTRY_LEN 64 -#define QSIZE(entries) (((entries) + 1) * QUEUE_ENTRY_LEN) - -struct isp_queue_entry { - char __opaque[QUEUE_ENTRY_LEN]; -}; - -struct isp1020_hostdata { - void __iomem *memaddr; - u_char revision; - struct host_param host_param; - struct dev_param dev_param[MAX_TARGETS]; - struct pci_dev *pci_dev; - - struct isp_queue_entry *res_cpu; /* CPU-side address of response queue. */ - struct isp_queue_entry *req_cpu; /* CPU-size address of request queue. */ - - /* result and request queues (shared with isp1020): */ - u_int req_in_ptr; /* index of next request slot */ - u_int res_out_ptr; /* index of next result slot */ - - /* this is here so the queues are nicely aligned */ - long send_marker; /* do we need to send a marker? */ - - /* The cmd->handle has a fixed size, and is only 32-bits. We - * need to take care to handle 64-bit systems correctly thus what - * we actually place in cmd->handle is an index to the following - * table. Kudos to Matt Jacob for the technique. -DaveM - */ - Scsi_Cmnd *cmd_slots[QLOGICISP_REQ_QUEUE_LEN + 1]; - - dma_addr_t res_dma; /* PCI side view of response queue */ - dma_addr_t req_dma; /* PCI side view of request queue */ -}; - -/* queue length's _must_ be power of two: */ -#define QUEUE_DEPTH(in, out, ql) ((in - out) & (ql)) -#define REQ_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, \ - QLOGICISP_REQ_QUEUE_LEN) -#define RES_QUEUE_DEPTH(in, out) QUEUE_DEPTH(in, out, RES_QUEUE_LEN) - -static void isp1020_enable_irqs(struct Scsi_Host *); -static void isp1020_disable_irqs(struct Scsi_Host *); -static int isp1020_init(struct Scsi_Host *); -static int isp1020_reset_hardware(struct Scsi_Host *); -static int isp1020_set_defaults(struct Scsi_Host *); -static int isp1020_load_parameters(struct Scsi_Host *); -static int isp1020_mbox_command(struct Scsi_Host *, u_short []); -static int isp1020_return_status(struct Status_Entry *); -static void isp1020_intr_handler(int, void *, struct pt_regs *); -static irqreturn_t do_isp1020_intr_handler(int, void *, struct pt_regs *); - -#if USE_NVRAM_DEFAULTS -static int isp1020_get_defaults(struct Scsi_Host *); -static int isp1020_verify_nvram(struct Scsi_Host *); -static u_short isp1020_read_nvram_word(struct Scsi_Host *, u_short); -#endif - -#if DEBUG_ISP1020 -static void isp1020_print_scsi_cmd(Scsi_Cmnd *); -#endif -#if DEBUG_ISP1020_INTR -static void isp1020_print_status_entry(struct Status_Entry *); -#endif - -/* memaddr should be used to determine if memmapped port i/o is being used - * non-null memaddr == mmap'd - * JV 7-Jan-2000 - */ -static inline u_short isp_inw(struct Scsi_Host *host, long offset) -{ - struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata; - if (h->memaddr) - return readw(h->memaddr + offset); - else - return inw(host->io_port + offset); -} - -static inline void isp_outw(u_short val, struct Scsi_Host *host, long offset) -{ - struct isp1020_hostdata *h = (struct isp1020_hostdata *)host->hostdata; - if (h->memaddr) - writew(val, h->memaddr + offset); - else - outw(val, host->io_port + offset); -} - -static inline void isp1020_enable_irqs(struct Scsi_Host *host) -{ - isp_outw(ISP_EN_INT|ISP_EN_RISC, host, PCI_INTF_CTL); -} - - -static inline void isp1020_disable_irqs(struct Scsi_Host *host) -{ - isp_outw(0x0, host, PCI_INTF_CTL); -} - - -static int isp1020_detect(Scsi_Host_Template *tmpt) -{ - int hosts = 0; - struct Scsi_Host *host; - struct isp1020_hostdata *hostdata; - struct pci_dev *pdev = NULL; - - ENTER("isp1020_detect"); - - tmpt->proc_name = "isp1020"; - - while ((pdev = pci_find_device(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, pdev))) - { - if (pci_enable_device(pdev)) - continue; - - host = scsi_register(tmpt, sizeof(struct isp1020_hostdata)); - if (!host) - continue; - - hostdata = (struct isp1020_hostdata *) host->hostdata; - - memset(hostdata, 0, sizeof(struct isp1020_hostdata)); - - hostdata->pci_dev = pdev; - - if (isp1020_init(host)) - goto fail_and_unregister; - - if (isp1020_reset_hardware(host) -#if USE_NVRAM_DEFAULTS - || isp1020_get_defaults(host) -#else - || isp1020_set_defaults(host) -#endif /* USE_NVRAM_DEFAULTS */ - || isp1020_load_parameters(host)) { - goto fail_uninit; - } - - host->this_id = hostdata->host_param.initiator_scsi_id; - host->max_sectors = 64; - - if (request_irq(host->irq, do_isp1020_intr_handler, SA_INTERRUPT | SA_SHIRQ, - "qlogicisp", host)) - { - printk("qlogicisp : interrupt %d already in use\n", - host->irq); - goto fail_uninit; - } - - isp_outw(0x0, host, PCI_SEMAPHORE); - isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - isp1020_enable_irqs(host); - - hosts++; - continue; - - fail_uninit: - iounmap(hostdata->memaddr); - release_region(host->io_port, 0xff); - fail_and_unregister: - if (hostdata->res_cpu) - pci_free_consistent(hostdata->pci_dev, - QSIZE(RES_QUEUE_LEN), - hostdata->res_cpu, - hostdata->res_dma); - if (hostdata->req_cpu) - pci_free_consistent(hostdata->pci_dev, - QSIZE(QLOGICISP_REQ_QUEUE_LEN), - hostdata->req_cpu, - hostdata->req_dma); - scsi_unregister(host); - } - - LEAVE("isp1020_detect"); - - return hosts; -} - - -static int isp1020_release(struct Scsi_Host *host) -{ - struct isp1020_hostdata *hostdata; - - ENTER("isp1020_release"); - - hostdata = (struct isp1020_hostdata *) host->hostdata; - - isp_outw(0x0, host, PCI_INTF_CTL); - free_irq(host->irq, host); - - iounmap(hostdata->memaddr); - - release_region(host->io_port, 0xff); - - LEAVE("isp1020_release"); - - return 0; -} - - -static const char *isp1020_info(struct Scsi_Host *host) -{ - static char buf[80]; - struct isp1020_hostdata *hostdata; - - ENTER("isp1020_info"); - - hostdata = (struct isp1020_hostdata *) host->hostdata; - sprintf(buf, - "QLogic ISP1020 SCSI on PCI bus %02x device %02x irq %d %s base 0x%lx", - hostdata->pci_dev->bus->number, hostdata->pci_dev->devfn, host->irq, - (hostdata->memaddr ? "MEM" : "I/O"), - (hostdata->memaddr ? (unsigned long)hostdata->memaddr : host->io_port)); - - LEAVE("isp1020_info"); - - return buf; -} - - -/* - * The middle SCSI layer ensures that queuecommand never gets invoked - * concurrently with itself or the interrupt handler (though the - * interrupt handler may call this routine as part of - * request-completion handling). - */ -static int isp1020_queuecommand(Scsi_Cmnd *Cmnd, void (*done)(Scsi_Cmnd *)) -{ - int i, n, num_free; - u_int in_ptr, out_ptr; - struct dataseg * ds; - struct scatterlist *sg; - struct Command_Entry *cmd; - struct Continuation_Entry *cont; - struct Scsi_Host *host; - struct isp1020_hostdata *hostdata; - dma_addr_t dma_addr; - - ENTER("isp1020_queuecommand"); - - host = Cmnd->device->host; - hostdata = (struct isp1020_hostdata *) host->hostdata; - Cmnd->scsi_done = done; - - DEBUG(isp1020_print_scsi_cmd(Cmnd)); - - out_ptr = isp_inw(host, + MBOX4); - in_ptr = hostdata->req_in_ptr; - - DEBUG(printk("qlogicisp : request queue depth %d\n", - REQ_QUEUE_DEPTH(in_ptr, out_ptr))); - - cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr]; - in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; - if (in_ptr == out_ptr) { - printk("qlogicisp : request queue overflow\n"); - return 1; - } - - if (hostdata->send_marker) { - struct Marker_Entry *marker; - - TRACE("queue marker", in_ptr, 0); - - DEBUG(printk("qlogicisp : adding marker entry\n")); - marker = (struct Marker_Entry *) cmd; - memset(marker, 0, sizeof(struct Marker_Entry)); - - marker->hdr.entry_type = ENTRY_MARKER; - marker->hdr.entry_cnt = 1; - marker->modifier = SYNC_ALL; - - hostdata->send_marker = 0; - - if (((in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN) == out_ptr) { - isp_outw(in_ptr, host, MBOX4); - hostdata->req_in_ptr = in_ptr; - printk("qlogicisp : request queue overflow\n"); - return 1; - } - cmd = (struct Command_Entry *) &hostdata->req_cpu[in_ptr]; - in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; - } - - TRACE("queue command", in_ptr, Cmnd); - - memset(cmd, 0, sizeof(struct Command_Entry)); - - cmd->hdr.entry_type = ENTRY_COMMAND; - cmd->hdr.entry_cnt = 1; - - cmd->target_lun = Cmnd->device->lun; - cmd->target_id = Cmnd->device->id; - cmd->cdb_length = cpu_to_le16(Cmnd->cmd_len); - cmd->control_flags = cpu_to_le16(CFLAG_READ | CFLAG_WRITE); - cmd->time_out = cpu_to_le16(30); - - memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len); - - if (Cmnd->use_sg) { - int sg_count; - - sg = (struct scatterlist *) Cmnd->request_buffer; - ds = cmd->dataseg; - - sg_count = pci_map_sg(hostdata->pci_dev, sg, Cmnd->use_sg, - Cmnd->sc_data_direction); - - cmd->segment_cnt = cpu_to_le16(sg_count); - - /* fill in first four sg entries: */ - n = sg_count; - if (n > IOCB_SEGS) - n = IOCB_SEGS; - for (i = 0; i < n; i++) { - dma_addr = sg_dma_address(sg); - ds[i].d_base = cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 - ds[i].d_base_hi = cpu_to_le32((u32) (dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ - ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); - ++sg; - } - sg_count -= IOCB_SEGS; - - while (sg_count > 0) { - ++cmd->hdr.entry_cnt; - cont = (struct Continuation_Entry *) - &hostdata->req_cpu[in_ptr]; - in_ptr = (in_ptr + 1) & QLOGICISP_REQ_QUEUE_LEN; - if (in_ptr == out_ptr) { - printk("isp1020: unexpected request queue " - "overflow\n"); - return 1; - } - TRACE("queue continuation", in_ptr, 0); - cont->hdr.entry_type = ENTRY_CONTINUATION; - cont->hdr.entry_cnt = 0; - cont->hdr.sys_def_1 = 0; - cont->hdr.flags = 0; -#ifndef CONFIG_QL_ISP_A64 - cont->reserved = 0; -#endif - ds = cont->dataseg; - n = sg_count; - if (n > CONTINUATION_SEGS) - n = CONTINUATION_SEGS; - for (i = 0; i < n; ++i) { - dma_addr = sg_dma_address(sg); - ds[i].d_base = cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 - ds[i].d_base_hi = cpu_to_le32((u32)(dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ - ds[i].d_count = cpu_to_le32(sg_dma_len(sg)); - ++sg; - } - sg_count -= n; - } - } else if (Cmnd->request_bufflen) { - /*Cmnd->SCp.ptr = (char *)(unsigned long)*/ - dma_addr = pci_map_single(hostdata->pci_dev, - Cmnd->request_buffer, - Cmnd->request_bufflen, - Cmnd->sc_data_direction); - Cmnd->SCp.ptr = (char *)(unsigned long) dma_addr; - - cmd->dataseg[0].d_base = - cpu_to_le32((u32) dma_addr); -#ifdef CONFIG_QL_ISP_A64 - cmd->dataseg[0].d_base_hi = - cpu_to_le32((u32) (dma_addr>>32)); -#endif /* CONFIG_QL_ISP_A64 */ - cmd->dataseg[0].d_count = - cpu_to_le32((u32)Cmnd->request_bufflen); - cmd->segment_cnt = cpu_to_le16(1); - } else { - cmd->dataseg[0].d_base = 0; -#ifdef CONFIG_QL_ISP_A64 - cmd->dataseg[0].d_base_hi = 0; -#endif /* CONFIG_QL_ISP_A64 */ - cmd->dataseg[0].d_count = 0; - cmd->segment_cnt = cpu_to_le16(1); /* Shouldn't this be 0? */ - } - - /* Committed, record Scsi_Cmd so we can find it later. */ - cmd->handle = in_ptr; - hostdata->cmd_slots[in_ptr] = Cmnd; - - isp_outw(in_ptr, host, MBOX4); - hostdata->req_in_ptr = in_ptr; - - num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr); - host->can_queue = host->host_busy + num_free; - host->sg_tablesize = QLOGICISP_MAX_SG(num_free); - - LEAVE("isp1020_queuecommand"); - - return 0; -} - - -#define ASYNC_EVENT_INTERRUPT 0x01 - -irqreturn_t do_isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - struct Scsi_Host *host = dev_id; - unsigned long flags; - - spin_lock_irqsave(host->host_lock, flags); - isp1020_intr_handler(irq, dev_id, regs); - spin_unlock_irqrestore(host->host_lock, flags); - - return IRQ_HANDLED; -} - -void isp1020_intr_handler(int irq, void *dev_id, struct pt_regs *regs) -{ - Scsi_Cmnd *Cmnd; - struct Status_Entry *sts; - struct Scsi_Host *host = dev_id; - struct isp1020_hostdata *hostdata; - u_int in_ptr, out_ptr; - u_short status; - - ENTER_INTR("isp1020_intr_handler"); - - hostdata = (struct isp1020_hostdata *) host->hostdata; - - DEBUG_INTR(printk("qlogicisp : interrupt on line %d\n", irq)); - - if (!(isp_inw(host, PCI_INTF_STS) & 0x04)) { - /* spurious interrupts can happen legally */ - DEBUG_INTR(printk("qlogicisp: got spurious interrupt\n")); - return; - } - in_ptr = isp_inw(host, MBOX5); - isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - - if ((isp_inw(host, PCI_SEMAPHORE) & ASYNC_EVENT_INTERRUPT)) { - status = isp_inw(host, MBOX0); - - DEBUG_INTR(printk("qlogicisp : mbox completion status: %x\n", - status)); - - switch (status) { - case ASYNC_SCSI_BUS_RESET: - case EXECUTION_TIMEOUT_RESET: - hostdata->send_marker = 1; - break; - case INVALID_COMMAND: - case HOST_INTERFACE_ERROR: - case COMMAND_ERROR: - case COMMAND_PARAM_ERROR: - printk("qlogicisp : bad mailbox return status\n"); - break; - } - isp_outw(0x0, host, PCI_SEMAPHORE); - } - out_ptr = hostdata->res_out_ptr; - - DEBUG_INTR(printk("qlogicisp : response queue update\n")); - DEBUG_INTR(printk("qlogicisp : response queue depth %d\n", - QUEUE_DEPTH(in_ptr, out_ptr, RES_QUEUE_LEN))); - - while (out_ptr != in_ptr) { - u_int cmd_slot; - - sts = (struct Status_Entry *) &hostdata->res_cpu[out_ptr]; - out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; - - cmd_slot = sts->handle; - Cmnd = hostdata->cmd_slots[cmd_slot]; - hostdata->cmd_slots[cmd_slot] = NULL; - - TRACE("done", out_ptr, Cmnd); - - if (le16_to_cpu(sts->completion_status) == CS_RESET_OCCURRED - || le16_to_cpu(sts->completion_status) == CS_ABORTED - || (le16_to_cpu(sts->status_flags) & STF_BUS_RESET)) - hostdata->send_marker = 1; - - if (le16_to_cpu(sts->state_flags) & SF_GOT_SENSE) - memcpy(Cmnd->sense_buffer, sts->req_sense_data, - sizeof(Cmnd->sense_buffer)); - - DEBUG_INTR(isp1020_print_status_entry(sts)); - - if (sts->hdr.entry_type == ENTRY_STATUS) - Cmnd->result = isp1020_return_status(sts); - else - Cmnd->result = DID_ERROR << 16; - - if (Cmnd->use_sg) - pci_unmap_sg(hostdata->pci_dev, - (struct scatterlist *)Cmnd->buffer, - Cmnd->use_sg, - Cmnd->sc_data_direction); - else if (Cmnd->request_bufflen) - pci_unmap_single(hostdata->pci_dev, -#ifdef CONFIG_QL_ISP_A64 - (dma_addr_t)((long)Cmnd->SCp.ptr), -#else - (u32)((long)Cmnd->SCp.ptr), -#endif - Cmnd->request_bufflen, - Cmnd->sc_data_direction); - - isp_outw(out_ptr, host, MBOX5); - (*Cmnd->scsi_done)(Cmnd); - } - hostdata->res_out_ptr = out_ptr; - - LEAVE_INTR("isp1020_intr_handler"); -} - - -static int isp1020_return_status(struct Status_Entry *sts) -{ - int host_status = DID_ERROR; -#if DEBUG_ISP1020_INTR - static char *reason[] = { - "DID_OK", - "DID_NO_CONNECT", - "DID_BUS_BUSY", - "DID_TIME_OUT", - "DID_BAD_TARGET", - "DID_ABORT", - "DID_PARITY", - "DID_ERROR", - "DID_RESET", - "DID_BAD_INTR" - }; -#endif /* DEBUG_ISP1020_INTR */ - - ENTER("isp1020_return_status"); - - DEBUG(printk("qlogicisp : completion status = 0x%04x\n", - le16_to_cpu(sts->completion_status))); - - switch(le16_to_cpu(sts->completion_status)) { - case CS_COMPLETE: - host_status = DID_OK; - break; - case CS_INCOMPLETE: - if (!(le16_to_cpu(sts->state_flags) & SF_GOT_BUS)) - host_status = DID_NO_CONNECT; - else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_TARGET)) - host_status = DID_BAD_TARGET; - else if (!(le16_to_cpu(sts->state_flags) & SF_SENT_CDB)) - host_status = DID_ERROR; - else if (!(le16_to_cpu(sts->state_flags) & SF_TRANSFERRED_DATA)) - host_status = DID_ERROR; - else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_STATUS)) - host_status = DID_ERROR; - else if (!(le16_to_cpu(sts->state_flags) & SF_GOT_SENSE)) - host_status = DID_ERROR; - break; - case CS_DMA_ERROR: - case CS_TRANSPORT_ERROR: - host_status = DID_ERROR; - break; - case CS_RESET_OCCURRED: - host_status = DID_RESET; - break; - case CS_ABORTED: - host_status = DID_ABORT; - break; - case CS_TIMEOUT: - host_status = DID_TIME_OUT; - break; - case CS_DATA_OVERRUN: - case CS_COMMAND_OVERRUN: - case CS_STATUS_OVERRUN: - case CS_BAD_MESSAGE: - case CS_NO_MESSAGE_OUT: - case CS_EXT_ID_FAILED: - case CS_IDE_MSG_FAILED: - case CS_ABORT_MSG_FAILED: - case CS_NOP_MSG_FAILED: - case CS_PARITY_ERROR_MSG_FAILED: - case CS_DEVICE_RESET_MSG_FAILED: - case CS_ID_MSG_FAILED: - case CS_UNEXP_BUS_FREE: - host_status = DID_ERROR; - break; - case CS_DATA_UNDERRUN: - host_status = DID_OK; - break; - default: - printk("qlogicisp : unknown completion status 0x%04x\n", - le16_to_cpu(sts->completion_status)); - host_status = DID_ERROR; - break; - } - - DEBUG_INTR(printk("qlogicisp : host status (%s) scsi status %x\n", - reason[host_status], le16_to_cpu(sts->scsi_status))); - - LEAVE("isp1020_return_status"); - - return (le16_to_cpu(sts->scsi_status) & STATUS_MASK) | (host_status << 16); -} - - -static int isp1020_biosparam(struct scsi_device *sdev, struct block_device *n, - sector_t capacity, int ip[]) -{ - int size = capacity; - - ENTER("isp1020_biosparam"); - - ip[0] = 64; - ip[1] = 32; - ip[2] = size >> 11; - if (ip[2] > 1024) { - ip[0] = 255; - ip[1] = 63; - ip[2] = size / (ip[0] * ip[1]); -#if 0 - if (ip[2] > 1023) - ip[2] = 1023; -#endif - } - - LEAVE("isp1020_biosparam"); - - return 0; -} - - -static int isp1020_reset_hardware(struct Scsi_Host *host) -{ - u_short param[6]; - int loop_count; - - ENTER("isp1020_reset_hardware"); - - isp_outw(ISP_RESET, host, PCI_INTF_CTL); - udelay(100); - isp_outw(HCCR_RESET, host, HOST_HCCR); - udelay(100); - isp_outw(HCCR_RELEASE, host, HOST_HCCR); - isp_outw(HCCR_BIOS_DISABLE, host, HOST_HCCR); - - loop_count = DEFAULT_LOOP_COUNT; - while (--loop_count && isp_inw(host, HOST_HCCR) == RISC_BUSY) { - barrier(); - cpu_relax(); - } - if (!loop_count) - printk("qlogicisp: reset_hardware loop timeout\n"); - - isp_outw(0, host, ISP_CFG1); - -#if DEBUG_ISP1020 - printk("qlogicisp : mbox 0 0x%04x \n", isp_inw(host, MBOX0)); - printk("qlogicisp : mbox 1 0x%04x \n", isp_inw(host, MBOX1)); - printk("qlogicisp : mbox 2 0x%04x \n", isp_inw(host, MBOX2)); - printk("qlogicisp : mbox 3 0x%04x \n", isp_inw(host, MBOX3)); - printk("qlogicisp : mbox 4 0x%04x \n", isp_inw(host, MBOX4)); - printk("qlogicisp : mbox 5 0x%04x \n", isp_inw(host, MBOX5)); -#endif /* DEBUG_ISP1020 */ - - param[0] = MBOX_NO_OP; - isp1020_mbox_command(host, param); - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : NOP test failed\n"); - return 1; - } - - DEBUG(printk("qlogicisp : loading risc ram\n")); - -#if RELOAD_FIRMWARE - for (loop_count = 0; loop_count < risc_code_length01; loop_count++) { - param[0] = MBOX_WRITE_RAM_WORD; - param[1] = risc_code_addr01 + loop_count; - param[2] = risc_code01[loop_count]; - isp1020_mbox_command(host, param); - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : firmware load failure at %d\n", - loop_count); - return 1; - } - } -#endif /* RELOAD_FIRMWARE */ - - DEBUG(printk("qlogicisp : verifying checksum\n")); - - param[0] = MBOX_VERIFY_CHECKSUM; - param[1] = risc_code_addr01; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : ram checksum failure\n"); - return 1; - } - - DEBUG(printk("qlogicisp : executing firmware\n")); - - param[0] = MBOX_EXEC_FIRMWARE; - param[1] = risc_code_addr01; - - isp1020_mbox_command(host, param); - - param[0] = MBOX_ABOUT_FIRMWARE; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : about firmware failure\n"); - return 1; - } - - DEBUG(printk("qlogicisp : firmware major revision %d\n", param[1])); - DEBUG(printk("qlogicisp : firmware minor revision %d\n", param[2])); - - LEAVE("isp1020_reset_hardware"); - - return 0; -} - - -static int isp1020_init(struct Scsi_Host *sh) -{ - u_long io_base, mem_base, io_flags, mem_flags; - struct isp1020_hostdata *hostdata; - u_char revision; - u_int irq; - u_short command; - struct pci_dev *pdev; - - ENTER("isp1020_init"); - - hostdata = (struct isp1020_hostdata *) sh->hostdata; - pdev = hostdata->pci_dev; - - if (pci_read_config_word(pdev, PCI_COMMAND, &command) - || pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision)) - { - printk("qlogicisp : error reading PCI configuration\n"); - return 1; - } - - io_base = pci_resource_start(pdev, 0); - mem_base = pci_resource_start(pdev, 1); - io_flags = pci_resource_flags(pdev, 0); - mem_flags = pci_resource_flags(pdev, 1); - irq = pdev->irq; - - if (pdev->vendor != PCI_VENDOR_ID_QLOGIC) { - printk("qlogicisp : 0x%04x is not QLogic vendor ID\n", - pdev->vendor); - return 1; - } - - if (pdev->device != PCI_DEVICE_ID_QLOGIC_ISP1020) { - printk("qlogicisp : 0x%04x does not match ISP1020 device id\n", - pdev->device); - return 1; - } - -#ifdef __alpha__ - /* Force ALPHA to use bus I/O and not bus MEM. - This is to avoid having to use HAE_MEM registers, - which is broken on some platforms and with SMP. */ - command &= ~PCI_COMMAND_MEMORY; -#endif - - sh->io_port = io_base; - - if (!request_region(sh->io_port, 0xff, "qlogicisp")) { - printk("qlogicisp : i/o region 0x%lx-0x%lx already " - "in use\n", - sh->io_port, sh->io_port + 0xff); - return 1; - } - - if ((command & PCI_COMMAND_MEMORY) && - ((mem_flags & 1) == 0)) { - hostdata->memaddr = ioremap(mem_base, PAGE_SIZE); - if (!hostdata->memaddr) { - printk("qlogicisp : i/o remapping failed.\n"); - goto out_release; - } - } else { - if (command & PCI_COMMAND_IO && (io_flags & 3) != 1) { - printk("qlogicisp : i/o mapping is disabled\n"); - goto out_release; - } - hostdata->memaddr = NULL; /* zero to signify no i/o mapping */ - mem_base = 0; - } - - if (revision != ISP1020_REV_ID) - printk("qlogicisp : new isp1020 revision ID (%d)\n", revision); - - if (isp_inw(sh, PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC - || isp_inw(sh, PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020) - { - printk("qlogicisp : can't decode %s address space 0x%lx\n", - (io_base ? "I/O" : "MEM"), - (io_base ? io_base : mem_base)); - goto out_unmap; - } - - hostdata->revision = revision; - - sh->irq = irq; - sh->max_id = MAX_TARGETS; - sh->max_lun = MAX_LUNS; - - hostdata->res_cpu = pci_alloc_consistent(hostdata->pci_dev, - QSIZE(RES_QUEUE_LEN), - &hostdata->res_dma); - if (hostdata->res_cpu == NULL) { - printk("qlogicisp : can't allocate response queue\n"); - goto out_unmap; - } - - hostdata->req_cpu = pci_alloc_consistent(hostdata->pci_dev, - QSIZE(QLOGICISP_REQ_QUEUE_LEN), - &hostdata->req_dma); - if (hostdata->req_cpu == NULL) { - pci_free_consistent(hostdata->pci_dev, - QSIZE(RES_QUEUE_LEN), - hostdata->res_cpu, - hostdata->res_dma); - printk("qlogicisp : can't allocate request queue\n"); - goto out_unmap; - } - - pci_set_master(pdev); - - LEAVE("isp1020_init"); - - return 0; - -out_unmap: - iounmap(hostdata->memaddr); -out_release: - release_region(sh->io_port, 0xff); - return 1; -} - - -#if USE_NVRAM_DEFAULTS - -static int isp1020_get_defaults(struct Scsi_Host *host) -{ - int i; - u_short value; - struct isp1020_hostdata *hostdata = - (struct isp1020_hostdata *) host->hostdata; - - ENTER("isp1020_get_defaults"); - - if (!isp1020_verify_nvram(host)) { - printk("qlogicisp : nvram checksum failure\n"); - printk("qlogicisp : attempting to use default parameters\n"); - return isp1020_set_defaults(host); - } - - value = isp1020_read_nvram_word(host, 2); - hostdata->host_param.fifo_threshold = (value >> 8) & 0x03; - hostdata->host_param.host_adapter_enable = (value >> 11) & 0x01; - hostdata->host_param.initiator_scsi_id = (value >> 12) & 0x0f; - - value = isp1020_read_nvram_word(host, 3); - hostdata->host_param.bus_reset_delay = value & 0xff; - hostdata->host_param.retry_count = value >> 8; - - value = isp1020_read_nvram_word(host, 4); - hostdata->host_param.retry_delay = value & 0xff; - hostdata->host_param.async_data_setup_time = (value >> 8) & 0x0f; - hostdata->host_param.req_ack_active_negation = (value >> 12) & 0x01; - hostdata->host_param.data_line_active_negation = (value >> 13) & 0x01; - hostdata->host_param.data_dma_burst_enable = (value >> 14) & 0x01; - hostdata->host_param.command_dma_burst_enable = (value >> 15); - - value = isp1020_read_nvram_word(host, 5); - hostdata->host_param.tag_aging = value & 0xff; - - value = isp1020_read_nvram_word(host, 6); - hostdata->host_param.selection_timeout = value & 0xffff; - - value = isp1020_read_nvram_word(host, 7); - hostdata->host_param.max_queue_depth = value & 0xffff; - -#if DEBUG_ISP1020_SETUP - printk("qlogicisp : fifo threshold=%d\n", - hostdata->host_param.fifo_threshold); - printk("qlogicisp : initiator scsi id=%d\n", - hostdata->host_param.initiator_scsi_id); - printk("qlogicisp : bus reset delay=%d\n", - hostdata->host_param.bus_reset_delay); - printk("qlogicisp : retry count=%d\n", - hostdata->host_param.retry_count); - printk("qlogicisp : retry delay=%d\n", - hostdata->host_param.retry_delay); - printk("qlogicisp : async data setup time=%d\n", - hostdata->host_param.async_data_setup_time); - printk("qlogicisp : req/ack active negation=%d\n", - hostdata->host_param.req_ack_active_negation); - printk("qlogicisp : data line active negation=%d\n", - hostdata->host_param.data_line_active_negation); - printk("qlogicisp : data DMA burst enable=%d\n", - hostdata->host_param.data_dma_burst_enable); - printk("qlogicisp : command DMA burst enable=%d\n", - hostdata->host_param.command_dma_burst_enable); - printk("qlogicisp : tag age limit=%d\n", - hostdata->host_param.tag_aging); - printk("qlogicisp : selection timeout limit=%d\n", - hostdata->host_param.selection_timeout); - printk("qlogicisp : max queue depth=%d\n", - hostdata->host_param.max_queue_depth); -#endif /* DEBUG_ISP1020_SETUP */ - - for (i = 0; i < MAX_TARGETS; i++) { - - value = isp1020_read_nvram_word(host, 14 + i * 3); - hostdata->dev_param[i].device_flags = value & 0xff; - hostdata->dev_param[i].execution_throttle = value >> 8; - - value = isp1020_read_nvram_word(host, 15 + i * 3); - hostdata->dev_param[i].synchronous_period = value & 0xff; - hostdata->dev_param[i].synchronous_offset = (value >> 8) & 0x0f; - hostdata->dev_param[i].device_enable = (value >> 12) & 0x01; - -#if DEBUG_ISP1020_SETUP - printk("qlogicisp : target 0x%02x\n", i); - printk("qlogicisp : device flags=0x%02x\n", - hostdata->dev_param[i].device_flags); - printk("qlogicisp : execution throttle=%d\n", - hostdata->dev_param[i].execution_throttle); - printk("qlogicisp : synchronous period=%d\n", - hostdata->dev_param[i].synchronous_period); - printk("qlogicisp : synchronous offset=%d\n", - hostdata->dev_param[i].synchronous_offset); - printk("qlogicisp : device enable=%d\n", - hostdata->dev_param[i].device_enable); -#endif /* DEBUG_ISP1020_SETUP */ - } - - LEAVE("isp1020_get_defaults"); - - return 0; -} - - -#define ISP1020_NVRAM_LEN 0x40 -#define ISP1020_NVRAM_SIG1 0x5349 -#define ISP1020_NVRAM_SIG2 0x2050 - -static int isp1020_verify_nvram(struct Scsi_Host *host) -{ - int i; - u_short value; - u_char checksum = 0; - - for (i = 0; i < ISP1020_NVRAM_LEN; i++) { - value = isp1020_read_nvram_word(host, i); - - switch (i) { - case 0: - if (value != ISP1020_NVRAM_SIG1) return 0; - break; - case 1: - if (value != ISP1020_NVRAM_SIG2) return 0; - break; - case 2: - if ((value & 0xff) != 0x02) return 0; - break; - } - checksum += value & 0xff; - checksum += value >> 8; - } - - return (checksum == 0); -} - -#define NVRAM_DELAY() udelay(2) /* 2 microsecond delay */ - - -u_short isp1020_read_nvram_word(struct Scsi_Host *host, u_short byte) -{ - int i; - u_short value, output, input; - - byte &= 0x3f; byte |= 0x0180; - - for (i = 8; i >= 0; i--) { - output = ((byte >> i) & 0x1) ? 0x4 : 0x0; - isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); - isp_outw(output | 0x3, host, PCI_NVRAM); NVRAM_DELAY(); - isp_outw(output | 0x2, host, PCI_NVRAM); NVRAM_DELAY(); - } - - for (i = 0xf, value = 0; i >= 0; i--) { - value <<= 1; - isp_outw(0x3, host, PCI_NVRAM); NVRAM_DELAY(); - input = isp_inw(host, PCI_NVRAM); NVRAM_DELAY(); - isp_outw(0x2, host, PCI_NVRAM); NVRAM_DELAY(); - if (input & 0x8) value |= 1; - } - - isp_outw(0x0, host, PCI_NVRAM); NVRAM_DELAY(); - - return value; -} - -#endif /* USE_NVRAM_DEFAULTS */ - - -static int isp1020_set_defaults(struct Scsi_Host *host) -{ - struct isp1020_hostdata *hostdata = - (struct isp1020_hostdata *) host->hostdata; - int i; - - ENTER("isp1020_set_defaults"); - - hostdata->host_param.fifo_threshold = 2; - hostdata->host_param.host_adapter_enable = 1; - hostdata->host_param.initiator_scsi_id = 7; - hostdata->host_param.bus_reset_delay = 3; - hostdata->host_param.retry_count = 0; - hostdata->host_param.retry_delay = 1; - hostdata->host_param.async_data_setup_time = 6; - hostdata->host_param.req_ack_active_negation = 1; - hostdata->host_param.data_line_active_negation = 1; - hostdata->host_param.data_dma_burst_enable = 1; - hostdata->host_param.command_dma_burst_enable = 1; - hostdata->host_param.tag_aging = 8; - hostdata->host_param.selection_timeout = 250; - hostdata->host_param.max_queue_depth = 256; - - for (i = 0; i < MAX_TARGETS; i++) { - hostdata->dev_param[i].device_flags = 0xfd; - hostdata->dev_param[i].execution_throttle = 16; - hostdata->dev_param[i].synchronous_period = 25; - hostdata->dev_param[i].synchronous_offset = 12; - hostdata->dev_param[i].device_enable = 1; - } - - LEAVE("isp1020_set_defaults"); - - return 0; -} - - -static int isp1020_load_parameters(struct Scsi_Host *host) -{ - int i, k; -#ifdef CONFIG_QL_ISP_A64 - u_long queue_addr; - u_short param[8]; -#else - u_int queue_addr; - u_short param[6]; -#endif - u_short isp_cfg1, hwrev; - struct isp1020_hostdata *hostdata = - (struct isp1020_hostdata *) host->hostdata; - - ENTER("isp1020_load_parameters"); - - hwrev = isp_inw(host, ISP_CFG0) & ISP_CFG0_HWMSK; - isp_cfg1 = ISP_CFG1_F64 | ISP_CFG1_BENAB; - if (hwrev == ISP_CFG0_1040A) { - /* Busted fifo, says mjacob. */ - isp_cfg1 &= ISP_CFG1_BENAB; - } - - isp_outw(isp_inw(host, ISP_CFG1) | isp_cfg1, host, ISP_CFG1); - isp_outw(isp_inw(host, CDMA_CONF) | DMA_CONF_BENAB, host, CDMA_CONF); - isp_outw(isp_inw(host, DDMA_CONF) | DMA_CONF_BENAB, host, DDMA_CONF); - - param[0] = MBOX_SET_INIT_SCSI_ID; - param[1] = hostdata->host_param.initiator_scsi_id; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set initiator id failure\n"); - return 1; - } - - param[0] = MBOX_SET_RETRY_COUNT; - param[1] = hostdata->host_param.retry_count; - param[2] = hostdata->host_param.retry_delay; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set retry count failure\n"); - return 1; - } - - param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME; - param[1] = hostdata->host_param.async_data_setup_time; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : async data setup time failure\n"); - return 1; - } - - param[0] = MBOX_SET_ACTIVE_NEG_STATE; - param[1] = (hostdata->host_param.req_ack_active_negation << 4) - | (hostdata->host_param.data_line_active_negation << 5); - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set active negation state failure\n"); - return 1; - } - - param[0] = MBOX_SET_PCI_CONTROL_PARAMS; - param[1] = hostdata->host_param.data_dma_burst_enable << 1; - param[2] = hostdata->host_param.command_dma_burst_enable << 1; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set pci control parameter failure\n"); - return 1; - } - - param[0] = MBOX_SET_TAG_AGE_LIMIT; - param[1] = hostdata->host_param.tag_aging; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set tag age limit failure\n"); - return 1; - } - - param[0] = MBOX_SET_SELECT_TIMEOUT; - param[1] = hostdata->host_param.selection_timeout; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set selection timeout failure\n"); - return 1; - } - - for (i = 0; i < MAX_TARGETS; i++) { - - if (!hostdata->dev_param[i].device_enable) - continue; - - param[0] = MBOX_SET_TARGET_PARAMS; - param[1] = i << 8; - param[2] = hostdata->dev_param[i].device_flags << 8; - param[3] = (hostdata->dev_param[i].synchronous_offset << 8) - | hostdata->dev_param[i].synchronous_period; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set target parameter failure\n"); - return 1; - } - - for (k = 0; k < MAX_LUNS; k++) { - - param[0] = MBOX_SET_DEV_QUEUE_PARAMS; - param[1] = (i << 8) | k; - param[2] = hostdata->host_param.max_queue_depth; - param[3] = hostdata->dev_param[i].execution_throttle; - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set device queue " - "parameter failure\n"); - return 1; - } - } - } - - queue_addr = hostdata->res_dma; -#ifdef CONFIG_QL_ISP_A64 - param[0] = MBOX_CMD_INIT_RESPONSE_QUEUE_64; -#else - param[0] = MBOX_INIT_RES_QUEUE; -#endif - param[1] = RES_QUEUE_LEN + 1; - param[2] = (u_short) (queue_addr >> 16); - param[3] = (u_short) (queue_addr & 0xffff); - param[4] = 0; - param[5] = 0; -#ifdef CONFIG_QL_ISP_A64 - param[6] = (u_short) (queue_addr >> 48); - param[7] = (u_short) (queue_addr >> 32); -#endif - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set response queue failure\n"); - return 1; - } - - queue_addr = hostdata->req_dma; -#ifdef CONFIG_QL_ISP_A64 - param[0] = MBOX_CMD_INIT_REQUEST_QUEUE_64; -#else - param[0] = MBOX_INIT_REQ_QUEUE; -#endif - param[1] = QLOGICISP_REQ_QUEUE_LEN + 1; - param[2] = (u_short) (queue_addr >> 16); - param[3] = (u_short) (queue_addr & 0xffff); - param[4] = 0; - -#ifdef CONFIG_QL_ISP_A64 - param[5] = 0; - param[6] = (u_short) (queue_addr >> 48); - param[7] = (u_short) (queue_addr >> 32); -#endif - - isp1020_mbox_command(host, param); - - if (param[0] != MBOX_COMMAND_COMPLETE) { - printk("qlogicisp : set request queue failure\n"); - return 1; - } - - LEAVE("isp1020_load_parameters"); - - return 0; -} - - -/* - * currently, this is only called during initialization or abort/reset, - * at which times interrupts are disabled, so polling is OK, I guess... - */ -static int isp1020_mbox_command(struct Scsi_Host *host, u_short param[]) -{ - int loop_count; - - if (mbox_param[param[0]] == 0) - return 1; - - loop_count = DEFAULT_LOOP_COUNT; - while (--loop_count && isp_inw(host, HOST_HCCR) & 0x0080) { - barrier(); - cpu_relax(); - } - if (!loop_count) - printk("qlogicisp: mbox_command loop timeout #1\n"); - - switch(mbox_param[param[0]] >> 4) { - case 8: isp_outw(param[7], host, MBOX7); - case 7: isp_outw(param[6], host, MBOX6); - case 6: isp_outw(param[5], host, MBOX5); - case 5: isp_outw(param[4], host, MBOX4); - case 4: isp_outw(param[3], host, MBOX3); - case 3: isp_outw(param[2], host, MBOX2); - case 2: isp_outw(param[1], host, MBOX1); - case 1: isp_outw(param[0], host, MBOX0); - } - - isp_outw(0x0, host, PCI_SEMAPHORE); - isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - isp_outw(HCCR_SET_HOST_INTR, host, HOST_HCCR); - - loop_count = DEFAULT_LOOP_COUNT; - while (--loop_count && !(isp_inw(host, PCI_INTF_STS) & 0x04)) { - barrier(); - cpu_relax(); - } - if (!loop_count) - printk("qlogicisp: mbox_command loop timeout #2\n"); - - loop_count = DEFAULT_LOOP_COUNT; - while (--loop_count && isp_inw(host, MBOX0) == 0x04) { - barrier(); - cpu_relax(); - } - if (!loop_count) - printk("qlogicisp: mbox_command loop timeout #3\n"); - - switch(mbox_param[param[0]] & 0xf) { - case 8: param[7] = isp_inw(host, MBOX7); - case 7: param[6] = isp_inw(host, MBOX6); - case 6: param[5] = isp_inw(host, MBOX5); - case 5: param[4] = isp_inw(host, MBOX4); - case 4: param[3] = isp_inw(host, MBOX3); - case 3: param[2] = isp_inw(host, MBOX2); - case 2: param[1] = isp_inw(host, MBOX1); - case 1: param[0] = isp_inw(host, MBOX0); - } - - isp_outw(0x0, host, PCI_SEMAPHORE); - isp_outw(HCCR_CLEAR_RISC_INTR, host, HOST_HCCR); - - return 0; -} - - -#if DEBUG_ISP1020_INTR - -void isp1020_print_status_entry(struct Status_Entry *status) -{ - int i; - - printk("qlogicisp : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n", - status->hdr.entry_cnt, status->hdr.entry_type, status->hdr.flags); - printk("qlogicisp : scsi status = 0x%04x, completion status = 0x%04x\n", - le16_to_cpu(status->scsi_status), le16_to_cpu(status->completion_status)); - printk("qlogicisp : state flags = 0x%04x, status flags = 0x%04x\n", - le16_to_cpu(status->state_flags), le16_to_cpu(status->status_flags)); - printk("qlogicisp : time = 0x%04x, request sense length = 0x%04x\n", - le16_to_cpu(status->time), le16_to_cpu(status->req_sense_len)); - printk("qlogicisp : residual transfer length = 0x%08x\n", - le32_to_cpu(status->residual)); - - for (i = 0; i < le16_to_cpu(status->req_sense_len); i++) - printk("qlogicisp : sense data = 0x%02x\n", status->req_sense_data[i]); -} - -#endif /* DEBUG_ISP1020_INTR */ - - -#if DEBUG_ISP1020 - -void isp1020_print_scsi_cmd(Scsi_Cmnd *cmd) -{ - int i; - - printk("qlogicisp : target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n", - cmd->target, cmd->lun, cmd->cmd_len); - printk("qlogicisp : command = "); - for (i = 0; i < cmd->cmd_len; i++) - printk("0x%02x ", cmd->cmnd[i]); - printk("\n"); -} - -#endif /* DEBUG_ISP1020 */ - -MODULE_LICENSE("GPL"); - -static Scsi_Host_Template driver_template = { - .detect = isp1020_detect, - .release = isp1020_release, - .info = isp1020_info, - .queuecommand = isp1020_queuecommand, - .bios_param = isp1020_biosparam, - .can_queue = QLOGICISP_REQ_QUEUE_LEN, - .this_id = -1, - .sg_tablesize = QLOGICISP_MAX_SG(QLOGICISP_REQ_QUEUE_LEN), - .cmd_per_lun = 1, - .use_clustering = DISABLE_CLUSTERING, -}; -#include "scsi_module.c" diff --git a/drivers/scsi/qlogicisp_asm.c b/drivers/scsi/qlogicisp_asm.c deleted file mode 100644 index 9ea4bec..0000000 --- a/drivers/scsi/qlogicisp_asm.c +++ /dev/null @@ -1,2034 +0,0 @@ -/* - * Firmware Version 7.63.00 (12:07 Jan 27, 1999) - */ -static const unsigned short risc_code_version = 7*1024+63; - -static const unsigned short risc_code_addr01 = 0x1000 ; - -#if RELOAD_FIRMWARE - -static const unsigned short risc_code01[] = { - 0x0078, 0x103a, 0x0000, 0x3f14, 0x0000, 0x2043, 0x4f50, 0x5952, - 0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943, - 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350, - 0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172, - 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3633, - 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, - 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, - 0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048, - 0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9, - 0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071, - 0x0010, 0x70c3, 0x0004, 0x20c9, 0x76ff, 0x2089, 0x1186, 0x70c7, - 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00, - 0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100, - 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc, - 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040, - 0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1, - 0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1, - 0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc, - 0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040, - 0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134, - 0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078, - 0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b, - 0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a, - 0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a, - 0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5000, 0x8424, - 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7700, 0x2009, - 0x0000, 0x2001, 0x0031, 0x1078, 0x1c9d, 0x2218, 0x2079, 0x5000, - 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, - 0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883, - 0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f, - 0x0002, 0x784f, 0x0003, 0x2069, 0x5040, 0x2001, 0x04fd, 0x2004, - 0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108, - 0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c, - 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008, - 0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008, - 0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5280, 0x2011, 0x0020, - 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00, - 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, - 0x8109, 0x00c0, 0x1122, 0x2069, 0x5300, 0x2009, 0x0002, 0x20a9, - 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff, - 0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c, - 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152, - 0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x21e9, 0x1078, - 0x46e9, 0x1078, 0x1946, 0x1078, 0x4bdf, 0x3200, 0xa085, 0x000d, - 0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002, - 0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005, - 0x00c0, 0x117a, 0x1078, 0x1cc6, 0x0010, 0x1180, 0x0068, 0x1180, - 0x1078, 0x20c8, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a2b, - 0x00e0, 0x116c, 0x1078, 0x4a66, 0x0078, 0x116c, 0x118e, 0x1190, - 0x23ea, 0x23ea, 0x476a, 0x476a, 0x23ea, 0x23ea, 0x0078, 0x118e, - 0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201, - 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814, - 0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009, - 0x505b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5064, 0x200b, - 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009, - 0x5062, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca, - 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce, - 0x1078, 0x192b, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0, - 0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5062, 0x2104, - 0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1996, - 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007, - 0x0103, 0x1078, 0x1907, 0x00c0, 0x11fb, 0x1078, 0x192b, 0x2009, - 0x5062, 0x200b, 0x0000, 0x2009, 0x505c, 0x2104, 0x200b, 0x0000, - 0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078, - 0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000, - 0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038, - 0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313, - 0x12a0, 0x1748, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3, - 0x174d, 0x1298, 0x1329, 0x1360, 0x1672, 0x1742, 0x12b5, 0x1591, - 0x15ad, 0x15c9, 0x15f4, 0x154a, 0x1558, 0x156c, 0x1580, 0x13df, - 0x1298, 0x138d, 0x1393, 0x1398, 0x139d, 0x13a3, 0x13a8, 0x13ad, - 0x13b2, 0x13b7, 0x13bb, 0x13d0, 0x13dc, 0x1298, 0x1298, 0x1298, - 0x1298, 0x13eb, 0x13f4, 0x1403, 0x1429, 0x1433, 0x143a, 0x1480, - 0x148f, 0x149e, 0x14b0, 0x152a, 0x153a, 0x1298, 0x1298, 0x1298, - 0x1298, 0x153f, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084, - 0x001f, 0x0079, 0x125b, 0x1786, 0x1789, 0x1799, 0x1298, 0x1298, - 0x18d8, 0x18f5, 0x1298, 0x1298, 0x1298, 0x18f9, 0x1901, 0x1298, - 0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668, - 0x1764, 0x1778, 0x1298, 0x1829, 0x1298, 0x18b4, 0x18be, 0x18c2, - 0x18d0, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, - 0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, - 0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0, - 0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c, - 0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287, - 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, - 0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078, - 0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3, - 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, - 0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031, - 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061, - 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091, - 0x4080, 0x0078, 0x0455, 0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520, - 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a70, 0x0040, 0x1284, - 0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b36, 0x00c0, 0x129c, - 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000, - 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1ad0, 0x0040, - 0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114, - 0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7, - 0x0007, 0x70cb, 0x003f, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078, - 0x1b36, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, - 0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, - 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1350, 0x8001, - 0x7892, 0xa084, 0xfc00, 0x0040, 0x1345, 0x78cc, 0xa085, 0x0001, - 0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2, - 0x7ea6, 0x7c96, 0x78cc, 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1354, - 0x78cc, 0xa085, 0x0001, 0x78ce, 0x0078, 0x1284, 0x1078, 0x1b36, - 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x1363, - 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, - 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1387, 0x8001, 0x78ae, - 0xa084, 0xfc00, 0x0040, 0x137c, 0x78cc, 0xa085, 0x0100, 0x78ce, - 0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba, 0x7dbe, 0x7ec2, - 0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078, 0x138b, 0x78cc, - 0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009, 0x5061, 0x210c, - 0x7aec, 0x0078, 0x1282, 0x2009, 0x5041, 0x210c, 0x0078, 0x1283, - 0x2009, 0x5042, 0x210c, 0x0078, 0x1283, 0x2061, 0x5040, 0x610c, - 0x6210, 0x0078, 0x1282, 0x2009, 0x5045, 0x210c, 0x0078, 0x1283, - 0x2009, 0x5046, 0x210c, 0x0078, 0x1283, 0x2009, 0x5048, 0x210c, - 0x0078, 0x1283, 0x2009, 0x5049, 0x210c, 0x0078, 0x1283, 0x7908, - 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, - 0x8003, 0x8003, 0xa0e8, 0x5280, 0x6a00, 0x6804, 0xa084, 0x0008, - 0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281, - 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, - 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4, - 0x1078, 0x1956, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091, - 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c, - 0x1078, 0x22c1, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, - 0x127c, 0x2011, 0x5041, 0x2204, 0x007e, 0x2112, 0x1078, 0x227a, - 0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008, - 0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078, - 0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5042, - 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2286, 0x017f, 0x0078, - 0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, - 0x004b, 0x2061, 0x5040, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8, - 0x6012, 0x0078, 0x1282, 0x2061, 0x5040, 0x6114, 0x70c4, 0x6016, - 0x0078, 0x1283, 0x2061, 0x5040, 0x71c4, 0x2011, 0x0004, 0x601f, - 0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x145b, 0x2011, - 0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040, - 0x145b, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186, - 0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084, - 0x0001, 0x00c0, 0x1476, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, - 0x0048, 0x146e, 0x0038, 0x1472, 0x0078, 0x1476, 0x0028, 0x1472, - 0x0078, 0x1476, 0x2019, 0x2222, 0x0078, 0x1478, 0x2019, 0x1212, - 0x23b8, 0x1078, 0x2297, 0x1078, 0x4bdf, 0x017f, 0x0078, 0x1283, - 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5048, 0x2204, - 0x2112, 0x007e, 0x1078, 0x22b9, 0x017f, 0x0078, 0x1283, 0x71c4, - 0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5049, 0x2204, 0x007e, - 0x2112, 0x1078, 0x22a8, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8, - 0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b, - 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282, - 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, - 0x5280, 0x2019, 0x0000, 0x72c8, 0xa284, 0x0080, 0x0040, 0x14c6, - 0x6c14, 0x84ff, 0x00c0, 0x14c6, 0x6817, 0x0040, 0xa284, 0x0040, - 0x0040, 0x14d0, 0x6c10, 0x84ff, 0x00c0, 0x14d0, 0x6813, 0x0001, - 0x6800, 0x007e, 0xa226, 0x0040, 0x14f3, 0x6a02, 0xa484, 0x2000, - 0x0040, 0x14dc, 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x14e2, - 0xa39d, 0x0008, 0xa484, 0x4000, 0x0040, 0x14f3, 0x810f, 0xa284, - 0x4000, 0x0040, 0x14ef, 0x1078, 0x22db, 0x0078, 0x14f3, 0x1078, - 0x22cd, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522, - 0xa2a4, 0x00ff, 0x2061, 0x5040, 0x6118, 0xa186, 0x0028, 0x0040, - 0x1509, 0xa186, 0x0032, 0x0040, 0x150f, 0xa186, 0x003c, 0x0040, - 0x1515, 0xa482, 0x0064, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, - 0x0050, 0x0048, 0x151f, 0x0078, 0x1519, 0xa482, 0x0043, 0x0048, - 0x151f, 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a, - 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, - 0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a14, - 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, - 0x0078, 0x1281, 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4, - 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x22e9, - 0x0078, 0x1281, 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08, - 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, - 0x77c4, 0x1078, 0x1956, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, - 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21b1, 0x2091, - 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1956, 0x2091, - 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, - 0x157b, 0x1078, 0x21b1, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, - 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, - 0x8000, 0x1078, 0x1963, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, - 0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, - 0x19c4, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708, - 0x1078, 0x22f9, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001, - 0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041, - 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, - 0x1963, 0x2061, 0x5040, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, - 0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21b1, 0x2091, 0x8001, - 0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, - 0x8000, 0x2061, 0x5040, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, - 0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21b1, 0x2091, 0x8001, - 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, - 0x1078, 0x1963, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, - 0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, - 0x0008, 0x1078, 0x1956, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a, - 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1601, 0xa7bc, - 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1601, - 0x2091, 0x8000, 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040, - 0x1641, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, - 0x0040, 0x162e, 0x0070, 0x162e, 0x0078, 0x1625, 0x684b, 0x0009, - 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x163b, 0x0070, - 0x163b, 0x0078, 0x1632, 0x20a9, 0x00fa, 0x0070, 0x1641, 0x0078, - 0x163d, 0x2079, 0x5000, 0x7817, 0x0018, 0x2061, 0x5040, 0x606f, - 0x0001, 0x6073, 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002, - 0x78ce, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091, - 0x8001, 0x007c, 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001, - 0x00c0, 0x1664, 0x1078, 0x1a0e, 0x71c4, 0x71c6, 0x794a, 0x007c, - 0x1078, 0x1b36, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de, - 0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, - 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078, - 0x1911, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1, - 0x5018, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020, - 0x1078, 0x190c, 0x0040, 0x1698, 0x1078, 0x192b, 0x0078, 0x172c, - 0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e, - 0x2c68, 0x2091, 0x8000, 0x1078, 0x1911, 0x2091, 0x8001, 0x0040, - 0x16cc, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x16a0, 0x609f, 0x0000, - 0x0c7f, 0x0c7e, 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c, - 0xa065, 0x0040, 0x16fa, 0x2009, 0x0020, 0x1078, 0x190c, 0x00c0, - 0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc, - 0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060, - 0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, - 0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1907, 0x1078, - 0x192b, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, - 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, - 0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1907, 0x1078, 0x192b, - 0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, - 0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5040, 0x706f, 0x0005, - 0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000, - 0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2, - 0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x467f, 0x0e7f, 0x6596, - 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078, - 0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, - 0x20a9, 0x0005, 0x2099, 0x5018, 0x2091, 0x8000, 0x530a, 0x2091, - 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, - 0x0000, 0x007c, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284, - 0x71c4, 0x71c6, 0x2168, 0x0078, 0x174f, 0x2069, 0x1000, 0x690c, - 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1751, 0xa285, - 0x0000, 0x00c0, 0x175f, 0x70c3, 0x4000, 0x0078, 0x1761, 0x70c3, - 0x4003, 0x70ca, 0x0078, 0x1287, 0x2011, 0x5067, 0x220c, 0x70c4, - 0x8003, 0x0048, 0x1771, 0x1078, 0x3b49, 0xa184, 0x7fff, 0x0078, - 0x1775, 0x1078, 0x3b3c, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283, - 0x71c4, 0x1078, 0x3b33, 0x6100, 0x2001, 0x5067, 0x2004, 0xa084, - 0x8000, 0xa10d, 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078, - 0x1283, 0x71c4, 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004, - 0x53a3, 0x21a0, 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078, - 0x1284, 0x70c4, 0x2068, 0x2079, 0x5000, 0x2091, 0x8000, 0x1078, - 0x1911, 0x2091, 0x8001, 0x0040, 0x1825, 0x6007, 0x0001, 0x600b, - 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f, - 0xa284, 0x00f0, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, - 0xa284, 0x0800, 0x0040, 0x17c0, 0x601b, 0x000a, 0x0078, 0x17c6, - 0xa284, 0x1000, 0x0040, 0x17c6, 0x601b, 0x000c, 0xa284, 0x0300, - 0x0040, 0x17cf, 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, - 0x0001, 0x601e, 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400, - 0x0040, 0x17dc, 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, - 0x20a0, 0xad80, 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, - 0x17f1, 0x6046, 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078, - 0x17fb, 0x6800, 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c, - 0x6552, 0x6596, 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042, - 0x2c08, 0x2061, 0x5040, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077, - 0x0000, 0x607b, 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284, - 0x0400, 0x608e, 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007, - 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000, - 0x1078, 0x21b1, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, - 0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, - 0x5040, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, - 0x18aa, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844, - 0xa286, 0x000f, 0x00c0, 0x18aa, 0x691c, 0xa184, 0x0080, 0x00c0, - 0x18aa, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0, - 0x81ff, 0x0040, 0x1865, 0x0d7e, 0x2069, 0x0020, 0x6908, 0x6808, - 0xa106, 0x00c0, 0x1856, 0x690c, 0x680c, 0xa106, 0x00c0, 0x185b, - 0xa184, 0x00ff, 0x00c0, 0x185b, 0x0d7f, 0x78b8, 0xa084, 0x801f, - 0x00c0, 0x1865, 0x7848, 0xa085, 0x000c, 0x784a, 0x71b0, 0x81ff, - 0x0040, 0x1888, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020, 0x6807, - 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1879, 0x6807, 0x0008, - 0x6804, 0xa084, 0x0008, 0x00c0, 0x1880, 0x6807, 0x0002, 0x0d7f, - 0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, 0x0e7e, 0x2071, - 0x5000, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f, 0x1078, 0x4598, - 0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080, - 0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, - 0x0078, 0x1284, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091, 0x8001, - 0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4, 0xa182, - 0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980, 0x71c6, - 0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978, 0x71ca, - 0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078, 0x1284, - 0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078, 0x1284, - 0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004, 0xa082, - 0x0005, 0x0048, 0x18e7, 0x0038, 0x18e9, 0x0078, 0x18f3, 0x00a8, - 0x18f3, 0xa18c, 0x0001, 0x00c0, 0x18f1, 0x20b9, 0x2222, 0x0078, - 0x18f3, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078, - 0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078, - 0x1284, 0x2009, 0x5074, 0x2104, 0x70c6, 0x0078, 0x1284, 0xac80, - 0x0001, 0x1078, 0x1af2, 0x007c, 0xac80, 0x0001, 0x1078, 0x1a92, - 0x007c, 0x7850, 0xa065, 0x0040, 0x1919, 0x2c04, 0x7852, 0x2063, - 0x0000, 0x007c, 0x0f7e, 0x2079, 0x5000, 0x7850, 0xa06d, 0x0040, - 0x1929, 0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b, - 0x0000, 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5000, - 0x7850, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1938, 0x1078, 0x23ca, - 0x7852, 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5000, - 0x7850, 0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7700, - 0x7a52, 0x7bec, 0x8319, 0x0040, 0x1953, 0xa280, 0x0031, 0x2012, - 0x2010, 0x0078, 0x194a, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, - 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, - 0xa0e8, 0x5300, 0x007c, 0x1078, 0x1956, 0x2900, 0x682a, 0x2a00, - 0x682e, 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5052, - 0x210c, 0x6804, 0xa005, 0x0040, 0x1995, 0xa116, 0x00c0, 0x1980, - 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1983, - 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1992, 0x6000, - 0x6806, 0x1078, 0x19a3, 0x1078, 0x1c42, 0x6810, 0x8001, 0x6812, - 0x00c0, 0x1983, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, - 0x19a2, 0x609c, 0x609f, 0x0000, 0x2008, 0x1078, 0x192b, 0x2100, - 0x0078, 0x1996, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, - 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, - 0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0x2071, 0x5040, 0x704c, - 0xa08c, 0x0200, 0x00c0, 0x19c2, 0xa088, 0x5080, 0x2d0a, 0x8000, - 0x704e, 0xa006, 0x0e7f, 0x007c, 0x1078, 0x1956, 0x2091, 0x8000, - 0x6804, 0x781e, 0xa065, 0x0040, 0x1a0d, 0x0078, 0x19d5, 0x2c00, - 0x781e, 0x6000, 0xa065, 0x0040, 0x1a0d, 0x600c, 0xa306, 0x00c0, - 0x19cf, 0x6010, 0xa206, 0x00c0, 0x19cf, 0x2c28, 0x2001, 0x5052, - 0x2004, 0xac06, 0x00c0, 0x19e6, 0x0078, 0x1a0b, 0x6804, 0xac06, - 0x00c0, 0x19f3, 0x6000, 0xa065, 0x6806, 0x00c0, 0x19fd, 0x6803, - 0x0000, 0x0078, 0x19fd, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486, - 0x0000, 0x00c0, 0x19fd, 0x2c00, 0x6802, 0x2560, 0x1078, 0x19a3, - 0x601b, 0x0005, 0x6023, 0x0020, 0x1078, 0x1c42, 0x6810, 0x8001, - 0x1050, 0x23ca, 0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000, - 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, - 0x1078, 0x1963, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a18, 0xa7bc, - 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a18, - 0x2091, 0x8001, 0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, - 0x00c0, 0x1a3c, 0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, - 0x8001, 0xa005, 0x00c0, 0x1a3d, 0x007c, 0xa08c, 0xfff0, 0x0040, - 0x1a43, 0x1078, 0x23ca, 0x0079, 0x1a45, 0x1a55, 0x1a58, 0x1a5e, - 0x1a62, 0x1a56, 0x1a66, 0x1a6c, 0x1a56, 0x1a56, 0x1c0c, 0x1c30, - 0x1c34, 0x1a56, 0x1a56, 0x1a56, 0x1a56, 0x007c, 0x1078, 0x23ca, - 0x1078, 0x1a0e, 0x2001, 0x8001, 0x0078, 0x1c3a, 0x2001, 0x8003, - 0x0078, 0x1c3a, 0x2001, 0x8004, 0x0078, 0x1c3a, 0x1078, 0x1a0e, - 0x2001, 0x8006, 0x0078, 0x1c3a, 0x2001, 0x8007, 0x0078, 0x1c3a, - 0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1a78, 0x2009, 0x0020, - 0x2600, 0x1078, 0x1a92, 0x00c0, 0x1a91, 0xa7ba, 0x0020, 0x0048, - 0x1a90, 0x0040, 0x1a90, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a72, - 0xa006, 0x007c, 0x81ff, 0x0040, 0x1acd, 0x2099, 0x0030, 0x20a0, - 0x700c, 0xa084, 0x00ff, 0x0040, 0x1aa4, 0x7007, 0x0004, 0x7004, - 0xa084, 0x0004, 0x00c0, 0x1a9f, 0x21a8, 0x7017, 0x0000, 0x810b, - 0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001, - 0x7002, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, - 0x00c8, 0x1ac1, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, - 0x1ab3, 0x7008, 0x800b, 0x00c8, 0x1ab3, 0x7007, 0x0002, 0xa08c, - 0x01e0, 0x00c0, 0x1acd, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, - 0x2030, 0x2138, 0xa782, 0x0021, 0x0048, 0x1ad8, 0x2009, 0x0020, - 0x2600, 0x1078, 0x1af2, 0x00c0, 0x1af1, 0xa7ba, 0x0020, 0x0048, - 0x1af0, 0x0040, 0x1af0, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, - 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1ad2, - 0xa006, 0x007c, 0x81ff, 0x0040, 0x1b33, 0x2098, 0x20a1, 0x0030, - 0x700c, 0xa084, 0x00ff, 0x0040, 0x1b04, 0x7007, 0x0004, 0x7004, - 0xa084, 0x0004, 0x00c0, 0x1aff, 0x21a8, 0x7017, 0x0000, 0x810b, - 0x7112, 0x721a, 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000, - 0x7002, 0x53a6, 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, - 0x0005, 0x00c8, 0x1b22, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, - 0x00c0, 0x1b14, 0x7010, 0xa084, 0xf000, 0x0040, 0x1b2b, 0x7007, - 0x0008, 0x0078, 0x1b2f, 0x7108, 0x8103, 0x00c8, 0x1b14, 0x7007, - 0x0002, 0xa184, 0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, - 0x2004, 0xa082, 0x0004, 0x00c8, 0x1b3f, 0x0078, 0x1b42, 0xa006, - 0x0078, 0x1b44, 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5000, - 0x2d08, 0x7058, 0x6802, 0xa005, 0x00c0, 0x1b4f, 0x715e, 0x715a, - 0x0e7f, 0x007c, 0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1b59, - 0x795e, 0x795a, 0x007c, 0x2091, 0x8000, 0x6003, 0x0000, 0x2c08, - 0x785c, 0xa065, 0x00c0, 0x1b67, 0x795a, 0x0078, 0x1b68, 0x6102, - 0x795e, 0x2091, 0x8001, 0x1078, 0x21ce, 0x007c, 0x0e7e, 0x2071, - 0x5000, 0x7058, 0xa06d, 0x0040, 0x1b7c, 0x6800, 0x705a, 0xa005, - 0x00c0, 0x1b7b, 0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, - 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, - 0x0040, 0x1bac, 0x2068, 0x6814, 0xa306, 0x00c0, 0x1b95, 0x6828, - 0xa084, 0x00ff, 0xa406, 0x0040, 0x1b98, 0x2d60, 0x0078, 0x1b86, - 0x6800, 0xa005, 0x6002, 0x00c0, 0x1ba4, 0xaf80, 0x0016, 0xac06, - 0x0040, 0x1ba3, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, - 0x1bab, 0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, - 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, - 0x2060, 0x6000, 0xa005, 0x0040, 0x1bdb, 0x2068, 0x6814, 0xa084, - 0x00ff, 0xa306, 0x0040, 0x1bc7, 0x2d60, 0x0078, 0x1bb9, 0x6800, - 0xa005, 0x6002, 0x00c0, 0x1bd3, 0xaf80, 0x0016, 0xac06, 0x0040, - 0x1bd2, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bda, - 0x1078, 0x1996, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, - 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5000, 0xaf80, 0x0016, 0x2060, - 0x6000, 0xa06d, 0x0040, 0x1c07, 0x6814, 0xa306, 0x0040, 0x1bf3, - 0x2d60, 0x0078, 0x1be8, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1bff, - 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bfe, 0x2c00, 0x785e, 0x0d7e, - 0x689c, 0xa005, 0x0040, 0x1c06, 0x1078, 0x1996, 0x007f, 0x0f7f, - 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069, 0x5040, - 0x6800, 0xa086, 0x0000, 0x0040, 0x1c1a, 0x2091, 0x8001, 0x78e3, - 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, - 0x0004, 0x2051, 0x0010, 0x1078, 0x1963, 0x8738, 0xa784, 0x001f, - 0x00c0, 0x1c23, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1c3a, - 0x2001, 0x800c, 0x0078, 0x1c3a, 0x1078, 0x1a0e, 0x2001, 0x800d, - 0x0078, 0x1c3a, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, - 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884, 0x8000, - 0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1c51, 0x2c02, 0x0078, - 0x1c52, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061, 0x5000, - 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088, 0xa005, - 0x618a, 0x0040, 0x1c66, 0x2d02, 0x0078, 0x1c67, 0x618e, 0x0c7f, - 0x007c, 0x1078, 0x1c7a, 0x0040, 0x1c79, 0x0c7e, 0x609c, 0xa065, - 0x0040, 0x1c74, 0x1078, 0x1996, 0x0c7f, 0x609f, 0x0000, 0x1078, - 0x192b, 0x007c, 0x788c, 0xa065, 0x0040, 0x1c8c, 0x2091, 0x8000, - 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0, 0x1c8a, - 0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010, 0xa006, - 0x8004, 0x8086, 0x818e, 0x00c8, 0x1c96, 0xa200, 0x0070, 0x1c9a, - 0x0078, 0x1c91, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, - 0xa005, 0x0040, 0x1cc0, 0xa11a, 0x00c8, 0x1cc0, 0x8213, 0x818d, - 0x0048, 0x1cb1, 0xa11a, 0x00c8, 0x1cb2, 0x0070, 0x1cb8, 0x0078, - 0x1ca6, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1cb8, 0x0078, 0x1ca6, - 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, - 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1cbc, 0x7994, 0x70d0, - 0xa106, 0x0040, 0x1d34, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, - 0xa005, 0x00c0, 0x1d34, 0x7008, 0x7208, 0xa206, 0x00c0, 0x1d34, - 0xa286, 0x0008, 0x00c0, 0x1d34, 0x2071, 0x0010, 0x1078, 0x1911, - 0x0040, 0x1d34, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00, - 0x0040, 0x1d02, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5, - 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, - 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000, - 0x0078, 0x1d0c, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000, - 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078, 0x190c, - 0x2091, 0x8001, 0x0040, 0x1d2b, 0x1078, 0x192b, 0x78a8, 0x8000, - 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1d34, 0x2091, 0x8000, 0x78e3, - 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091, - 0x8001, 0x0078, 0x1d34, 0x78ab, 0x0000, 0x1078, 0x208b, 0x6004, - 0xa084, 0x000f, 0x0079, 0x1d39, 0x2071, 0x0010, 0x2091, 0x8001, - 0x007c, 0x1d49, 0x1d6b, 0x1d91, 0x1d49, 0x1dae, 0x1d58, 0x1f0d, - 0x1f28, 0x1d49, 0x1d65, 0x1d8b, 0x1df6, 0x1e63, 0x1eb3, 0x1ec5, - 0x1f24, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008, 0xa705, - 0x600a, 0x1078, 0x1fa6, 0x609c, 0x78da, 0x1078, 0x2073, 0x007c, - 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d5f, 0x0078, 0x1d49, 0x601c, - 0xa085, 0x0080, 0x601e, 0x0078, 0x1d72, 0x1078, 0x1b36, 0x00c0, - 0x1d49, 0x1078, 0x20a5, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d72, - 0x0078, 0x1d49, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, - 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1d88, 0x1078, 0x1fa6, - 0x0040, 0x1d88, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078, 0x1d8a, - 0x1078, 0x1fca, 0x007c, 0x1078, 0x1b36, 0x00c0, 0x1d49, 0x1078, - 0x20a1, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1d9a, 0xa084, 0x0100, - 0x00c0, 0x1d9c, 0x0078, 0x1d49, 0x1078, 0x1fa6, 0x00c0, 0x1dad, - 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x1f63, 0xa186, - 0x000f, 0x0040, 0x1f63, 0x1078, 0x1fca, 0x007c, 0x78dc, 0xa084, - 0x0100, 0x0040, 0x1db5, 0x0078, 0x1d49, 0x78df, 0x0000, 0x6714, - 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, - 0x0040, 0x1dd8, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, - 0xa08e, 0x0001, 0x0040, 0x1dd8, 0x2039, 0x0000, 0x2011, 0x0002, - 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1dd8, 0x0078, 0x1df3, - 0x1078, 0x1956, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, - 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, - 0x0070, 0x1dec, 0x0078, 0x1dda, 0x8211, 0x0040, 0x1df3, 0x20a9, - 0x0100, 0x0078, 0x1dda, 0x1078, 0x192b, 0x007c, 0x2001, 0x5067, - 0x2004, 0xa084, 0x8000, 0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2, - 0x6900, 0xa184, 0x0001, 0x0040, 0x1e17, 0x6028, 0xa084, 0x00ff, - 0x00c0, 0x1f83, 0x6800, 0xa084, 0x0001, 0x0040, 0x1f8b, 0x6803, - 0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x1f93, 0x2011, - 0x0001, 0x6020, 0xa084, 0x4000, 0x0040, 0x1e20, 0xa295, 0x0002, - 0x6020, 0xa084, 0x0100, 0x0040, 0x1e27, 0xa295, 0x0008, 0x601c, - 0xa084, 0x0002, 0x0040, 0x1e2e, 0xa295, 0x0004, 0x602c, 0xa08c, - 0x00ff, 0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8, - 0x1f8f, 0x0040, 0x1f8f, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff, - 0xa182, 0x0002, 0x0048, 0x1f8f, 0xa182, 0x001b, 0x00c8, 0x1f8f, - 0x0040, 0x1f8f, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e51, 0x2001, - 0x001e, 0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1f8b, - 0x6806, 0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f8b, 0x680a, - 0x6a02, 0x0078, 0x1f93, 0x2001, 0x5067, 0x2004, 0xa084, 0x8000, - 0x0040, 0x1f8b, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000, 0x6a04, - 0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1e89, 0x6128, 0xa18c, - 0x00ff, 0x8001, 0x00c0, 0x1e82, 0x2100, 0xa210, 0x0048, 0x1eaf, - 0x0078, 0x1e89, 0x8001, 0x00c0, 0x1eaf, 0x2100, 0xa212, 0x0048, - 0x1eaf, 0xa484, 0x000c, 0x0040, 0x1ea3, 0x6128, 0x810f, 0xa18c, - 0x00ff, 0xa082, 0x0004, 0x00c0, 0x1e9b, 0x2100, 0xa318, 0x0048, - 0x1eaf, 0x0078, 0x1ea3, 0xa082, 0x0004, 0x00c0, 0x1eaf, 0x2100, - 0xa31a, 0x0048, 0x1eaf, 0x6030, 0xa005, 0x0040, 0x1ea9, 0x8000, - 0x6816, 0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1f93, 0x2091, - 0x8001, 0x0078, 0x1f8f, 0x6114, 0x1078, 0x20c2, 0x2091, 0x8000, - 0x6b08, 0x8318, 0x0048, 0x1ec1, 0x6b0a, 0x2091, 0x8001, 0x0078, - 0x1fa2, 0x2091, 0x8001, 0x0078, 0x1f8f, 0x6024, 0x8007, 0xa084, - 0x00ff, 0x0040, 0x1ee3, 0xa086, 0x0080, 0x00c0, 0x1f0b, 0x20a9, - 0x0008, 0x2069, 0x7410, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff, - 0x6802, 0xade8, 0x0008, 0x0070, 0x1edf, 0x0078, 0x1ed5, 0x2091, - 0x8001, 0x0078, 0x1f93, 0x6028, 0xa015, 0x0040, 0x1f0b, 0x6114, - 0x1078, 0x20c2, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, - 0xa00d, 0x0040, 0x1f08, 0xa206, 0x0040, 0x1ef9, 0x2168, 0x0078, - 0x1eef, 0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x192b, 0x0c7f, - 0x0d7f, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fa2, - 0x2091, 0x8001, 0x0d7f, 0x0078, 0x1f8b, 0x6114, 0x1078, 0x20c2, - 0x6800, 0xa084, 0x0001, 0x0040, 0x1f7b, 0x2091, 0x8000, 0x6a04, - 0x8210, 0x0048, 0x1f20, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fa2, - 0x2091, 0x8001, 0x0078, 0x1f8f, 0x1078, 0x1b36, 0x00c0, 0x1d49, - 0x6114, 0x1078, 0x20c2, 0x60be, 0x6900, 0xa184, 0x0008, 0x0040, - 0x1f35, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040, - 0x1f8b, 0xa184, 0x0100, 0x00c0, 0x1f77, 0xa184, 0x0200, 0x00c0, - 0x1f73, 0x681c, 0xa005, 0x00c0, 0x1f7f, 0x6004, 0xa084, 0x00ff, - 0xa086, 0x000f, 0x00c0, 0x1f4e, 0x1078, 0x20a5, 0x78df, 0x0000, - 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, - 0x0040, 0x1f63, 0x1078, 0x1fa6, 0x0040, 0x1f63, 0x78dc, 0xa085, - 0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024, - 0xa084, 0xff00, 0x6026, 0x1078, 0x39aa, 0x0040, 0x1cc6, 0x1078, - 0x1b5b, 0x0078, 0x1cc6, 0x2009, 0x0017, 0x0078, 0x1f95, 0x2009, - 0x000e, 0x0078, 0x1f95, 0x2009, 0x0007, 0x0078, 0x1f95, 0x2009, - 0x0035, 0x0078, 0x1f95, 0x2009, 0x003e, 0x0078, 0x1f95, 0x2009, - 0x0004, 0x0078, 0x1f95, 0x2009, 0x0006, 0x0078, 0x1f95, 0x2009, - 0x0016, 0x0078, 0x1f95, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, - 0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c42, 0x2091, 0x8001, - 0x0078, 0x1cc6, 0x1078, 0x192b, 0x0078, 0x1cc6, 0x78d4, 0xa06d, - 0x00c0, 0x1fb1, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078, - 0x1fbd, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002, - 0x78d8, 0xad06, 0x00c0, 0x1fbd, 0x6002, 0x78d0, 0x8001, 0x78d2, - 0x00c0, 0x1fc9, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060, - 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff, - 0x601e, 0xa184, 0x0060, 0x0040, 0x1fd9, 0x0e7e, 0x1078, 0x467f, - 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, - 0x0000, 0x6714, 0x1078, 0x1956, 0x2091, 0x8000, 0x60a0, 0xa084, - 0x8000, 0x00c0, 0x2000, 0x6808, 0xa084, 0x0001, 0x0040, 0x2000, - 0x2091, 0x8001, 0x1078, 0x19a3, 0x2091, 0x8000, 0x1078, 0x1c42, - 0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2072, - 0x6024, 0xa096, 0x0001, 0x00c0, 0x2007, 0x8000, 0x6026, 0x6a10, - 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2016, 0x0040, 0x2016, - 0x2039, 0x0200, 0x1078, 0x2073, 0x0078, 0x2072, 0x2c08, 0x2091, - 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2043, 0x6800, 0xa065, - 0x0040, 0x2048, 0x6a04, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa084, - 0x0001, 0x0040, 0x203d, 0x7048, 0xa206, 0x00c0, 0x203d, 0x6b04, - 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2038, 0x6902, - 0x2260, 0x6102, 0x0e7f, 0x0078, 0x204f, 0x2160, 0x6202, 0x6906, - 0x0e7f, 0x0078, 0x204f, 0x6800, 0xa065, 0x0040, 0x2048, 0x6102, - 0x6902, 0x00c0, 0x204c, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, - 0x60a0, 0xa084, 0x8000, 0x0040, 0x2059, 0x6808, 0xa084, 0xfffc, - 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c, - 0x0040, 0x0040, 0x2068, 0xa086, 0x0040, 0x680a, 0x1078, 0x19b4, - 0x2091, 0x8000, 0x1078, 0x21b1, 0x2091, 0x8001, 0x78db, 0x0000, - 0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, - 0x1078, 0x1c42, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2086, - 0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2076, 0x78d7, 0x0000, - 0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, - 0x2092, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x20a0, - 0x8001, 0x7806, 0x00c0, 0x20a0, 0x0068, 0x20a0, 0x2091, 0x4080, - 0x007c, 0x2039, 0x20b9, 0x0078, 0x20a7, 0x2039, 0x20bf, 0x2704, - 0xa005, 0x0040, 0x20b8, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910, - 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x20a7, - 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, - 0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b33, 0x2c68, 0x0c7f, 0x007c, - 0x0010, 0x2139, 0x0068, 0x2139, 0x2029, 0x0000, 0x78cb, 0x0000, - 0x788c, 0xa065, 0x0040, 0x2132, 0x2009, 0x5074, 0x2104, 0xa084, - 0x0001, 0x0040, 0x2100, 0x6004, 0xa086, 0x0103, 0x00c0, 0x2100, - 0x6018, 0xa005, 0x00c0, 0x2100, 0x6014, 0xa005, 0x00c0, 0x2100, - 0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x20ff, - 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, - 0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c69, 0x0078, 0x2137, 0x0d7f, - 0x1078, 0x213a, 0x0040, 0x2132, 0x6204, 0xa294, 0x00ff, 0xa296, - 0x0003, 0x0040, 0x2112, 0x6204, 0xa296, 0x0110, 0x00c0, 0x2120, - 0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040, - 0x2120, 0x85ff, 0x00c0, 0x2132, 0x8210, 0xa202, 0x00c8, 0x2132, - 0x057e, 0x1078, 0x2149, 0x057f, 0x0040, 0x212d, 0x78e0, 0xa086, - 0x0003, 0x0040, 0x2132, 0x0078, 0x2120, 0x8528, 0x78c8, 0xa005, - 0x0040, 0x20d0, 0x85ff, 0x0040, 0x2139, 0x2091, 0x4080, 0x78b0, - 0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2143, - 0x2300, 0xa005, 0x007c, 0x0048, 0x2147, 0xa302, 0x007c, 0x8002, - 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2163, - 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2198, - 0x7008, 0x7208, 0xa206, 0x00c0, 0x2198, 0xa286, 0x0008, 0x00c0, - 0x2198, 0x2071, 0x0010, 0x1078, 0x219d, 0x2009, 0x0020, 0x6004, - 0xa086, 0x0103, 0x00c0, 0x2172, 0x6028, 0xa005, 0x00c0, 0x2172, - 0x2009, 0x000c, 0x1078, 0x1907, 0x0040, 0x218b, 0x78c4, 0x8000, - 0x78c6, 0xa086, 0x0002, 0x00c0, 0x2198, 0x2091, 0x8000, 0x78e3, - 0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091, - 0x8001, 0x0078, 0x2198, 0x78c7, 0x0000, 0x1078, 0x1c69, 0x79ac, - 0x78b0, 0x8000, 0xa10a, 0x00c8, 0x2196, 0xa006, 0x78b2, 0xa006, - 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004, - 0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1, - 0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x505b, 0x2091, 0x8000, - 0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5040, 0x7000, 0xa086, 0x0000, - 0x00c0, 0x21cb, 0x2009, 0x5012, 0x2104, 0xa005, 0x00c0, 0x21cb, - 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21cb, 0x0018, - 0x21cb, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, - 0x2071, 0x5040, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, - 0x21e4, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21e4, - 0x0018, 0x21e4, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, - 0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5040, 0x2079, 0x0100, - 0x784b, 0x000f, 0x0098, 0x21f7, 0x7838, 0x0078, 0x21f0, 0x20a9, - 0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2200, 0x20a9, 0x0060, - 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x220a, - 0x0078, 0x2202, 0x7800, 0xa082, 0x0004, 0x0048, 0x2219, 0x70b7, - 0x009b, 0x2019, 0x4da4, 0x1078, 0x2255, 0x702f, 0x8001, 0x0078, - 0x2225, 0x70b7, 0x0000, 0x2019, 0x4c1c, 0x1078, 0x2255, 0x2019, - 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078, - 0x235e, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c, - 0xa18a, 0x0005, 0x0048, 0x223a, 0x0038, 0x2240, 0xa085, 0x6280, - 0x0078, 0x2242, 0x0028, 0x2240, 0xa085, 0x6280, 0x0078, 0x2242, - 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8, - 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x507f, - 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e, - 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2275, - 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040, - 0x226d, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005, - 0x00c0, 0x2264, 0x3318, 0x0078, 0x225b, 0x047f, 0x157f, 0x147f, - 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, - 0xfff0, 0xa105, 0x2012, 0x1078, 0x235e, 0x007c, 0x2011, 0x0101, - 0x20a9, 0x0009, 0x810b, 0x0070, 0x228f, 0x0078, 0x228a, 0xa18c, - 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, - 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22a0, 0x0078, 0x229b, - 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, - 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22b1, 0x0078, - 0x22ac, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, - 0x007c, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, - 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, - 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, - 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, - 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, - 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, - 0x007c, 0x8103, 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, - 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, - 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, - 0x233c, 0x2061, 0x7400, 0x1078, 0x2344, 0x0040, 0x2328, 0x20a9, - 0x0000, 0x2061, 0x7300, 0x0c7e, 0x1078, 0x2344, 0x0040, 0x2318, - 0x0c7f, 0x8c60, 0x0070, 0x2316, 0x0078, 0x230b, 0x0078, 0x233c, - 0x007f, 0xa082, 0x7300, 0x2071, 0x5040, 0x7086, 0x7182, 0x2001, - 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac, 0x0078, 0x2338, - 0x60c0, 0xa005, 0x00c0, 0x233c, 0x2071, 0x5040, 0x7182, 0x2c00, - 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078, 0x21ac, - 0x2001, 0x0000, 0x0078, 0x233e, 0x2001, 0x0001, 0x2091, 0x8001, - 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x235b, - 0x2060, 0x600c, 0xa306, 0x00c0, 0x2358, 0x6010, 0xa206, 0x00c0, - 0x2358, 0x6014, 0xa106, 0x00c0, 0x2358, 0xa006, 0x0078, 0x235d, - 0x6000, 0x0078, 0x2345, 0xa085, 0x0001, 0x007c, 0x2011, 0x5041, - 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084, 0x0100, - 0x0040, 0x2374, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b, 0x810b, - 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4, 0xa08c, - 0x0020, 0x0040, 0x23c8, 0xa084, 0x0006, 0x00c0, 0x23c8, 0x6014, - 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x5280, - 0x7004, 0xa084, 0x000a, 0x00c0, 0x23c8, 0x7108, 0xa194, 0xff00, - 0x0040, 0x23c8, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106, 0x0040, - 0x23af, 0x2001, 0x0012, 0xa106, 0x0040, 0x23b3, 0x2001, 0x0014, - 0xa106, 0x0040, 0x23b7, 0x2001, 0x0019, 0xa106, 0x0040, 0x23bb, - 0x2001, 0x0032, 0xa106, 0x0040, 0x23bf, 0x0078, 0x23c3, 0x2009, - 0x0012, 0x0078, 0x23c5, 0x2009, 0x0014, 0x0078, 0x23c5, 0x2009, - 0x0019, 0x0078, 0x23c5, 0x2009, 0x0020, 0x0078, 0x23c5, 0x2009, - 0x003f, 0x0078, 0x23c5, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, - 0x0e7f, 0x007c, 0x0068, 0x23ca, 0x2091, 0x8000, 0x2071, 0x0000, - 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23d1, 0x007f, 0x2071, - 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x073f, - 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, - 0x0078, 0x23e8, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300, 0x7f3c, - 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce, 0xa594, - 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x23ff, 0x2411, - 0x2411, 0x2411, 0x274b, 0x3907, 0x240f, 0x2440, 0x244a, 0x240f, - 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x240f, 0x1078, - 0x23ca, 0x8507, 0xa084, 0x001f, 0x0079, 0x2416, 0x2454, 0x274b, - 0x2905, 0x2a02, 0x2a2a, 0x2cc3, 0x2f6e, 0x2fb1, 0x2ffc, 0x3081, - 0x3139, 0x31e2, 0x2440, 0x2827, 0x2f43, 0x2436, 0x3c78, 0x3c98, - 0x3e5e, 0x3e6a, 0x3f3f, 0x2436, 0x2436, 0x4012, 0x4016, 0x3c76, - 0x2436, 0x3dc9, 0x2436, 0x3b56, 0x244a, 0x2436, 0x1078, 0x23ca, - 0x0018, 0x23ef, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, - 0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f, 0x0001, 0x781b, 0x004f, - 0x0078, 0x2438, 0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, - 0x781b, 0x00d5, 0x0078, 0x2438, 0x7242, 0x2009, 0x500f, 0x200b, - 0x0000, 0xa584, 0x0001, 0x00c0, 0x3b6a, 0x0040, 0x2471, 0x1078, - 0x23ca, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, 0x7037, - 0x0000, 0x1078, 0x38de, 0x0018, 0x23ef, 0x2009, 0x500f, 0x200b, - 0x0000, 0x7068, 0xa005, 0x00c0, 0x253c, 0x706c, 0xa084, 0x0007, - 0x0079, 0x247a, 0x2573, 0x2482, 0x248e, 0x24ab, 0x24cd, 0x251a, - 0x24f3, 0x2482, 0x1078, 0x38c6, 0x2009, 0x0048, 0x1078, 0x2e0f, - 0x00c0, 0x248c, 0x7003, 0x0004, 0x0078, 0x2438, 0x1078, 0x38c6, - 0x00c0, 0x24a9, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010, 0x78ab, - 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009, - 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24a9, 0x7003, 0x0004, 0x7093, - 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x24cb, 0x7180, - 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0, - 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, - 0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24cb, 0x7003, - 0x0004, 0x7093, 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, - 0x24f1, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, - 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa, 0x78ab, - 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009, - 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x24f1, 0x7003, 0x0004, 0x7093, - 0x000f, 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2518, 0x7180, - 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, 0x00c0, - 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, 0x785b, - 0x0004, 0x2009, 0x00e5, 0x1078, 0x2e03, 0x00c0, 0x2518, 0x7088, - 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093, 0x000f, - 0x0078, 0x2438, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x7088, 0x2068, - 0x6f14, 0x1078, 0x37bd, 0x2c50, 0x1078, 0x3978, 0x789b, 0x0010, - 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c, 0x2041, - 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040, 0x253a, - 0x2001, 0x0006, 0x0078, 0x265b, 0x1078, 0x38c6, 0x00c0, 0x2438, - 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37bd, 0x2c50, - 0x1078, 0x3978, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824, 0xa005, - 0x0040, 0x255a, 0xa082, 0x0006, 0x0048, 0x2558, 0x0078, 0x255a, - 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058, - 0xa084, 0x8000, 0x0040, 0x2568, 0xa684, 0x0001, 0x0040, 0x256a, - 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, - 0x0003, 0x0078, 0x265b, 0x0018, 0x23ef, 0x744c, 0xa485, 0x0000, - 0x0040, 0x258d, 0xa080, 0x5080, 0x2030, 0x7150, 0x8108, 0xa12a, - 0x0048, 0x2584, 0x2009, 0x5080, 0x2164, 0x6504, 0x85ff, 0x00c0, - 0x259e, 0x8421, 0x00c0, 0x257e, 0x7152, 0x7003, 0x0000, 0x704b, - 0x0000, 0x7040, 0xa005, 0x0040, 0x3b6a, 0x0078, 0x2438, 0x764c, - 0xa6b0, 0x5080, 0x7150, 0x2600, 0x0078, 0x2589, 0x7152, 0x2568, - 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, 0x259b, - 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25d4, 0xa784, 0x0021, - 0x00c0, 0x259b, 0xa784, 0x0002, 0x0040, 0x25bd, 0xa784, 0x0004, - 0x0040, 0x259b, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, 0x00c0, - 0x259b, 0xa784, 0x0010, 0x00c0, 0x259b, 0xa784, 0x0200, 0x00c0, - 0x259b, 0xa784, 0x0100, 0x0040, 0x25d4, 0x6018, 0xa005, 0x00c0, - 0x259b, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c, 0xa684, - 0x000e, 0x6118, 0x0040, 0x25e4, 0x601c, 0xa102, 0x0048, 0x25e7, - 0x0040, 0x25e7, 0x0078, 0x2597, 0x81ff, 0x00c0, 0x2597, 0x68c3, - 0x0000, 0xa784, 0x0080, 0x00c0, 0x25ef, 0x700c, 0x6022, 0xa7bc, - 0xff7f, 0x670a, 0x1078, 0x3978, 0x0018, 0x23ef, 0x789b, 0x0010, - 0xa046, 0x1078, 0x38c6, 0x00c0, 0x2438, 0x6b14, 0xa39c, 0x001f, - 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x260b, 0xa684, - 0x0001, 0x0040, 0x260d, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040, - 0x2613, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0, - 0x261e, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x2659, 0x7158, 0xa18c, - 0x0800, 0x0040, 0x33d7, 0x2011, 0x0020, 0xa684, 0x0008, 0x00c0, - 0x262f, 0x8210, 0xa684, 0x0002, 0x00c0, 0x262f, 0x8210, 0x7aaa, - 0x8840, 0x1078, 0x38de, 0x6a14, 0x610c, 0x8108, 0xa18c, 0x00ff, - 0xa1e0, 0x7300, 0x2c64, 0x8cff, 0x0040, 0x2650, 0x6014, 0xa206, - 0x00c0, 0x263a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2635, 0x0c7e, - 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x2573, - 0x1078, 0x38c6, 0x00c0, 0x2438, 0x2a60, 0x610e, 0x79aa, 0x8840, - 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018, 0x0040, - 0x2676, 0xa184, 0x0010, 0x0040, 0x2669, 0x1078, 0x35d6, 0x00c0, - 0x2699, 0xa184, 0x0008, 0x0040, 0x2676, 0x69a0, 0xa184, 0x0600, - 0x00c0, 0x2676, 0x1078, 0x34c7, 0x0078, 0x2699, 0x69a0, 0xa184, - 0x0800, 0x0040, 0x268d, 0x0c7e, 0x027e, 0x2960, 0x6000, 0xa085, - 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f, 0x0c7f, - 0x1078, 0x35d6, 0x00c0, 0x2699, 0x69a0, 0xa184, 0x0200, 0x0040, - 0x2695, 0x1078, 0x3516, 0x0078, 0x2699, 0xa184, 0x0400, 0x00c0, - 0x2672, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26a4, 0x6914, 0xa18c, - 0xff00, 0x810f, 0x1078, 0x22cd, 0x007f, 0x7002, 0xa68c, 0x00e0, - 0xa684, 0x0060, 0x0040, 0x26b2, 0xa086, 0x0060, 0x00c0, 0x26b2, - 0xa18d, 0x4000, 0x88ff, 0x0040, 0x26b7, 0xa18d, 0x0004, 0x795a, - 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6818, - 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080, 0x0040, - 0x26d6, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26d4, 0xa08a, - 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa, 0x8008, - 0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0, 0x33dd, 0x157e, - 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac, - 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, - 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98, 0x7ed2, 0x7eda, - 0x1078, 0x38c6, 0x00c0, 0x270d, 0x702c, 0x8003, 0x0048, 0x2706, - 0x2019, 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x7830, 0xa084, - 0x00c0, 0x00c0, 0x270d, 0x0098, 0x2715, 0x6008, 0xa084, 0xffef, - 0x600a, 0x1078, 0x38de, 0x0078, 0x2461, 0x7200, 0xa284, 0x0007, - 0xa086, 0x0001, 0x00c0, 0x2722, 0x781b, 0x004f, 0x1078, 0x38de, - 0x0078, 0x2733, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x004f, - 0x1078, 0x38de, 0x7200, 0x2500, 0xa605, 0x0040, 0x2733, 0xa284, - 0x0007, 0x1079, 0x2741, 0xad80, 0x0009, 0x7036, 0xa284, 0x0007, - 0xa086, 0x0001, 0x00c0, 0x2438, 0x6018, 0x8000, 0x601a, 0x0078, - 0x2438, 0x2749, 0x48f7, 0x48f7, 0x48e6, 0x48f7, 0x2749, 0x48e6, - 0x2749, 0x1078, 0x23ca, 0x1078, 0x38c6, 0x0f7e, 0x2079, 0x5000, - 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x276f, 0x706c, 0xa086, - 0x0001, 0x00c0, 0x275e, 0x706e, 0x0078, 0x2802, 0x706c, 0xa086, - 0x0005, 0x00c0, 0x276d, 0x7088, 0x2068, 0x681b, 0x0004, 0x6817, - 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000, 0x2011, - 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2790, 0xa186, 0x0007, - 0x00c0, 0x2780, 0x2009, 0x5038, 0x200b, 0x0005, 0x0078, 0x2790, - 0x2009, 0x5013, 0x2104, 0x2009, 0x5012, 0x200a, 0x2009, 0x5038, - 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078, 0x2792, - 0x706f, 0x0000, 0x1078, 0x4633, 0x157e, 0x20a9, 0x0010, 0x2039, - 0x0000, 0x1078, 0x36b0, 0xa7b8, 0x0100, 0x0070, 0x27a1, 0x0078, - 0x2799, 0x157f, 0x7000, 0x0079, 0x27a5, 0x27d3, 0x27ba, 0x27ba, - 0x27ad, 0x27d3, 0x27d3, 0x27d3, 0x27d3, 0x2021, 0x505a, 0x2404, - 0xa005, 0x0040, 0x27d3, 0xad06, 0x00c0, 0x27ba, 0x6800, 0x2022, - 0x0078, 0x27ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27c6, 0x6f14, - 0x1078, 0x37bd, 0x1078, 0x33ae, 0x0078, 0x27ca, 0x7060, 0x2060, - 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, - 0x6822, 0x1078, 0x1c53, 0x2021, 0x7400, 0x1078, 0x280f, 0x2021, - 0x505a, 0x1078, 0x280f, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7300, - 0x1078, 0x280f, 0x8420, 0x0070, 0x27e7, 0x0078, 0x27e0, 0x2061, - 0x5300, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, 0x81ff, - 0x0040, 0x27f6, 0xa102, 0x0050, 0x27f6, 0x6012, 0x601b, 0x0000, - 0xace0, 0x0010, 0x0070, 0x27fe, 0x0078, 0x27ed, 0x8421, 0x00c0, - 0x27eb, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x2809, 0x1078, - 0x39cc, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x047e, - 0x2404, 0xa005, 0x0040, 0x2823, 0x2068, 0x6800, 0x007e, 0x6a1a, - 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, 0x1c53, - 0x007f, 0x0078, 0x2811, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, - 0x0003, 0x0050, 0x282d, 0x1078, 0x23ca, 0x2300, 0x0079, 0x2830, - 0x2833, 0x28a6, 0x28c3, 0xa282, 0x0002, 0x0040, 0x2839, 0x1078, - 0x23ca, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x2840, - 0x2848, 0x2848, 0x284a, 0x287e, 0x33e3, 0x2848, 0x287e, 0x2848, - 0x1078, 0x23ca, 0x7780, 0x1078, 0x36b0, 0x7780, 0xa7bc, 0x0f00, - 0x1078, 0x37bd, 0x6018, 0xa005, 0x0040, 0x2875, 0x2021, 0x7400, - 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28de, 0x0040, 0x2875, - 0x157e, 0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0004, - 0x2011, 0x0010, 0x1078, 0x28de, 0x047f, 0x0040, 0x2874, 0x8420, - 0x0070, 0x2874, 0x0078, 0x2865, 0x157f, 0x8738, 0xa784, 0x001f, - 0x00c0, 0x2850, 0x0078, 0x2461, 0x0078, 0x2461, 0x7780, 0x1078, - 0x37bd, 0x6018, 0xa005, 0x0040, 0x28a4, 0x2021, 0x7400, 0x2009, - 0x0005, 0x2011, 0x0020, 0x1078, 0x28de, 0x0040, 0x28a4, 0x157e, - 0x20a9, 0x0000, 0x2021, 0x7300, 0x047e, 0x2009, 0x0005, 0x2011, - 0x0020, 0x1078, 0x28de, 0x047f, 0x0040, 0x28a3, 0x8420, 0x0070, - 0x28a3, 0x0078, 0x2894, 0x157f, 0x0078, 0x2461, 0x2200, 0x0079, - 0x28a9, 0x28ac, 0x28ae, 0x28ae, 0x1078, 0x23ca, 0x2009, 0x0012, - 0x706c, 0xa086, 0x0002, 0x0040, 0x28b7, 0x2009, 0x000e, 0x6818, - 0xa084, 0x8000, 0x0040, 0x28bd, 0x691a, 0x706f, 0x0000, 0x7073, - 0x0001, 0x0078, 0x3854, 0x2200, 0x0079, 0x28c6, 0x28cb, 0x28ae, - 0x28c9, 0x1078, 0x23ca, 0x1078, 0x4633, 0x7000, 0xa086, 0x0001, - 0x00c0, 0x3373, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, - 0x1078, 0x3366, 0x0040, 0x3373, 0x0078, 0x2573, 0x2404, 0xa005, - 0x0040, 0x2901, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, - 0x28ed, 0x2d20, 0x007f, 0x0078, 0x28df, 0x007f, 0x2022, 0x691a, - 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c53, 0x6010, - 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x33c4, - 0x007c, 0xa085, 0x0001, 0x0078, 0x2900, 0x2300, 0x0079, 0x2908, - 0x290d, 0x290b, 0x29a6, 0x1078, 0x23ca, 0x78ec, 0xa084, 0x0001, - 0x00c0, 0x2921, 0x7000, 0xa086, 0x0004, 0x00c0, 0x2919, 0x0078, - 0x2944, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, - 0x3373, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018, 0x2438, 0x2008, - 0xa084, 0x0030, 0x00c0, 0x2930, 0x781b, 0x004f, 0x0078, 0x2438, - 0x78ec, 0xa084, 0x0003, 0x0040, 0x292c, 0x2100, 0xa084, 0x0007, - 0x0079, 0x293a, 0x297d, 0x2988, 0x296e, 0x2942, 0x38b9, 0x38b9, - 0x2942, 0x2997, 0x1078, 0x23ca, 0x7000, 0xa086, 0x0004, 0x00c0, - 0x295e, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2954, 0x2011, 0x0002, - 0x2019, 0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040, - 0x294e, 0x706c, 0xa086, 0x0004, 0x0040, 0x294e, 0x79e4, 0xa184, - 0x0030, 0x0040, 0x2968, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x296a, - 0x0078, 0x2f43, 0x2001, 0x0003, 0x0078, 0x2cd7, 0x6818, 0xa084, - 0x8000, 0x0040, 0x2975, 0x681b, 0x001d, 0x1078, 0x368f, 0x782b, - 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000, - 0x0040, 0x2984, 0x681b, 0x001d, 0x1078, 0x368f, 0x0078, 0x3884, - 0x6818, 0xa084, 0x8000, 0x0040, 0x298f, 0x681b, 0x001d, 0x1078, - 0x368f, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x6818, - 0xa084, 0x8000, 0x0040, 0x299e, 0x681b, 0x001d, 0x1078, 0x368f, - 0x782b, 0x3008, 0x781b, 0x0093, 0x0078, 0x2438, 0xa584, 0x000f, - 0x00c0, 0x29c3, 0x7000, 0x0079, 0x29ad, 0x2461, 0x29b7, 0x29b5, - 0x3373, 0x3373, 0x3373, 0x3373, 0x29b5, 0x1078, 0x23ca, 0x1078, - 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3366, 0x0040, - 0x3373, 0x0078, 0x2573, 0x78e4, 0xa005, 0x00d0, 0x2944, 0x0018, - 0x2944, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29d2, 0x781b, 0x004f, - 0x0078, 0x2438, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ce, 0x2100, - 0xa184, 0x0007, 0x0079, 0x29dc, 0x29ee, 0x29f2, 0x29e6, 0x29e4, - 0x38b9, 0x38b9, 0x29e4, 0x38af, 0x1078, 0x23ca, 0x1078, 0x3697, - 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x1078, 0x3697, - 0x0078, 0x3884, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x00d2, - 0x0078, 0x2438, 0x1078, 0x3697, 0x782b, 0x3008, 0x781b, 0x0093, - 0x0078, 0x2438, 0x2300, 0x0079, 0x2a05, 0x2a0a, 0x2a08, 0x2a0c, - 0x1078, 0x23ca, 0x0078, 0x3081, 0x681b, 0x0008, 0x78a3, 0x0000, - 0x79e4, 0xa184, 0x0030, 0x0040, 0x3081, 0x78ec, 0xa084, 0x0003, - 0x0040, 0x3081, 0xa184, 0x0007, 0x0079, 0x2a1e, 0x2a26, 0x29f2, - 0x296e, 0x3854, 0x38b9, 0x38b9, 0x2a26, 0x38af, 0x1078, 0x3868, - 0x0078, 0x2438, 0xa282, 0x0005, 0x0050, 0x2a30, 0x1078, 0x23ca, - 0x2300, 0x0079, 0x2a33, 0x2a36, 0x2c84, 0x2c92, 0x2200, 0x0079, - 0x2a39, 0x2a53, 0x2a40, 0x2a53, 0x2a3e, 0x2c69, 0x1078, 0x23ca, - 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, - 0x366b, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2a4f, 0x366b, - 0x366b, 0x366b, 0x3619, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, - 0x0040, 0x2a64, 0x0078, 0x366b, 0x7000, 0xa005, 0x00c0, 0x2a5a, - 0x2011, 0x0004, 0x0078, 0x31f5, 0xa184, 0x00ff, 0xa08a, 0x0010, - 0x00c8, 0x366b, 0x0079, 0x2a6c, 0x2a7e, 0x2a7c, 0x2a96, 0x2a9a, - 0x2b55, 0x366b, 0x366b, 0x2b57, 0x366b, 0x366b, 0x2c65, 0x2c65, - 0x366b, 0x366b, 0x366b, 0x2c67, 0x1078, 0x23ca, 0xa684, 0x1000, - 0x0040, 0x2a8b, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a, 0x781b, - 0x0091, 0x0078, 0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a94, - 0x681b, 0x001d, 0x0078, 0x2a82, 0x0078, 0x3854, 0x681b, 0x001d, - 0x0078, 0x367b, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x2adb, - 0x6820, 0xa084, 0x0001, 0x00c0, 0x2ae1, 0x6818, 0xa086, 0x0008, - 0x00c0, 0x2aac, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040, 0x2b51, - 0xa684, 0x0080, 0x0040, 0x2ad7, 0x7097, 0x0000, 0x6818, 0xa084, - 0x003f, 0xa08a, 0x000d, 0x0050, 0x2ad7, 0xa08a, 0x000c, 0x7196, - 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061, 0x78aa, 0x157e, - 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000, 0x80ac, - 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b, - 0x0058, 0x0078, 0x2438, 0xa684, 0x1000, 0x0040, 0x2ae1, 0x0078, - 0x2438, 0xa684, 0x0060, 0x0040, 0x2b4d, 0xa684, 0x0800, 0x0040, - 0x2b4d, 0xa684, 0x8000, 0x00c0, 0x2aef, 0x0078, 0x2b09, 0xa6b4, - 0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076, 0x7aac, 0x79ac, 0x78ac, - 0x801b, 0x00c8, 0x2afc, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, - 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, - 0x68ae, 0xa684, 0x4000, 0x0040, 0x2b11, 0xa6b4, 0xbfff, 0x7e5a, - 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2b1e, 0x1078, 0x46e9, - 0x1078, 0x48e6, 0x781b, 0x0064, 0x0078, 0x2438, 0xa006, 0x1078, - 0x49ed, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, - 0x2b2d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, - 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x2b3f, 0xa6b5, - 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b, - 0x0064, 0x2200, 0xa115, 0x00c0, 0x2b49, 0x1078, 0x48f7, 0x0078, - 0x2438, 0x1078, 0x4942, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078, - 0x2438, 0x781b, 0x0058, 0x0078, 0x2438, 0x1078, 0x23ca, 0x0078, - 0x2bb8, 0x6920, 0xa184, 0x0100, 0x0040, 0x2b6f, 0xa18c, 0xfeff, - 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xefff, 0x6002, - 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x2ba7, 0xa184, - 0x0200, 0x0040, 0x2ba7, 0xa18c, 0xfdff, 0x6922, 0x0c7e, 0x7054, - 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef, - 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7, - 0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b, - 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, - 0x0400, 0x00c0, 0x2ba1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, - 0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58, - 0xa684, 0x0400, 0x00c0, 0x2bb0, 0x781b, 0x0058, 0x0078, 0x2438, - 0x781b, 0x0065, 0x0078, 0x2438, 0x0078, 0x3673, 0x0078, 0x3673, - 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x2bb6, 0x789b, - 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0, 0x2bf6, - 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2bee, 0x0048, - 0x2bd3, 0x0078, 0x2bf0, 0xa380, 0x0002, 0xa102, 0x00c8, 0x2bee, - 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, - 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006, 0x0c7f, - 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2ba8, 0x0078, 0x2b59, - 0x24a8, 0x7aa8, 0x00f0, 0x2bf0, 0x0078, 0x2bc1, 0xa284, 0x00f0, - 0xa086, 0x0020, 0x00c0, 0x2c56, 0x8318, 0x8318, 0x2300, 0xa102, - 0x0040, 0x2c06, 0x0048, 0x2c06, 0x0078, 0x2c53, 0xa286, 0x0023, - 0x0040, 0x2bb6, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, - 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010, - 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, - 0xa184, 0x0010, 0x0040, 0x2c2a, 0x1078, 0x37b9, 0x1078, 0x35d6, - 0x0078, 0x2c39, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48, - 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2ba7, 0x1078, 0x37b9, 0x1078, - 0x34c7, 0x88ff, 0x0040, 0x2ba7, 0x789b, 0x0060, 0x2800, 0x78aa, - 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c4d, 0x782b, - 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, - 0x0065, 0x0078, 0x2438, 0x7aa8, 0x0078, 0x2bc1, 0x8318, 0x2300, - 0xa102, 0x0040, 0x2c5f, 0x0048, 0x2c5f, 0x0078, 0x2bc1, 0xa284, - 0x0080, 0x00c0, 0x367b, 0x0078, 0x3673, 0x0078, 0x367b, 0x0078, - 0x366b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, - 0x0040, 0x2c74, 0x1078, 0x23ca, 0x7aa8, 0xa294, 0x00ff, 0x78a8, - 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x366b, 0x0079, 0x2c80, - 0x366b, 0x3414, 0x366b, 0x356b, 0xa282, 0x0000, 0x00c0, 0x2c8a, - 0x1078, 0x23ca, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065, - 0x0078, 0x2438, 0xa282, 0x0003, 0x00c0, 0x2c98, 0x1078, 0x23ca, - 0xa484, 0x8000, 0x00c0, 0x2cbb, 0x706c, 0xa005, 0x0040, 0x2ca2, - 0x1078, 0x23ca, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078, 0x37bd, - 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x2ca6, 0x1078, 0x3693, 0x706f, 0x0002, 0x2009, 0x5038, 0x200b, - 0x0009, 0x0078, 0x2cbd, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b, - 0x0065, 0x0078, 0x2438, 0xa282, 0x0004, 0x0050, 0x2cc9, 0x1078, - 0x23ca, 0x2300, 0x0079, 0x2ccc, 0x2ccf, 0x2db8, 0x2deb, 0xa286, - 0x0003, 0x0040, 0x2cd5, 0x1078, 0x23ca, 0x2001, 0x0000, 0x007e, - 0x68c0, 0xa005, 0x0040, 0x2cde, 0x7003, 0x0003, 0x68a0, 0xa084, - 0x2000, 0x0040, 0x2ce7, 0x6008, 0xa085, 0x0002, 0x600a, 0x007f, - 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2cee, 0x2461, 0x2cf8, - 0x2cf8, 0x2eed, 0x2f29, 0x2461, 0x2f29, 0x2cf6, 0x1078, 0x23ca, - 0xa684, 0x1000, 0x00c0, 0x2d00, 0x1078, 0x4633, 0x0040, 0x2d92, - 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d48, 0xa186, 0x0008, 0x00c0, - 0x2d17, 0x1078, 0x33c4, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, - 0x3366, 0x0040, 0x2d48, 0x1078, 0x4633, 0x0078, 0x2d2f, 0xa186, - 0x0028, 0x00c0, 0x2d48, 0x1078, 0x4633, 0x6008, 0xa084, 0xffef, - 0x600a, 0x6018, 0xa005, 0x0040, 0x2d2f, 0x8001, 0x601a, 0xa005, - 0x0040, 0x2d2f, 0x8001, 0xa005, 0x0040, 0x2d2f, 0x601e, 0x6820, - 0xa084, 0x0001, 0x0040, 0x2461, 0x6820, 0xa084, 0xfffe, 0x6822, - 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, - 0xa005, 0x2d00, 0x00c0, 0x2d45, 0x6002, 0x6006, 0x0078, 0x2461, - 0x017e, 0x1078, 0x2e1c, 0x017f, 0xa684, 0xdf00, 0x681e, 0x682b, - 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2d92, 0xa186, 0x0002, 0x00c0, - 0x2d92, 0xa684, 0x0800, 0x00c0, 0x2d65, 0xa684, 0x0060, 0x0040, - 0x2d65, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084, 0x0800, - 0x00c0, 0x2d92, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, - 0xa290, 0x5280, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100, 0x00c0, - 0x2d7b, 0x0078, 0x2d81, 0x8210, 0x2204, 0xa085, 0x0018, 0x2012, - 0x8211, 0xa384, 0x0400, 0x0040, 0x2d8e, 0x68a0, 0xa084, 0x0100, - 0x00c0, 0x2d8e, 0x1078, 0x2ea0, 0x0078, 0x2461, 0x6008, 0xa085, - 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040, 0x2d9a, - 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x33b5, 0x1078, - 0x33c4, 0x00c0, 0x2da7, 0x6008, 0xa084, 0xffef, 0x600a, 0x6820, - 0xa084, 0x0001, 0x00c0, 0x2db0, 0x1078, 0x33ae, 0x0078, 0x2db4, - 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c53, 0x0078, 0x2461, - 0xa282, 0x0004, 0x0048, 0x2dbe, 0x1078, 0x23ca, 0x2200, 0x0079, - 0x2dc1, 0x2dbc, 0x2dc5, 0x2dd2, 0x2dc5, 0x7000, 0xa086, 0x0005, - 0x0040, 0x2dce, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, 0x0065, - 0x0078, 0x2438, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, - 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0040, - 0x2de7, 0xa186, 0x0000, 0x0040, 0x2de7, 0x0078, 0x366b, 0x781b, - 0x0065, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822, 0x82ff, - 0x00c0, 0x2df6, 0x1078, 0x368f, 0x0078, 0x2dfd, 0x8211, 0x0040, - 0x2dfb, 0x1078, 0x23ca, 0x1078, 0x369f, 0x782b, 0x3008, 0x781b, - 0x0065, 0x0078, 0x2438, 0x702c, 0x8003, 0x0048, 0x2e0d, 0x2019, - 0x4c5b, 0x1078, 0x2255, 0x702f, 0x8000, 0x1078, 0x38de, 0x7830, - 0xa084, 0x00c0, 0x00c0, 0x2e19, 0x0018, 0x2e19, 0x791a, 0xa006, - 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0, 0x2e26, - 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e9f, 0xa684, 0x0800, - 0x00c0, 0x2e48, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x0800, - 0x00c0, 0x2e48, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c, 0xa005, - 0x00c0, 0x2e40, 0x2200, 0xa105, 0x0040, 0x2e47, 0x703f, 0x0015, - 0x7000, 0xa086, 0x0006, 0x0040, 0x2e47, 0x1078, 0x4633, 0x007c, - 0xa684, 0x0020, 0x0040, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e56, - 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084, - 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e50, 0x703c, 0xa005, - 0x00c0, 0x2e64, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e, 0x6a32, - 0x0078, 0x2e40, 0xa684, 0x4000, 0x0040, 0x2e74, 0x682f, 0x0000, - 0x6833, 0x0000, 0x0078, 0x2e40, 0x68b4, 0xa084, 0x4800, 0xa635, - 0xa684, 0x4000, 0x00c0, 0x2e6e, 0x703c, 0xa005, 0x00c0, 0x2e82, - 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8, 0x2e89, - 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, - 0x2100, 0xa205, 0x00c0, 0x2e96, 0x0078, 0x2e40, 0x7000, 0xa086, - 0x0006, 0x0040, 0x2e9f, 0x1078, 0x49ed, 0x0078, 0x2e40, 0x007c, - 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040, 0x2eac, - 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f, 0x0000, - 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, - 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, - 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2ec7, 0x2461, - 0x2ed1, 0x2eda, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x2ecf, 0x1078, - 0x23ca, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2eda, 0x1078, 0x33ae, - 0x0078, 0x2ee0, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, - 0x2021, 0x505a, 0x2404, 0xa005, 0x0040, 0x2ee9, 0x2020, 0x0078, - 0x2ee2, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x33b5, 0x1078, - 0x33c4, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000, 0x789b, - 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4a35, 0xa684, 0x0800, - 0x0040, 0x2f06, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818, 0xa084, - 0x8000, 0x0040, 0x2f16, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2f14, - 0x681b, 0x001e, 0x0078, 0x2f16, 0x681b, 0x0000, 0x2021, 0x505a, - 0x2404, 0xad06, 0x0040, 0x2f1d, 0x7460, 0x6800, 0x2022, 0x68c3, - 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1c53, 0x0078, - 0x2461, 0x1078, 0x2e1c, 0x682b, 0x0000, 0x2001, 0x000e, 0x6f14, - 0x1078, 0x38e4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084, 0x8000, - 0x0040, 0x2f3c, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x706f, - 0x0000, 0x0078, 0x2461, 0x7000, 0xa005, 0x00c0, 0x2f49, 0x0078, - 0x2461, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000, 0x681b, 0x0014, - 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085, 0x00ff, - 0x6822, 0x7000, 0x0079, 0x2f5c, 0x2461, 0x2f66, 0x2f66, 0x2f68, - 0x2f68, 0x2f68, 0x2f68, 0x2f64, 0x1078, 0x23ca, 0x1078, 0x33c4, - 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x337e, 0x2300, 0x0079, - 0x2f71, 0x2f74, 0x2f76, 0x2faf, 0x1078, 0x23ca, 0x7000, 0x0079, - 0x2f79, 0x2461, 0x2f83, 0x2f83, 0x2f9e, 0x2f83, 0x2fab, 0x2f9e, - 0x2f81, 0x1078, 0x23ca, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, - 0x2f9a, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, - 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4633, 0x1078, 0x48f7, - 0x0078, 0x3854, 0xa684, 0x2000, 0x0040, 0x2f8d, 0x6818, 0xa084, - 0x8000, 0x0040, 0x2fab, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, - 0x2fab, 0x681b, 0x0007, 0x1078, 0x3868, 0x0078, 0x2438, 0x1078, - 0x23ca, 0x2300, 0x0079, 0x2fb4, 0x2fb7, 0x2fb9, 0x2fec, 0x1078, - 0x23ca, 0x7000, 0x0079, 0x2fbc, 0x2461, 0x2fc6, 0x2fc6, 0x2fe1, - 0x2fc6, 0x2fe8, 0x2fe1, 0x2fc4, 0x1078, 0x23ca, 0xa684, 0x0060, - 0xa086, 0x0060, 0x00c0, 0x2fdd, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff, - 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078, - 0x4633, 0x1078, 0x48f7, 0x0078, 0x3854, 0xa684, 0x2000, 0x0040, - 0x2fd0, 0x6818, 0xa084, 0x8000, 0x0040, 0x2fe8, 0x681b, 0x0007, - 0x781b, 0x00d2, 0x0078, 0x2438, 0x6820, 0xa085, 0x0004, 0x6822, - 0x1078, 0x381f, 0xa6b5, 0x0800, 0x1078, 0x368f, 0x782b, 0x3008, - 0x781b, 0x0065, 0x0078, 0x2438, 0x2300, 0x0079, 0x2fff, 0x3002, - 0x3004, 0x3006, 0x1078, 0x23ca, 0x0078, 0x367b, 0xa684, 0x0400, - 0x00c0, 0x302f, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3016, 0x78ec, - 0xa084, 0x0003, 0x0040, 0x3016, 0x782b, 0x3009, 0x789b, 0x0060, - 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020, - 0x0040, 0x3027, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x302b, 0x2001, - 0x0014, 0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x3067, 0x7a90, - 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3065, - 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3056, 0x7ba8, - 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3049, 0x2009, 0xfff7, 0x0078, - 0x304f, 0xa386, 0x0003, 0x00c0, 0x3056, 0x2009, 0xffef, 0x0c7e, - 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, - 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, - 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3854, 0x297d, - 0x2988, 0x3071, 0x3079, 0x306f, 0x306f, 0x3854, 0x3854, 0x1078, - 0x23ca, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, - 0x385e, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, - 0x3854, 0x79e4, 0xa184, 0x0030, 0x0040, 0x308b, 0x78ec, 0xa084, - 0x0003, 0x00c0, 0x30b2, 0x7000, 0xa086, 0x0004, 0x00c0, 0x30a5, - 0x706c, 0xa086, 0x0002, 0x00c0, 0x309b, 0x2011, 0x0002, 0x2019, - 0x0000, 0x0078, 0x2827, 0x706c, 0xa086, 0x0006, 0x0040, 0x3095, - 0x706c, 0xa086, 0x0004, 0x0040, 0x3095, 0x7000, 0xa086, 0x0000, - 0x0040, 0x2438, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014, - 0x0078, 0x2cd7, 0xa184, 0x0007, 0x0079, 0x30b6, 0x3854, 0x3854, - 0x30be, 0x3854, 0x38b9, 0x38b9, 0x3854, 0x3854, 0xa684, 0x0080, - 0x0040, 0x30ed, 0x7194, 0x81ff, 0x0040, 0x30ed, 0xa182, 0x000d, - 0x00d0, 0x30ce, 0x7097, 0x0000, 0x0078, 0x30d3, 0xa182, 0x000c, - 0x7096, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, - 0x147e, 0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00, - 0x2098, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, - 0x147f, 0x137f, 0x157f, 0x0078, 0x385e, 0xa684, 0x0400, 0x00c0, - 0x312e, 0x6820, 0xa084, 0x0001, 0x0040, 0x385e, 0xa68c, 0x0060, - 0xa684, 0x0060, 0x0040, 0x3102, 0xa086, 0x0060, 0x00c0, 0x3102, - 0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060, - 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a, - 0x78aa, 0x8008, 0x810c, 0x0040, 0x33dd, 0xa18c, 0x00f8, 0x00c0, - 0x33dd, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, - 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, - 0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x385e, 0x6818, 0xa084, - 0x8000, 0x0040, 0x3135, 0x681b, 0x0008, 0x781b, 0x00c8, 0x0078, - 0x2438, 0x2300, 0x0079, 0x313c, 0x3141, 0x31e0, 0x313f, 0x1078, - 0x23ca, 0x7000, 0xa084, 0x0007, 0x0079, 0x3146, 0x2461, 0x3150, - 0x3185, 0x315b, 0x314e, 0x2461, 0x314e, 0x314e, 0x1078, 0x23ca, - 0x681c, 0xa084, 0x2000, 0x0040, 0x3169, 0x6008, 0xa085, 0x0002, - 0x600a, 0x0078, 0x3169, 0x68c0, 0xa005, 0x00c0, 0x3185, 0x6920, - 0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078, - 0x317f, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005, - 0x00c0, 0x3173, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x317f, - 0x7014, 0x68ba, 0x7130, 0xa188, 0x7300, 0x0078, 0x3181, 0x2009, - 0x7400, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060, - 0x0040, 0x31de, 0xa684, 0x0800, 0x00c0, 0x3199, 0xa684, 0x7fff, - 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4633, 0x0078, - 0x31de, 0xa684, 0x0020, 0x0040, 0x31ae, 0x68c0, 0xa005, 0x0040, - 0x31a5, 0x1078, 0x4a35, 0x0078, 0x31a8, 0xa006, 0x1078, 0x49ed, - 0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31b4, 0x1078, 0x37ca, - 0x69aa, 0x6aa6, 0x1078, 0x49ed, 0xa684, 0x8000, 0x0040, 0x31de, - 0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078, 0x38e4, 0x2010, - 0x2001, 0x0078, 0x1078, 0x38e4, 0x2008, 0xa684, 0x0020, 0x00c0, - 0x31d6, 0x2001, 0x007a, 0x1078, 0x38e4, 0x801b, 0x00c8, 0x31d1, - 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, - 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x0078, 0x2461, - 0x0078, 0x367b, 0x7037, 0x0000, 0xa282, 0x0006, 0x0050, 0x31ea, - 0x1078, 0x23ca, 0x7000, 0xa084, 0x0007, 0x10c0, 0x398a, 0x2300, - 0x0079, 0x31f2, 0x31f5, 0x321e, 0x3232, 0x2200, 0x0079, 0x31f8, - 0x321c, 0x367b, 0x31fe, 0x321c, 0x324e, 0x3290, 0x7003, 0x0005, - 0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031, 0x2003, - 0x0000, 0x8000, 0x0070, 0x320e, 0x0078, 0x3207, 0x157f, 0xad80, - 0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700, 0x6823, 0x0800, - 0x6827, 0x0003, 0x0078, 0x366b, 0x1078, 0x23ca, 0x7003, 0x0005, - 0x2001, 0x7510, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200, - 0x0079, 0x322a, 0x367b, 0x3230, 0x3230, 0x324e, 0x3230, 0x367b, - 0x1078, 0x23ca, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, - 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x323e, 0x3246, 0x3244, - 0x3244, 0x3246, 0x3244, 0x3246, 0x1078, 0x23ca, 0x1078, 0x369f, - 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7003, 0x0002, - 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, - 0xa215, 0x2069, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, - 0x0040, 0x3269, 0x6814, 0xa206, 0x0040, 0x3285, 0x6800, 0x0078, - 0x325c, 0x7003, 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x7036, - 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x327a, - 0x0078, 0x3273, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, - 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, - 0xa084, 0x0c00, 0x0040, 0x32df, 0x1078, 0x3697, 0x0078, 0x32df, - 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, - 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0xa1e8, - 0x7300, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x32af, - 0x6814, 0xa206, 0x0040, 0x32ca, 0x6800, 0x0078, 0x32a2, 0x7003, - 0x0005, 0x2001, 0x7510, 0x2068, 0x704a, 0x157e, 0x20a9, 0x0031, - 0x2003, 0x0000, 0x8000, 0x0070, 0x32bf, 0x0078, 0x32b8, 0x157f, - 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, - 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, - 0x32df, 0xa084, 0x0800, 0x0040, 0x32d9, 0x1078, 0x369b, 0x0078, - 0x32df, 0x1078, 0x3697, 0x708b, 0x0000, 0x0078, 0x32df, 0x027e, - 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5280, - 0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e, 0xa684, 0x0060, - 0x0040, 0x3337, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, - 0x3319, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, - 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3337, 0x68c0, 0xa005, - 0x0040, 0x3312, 0x7003, 0x0003, 0x682b, 0x0000, 0x1078, 0x48e6, - 0x0078, 0x3314, 0x1078, 0x48f7, 0xa6b5, 0x2000, 0x7e5a, 0x0078, - 0x3337, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, - 0x3337, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xa6b4, 0xbfff, - 0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040, 0x3335, 0x7003, - 0x0003, 0x1078, 0x48e6, 0x0078, 0x3337, 0x1078, 0x4942, 0x077f, - 0x1078, 0x37bd, 0x2009, 0x0065, 0xa684, 0x0004, 0x0040, 0x3358, - 0x78e4, 0xa084, 0x0030, 0x0040, 0x3350, 0x78ec, 0xa084, 0x0003, - 0x0040, 0x3350, 0x782b, 0x3008, 0x2009, 0x0065, 0x0078, 0x3358, - 0x0f7e, 0x2079, 0x5000, 0x1078, 0x4633, 0x0f7f, 0x0040, 0x2461, - 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa080, 0x5280, 0x2048, 0x0078, 0x2438, 0x6020, 0xa005, - 0x0040, 0x3372, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a, - 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4633, 0x6817, 0x0000, - 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, - 0x0007, 0x0079, 0x3383, 0x2461, 0x338d, 0x338d, 0x33aa, 0x3395, - 0x3393, 0x3395, 0x338b, 0x1078, 0x23ca, 0x1078, 0x33b5, 0x1078, - 0x33ae, 0x1078, 0x1c53, 0x0078, 0x2461, 0x706c, 0x706f, 0x0000, - 0x7093, 0x0000, 0x0079, 0x339c, 0x33a6, 0x33a6, 0x33a4, 0x33a4, - 0x33a4, 0x33a6, 0x33a4, 0x33a6, 0x0079, 0x2840, 0x706f, 0x0000, - 0x0078, 0x2461, 0x681b, 0x0000, 0x0078, 0x2eed, 0x6800, 0xa005, - 0x00c0, 0x33b3, 0x6002, 0x6006, 0x007c, 0x6010, 0xa005, 0x0040, - 0x33be, 0x8001, 0x00d0, 0x33be, 0x1078, 0x23ca, 0x6012, 0x6008, - 0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x33ca, - 0x8001, 0x601a, 0x007c, 0x1078, 0x38de, 0x681b, 0x0018, 0x0078, - 0x3401, 0x1078, 0x38de, 0x681b, 0x0019, 0x0078, 0x3401, 0x1078, - 0x38de, 0x681b, 0x001a, 0x0078, 0x3401, 0x1078, 0x38de, 0x681b, - 0x0003, 0x0078, 0x3401, 0x7780, 0x1078, 0x37bd, 0x7184, 0xa18c, - 0x00ff, 0xa1e8, 0x7300, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, - 0x33f3, 0x0078, 0x2461, 0x6814, 0x7280, 0xa206, 0x0040, 0x33fb, - 0x6800, 0x0078, 0x33ec, 0x6800, 0x200a, 0x681b, 0x0005, 0x708b, - 0x0000, 0x1078, 0x33b5, 0x6820, 0xa084, 0x0001, 0x00c0, 0x340a, - 0x1078, 0x33ae, 0x1078, 0x33c4, 0x681f, 0x0000, 0x6823, 0x0020, - 0x1078, 0x1c53, 0x0078, 0x2461, 0xa282, 0x0003, 0x00c0, 0x366b, - 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x6920, 0xa18d, - 0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x3478, 0xa18c, 0xfeff, - 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x3462, 0xa482, 0x000c, 0x0048, - 0x3435, 0x0040, 0x3435, 0x2021, 0x000c, 0x852b, 0x852b, 0x1078, - 0x372e, 0x0040, 0x343f, 0x1078, 0x3531, 0x0078, 0x346b, 0x1078, - 0x36e9, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, - 0x3558, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922, 0x7e58, 0xa6b5, - 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x345c, 0x782b, 0x3008, - 0x781b, 0x0056, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0065, - 0x0078, 0x2438, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, - 0x1078, 0x3558, 0x0c7f, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x3474, - 0x781b, 0x0058, 0x0078, 0x2438, 0x781b, 0x0065, 0x0078, 0x2438, - 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000, 0x0040, 0x34b8, - 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x348c, - 0x0040, 0x348c, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x3491, - 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, - 0x34a1, 0xa282, 0x0019, 0x00c8, 0x34a7, 0x2011, 0x0019, 0x0078, - 0x34a7, 0xa282, 0x000c, 0x00c8, 0x34a7, 0x2011, 0x000c, 0x2200, - 0xa502, 0x00c8, 0x34ac, 0x2228, 0x1078, 0x36ed, 0x852b, 0x852b, - 0x1078, 0x372e, 0x0040, 0x34b8, 0x1078, 0x3531, 0x0078, 0x34bc, - 0x1078, 0x36e9, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a, - 0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e, - 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x34df, 0x6010, 0xa084, - 0x000f, 0x00c0, 0x34d9, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f, - 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3506, 0x68a0, - 0xa084, 0x0200, 0x00c0, 0x34d9, 0x6208, 0xa294, 0x00ff, 0x7018, - 0xa086, 0x0028, 0x00c0, 0x34f4, 0xa282, 0x0019, 0x00c8, 0x34fa, - 0x2011, 0x0019, 0x0078, 0x34fa, 0xa282, 0x000c, 0x00c8, 0x34fa, - 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, - 0x0048, 0x3506, 0x0040, 0x3506, 0x2019, 0x000c, 0x78ab, 0x0001, - 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, - 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960, - 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, - 0x3521, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, - 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, - 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3538, 0x0c7f, 0x007c, - 0x2008, 0xa084, 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae, - 0x6412, 0x78a4, 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, - 0x6016, 0x788a, 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084, - 0x00ff, 0xa405, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c, - 0x0c7e, 0x7054, 0x2060, 0x1078, 0x355f, 0x0c7f, 0x007c, 0x6018, - 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, - 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0, 0x366b, 0x7aa8, - 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35b4, - 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, - 0x366b, 0x1078, 0x35fd, 0x1078, 0x3558, 0xa980, 0x0001, 0x200c, - 0x1078, 0x37b9, 0x1078, 0x34c7, 0x88ff, 0x0040, 0x35a7, 0x789b, - 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, - 0x0400, 0x00c0, 0x35a1, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, - 0x2438, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x7e58, - 0xa684, 0x0400, 0x00c0, 0x35b0, 0x781b, 0x0058, 0x0078, 0x2438, - 0x781b, 0x0065, 0x0078, 0x2438, 0xa282, 0x0002, 0x00c8, 0x35bc, - 0xa284, 0x0001, 0x0040, 0x35c6, 0x7154, 0xa188, 0x0000, 0x210c, - 0xa18c, 0x2000, 0x00c0, 0x35c6, 0x2011, 0x0000, 0x1078, 0x36db, - 0x1078, 0x35fd, 0x1078, 0x3558, 0x7858, 0xa085, 0x0004, 0x785a, - 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x0c7e, 0x027e, - 0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x35ed, - 0x6014, 0xa084, 0x0040, 0x00c0, 0x35eb, 0xa18c, 0xffef, 0x6106, - 0xa006, 0x0078, 0x35fa, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, - 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, - 0x0200, 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060, - 0x1078, 0x3604, 0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3609, 0x2011, - 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf, - 0xa205, 0x78a6, 0x788a, 0x6016, 0x6004, 0xa084, 0xffef, 0x6006, - 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3622, 0x007f, - 0x0078, 0x3625, 0x007f, 0x0078, 0x3667, 0xa684, 0x0020, 0x0040, - 0x3667, 0x7888, 0xa084, 0x0040, 0x0040, 0x3667, 0x7bb8, 0xa384, - 0x003f, 0x831b, 0x00c8, 0x3635, 0x8000, 0xa005, 0x0040, 0x364b, - 0x831b, 0x00c8, 0x363e, 0x8001, 0x0040, 0x3663, 0xa684, 0x4000, - 0x0040, 0x364b, 0x78b8, 0x801b, 0x00c8, 0x3647, 0x8000, 0xa084, - 0x003f, 0x00c0, 0x3663, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc, - 0x2001, 0x0001, 0xa108, 0x00c8, 0x3657, 0xa291, 0x0000, 0x79d2, - 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x49ed, 0x781b, 0x0064, 0x1078, - 0x4872, 0x0078, 0x2438, 0x781b, 0x0064, 0x0078, 0x2438, 0x781b, - 0x0065, 0x0078, 0x2438, 0x1078, 0x36a3, 0x782b, 0x3008, 0x781b, - 0x0065, 0x0078, 0x2438, 0x1078, 0x368f, 0x782b, 0x3008, 0x781b, - 0x0065, 0x0078, 0x2438, 0x6827, 0x0002, 0x1078, 0x3697, 0x78e4, - 0xa084, 0x0030, 0x0040, 0x2461, 0x78ec, 0xa084, 0x0003, 0x0040, - 0x2461, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x2001, - 0x0005, 0x0078, 0x36a5, 0x2001, 0x000c, 0x0078, 0x36a5, 0x2001, - 0x0006, 0x0078, 0x36a5, 0x2001, 0x000d, 0x0078, 0x36a5, 0x2001, - 0x0009, 0x0078, 0x36a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa, - 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c, - 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, - 0x5280, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, - 0x36c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008, - 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040, - 0x36d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010, - 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, - 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, - 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, - 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, - 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, - 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, - 0x2001, 0x5046, 0x2004, 0xa082, 0x0028, 0x0040, 0x3717, 0x2021, - 0x37a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x371d, 0x2021, - 0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404, - 0xa084, 0xfff0, 0xa106, 0x0040, 0x372c, 0x8420, 0x2300, 0xa210, - 0x0070, 0x372c, 0x0078, 0x371f, 0x157f, 0x007c, 0x157e, 0x2009, - 0x5046, 0x210c, 0xa182, 0x0032, 0x0048, 0x3742, 0x0040, 0x3746, - 0x2009, 0x3792, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, - 0x0078, 0x3758, 0xa182, 0x0028, 0x0040, 0x3750, 0x2009, 0x37a0, - 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3758, - 0x2009, 0x37ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, - 0x2200, 0xa502, 0x0040, 0x3768, 0x0048, 0x3768, 0x8108, 0x2300, - 0xa210, 0x0070, 0x3765, 0x0078, 0x3758, 0x157f, 0xa006, 0x007c, - 0x157f, 0xa582, 0x0064, 0x00c8, 0x3777, 0x7808, 0xa085, 0x0070, - 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3777, 0x78ec, - 0xa084, 0x0300, 0x0040, 0x377f, 0x2104, 0x0078, 0x3790, 0x2104, - 0xa09e, 0x1102, 0x00c0, 0x3790, 0x2001, 0x04fd, 0x2004, 0xa082, - 0x0005, 0x0048, 0x378f, 0x2001, 0x1201, 0x0078, 0x3790, 0x2104, - 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404, - 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07, - 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805, - 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202, - 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04, - 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b, - 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0, - 0x5300, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x37d1, - 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e, - 0x2079, 0x0100, 0x2009, 0x5040, 0x2091, 0x8000, 0x2104, 0x0079, - 0x37e1, 0x3817, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb, 0x37eb, - 0x381b, 0x1078, 0x23ca, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, - 0x00c0, 0x37ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0, - 0x37f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000, - 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3817, 0x0018, 0x3817, - 0x681c, 0xa084, 0x0020, 0x00c0, 0x3815, 0x0e7e, 0x2071, 0x5040, - 0x1078, 0x3868, 0x0e7f, 0x0078, 0x3817, 0x781b, 0x00d2, 0x2091, - 0x8001, 0x0f7f, 0x007c, 0x1078, 0x3a42, 0x0078, 0x3817, 0x0c7e, - 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, - 0x5280, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3852, 0x6108, 0xa194, - 0xff00, 0x0040, 0x3852, 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106, - 0x0040, 0x3841, 0x2001, 0x0032, 0xa106, 0x0040, 0x3845, 0x0078, - 0x3849, 0x2009, 0x0020, 0x0078, 0x384b, 0x2009, 0x003f, 0x0078, - 0x384b, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, - 0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065, 0x0078, 0x2438, - 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2438, 0x781b, 0x0058, - 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2438, - 0x2009, 0x5020, 0x210c, 0xa186, 0x0000, 0x0040, 0x387c, 0xa186, - 0x0001, 0x0040, 0x387f, 0x2009, 0x5038, 0x200b, 0x000b, 0x706f, - 0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00cc, 0x007c, 0x2009, - 0x5038, 0x200b, 0x000a, 0x007c, 0x2009, 0x5020, 0x210c, 0xa186, - 0x0000, 0x0040, 0x389f, 0xa186, 0x0001, 0x0040, 0x3899, 0x2009, - 0x5038, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, - 0x2438, 0x2009, 0x5038, 0x200b, 0x000a, 0x0078, 0x2438, 0x782b, - 0x3008, 0x781b, 0x00cc, 0x0078, 0x2438, 0x781b, 0x00d2, 0x0078, - 0x2438, 0x782b, 0x3008, 0x781b, 0x00d2, 0x0078, 0x2438, 0x781b, - 0x0093, 0x0078, 0x2438, 0x782b, 0x3008, 0x781b, 0x0093, 0x0078, - 0x2438, 0x6818, 0xa084, 0x8000, 0x0040, 0x38c0, 0x681b, 0x001d, - 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x2438, 0x007e, 0x7830, - 0xa084, 0x00c0, 0x00c0, 0x38dc, 0x7808, 0xa084, 0xfffc, 0x780a, - 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, - 0x38dc, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c, 0x7044, 0xa085, - 0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830, 0xa084, 0x0040, - 0x00c0, 0x38e5, 0x0098, 0x38f0, 0x007f, 0x789a, 0x78ac, 0x007c, - 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x38ff, 0x0098, 0x38fd, 0x007f, - 0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f, 0x007c, 0x78ec, - 0xa084, 0x0002, 0x00c0, 0x461d, 0xa784, 0x007d, 0x00c0, 0x3913, - 0x2700, 0x1078, 0x23ca, 0xa784, 0x0001, 0x00c0, 0x2f43, 0xa784, - 0x0070, 0x0040, 0x3923, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2375, - 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x3930, 0x784b, - 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461, 0x0078, 0x3854, - 0xa784, 0x0004, 0x0040, 0x3963, 0x78b8, 0xa084, 0x4001, 0x0040, - 0x3963, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2461, - 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x3963, 0x78c0, - 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00d2, 0x0078, 0x2438, - 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040, 0x395f, 0x681b, - 0x0015, 0xa684, 0x4000, 0x0040, 0x395f, 0x681b, 0x0007, 0x1078, - 0x3868, 0x0078, 0x2438, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, - 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, - 0xa084, 0x0003, 0x0040, 0x2944, 0x0018, 0x2438, 0x0078, 0x3673, - 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, - 0x5280, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e, - 0x2a60, 0x007c, 0x0079, 0x398c, 0x3994, 0x3995, 0x3994, 0x3997, - 0x3994, 0x3994, 0x3994, 0x399c, 0x007c, 0x1078, 0x33c4, 0x1078, - 0x4633, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005, 0x0040, 0x39a9, - 0x2068, 0x1078, 0x1b45, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x70a3, - 0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x5040, 0x7000, - 0xa086, 0x0007, 0x00c0, 0x39c0, 0x6110, 0x70bc, 0xa106, 0x00c0, - 0x39c0, 0x0e7f, 0x1078, 0x1b52, 0x1078, 0x39c6, 0xa006, 0x007c, - 0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, - 0x2071, 0x5040, 0x0078, 0x21d9, 0x785b, 0x0000, 0x70af, 0x000e, - 0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040, 0x39db, 0x70a3, - 0x0000, 0x0078, 0x39e1, 0x70b3, 0x0000, 0x1078, 0x1b6e, 0x0040, - 0x39e7, 0x70ac, 0x6826, 0x1078, 0x3ac2, 0x0078, 0x39db, 0x017f, - 0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061, 0x7410, 0x6000, - 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x39ff, 0x6800, 0x601e, - 0x1078, 0x193d, 0x6008, 0x8000, 0x600a, 0x0078, 0x39f2, 0x6018, - 0xa06d, 0x0040, 0x3a09, 0x6800, 0x601a, 0x1078, 0x193d, 0x0078, - 0x39ff, 0xace0, 0x0008, 0x0070, 0x3a0f, 0x0078, 0x39ef, 0x709c, - 0xa084, 0x8000, 0x0040, 0x3a16, 0x1078, 0x3b3c, 0x0d7f, 0x0c7f, - 0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804, 0xa084, 0x000f, - 0x0079, 0x3a22, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, - 0x3a34, 0x3a3a, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a32, 0x3a3c, - 0x3a32, 0x3a34, 0x1078, 0x23ca, 0x1078, 0x4466, 0x1078, 0x193d, - 0x0078, 0x3a40, 0x6827, 0x000b, 0x1078, 0x4466, 0x1078, 0x3ac2, - 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098, 0x3a5e, 0x7830, - 0xa084, 0x00c0, 0x00c0, 0x3a5e, 0x0d7e, 0x1078, 0x45c5, 0x2d00, - 0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827, 0x0084, 0x1078, - 0x457e, 0x1078, 0x3ac2, 0x0d7f, 0x0078, 0x3a90, 0x7948, 0xa185, - 0x4000, 0x784a, 0x0098, 0x3a67, 0x794a, 0x0078, 0x3a4c, 0x7828, - 0xa086, 0x1834, 0x00c0, 0x3a70, 0xa185, 0x0004, 0x0078, 0x3a77, - 0x7828, 0xa186, 0x1814, 0x00c0, 0x3a64, 0xa185, 0x000c, 0x784a, - 0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084, 0x00ff, 0xa085, - 0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x6827, 0x0002, - 0x6827, 0x0084, 0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x457e, - 0x127f, 0x007c, 0x0d7e, 0x6b14, 0x1078, 0x1be0, 0x0040, 0x3a9f, - 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3a94, 0x0d7f, - 0x007c, 0x0d7e, 0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b7e, - 0x0040, 0x3aaf, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0d7f, - 0x007c, 0x0d7e, 0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bb1, 0x0040, - 0x3ac0, 0x2068, 0x6827, 0x0002, 0x1078, 0x3ac2, 0x0078, 0x3ab5, - 0x0d7f, 0x007c, 0x0c7e, 0x6914, 0x1078, 0x3b33, 0x6904, 0xa18c, - 0x00ff, 0xa186, 0x0006, 0x0040, 0x3add, 0xa186, 0x000d, 0x0040, - 0x3afc, 0xa186, 0x0017, 0x00c0, 0x3ad9, 0x1078, 0x193d, 0x0078, - 0x3adb, 0x1078, 0x1c55, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048, - 0x3afa, 0x6006, 0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3aea, - 0xa18d, 0x8000, 0xa684, 0x0004, 0x0040, 0x3af0, 0xa18d, 0x0002, - 0x691e, 0x6823, 0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a, - 0x0078, 0x3ad9, 0x1078, 0x23ca, 0x6018, 0xa005, 0x00c0, 0x3b0b, - 0x6008, 0x8001, 0x0048, 0x3b0b, 0x600a, 0x601c, 0x6802, 0x2d00, - 0x601e, 0x0078, 0x3b21, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040, - 0x3b14, 0x2008, 0x0078, 0x3b0d, 0x6802, 0x2d0a, 0x6008, 0x8001, - 0x0048, 0x3adb, 0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078, - 0x3b05, 0x157e, 0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x191a, - 0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f, - 0x157f, 0x0078, 0x3ad9, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003, - 0xa080, 0x7410, 0x2060, 0x007c, 0x2019, 0x5051, 0x2304, 0xa085, - 0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a, - 0x007c, 0x2019, 0x5051, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019, - 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c, - 0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x2438, - 0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000, - 0x0018, 0x23ef, 0x1078, 0x1b6e, 0x0040, 0x3b91, 0x2009, 0x500f, - 0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040, - 0x3b85, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3b81, 0x6827, - 0x0017, 0x1078, 0x3ac2, 0x0078, 0x3b60, 0x7000, 0xa086, 0x0007, - 0x00c0, 0x3be3, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078, - 0x3b98, 0x7040, 0xa086, 0x0001, 0x0040, 0x2471, 0x0078, 0x2438, - 0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ba1, 0xa6b5, - 0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72, - 0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3bb9, 0x789b, - 0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, - 0x1000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3bc5, 0xa6b5, 0x0400, - 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0xa684, 0x0200, 0x0040, - 0x3bdf, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040, - 0x3bdd, 0x682c, 0xa084, 0x0001, 0x0040, 0x3bdd, 0x7888, 0xa084, - 0x0040, 0x0040, 0x3bdd, 0xa6b5, 0x8000, 0x1078, 0x45ad, 0x7e5a, - 0x6eb6, 0x0078, 0x45e4, 0x1078, 0x38c6, 0x00c0, 0x3c6c, 0x702c, - 0x8004, 0x0048, 0x3bf1, 0x2019, 0x4cfd, 0x1078, 0x2255, 0x702f, - 0x0001, 0x2011, 0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814, - 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002, - 0x0040, 0x3c0a, 0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa, - 0xa290, 0x0002, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c18, 0xa6b5, - 0x0400, 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c26, - 0x681c, 0xa084, 0x8000, 0x00c0, 0x3c26, 0xa6b5, 0x0800, 0x6820, - 0xa084, 0x0100, 0x0040, 0x3c26, 0xa6b5, 0x4000, 0x681c, 0xa084, - 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3c72, 0x2004, 0xa635, - 0xa684, 0x0100, 0x0040, 0x3c40, 0x682c, 0xa084, 0x0001, 0x0040, - 0x3c40, 0x7888, 0xa084, 0x0040, 0x0040, 0x3c40, 0xa6b5, 0x8000, - 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882, - 0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3c6c, 0x0018, 0x3c6c, - 0x70b4, 0xa080, 0x00dd, 0x781a, 0x1078, 0x38de, 0xa684, 0x0200, - 0x0040, 0x3c60, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad, - 0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80, - 0x000f, 0x7036, 0x0078, 0x2438, 0x1078, 0x1b45, 0x1078, 0x38de, - 0x0078, 0x2438, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23ca, - 0x2300, 0x0079, 0x3c7b, 0x3c7e, 0x3c7e, 0x3c80, 0x1078, 0x23ca, - 0x1078, 0x45bc, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040, - 0x3c92, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b45, - 0x0078, 0x3b60, 0x2001, 0x000a, 0x1078, 0x454c, 0x0078, 0x3b60, - 0xa282, 0x0005, 0x0050, 0x3c9e, 0x1078, 0x23ca, 0x7000, 0xa084, - 0x0007, 0x10c0, 0x398a, 0x1078, 0x191a, 0x00c0, 0x3cbd, 0xa684, - 0x0004, 0x0040, 0x3caf, 0x2001, 0x2800, 0x0078, 0x3cb1, 0x2001, - 0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031, - 0x0400, 0x7e5a, 0x791a, 0x0078, 0x2438, 0x6807, 0x0106, 0x680b, - 0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0, - 0x3cde, 0xa286, 0x0002, 0x00c0, 0x3cde, 0x78a0, 0xa005, 0x00c0, - 0x3cde, 0xa484, 0x8000, 0x00c0, 0x3cde, 0x78e4, 0xa084, 0x0008, - 0x0040, 0x3cde, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x40d3, - 0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824, - 0xa084, 0x0080, 0x0040, 0x3cf0, 0x1078, 0x4180, 0x0078, 0x2438, - 0x2300, 0x0079, 0x3cf3, 0x3cf6, 0x3d77, 0x3d96, 0x2200, 0x0079, - 0x3cf9, 0x3cfe, 0x3d0e, 0x3d34, 0x3d40, 0x3d63, 0x2029, 0x0001, - 0xa026, 0x2011, 0x0000, 0x1078, 0x428d, 0x0079, 0x3d07, 0x3d0c, - 0x2438, 0x3b60, 0x3d0c, 0x3d0c, 0x1078, 0x23ca, 0x7990, 0xa18c, - 0x0007, 0x00c0, 0x3d15, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, - 0x0004, 0x0040, 0x3d1d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, - 0x0001, 0x1078, 0x428d, 0x0079, 0x3d25, 0x3d2a, 0x2438, 0x3b60, - 0x3d32, 0x3d2c, 0x0078, 0x45ea, 0x70ab, 0x3d30, 0x0078, 0x2438, - 0x0078, 0x3d2a, 0x1078, 0x23ca, 0xa684, 0x0010, 0x0040, 0x3d3e, - 0x1078, 0x414f, 0x0040, 0x3d3e, 0x0078, 0x2438, 0x0078, 0x41bc, - 0x6000, 0xa084, 0x0002, 0x0040, 0x3d5d, 0x70b4, 0xa080, 0x00cd, - 0x781a, 0x0d7e, 0x1078, 0x45c5, 0x2d00, 0x682e, 0x6827, 0x0000, - 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x193d, 0x7003, 0x0000, 0x7037, - 0x0000, 0x704b, 0x0000, 0x0078, 0x3b60, 0xa684, 0x0004, 0x00c0, - 0x3d63, 0x0078, 0x45ea, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3d75, - 0x6000, 0xa084, 0x0001, 0x0040, 0x3d75, 0x70ab, 0x3d75, 0x2001, - 0x0007, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x2200, - 0x0079, 0x3d7a, 0x3d7f, 0x3d7f, 0x3d7f, 0x3d81, 0x3d7f, 0x1078, - 0x23ca, 0x70a7, 0x3d85, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078, - 0x4287, 0x0079, 0x3d8b, 0x3d90, 0x2438, 0x3b60, 0x3d92, 0x3d94, - 0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x2200, 0x0079, - 0x3d99, 0x3d9e, 0x3da0, 0x3da0, 0x3d9e, 0x3d9e, 0x1078, 0x23ca, - 0x78e4, 0xa084, 0x0008, 0x0040, 0x3db5, 0x70a7, 0x3da9, 0x0078, - 0x45f6, 0x2011, 0x0004, 0x1078, 0x4287, 0x0079, 0x3daf, 0x3db5, - 0x2438, 0x3b60, 0x3db5, 0x3dbf, 0x3dc3, 0x70ab, 0x3dbd, 0x2001, - 0x0003, 0x1078, 0x4544, 0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab, - 0x3db5, 0x0078, 0x2438, 0x70ab, 0x3dc7, 0x0078, 0x2438, 0x0078, - 0x3dbd, 0xa282, 0x0003, 0x0050, 0x3dcf, 0x1078, 0x23ca, 0xa386, - 0x0002, 0x00c0, 0x3de8, 0xa286, 0x0002, 0x00c0, 0x3dee, 0x78a0, - 0xa005, 0x00c0, 0x3dee, 0xa484, 0x8000, 0x00c0, 0x3dee, 0x78e4, - 0xa084, 0x0008, 0x0040, 0x3de8, 0xa6b5, 0x0008, 0x2019, 0x0000, - 0xa684, 0x0008, 0x0040, 0x3dee, 0x1078, 0x412c, 0x6810, 0x70be, - 0x7003, 0x0007, 0x2300, 0x0079, 0x3df5, 0x3df8, 0x3e25, 0x3e2d, - 0x2200, 0x0079, 0x3dfb, 0x3e00, 0x3dfe, 0x3e19, 0x1078, 0x23ca, - 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x428d, - 0x0079, 0x3e0a, 0x3e0f, 0x2438, 0x3b60, 0x3e17, 0x3e11, 0x0078, - 0x45ea, 0x70ab, 0x3e15, 0x0078, 0x2438, 0x0078, 0x3e0f, 0x1078, - 0x23ca, 0xa684, 0x0010, 0x0040, 0x3e23, 0x1078, 0x414f, 0x0040, - 0x3e23, 0x0078, 0x2438, 0x0078, 0x41bc, 0x2200, 0x0079, 0x3e28, - 0x3e2b, 0x3e2b, 0x3e2b, 0x1078, 0x23ca, 0x2200, 0x0079, 0x3e30, - 0x3e33, 0x3e35, 0x3e35, 0x1078, 0x23ca, 0x78e4, 0xa084, 0x0008, - 0x0040, 0x3e4a, 0x70a7, 0x3e3e, 0x0078, 0x45f6, 0x2011, 0x0004, - 0x1078, 0x4287, 0x0079, 0x3e44, 0x3e4a, 0x2438, 0x3b60, 0x3e4a, - 0x3e54, 0x3e58, 0x70ab, 0x3e52, 0x2001, 0x0003, 0x1078, 0x4544, - 0x0078, 0x45f0, 0x0078, 0x45ea, 0x70ab, 0x3e4a, 0x0078, 0x2438, - 0x70ab, 0x3e5c, 0x0078, 0x2438, 0x0078, 0x3e52, 0x2300, 0x0079, - 0x3e61, 0x3e66, 0x3e68, 0x3e64, 0x1078, 0x23ca, 0x70a4, 0x007a, - 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3e70, 0x1078, 0x23ca, - 0xa684, 0x0200, 0x0040, 0x3e7a, 0x1078, 0x45b5, 0x1078, 0x426f, - 0x1078, 0x45bc, 0x2300, 0x0079, 0x3e7d, 0x3e80, 0x3ea4, 0x3f0a, - 0xa286, 0x0001, 0x0040, 0x3e86, 0x1078, 0x23ca, 0xa684, 0x0200, - 0x0040, 0x3e8e, 0x1078, 0x45b5, 0x1078, 0x45bc, 0x2001, 0x0001, - 0x1078, 0x454c, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ea0, 0x7848, - 0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3e9b, - 0x7003, 0x0000, 0x0078, 0x3b60, 0x2200, 0x0079, 0x3ea7, 0x3ea9, - 0x3eda, 0x70a7, 0x3ead, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078, - 0x4287, 0x0079, 0x3eb3, 0x3eba, 0x2438, 0x3b60, 0x3ec2, 0x3eca, - 0x3ed0, 0x3ed2, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x0078, 0x45e4, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x0078, 0x45e4, 0x70ab, 0x3ece, 0x0078, 0x2438, 0x0078, 0x3eba, - 0x1078, 0x23ca, 0x70ab, 0x3ed6, 0x0078, 0x2438, 0x1078, 0x45fc, - 0x0078, 0x2438, 0x70a7, 0x3ede, 0x0078, 0x45f6, 0x2011, 0x0012, - 0x1078, 0x4287, 0x0079, 0x3ee4, 0x3eea, 0x2438, 0x3b60, 0x3ef6, - 0x3efe, 0x3f04, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff, - 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab, 0x3f02, - 0x0078, 0x2438, 0x0078, 0x3eea, 0x70ab, 0x3f08, 0x0078, 0x2438, - 0x0078, 0x3ef6, 0xa286, 0x0001, 0x0040, 0x3f10, 0x1078, 0x23ca, - 0x70a7, 0x3f14, 0x0078, 0x45f6, 0x2011, 0x0015, 0x1078, 0x4287, - 0x0079, 0x3f1a, 0x3f1f, 0x2438, 0x3b60, 0x3f2d, 0x3f39, 0xa6b4, - 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4, - 0xa080, 0x00b5, 0x781a, 0x0078, 0x2438, 0xa6b4, 0x00ff, 0xa6b5, - 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a5, 0x781a, 0x0078, - 0x2438, 0x70ab, 0x3f3d, 0x0078, 0x2438, 0x0078, 0x3f1f, 0xa282, - 0x0003, 0x0050, 0x3f45, 0x1078, 0x23ca, 0x2300, 0x0079, 0x3f48, - 0x3f4b, 0x3f82, 0x3fdd, 0xa286, 0x0001, 0x0040, 0x3f51, 0x1078, - 0x23ca, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3f5e, - 0x1078, 0x3ac2, 0x7003, 0x0000, 0x0078, 0x3b60, 0x683b, 0x0000, - 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3f6c, 0x1078, 0x45b5, - 0x1078, 0x426f, 0x1078, 0x45bc, 0x2001, 0x0001, 0x1078, 0x454c, - 0x78b8, 0xa084, 0xc001, 0x0040, 0x3f7e, 0x7848, 0xa085, 0x0008, - 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3f79, 0x7003, 0x0000, - 0x0078, 0x3b60, 0x2200, 0x0079, 0x3f85, 0x3f87, 0x3fb8, 0x70a7, - 0x3f8b, 0x0078, 0x45f6, 0x2011, 0x000d, 0x1078, 0x4287, 0x0079, - 0x3f91, 0x3f98, 0x2438, 0x3b60, 0x3fa0, 0x3fa8, 0x3fae, 0x3fb0, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, - 0x70ab, 0x3fac, 0x0078, 0x2438, 0x0078, 0x3f98, 0x1078, 0x23ca, - 0x70ab, 0x3fb4, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078, 0x2438, - 0x70a7, 0x3fbc, 0x0078, 0x45f6, 0x2011, 0x0005, 0x1078, 0x4287, - 0x0079, 0x3fc2, 0x3fc7, 0x2438, 0x3b60, 0x3fcf, 0x3fd7, 0xa6b4, - 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0xa6b4, - 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, 0x70ab, - 0x3fdb, 0x0078, 0x2438, 0x0078, 0x3fc7, 0xa286, 0x0001, 0x0040, - 0x3fe3, 0x1078, 0x23ca, 0x70a7, 0x3fe7, 0x0078, 0x45f6, 0x2011, - 0x0006, 0x1078, 0x4287, 0x0079, 0x3fed, 0x3ff2, 0x2438, 0x3b60, - 0x3ff8, 0x4002, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x45e4, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, - 0x0078, 0x45e4, 0x70ab, 0x4006, 0x0078, 0x2438, 0x0078, 0x3ff2, - 0x2300, 0x0079, 0x400b, 0x4010, 0x400e, 0x400e, 0x1078, 0x23ca, - 0x1078, 0x23ca, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be, - 0xa282, 0x0003, 0x0050, 0x401e, 0x1078, 0x23ca, 0x2300, 0x0079, - 0x4021, 0x4024, 0x4037, 0x4059, 0x82ff, 0x00c0, 0x4029, 0x1078, - 0x23ca, 0xa684, 0x0200, 0x0040, 0x4031, 0x1078, 0x45b5, 0x1078, - 0x45bc, 0x2001, 0x0001, 0x1078, 0x454c, 0x0078, 0x2438, 0xa296, - 0x0002, 0x0040, 0x4040, 0x82ff, 0x0040, 0x4040, 0x1078, 0x23ca, - 0x70a7, 0x4044, 0x0078, 0x45f6, 0x2011, 0x0018, 0x1078, 0x4287, - 0x0079, 0x404a, 0x404f, 0x2438, 0x3b60, 0x4051, 0x4053, 0x0078, - 0x45e4, 0x0078, 0x45e4, 0x70ab, 0x4057, 0x0078, 0x2438, 0x0078, - 0x404f, 0x2200, 0x0079, 0x405c, 0x405e, 0x4077, 0x70a7, 0x4062, - 0x0078, 0x45f6, 0x2011, 0x0017, 0x1078, 0x4287, 0x0079, 0x4068, - 0x406d, 0x2438, 0x3b60, 0x406f, 0x4071, 0x0078, 0x45e4, 0x0078, - 0x45e4, 0x70ab, 0x4075, 0x0078, 0x2438, 0x0078, 0x406d, 0xa484, - 0x8000, 0x00c0, 0x40c1, 0xa684, 0x0100, 0x0040, 0x408b, 0x1078, - 0x45b5, 0x1078, 0x426f, 0x1078, 0x45bc, 0x7848, 0xa085, 0x000c, - 0x784a, 0x0078, 0x408f, 0x78d8, 0x78d2, 0x78dc, 0x78d6, 0xa6b4, - 0xefff, 0x7e5a, 0x70a7, 0x4096, 0x0078, 0x45f6, 0x2011, 0x000d, - 0x1078, 0x4287, 0x0079, 0x409c, 0x40a3, 0x2438, 0x3b60, 0x40a3, - 0x40b1, 0x40b7, 0x40b9, 0xa684, 0x0100, 0x0040, 0x40af, 0x1078, - 0x4573, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x45ad, 0x0078, - 0x45e4, 0x70ab, 0x40b5, 0x0078, 0x2438, 0x0078, 0x40a3, 0x1078, - 0x23ca, 0x70ab, 0x40bd, 0x0078, 0x2438, 0x1078, 0x45fc, 0x0078, - 0x2438, 0x1078, 0x45bc, 0x70ab, 0x40cb, 0x2001, 0x0003, 0x1078, - 0x4544, 0x0078, 0x45f0, 0x1078, 0x45ad, 0x682c, 0x78d2, 0x6830, - 0x78d6, 0x0078, 0x45e4, 0x70b8, 0x6812, 0x70be, 0x8000, 0x70ba, - 0x681b, 0x0000, 0xa684, 0x0008, 0x0040, 0x40f6, 0x157e, 0x137e, - 0x147e, 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, - 0x681a, 0x80ac, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0xad80, - 0x000b, 0x20a0, 0x53a5, 0x147f, 0x137f, 0x157f, 0xa6c4, 0x0f00, - 0xa684, 0x0002, 0x00c0, 0x4102, 0x692c, 0x810d, 0x810d, 0x810d, - 0x0078, 0x410f, 0x789b, 0x0010, 0x79ac, 0x0078, 0x410f, 0x017e, - 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x457e, 0x017f, 0xa184, - 0x001f, 0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0xa684, 0x0004, - 0x0040, 0x4120, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, - 0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x412a, - 0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918, - 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e, - 0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x414b, 0x20a8, - 0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, - 0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c, - 0xa084, 0x0020, 0x00c0, 0x4157, 0x620c, 0x0078, 0x4158, 0x6210, - 0x6b18, 0x2300, 0xa202, 0x0040, 0x4178, 0x2018, 0xa382, 0x000e, - 0x0048, 0x4168, 0x0040, 0x4168, 0x2019, 0x000e, 0x0078, 0x416c, - 0x7858, 0xa084, 0xffef, 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000, - 0x7ba2, 0x70b4, 0xa080, 0x008e, 0x781a, 0xa085, 0x0001, 0x007c, - 0x7858, 0xa084, 0xffef, 0x785a, 0x7893, 0x0000, 0xa006, 0x007c, - 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x418d, 0xa196, - 0x000f, 0x0040, 0x418d, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b33, - 0x6100, 0x8104, 0x00c8, 0x41a8, 0x601c, 0xa005, 0x0040, 0x419c, - 0x2001, 0x0800, 0x0078, 0x41aa, 0x0d7e, 0x6824, 0x007e, 0x1078, - 0x45c5, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3ac2, 0x0d7f, - 0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, - 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4, - 0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684, 0x0002, - 0x00c0, 0x41cf, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x001f, - 0xa805, 0x6816, 0x1078, 0x3b33, 0x68be, 0x0078, 0x41d2, 0x6914, - 0x1078, 0x3b33, 0x6100, 0x8104, 0x00c8, 0x421c, 0xa184, 0x0300, - 0x0040, 0x41de, 0x6807, 0x0117, 0x0078, 0x41fc, 0x6004, 0xa005, - 0x00c0, 0x4205, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0, 0x41f2, - 0x0d7e, 0x1078, 0x45c5, 0x6827, 0x0034, 0x2d00, 0x682e, 0x1078, - 0x3ac2, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x41fc, 0x2031, 0x0400, - 0x2001, 0x2800, 0x0078, 0x4200, 0x2031, 0x0400, 0x2001, 0x0800, - 0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x6018, 0xa005, 0x00c0, - 0x41f2, 0x601c, 0xa005, 0x00c0, 0x41f2, 0x689f, 0x0000, 0x6827, - 0x003d, 0xa684, 0x0001, 0x0040, 0x4258, 0xa6b5, 0x0800, 0x71b4, - 0xa188, 0x00ae, 0x0078, 0x4253, 0x6807, 0x0117, 0x2031, 0x0400, - 0x692c, 0xa18c, 0x00ff, 0xa186, 0x0012, 0x00c0, 0x422d, 0x2001, - 0x4265, 0x2009, 0x0001, 0x0078, 0x423e, 0xa186, 0x0003, 0x00c0, - 0x4237, 0x2001, 0x4266, 0x2009, 0x0012, 0x0078, 0x423e, 0x2001, - 0x0200, 0x71b4, 0xa188, 0x0091, 0x0078, 0x424a, 0x1078, 0x4598, - 0x78a3, 0x0000, 0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188, - 0x00da, 0xa006, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, - 0xa085, 0x8000, 0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x2438, - 0x6eb6, 0x1078, 0x3ac2, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3, - 0x0000, 0x704b, 0x0000, 0x0078, 0x2438, 0x0023, 0x0070, 0x0005, - 0x0000, 0x0a00, 0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b, - 0x0000, 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x4286, 0x78b8, - 0xa08c, 0x001f, 0xa084, 0x8000, 0x0040, 0x427f, 0x8108, 0x78d8, - 0xa100, 0x6836, 0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990, - 0x810f, 0xa5ac, 0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a, - 0x79a8, 0xa18c, 0x00ff, 0xa184, 0x0080, 0x00c0, 0x42b5, 0xa182, - 0x0020, 0x00c8, 0x42cf, 0xa182, 0x0012, 0x00c8, 0x4536, 0x2100, - 0x1079, 0x42a3, 0x007c, 0x4536, 0x447e, 0x4536, 0x4536, 0x42dc, - 0x42df, 0x4319, 0x434f, 0x4381, 0x4384, 0x4536, 0x4536, 0x433a, - 0x43a8, 0x43e2, 0x4536, 0x4536, 0x4409, 0xa18c, 0x001f, 0x6814, - 0xa084, 0x001f, 0xa106, 0x0040, 0x42cc, 0x70b4, 0xa080, 0x00cd, - 0x781a, 0x2001, 0x0014, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003, - 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182, - 0x0024, 0x00c8, 0x4536, 0xa184, 0x0003, 0x1079, 0x42a3, 0x007c, - 0x4536, 0x4536, 0x4536, 0x4536, 0x1078, 0x4536, 0x007c, 0x2200, - 0x0079, 0x42e2, 0x440c, 0x440c, 0x4306, 0x4306, 0x4306, 0x4306, - 0x4306, 0x4306, 0x4306, 0x4306, 0x4304, 0x4306, 0x42fb, 0x4306, - 0x4306, 0x4306, 0x4306, 0x4306, 0x430e, 0x4311, 0x440c, 0x4311, - 0x4306, 0x4306, 0x4306, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36b0, - 0x077f, 0x0c7f, 0x0078, 0x4306, 0x1078, 0x44d1, 0x6827, 0x02b3, - 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x4440, 0x1078, 0x452b, - 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, - 0x4428, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, - 0x4323, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827, - 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3a92, 0x1078, - 0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001, - 0x0002, 0x007c, 0x1078, 0x4466, 0x2001, 0x0017, 0x1078, 0x454c, - 0x70a3, 0x0000, 0x2009, 0x5038, 0x200b, 0x0006, 0x70af, 0x0017, - 0x2009, 0x0200, 0x1078, 0x39d2, 0x2001, 0x0001, 0x007c, 0x2200, - 0x0079, 0x4352, 0x440c, 0x443d, 0x443d, 0x443d, 0x4373, 0x444d, - 0x4379, 0x444d, 0x444d, 0x4450, 0x4450, 0x4455, 0x4455, 0x436b, - 0x436b, 0x443d, 0x443d, 0x444d, 0x443d, 0x4379, 0x440c, 0x4379, - 0x4379, 0x4379, 0x4379, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001, - 0x4300, 0x0078, 0x445f, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, - 0x4440, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, - 0x4428, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079, 0x4387, 0x440c, - 0x43a0, 0x43a0, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d, - 0x444d, 0x444d, 0x444d, 0x444d, 0x43a0, 0x43a0, 0x43a0, 0x43a0, - 0x444d, 0x43a0, 0x43a0, 0x444d, 0x444d, 0x444d, 0x444d, 0x440c, - 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, 0x0078, 0x4428, - 0xa684, 0x0004, 0x00c0, 0x43bc, 0x6804, 0xa084, 0x00ff, 0xa086, - 0x0006, 0x00c0, 0x4536, 0x1078, 0x4466, 0x6807, 0x0117, 0x1078, - 0x3ac2, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, - 0x4536, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, - 0x43cb, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x45c5, 0x6827, - 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3aa1, 0x1078, - 0x4466, 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001, - 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, 0x4536, 0x2d58, - 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0, 0x43f1, 0x6807, - 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x45c5, 0x6827, 0x0036, - 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ab1, 0x1078, 0x4466, - 0x2b68, 0x1078, 0x3ac2, 0x0d7f, 0x1078, 0x3ac2, 0x2001, 0x0002, - 0x007c, 0x1078, 0x4536, 0x007c, 0x70b4, 0xa080, 0x00cd, 0x781a, - 0x2001, 0x0001, 0x1078, 0x454c, 0x1078, 0x45bc, 0x7003, 0x0000, - 0x2001, 0x0002, 0x007c, 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, - 0x426f, 0x1078, 0x4180, 0x1078, 0x45bc, 0x2001, 0x0001, 0x007c, - 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080, - 0x00cd, 0x781a, 0x2001, 0x0013, 0x1078, 0x454c, 0x1078, 0x45bc, - 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x4536, 0x007c, - 0x1078, 0x457e, 0x1078, 0x45b5, 0x1078, 0x426f, 0x1078, 0x4180, - 0x1078, 0x45bc, 0x2001, 0x0001, 0x007c, 0x2001, 0x0003, 0x007c, - 0x1078, 0x44d1, 0x2001, 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, - 0x1078, 0x36b0, 0x077f, 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, - 0x457e, 0x1078, 0x4536, 0x2001, 0x0006, 0x007c, 0x6904, 0xa18c, - 0x00ff, 0xa186, 0x0007, 0x0040, 0x4471, 0xa186, 0x000f, 0x00c0, - 0x4475, 0x1078, 0x45b5, 0x1078, 0x426f, 0x70b4, 0xa080, 0x00cd, - 0x781a, 0x1078, 0x45bc, 0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294, - 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4536, - 0x1079, 0x448b, 0x007c, 0x4536, 0x448f, 0x4536, 0x44df, 0xa282, - 0x0003, 0x0040, 0x4496, 0x1078, 0x4536, 0x007c, 0x7da8, 0xa5ac, - 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x44a4, - 0x0040, 0x44a4, 0x2021, 0x000c, 0x701c, 0xa502, 0x00c8, 0x44a9, - 0x751c, 0x1078, 0x451c, 0x852b, 0x852b, 0x1078, 0x372e, 0x0040, - 0x44b5, 0x1078, 0x44c3, 0x0078, 0x44b9, 0x1078, 0x4518, 0x1078, - 0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, - 0x2001, 0x0004, 0x007c, 0x0c7e, 0x6914, 0x810f, 0xa18c, 0x000f, - 0x810b, 0x810b, 0x810b, 0xa1e0, 0x5280, 0x1078, 0x3538, 0x0c7f, - 0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, - 0x8003, 0xa0e0, 0x5280, 0x1078, 0x355f, 0x0c7f, 0x007c, 0xa282, - 0x0002, 0x00c0, 0x4536, 0x7aa8, 0xa294, 0x00ff, 0xa284, 0xfffe, - 0x0040, 0x44ec, 0x2011, 0x0001, 0x1078, 0x450a, 0x1078, 0x44fc, - 0x1078, 0x44d1, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, - 0x781a, 0x2001, 0x0004, 0x007c, 0x0c7e, 0x6814, 0x8007, 0xa084, - 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, 0x5280, 0x1078, 0x3604, - 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002, - 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c, - 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001, - 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081, - 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x4544, 0x70b4, - 0xa080, 0x00b9, 0x781a, 0x2001, 0x0005, 0x007c, 0x2001, 0x0007, - 0x1078, 0x4544, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, - 0x781a, 0x2001, 0x0004, 0x007c, 0x789b, 0x0018, 0x78aa, 0x789b, - 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196, - 0x0007, 0x0040, 0x455a, 0xa196, 0x000f, 0x0040, 0x455a, 0x1078, - 0x193d, 0x007c, 0x6924, 0xa194, 0x003f, 0x00c0, 0x4563, 0xa18c, - 0xffc0, 0xa105, 0x6826, 0x1078, 0x3ac2, 0x691c, 0xa184, 0x0100, - 0x0040, 0x4572, 0x1078, 0x1b7e, 0x6914, 0x1078, 0x3b33, 0x6204, - 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112, 0x6930, - 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e, 0xade0, - 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f, 0x0a00, - 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f, 0x0000, - 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826, 0x007c, - 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0, 0x81ac, - 0x0040, 0x45a3, 0x53a6, 0xa184, 0x0001, 0x0040, 0x45a9, 0x3304, - 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005, 0x10c0, - 0x23ca, 0x70b3, 0x8000, 0x0078, 0x48f7, 0x71b0, 0x81ff, 0x0040, - 0x45bb, 0x1078, 0x49ed, 0x007c, 0x71b0, 0x81ff, 0x0040, 0x45c4, - 0x70b3, 0x0000, 0x1078, 0x4633, 0x007c, 0x0c7e, 0x0d7e, 0x1078, - 0x191a, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98, 0x20a9, - 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d, 0x680b, - 0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f, 0x0000, - 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091, 0x781a, - 0x0078, 0x2438, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078, 0x2438, - 0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x2438, 0x70b4, 0xa080, - 0x00c3, 0x781a, 0x0078, 0x2438, 0x6904, 0xa18c, 0x00ff, 0xa196, - 0x0007, 0x0040, 0x4609, 0xa196, 0x000f, 0x0040, 0x4609, 0x6807, - 0x0117, 0x2001, 0x0200, 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, - 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a, - 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0x1078, 0x45bc, 0x7848, - 0xa085, 0x000c, 0x784a, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2009, - 0x000b, 0x2001, 0x4400, 0x1078, 0x457e, 0x2001, 0x0013, 0x1078, - 0x454c, 0x0078, 0x3b60, 0x127e, 0x2091, 0x2200, 0x2049, 0x4633, - 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, 0x7008, 0xa084, 0xfff7, - 0xa205, 0x0040, 0x4645, 0x0078, 0x464a, 0x7003, 0x0000, 0x127f, - 0x2000, 0x007c, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4678, 0x7108, - 0x8103, 0x00c8, 0x4657, 0x1078, 0x477a, 0x0078, 0x464f, 0x700c, - 0xa08c, 0x00ff, 0x0040, 0x4678, 0x7004, 0x8004, 0x00c8, 0x466f, - 0x7014, 0xa005, 0x00c0, 0x466b, 0x7010, 0xa005, 0x0040, 0x466f, - 0xa102, 0x00c8, 0x464f, 0x7007, 0x0010, 0x0078, 0x4678, 0x8aff, - 0x0040, 0x4678, 0x1078, 0x49c4, 0x00c0, 0x4672, 0x0040, 0x464f, - 0x1078, 0x4703, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x017e, - 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x468b, 0xa18e, - 0x000f, 0x00c0, 0x468e, 0x6040, 0x0078, 0x468f, 0x6428, 0x017f, - 0x84ff, 0x0040, 0x46b9, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, - 0x46c9, 0x273c, 0x87fb, 0x00c0, 0x46a7, 0x0048, 0x46a1, 0x1078, - 0x23ca, 0x609c, 0xa075, 0x0040, 0x46b9, 0x0078, 0x4694, 0x2704, - 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040, 0x46b9, - 0x8738, 0x2704, 0xa005, 0x00c0, 0x46a8, 0x709c, 0xa075, 0x00c0, - 0x4694, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015, - 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, - 0x0000, 0x0000, 0x46be, 0x46bb, 0x0000, 0x0000, 0x8000, 0x0000, - 0x46be, 0x0000, 0x46c6, 0x46c3, 0x0000, 0x0000, 0x0000, 0x0000, - 0x46c6, 0x0000, 0x46c1, 0x46c1, 0x0000, 0x0000, 0x8000, 0x0000, - 0x46c1, 0x0000, 0x46c7, 0x46c7, 0x0000, 0x0000, 0x0000, 0x0000, - 0x46c7, 0x127e, 0x2091, 0x2200, 0x2079, 0x5000, 0x2071, 0x0010, - 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071, 0x0020, - 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049, 0x0000, - 0x127f, 0x2000, 0x007c, 0x2049, 0x4703, 0x2019, 0x0000, 0x7004, - 0x8004, 0x00c8, 0x4756, 0x7007, 0x0012, 0x7108, 0x7008, 0xa106, - 0x00c0, 0x470d, 0xa184, 0x01e0, 0x0040, 0x4718, 0x1078, 0x23ca, - 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x4723, 0xa184, - 0x4000, 0x00c0, 0x470d, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, - 0x4731, 0xa386, 0x0008, 0x0040, 0x473c, 0xa386, 0x200c, 0x00c0, - 0x470d, 0x7200, 0x8204, 0x0048, 0x473c, 0x730c, 0xa384, 0x00ff, - 0x0040, 0x473c, 0x1078, 0x23ca, 0x7007, 0x0012, 0x7000, 0xa084, - 0x0001, 0x00c0, 0x4756, 0x7008, 0xa084, 0x01e0, 0x00c0, 0x4756, - 0x7310, 0x7014, 0xa305, 0x0040, 0x4756, 0x710c, 0xa184, 0x0300, - 0x00c0, 0x4756, 0xa184, 0x00ff, 0x00c0, 0x4703, 0x7007, 0x0012, - 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, 0x475a, 0x7007, - 0x0012, 0x7108, 0x8103, 0x0048, 0x475f, 0x7003, 0x0000, 0x2049, - 0x0000, 0x007c, 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200, - 0x7108, 0x1078, 0x477a, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f, - 0x107f, 0x007c, 0x7204, 0x7500, 0x730c, 0xa384, 0x0300, 0x00c0, - 0x47a1, 0xa184, 0x01e0, 0x00c0, 0x47c5, 0x7108, 0xa184, 0x01e0, - 0x00c0, 0x47c5, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, - 0x4795, 0xa184, 0x4000, 0x00c0, 0x4785, 0xa184, 0x0007, 0x0079, - 0x4799, 0x47a3, 0x47b5, 0x47a1, 0x47b5, 0x47a1, 0x4801, 0x47a1, - 0x47ff, 0x1078, 0x23ca, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, - 0x7006, 0x8aff, 0x00c0, 0x47b0, 0x2049, 0x0000, 0x0078, 0x47b4, - 0x1078, 0x49c4, 0x00c0, 0x47b0, 0x007c, 0x7004, 0xa084, 0x0010, - 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x47c0, 0x0078, 0x47c4, - 0x1078, 0x49c4, 0x00c0, 0x47c0, 0x007c, 0x7007, 0x0012, 0x7108, - 0x00e0, 0x47c8, 0x2091, 0x6000, 0x00e0, 0x47cc, 0x2091, 0x6000, - 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, 0x00c0, - 0x47d4, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x47d9, 0x7003, - 0x0000, 0x7000, 0xa005, 0x00c0, 0x47ed, 0x7004, 0xa005, 0x00c0, - 0x47ed, 0x700c, 0xa005, 0x0040, 0x47ef, 0x0078, 0x47d0, 0x2049, - 0x0000, 0x1078, 0x37d7, 0x6818, 0xa084, 0x8000, 0x0040, 0x47fa, - 0x681b, 0x0002, 0x007c, 0x1078, 0x23ca, 0x1078, 0x23ca, 0x1078, - 0x485d, 0x7210, 0x7114, 0x700c, 0xa09c, 0x00ff, 0x2800, 0xa300, - 0xa211, 0xa189, 0x0000, 0x1078, 0x485d, 0x2704, 0x2c58, 0xac60, - 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, - 0x0040, 0x4824, 0x00c8, 0x4824, 0x8412, 0x8210, 0x830a, 0xa189, - 0x0000, 0x2b60, 0x0078, 0x480b, 0x2b60, 0x8a07, 0x007e, 0x6004, - 0xa084, 0x0008, 0x0040, 0x4830, 0xa7ba, 0x46c3, 0x0078, 0x4832, - 0xa7ba, 0x46bb, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, - 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4703, 0x007c, 0x8738, 0x2704, - 0xa005, 0x00c0, 0x4851, 0x609c, 0xa005, 0x0040, 0x485a, 0x2060, - 0x6004, 0xa084, 0x000f, 0xa080, 0x46c9, 0x203c, 0x87fb, 0x1040, - 0x23ca, 0x8a51, 0x0040, 0x4859, 0x7008, 0xa084, 0x0003, 0xa086, - 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x8a50, 0x8739, 0x2704, - 0xa004, 0x00c0, 0x4871, 0x6000, 0xa064, 0x00c0, 0x4868, 0x2d60, - 0x6004, 0xa084, 0x000f, 0xa080, 0x46d9, 0x203c, 0x87fb, 0x1040, - 0x23ca, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x6884, - 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, - 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x488c, - 0xa0b8, 0x46c3, 0x0078, 0x488e, 0xa0b8, 0x46bb, 0x7e08, 0xa6b5, - 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x489c, - 0xa18e, 0x000f, 0x00c0, 0x48a5, 0x681c, 0xa084, 0x0040, 0x0040, - 0x48ac, 0xa6b5, 0x0001, 0x0078, 0x48ac, 0x681c, 0xa084, 0x0040, - 0x0040, 0x48ac, 0xa6b5, 0x0001, 0x7007, 0x0004, 0x7004, 0xa084, - 0x0004, 0x00c0, 0x48ae, 0x2400, 0xa305, 0x00c0, 0x48b9, 0x0078, - 0x48df, 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, - 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, 0x0040, 0x48cf, 0x6010, - 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, - 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, - 0x7007, 0x0001, 0x2b60, 0x1078, 0x483e, 0x0078, 0x48e1, 0x1078, - 0x49c4, 0x00c0, 0x48df, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, - 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, - 0x00c0, 0x48ed, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, - 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x48f7, 0x7007, 0x0004, - 0x7004, 0xa084, 0x0004, 0x00c0, 0x4900, 0x7e08, 0xa6b5, 0x000c, - 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4913, 0xa18e, - 0x000f, 0x00c0, 0x491e, 0x681c, 0xa084, 0x0040, 0x0040, 0x491a, - 0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078, 0x4927, 0x681c, 0xa084, - 0x0020, 0x00c0, 0x4925, 0xa6b5, 0x0001, 0x6828, 0x2050, 0x2d60, - 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb, 0x00c0, - 0x493b, 0x0048, 0x4935, 0x1078, 0x23ca, 0x689c, 0xa065, 0x0040, - 0x493f, 0x0078, 0x4928, 0x1078, 0x49c4, 0x00c0, 0x493b, 0x127f, - 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, 0x0d7e, 0x2091, 0x2200, - 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, - 0x00ff, 0xa186, 0x0007, 0x0040, 0x4959, 0xa18e, 0x000f, 0x00c0, - 0x4962, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5, 0x0001, - 0x0078, 0x4969, 0x681c, 0xa084, 0x0040, 0x0040, 0x4969, 0xa6b5, - 0x0001, 0x2049, 0x4942, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186, - 0x0007, 0x0040, 0x4977, 0xa18e, 0x000f, 0x00c0, 0x497a, 0x6840, - 0x0078, 0x497b, 0x6828, 0x017f, 0xa055, 0x0040, 0x49c1, 0x2d70, - 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46c9, 0x273c, 0x87fb, - 0x00c0, 0x4995, 0x0048, 0x498e, 0x1078, 0x23ca, 0x709c, 0xa075, - 0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x2704, 0xae68, 0x6808, - 0xa422, 0x680c, 0xa31b, 0x0048, 0x49ae, 0x8a51, 0x00c0, 0x49a2, - 0x1078, 0x23ca, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4996, 0x709c, - 0xa075, 0x2060, 0x0040, 0x49c1, 0x0078, 0x4981, 0x8422, 0x8420, - 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, - 0xa11b, 0x00c8, 0x49bd, 0x1078, 0x23ca, 0x2071, 0x0020, 0x0078, - 0x48ac, 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086, - 0x0003, 0x0040, 0x49ec, 0x2704, 0xac08, 0x2104, 0x701a, 0x8108, - 0x2104, 0x701e, 0x8108, 0x2104, 0x7012, 0x8108, 0x2104, 0x7016, - 0x6004, 0xa084, 0x0008, 0x0040, 0x49e3, 0x8108, 0x2104, 0x7022, - 0x8108, 0x2104, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xa085, - 0x0001, 0x7006, 0x1078, 0x483e, 0x007c, 0x127e, 0x007e, 0x0d7e, - 0x2091, 0x2200, 0x2049, 0x49ed, 0x0d7f, 0x087f, 0x7108, 0xa184, - 0x0003, 0x00c0, 0x4a17, 0x017e, 0x6904, 0xa18c, 0x00ff, 0xa186, - 0x0007, 0x0040, 0x4a07, 0xa18e, 0x000f, 0x00c0, 0x4a0a, 0x6840, - 0x0078, 0x4a0b, 0x6828, 0x017f, 0xa005, 0x0040, 0x4a25, 0x0078, - 0x464a, 0x0020, 0x4a17, 0x1078, 0x4801, 0x0078, 0x4a25, 0x00a0, - 0x4a1e, 0x7108, 0x1078, 0x477a, 0x0078, 0x49f6, 0x7007, 0x0010, - 0x00a0, 0x4a20, 0x7108, 0x1078, 0x477a, 0x7008, 0xa086, 0x0008, - 0x00c0, 0x49f6, 0x7000, 0xa005, 0x00c0, 0x49f6, 0x7003, 0x0000, - 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, - 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x4a35, - 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031, 0x700c, 0xa084, 0x00ff, - 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040, - 0x4a54, 0x8000, 0x80ac, 0x53a5, 0x7007, 0x0004, 0x7004, 0xa084, - 0x0004, 0x00c0, 0x4a56, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, - 0x157f, 0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x6000, - 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040, 0x4a7d, 0x7994, 0x70d0, - 0xa106, 0x00c0, 0x4a7d, 0x7804, 0xa005, 0x0040, 0x4a7d, 0x7807, - 0x0000, 0x0068, 0x4a7d, 0x2091, 0x4080, 0x7820, 0x8001, 0x7822, - 0x00c0, 0x4ad8, 0x7824, 0x7822, 0x2069, 0x5040, 0x6800, 0xa084, - 0x0007, 0x0040, 0x4a9b, 0xa086, 0x0002, 0x0040, 0x4a9b, 0x6834, - 0xa00d, 0x0040, 0x4a9b, 0x2104, 0xa005, 0x0040, 0x4a9b, 0x8001, - 0x200a, 0x0040, 0x4b80, 0x7848, 0xa005, 0x0040, 0x4aa9, 0x8001, - 0x784a, 0x00c0, 0x4aa9, 0x2009, 0x0102, 0x6844, 0x200a, 0x1078, - 0x21b1, 0x6890, 0xa005, 0x0040, 0x4ab5, 0x8001, 0x6892, 0x00c0, - 0x4ab5, 0x686f, 0x0000, 0x6873, 0x0001, 0x2061, 0x5300, 0x20a9, - 0x0100, 0x2009, 0x0002, 0x6034, 0xa005, 0x0040, 0x4acb, 0x8001, - 0x6036, 0x00c0, 0x4acb, 0x6010, 0xa005, 0x0040, 0x4acb, 0x017e, - 0x1078, 0x21b1, 0x017f, 0xace0, 0x0010, 0x0070, 0x4ad1, 0x0078, - 0x4abb, 0x8109, 0x0040, 0x4ad8, 0x20a9, 0x0100, 0x0078, 0x4abb, - 0x1078, 0x4ae5, 0x1078, 0x4b0a, 0x2009, 0x5051, 0x2104, 0x2009, - 0x0102, 0x200a, 0x2091, 0x8001, 0x007c, 0x7834, 0x8001, 0x7836, - 0x00c0, 0x4b09, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005, - 0x00c0, 0x4af4, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x7300, - 0x2040, 0x2004, 0xa065, 0x0040, 0x4b09, 0x6024, 0xa005, 0x0040, - 0x4b05, 0x8001, 0x6026, 0x0040, 0x4b39, 0x6000, 0x2c40, 0x0078, - 0x4afa, 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x4b38, 0x782c, - 0x782a, 0x7830, 0xa005, 0x00c0, 0x4b17, 0x2001, 0x0200, 0x8001, - 0x7832, 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x5300, 0xa298, - 0x0002, 0x2304, 0xa084, 0x0008, 0x0040, 0x4b38, 0xa290, 0x0009, - 0x2204, 0xa005, 0x0040, 0x4b30, 0x8001, 0x2012, 0x00c0, 0x4b38, - 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x21b1, - 0x007c, 0x2069, 0x5040, 0x6800, 0xa005, 0x0040, 0x4b43, 0x6848, - 0xac06, 0x0040, 0x4b80, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, - 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, - 0x2042, 0x6714, 0x6f82, 0x1078, 0x1956, 0x6818, 0xa005, 0x0040, - 0x4b5b, 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810, - 0x8001, 0x00d0, 0x4b65, 0x1078, 0x23ca, 0x6812, 0x602f, 0x0000, - 0x6033, 0x0000, 0x2c68, 0x1078, 0x1c53, 0x2069, 0x5040, 0x7944, - 0xa184, 0x0100, 0x2001, 0x0006, 0x686e, 0x00c0, 0x4b7b, 0x6986, - 0x2001, 0x0004, 0x686e, 0x1078, 0x21ac, 0x2091, 0x8001, 0x007c, - 0x2069, 0x0100, 0x2009, 0x5040, 0x2104, 0xa084, 0x0007, 0x0040, - 0x4bdc, 0xa086, 0x0007, 0x00c0, 0x4b96, 0x0d7e, 0x2009, 0x5052, - 0x216c, 0x1078, 0x3a1a, 0x0d7f, 0x0078, 0x4bdc, 0x2009, 0x5052, - 0x2164, 0x1078, 0x2375, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, - 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, - 0x0000, 0x6033, 0x0000, 0x6830, 0xa084, 0x0040, 0x0040, 0x4bd0, - 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, - 0x4bbd, 0x0070, 0x4bbd, 0x0078, 0x4bb4, 0x684b, 0x0009, 0x20a9, - 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, 0x4bca, 0x0070, 0x4bca, - 0x0078, 0x4bc1, 0x20a9, 0x00fa, 0x0070, 0x4bd0, 0x0078, 0x4bcc, - 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2009, 0x505b, - 0x200b, 0x0007, 0x784c, 0x784a, 0x2091, 0x8001, 0x007c, 0x2079, - 0x5000, 0x1078, 0x4c0a, 0x1078, 0x4bee, 0x1078, 0x4bfc, 0x7833, - 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, 0x007c, 0x2019, 0x0003, - 0x2011, 0x5046, 0x2204, 0xa086, 0x003c, 0x0040, 0x4bf9, 0x2019, - 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, 0x0039, 0x2011, 0x5046, - 0x2204, 0xa086, 0x003c, 0x0040, 0x4c07, 0x2019, 0x0027, 0x7b36, - 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011, 0x5046, 0x2204, 0xa086, - 0x003c, 0x0040, 0x4c15, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x783f, - 0x0000, 0x7843, 0x000a, 0x007c, 0x0020, 0x002b, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014, - 0x0014, 0x9849, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, - 0x0014, 0x0080, 0x000f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120, - 0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014, - 0xa200, 0x0214, 0x0000, 0x006c, 0x0002, 0x0014, 0x98d5, 0x009e, - 0x009b, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864, 0x9889, - 0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, 0x8300, - 0x1856, 0x883a, 0x9865, 0x28f2, 0x9c95, 0x9858, 0x300c, 0x28e1, - 0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814, 0x883b, - 0x782c, 0x786d, 0x9879, 0x282b, 0xa207, 0x64a0, 0x67a0, 0x6fc0, - 0x1814, 0x883b, 0x7822, 0x883e, 0x987d, 0x8576, 0x8677, 0x206b, - 0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209, - 0x2901, 0x9891, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, - 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014, 0xa204, - 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, - 0x87a9, 0x883f, 0x08e6, 0x9895, 0xf881, 0x9890, 0xc801, 0x0014, - 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, - 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, - 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, - 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, - 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0x98c8, 0x8000, 0xa000, - 0x2802, 0x1011, 0x98ce, 0x9865, 0x283e, 0x1011, 0x98d2, 0xa20b, - 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98df, - 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, - 0x3806, 0x0210, 0x9cbb, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f, - 0x0014, 0x009e, 0x00a0, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, - 0x9cd0, 0x8772, 0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd3, - 0x9859, 0xd984, 0xf0e2, 0xf0a1, 0x98cd, 0x0014, 0x8831, 0xd166, - 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301, - 0x987a, 0x10d2, 0x78e4, 0x9cd3, 0x8821, 0x8820, 0x9859, 0xf123, - 0xf142, 0xf101, 0x98c6, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, - 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd0, 0x2001, - 0x98c5, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d, - 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cbc, - 0x6b2a, 0x6902, 0x1834, 0x989d, 0x1814, 0x8010, 0x8592, 0x8026, - 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9ca9, 0x694b, 0xa213, - 0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x8023, 0x16e1, 0x8001, - 0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004, - 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, 0x9cbc, 0x0014, - 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, - 0x9cd0, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9cd3, - 0x98c5, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, - 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, - 0x9891, 0xa210, 0xa000, 0x8010, 0x8592, 0x853b, 0xd044, 0x8022, - 0x3807, 0x84bb, 0x98ea, 0x8021, 0x3807, 0x84b9, 0x300c, 0x817e, - 0x872b, 0x8772, 0x9891, 0x0000, 0x0020, 0x002b, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, - 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0014, - 0x0014, 0x9849, 0x0014, 0x0014, 0x98ea, 0x98d5, 0x0014, 0x0014, - 0x0014, 0x0080, 0x013f, 0x0000, 0x0201, 0x0604, 0x0c08, 0x2120, - 0x4022, 0xf880, 0x0018, 0x300b, 0xa201, 0x0014, 0xa200, 0x0014, - 0xa200, 0x0214, 0xa202, 0x8838, 0x3806, 0x8839, 0x20c3, 0x0864, - 0xa833, 0x28c1, 0x9cb6, 0xa203, 0x300c, 0x2846, 0x8161, 0x846a, - 0x8300, 0x1856, 0x883a, 0xa804, 0x28f2, 0x9c95, 0xa8f4, 0x300c, - 0x28e1, 0x9c95, 0x2809, 0xa206, 0x64c0, 0x67a0, 0x6fc0, 0x1814, - 0x883b, 0x782c, 0x786d, 0xa808, 0x282b, 0xa207, 0x64a0, 0x67a0, - 0x6fc0, 0x1814, 0x883b, 0x7822, 0x883e, 0xa802, 0x8576, 0x8677, - 0x206b, 0x28c1, 0x9cb6, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e0, - 0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, - 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c95, 0x0014, - 0xa204, 0xa300, 0x3009, 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, - 0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f3, 0xf881, 0xa8ec, 0xc801, - 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfb02, 0x1de2, - 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, - 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1, 0x0016, 0x8300, 0x8160, - 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, - 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847, 0x1011, 0xa8fc, 0x8000, - 0xa000, 0x2802, 0x1011, 0xa8fd, 0xa893, 0x283e, 0x1011, 0xa8fd, - 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, - 0xa801, 0x0014, 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, - 0xa20d, 0x3806, 0x0210, 0x9cbb, 0x0704, 0x0017, 0x60ff, 0x300c, - 0x8720, 0xa211, 0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2, - 0x78e2, 0x9d6e, 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa86c, 0x0014, - 0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, - 0xa80f, 0x2301, 0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820, - 0xa8e6, 0xf123, 0xf142, 0xf101, 0xa84f, 0x10d2, 0x70f6, 0x8832, - 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, - 0x9d6b, 0x2001, 0xa840, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, - 0x8001, 0xa801, 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, - 0x6981, 0x9d57, 0x6b2a, 0x6902, 0x1834, 0xa805, 0x1814, 0x8010, - 0x8592, 0x8026, 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d44, - 0x694b, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80c, 0x8023, - 0x16e1, 0x8001, 0x10f1, 0x0016, 0x6969, 0xa214, 0x61c2, 0x8002, - 0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827, 0x0014, 0xa217, - 0x9d57, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, 0x882c, - 0x0016, 0xa212, 0x9d6b, 0x10d2, 0x70e4, 0x0004, 0x8007, 0x9424, - 0xcc1a, 0x9d6e, 0xa8f8, 0x8827, 0x300a, 0x0013, 0x8000, 0x84a4, - 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014, 0x878e, 0x0016, - 0xa21c, 0x1035, 0xa8b4, 0xa210, 0x3807, 0x300c, 0x817e, 0x872b, - 0x8772, 0xa8ad, 0x0000, 0x8ec6 -}; - -#endif /* RELOAD_FIRMWARE */ - -static const unsigned short risc_code_length01 = 0x3f14; diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index caa0c36..5b1c120 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c @@ -1,5 +1,13 @@ /* - * RAID Attributes + * raid_class.c - implementation of a simple raid visualisation class + * + * Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com> + * + * This file is licensed under GPLv2 + * + * This class is designed to allow raid attributes to be visualised and + * manipulated in a form independent of the underlying raid. Ultimately this + * should work for both hardware and software raids. */ #include <linux/init.h> #include <linux/module.h> @@ -24,7 +32,7 @@ struct raid_internal { struct raid_component { struct list_head node; - struct device *dev; + struct class_device cdev; int num; }; @@ -74,11 +82,10 @@ static int raid_setup(struct transport_container *tc, struct device *dev, BUG_ON(class_get_devdata(cdev)); - rd = kmalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc(sizeof(*rd), GFP_KERNEL); if (!rd) return -ENOMEM; - memset(rd, 0, sizeof(*rd)); INIT_LIST_HEAD(&rd->component_list); class_set_devdata(cdev, rd); @@ -90,15 +97,15 @@ static int raid_remove(struct transport_container *tc, struct device *dev, { struct raid_data *rd = class_get_devdata(cdev); struct raid_component *rc, *next; + dev_printk(KERN_ERR, dev, "RAID REMOVE\n"); class_set_devdata(cdev, NULL); list_for_each_entry_safe(rc, next, &rd->component_list, node) { - char buf[40]; - snprintf(buf, sizeof(buf), "component-%d", rc->num); list_del(&rc->node); - sysfs_remove_link(&cdev->kobj, buf); - kfree(rc); + dev_printk(KERN_ERR, rc->cdev.dev, "RAID COMPONENT REMOVE\n"); + class_device_unregister(&rc->cdev); } - kfree(class_get_devdata(cdev)); + dev_printk(KERN_ERR, dev, "RAID REMOVE DONE\n"); + kfree(rd); return 0; } @@ -112,10 +119,11 @@ static struct { enum raid_state value; char *name; } raid_states[] = { - { RAID_ACTIVE, "active" }, - { RAID_DEGRADED, "degraded" }, - { RAID_RESYNCING, "resyncing" }, - { RAID_OFFLINE, "offline" }, + { RAID_STATE_UNKNOWN, "unknown" }, + { RAID_STATE_ACTIVE, "active" }, + { RAID_STATE_DEGRADED, "degraded" }, + { RAID_STATE_RESYNCING, "resyncing" }, + { RAID_STATE_OFFLINE, "offline" }, }; static const char *raid_state_name(enum raid_state state) @@ -132,6 +140,33 @@ static const char *raid_state_name(enum raid_state state) return name; } +static struct { + enum raid_level value; + char *name; +} raid_levels[] = { + { RAID_LEVEL_UNKNOWN, "unknown" }, + { RAID_LEVEL_LINEAR, "linear" }, + { RAID_LEVEL_0, "raid0" }, + { RAID_LEVEL_1, "raid1" }, + { RAID_LEVEL_3, "raid3" }, + { RAID_LEVEL_4, "raid4" }, + { RAID_LEVEL_5, "raid5" }, + { RAID_LEVEL_6, "raid6" }, +}; + +static const char *raid_level_name(enum raid_level level) +{ + int i; + char *name = NULL; + + for (i = 0; i < sizeof(raid_levels)/sizeof(raid_levels[0]); i++) { + if (raid_levels[i].value == level) { + name = raid_levels[i].name; + break; + } + } + return name; +} #define raid_attr_show_internal(attr, fmt, var, code) \ static ssize_t raid_show_##attr(struct class_device *cdev, char *buf) \ @@ -161,11 +196,22 @@ static CLASS_DEVICE_ATTR(attr, S_IRUGO, raid_show_##attr, NULL) #define raid_attr_ro(attr) raid_attr_ro_internal(attr, ) #define raid_attr_ro_fn(attr) raid_attr_ro_internal(attr, ATTR_CODE(attr)) -#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr)) +#define raid_attr_ro_state(attr) raid_attr_ro_states(attr, attr, ) +#define raid_attr_ro_state_fn(attr) raid_attr_ro_states(attr, attr, ATTR_CODE(attr)) + -raid_attr_ro(level); +raid_attr_ro_state(level); raid_attr_ro_fn(resync); -raid_attr_ro_state(state); +raid_attr_ro_state_fn(state); + +static void raid_component_release(struct class_device *cdev) +{ + struct raid_component *rc = container_of(cdev, struct raid_component, + cdev); + dev_printk(KERN_ERR, rc->cdev.dev, "COMPONENT RELEASE\n"); + put_device(rc->cdev.dev); + kfree(rc); +} void raid_component_add(struct raid_template *r,struct device *raid_dev, struct device *component_dev) @@ -175,34 +221,36 @@ void raid_component_add(struct raid_template *r,struct device *raid_dev, raid_dev); struct raid_component *rc; struct raid_data *rd = class_get_devdata(cdev); - char buf[40]; - rc = kmalloc(sizeof(*rc), GFP_KERNEL); + rc = kzalloc(sizeof(*rc), GFP_KERNEL); if (!rc) return; INIT_LIST_HEAD(&rc->node); - rc->dev = component_dev; + class_device_initialize(&rc->cdev); + rc->cdev.release = raid_component_release; + rc->cdev.dev = get_device(component_dev); rc->num = rd->component_count++; - snprintf(buf, sizeof(buf), "component-%d", rc->num); + snprintf(rc->cdev.class_id, sizeof(rc->cdev.class_id), + "component-%d", rc->num); list_add_tail(&rc->node, &rd->component_list); - sysfs_create_link(&cdev->kobj, &component_dev->kobj, buf); + rc->cdev.parent = cdev; + rc->cdev.class = &raid_class.class; + class_device_add(&rc->cdev); } EXPORT_SYMBOL(raid_component_add); struct raid_template * raid_class_attach(struct raid_function_template *ft) { - struct raid_internal *i = kmalloc(sizeof(struct raid_internal), + struct raid_internal *i = kzalloc(sizeof(struct raid_internal), GFP_KERNEL); int count = 0; if (unlikely(!i)) return NULL; - memset(i, 0, sizeof(*i)); - i->f = ft; i->r.raid_attrs.ac.class = &raid_class.class; diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 93d5523..9321cdf 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -1,7 +1,8 @@ /* * sata_mv.c - Marvell SATA support * - * Copyright 2005: EMC Corporation, all rights reserved. + * Copyright 2005: EMC Corporation, all rights reserved. + * Copyright 2005 Red Hat, Inc. All rights reserved. * * Please ALWAYS copy linux-ide@vger.kernel.org on emails. * @@ -36,7 +37,7 @@ #include <asm/io.h> #define DRV_NAME "sata_mv" -#define DRV_VERSION "0.25" +#define DRV_VERSION "0.5" enum { /* BAR's are enumerated in terms of pci_resource_start() terms */ @@ -50,6 +51,9 @@ enum { MV_PCI_REG_BASE = 0, MV_IRQ_COAL_REG_BASE = 0x18000, /* 6xxx part only */ MV_SATAHC0_REG_BASE = 0x20000, + MV_FLASH_CTL = 0x1046c, + MV_GPIO_PORT_CTL = 0x104f0, + MV_RESET_CFG = 0x180d8, MV_PCI_REG_SZ = MV_MAJOR_REG_AREA_SZ, MV_SATAHC_REG_SZ = MV_MAJOR_REG_AREA_SZ, @@ -72,11 +76,6 @@ enum { MV_SG_TBL_SZ = (16 * MV_MAX_SG_CT), MV_PORT_PRIV_DMA_SZ = (MV_CRQB_Q_SZ + MV_CRPB_Q_SZ + MV_SG_TBL_SZ), - /* Our DMA boundary is determined by an ePRD being unable to handle - * anything larger than 64KB - */ - MV_DMA_BOUNDARY = 0xffffU, - MV_PORTS_PER_HC = 4, /* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */ MV_PORT_HC_SHIFT = 2, @@ -86,16 +85,10 @@ enum { /* Host Flags */ MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */ MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */ - MV_FLAG_GLBL_SFT_RST = (1 << 28), /* Global Soft Reset support */ MV_COMMON_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO), - MV_6XXX_FLAGS = (MV_FLAG_IRQ_COALESCE | - MV_FLAG_GLBL_SFT_RST), - - chip_504x = 0, - chip_508x = 1, - chip_604x = 2, - chip_608x = 3, + ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_NO_ATAPI), + MV_6XXX_FLAGS = MV_FLAG_IRQ_COALESCE, CRQB_FLAG_READ = (1 << 0), CRQB_TAG_SHIFT = 1, @@ -116,8 +109,19 @@ enum { PCI_MASTER_EMPTY = (1 << 3), GLOB_SFT_RST = (1 << 4), - PCI_IRQ_CAUSE_OFS = 0x1d58, - PCI_IRQ_MASK_OFS = 0x1d5c, + MV_PCI_MODE = 0xd00, + MV_PCI_EXP_ROM_BAR_CTL = 0xd2c, + MV_PCI_DISC_TIMER = 0xd04, + MV_PCI_MSI_TRIGGER = 0xc38, + MV_PCI_SERR_MASK = 0xc28, + MV_PCI_XBAR_TMOUT = 0x1d04, + MV_PCI_ERR_LOW_ADDRESS = 0x1d40, + MV_PCI_ERR_HIGH_ADDRESS = 0x1d44, + MV_PCI_ERR_ATTRIBUTE = 0x1d48, + MV_PCI_ERR_COMMAND = 0x1d50, + + PCI_IRQ_CAUSE_OFS = 0x1d58, + PCI_IRQ_MASK_OFS = 0x1d5c, PCI_UNMASK_ALL_IRQS = 0x7fffff, /* bits 22-0 */ HC_MAIN_IRQ_CAUSE_OFS = 0x1d60, @@ -134,7 +138,7 @@ enum { SELF_INT = (1 << 23), TWSI_INT = (1 << 24), HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */ - HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | + HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE | PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT | HC_MAIN_RSVD), @@ -153,6 +157,15 @@ enum { /* SATA registers */ SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */ SATA_ACTIVE_OFS = 0x350, + PHY_MODE3 = 0x310, + PHY_MODE4 = 0x314, + PHY_MODE2 = 0x330, + MV5_PHY_MODE = 0x74, + MV5_LT_MODE = 0x30, + MV5_PHY_CTL = 0x0C, + SATA_INTERFACE_CTL = 0x050, + + MV_M2_PREAMP_MASK = 0x7e0, /* Port registers */ EDMA_CFG_OFS = 0, @@ -182,17 +195,16 @@ enum { EDMA_ERR_LNK_CTRL_TX = (0x1f << 21), EDMA_ERR_LNK_DATA_TX = (0x1f << 26), EDMA_ERR_TRANS_PROTO = (1 << 31), - EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | + EDMA_ERR_FATAL = (EDMA_ERR_D_PAR | EDMA_ERR_PRD_PAR | EDMA_ERR_DEV_DCON | EDMA_ERR_CRBQ_PAR | EDMA_ERR_CRPB_PAR | EDMA_ERR_INTRL_PAR | - EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 | + EDMA_ERR_IORDY | EDMA_ERR_LNK_CTRL_RX_2 | EDMA_ERR_LNK_DATA_RX | - EDMA_ERR_LNK_DATA_TX | + EDMA_ERR_LNK_DATA_TX | EDMA_ERR_TRANS_PROTO), EDMA_REQ_Q_BASE_HI_OFS = 0x10, EDMA_REQ_Q_IN_PTR_OFS = 0x14, /* also contains BASE_LO */ - EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, EDMA_REQ_Q_OUT_PTR_OFS = 0x18, EDMA_REQ_Q_PTR_SHIFT = 5, @@ -200,7 +212,6 @@ enum { EDMA_RSP_Q_BASE_HI_OFS = 0x1c, EDMA_RSP_Q_IN_PTR_OFS = 0x20, EDMA_RSP_Q_OUT_PTR_OFS = 0x24, /* also contains BASE_LO */ - EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, EDMA_RSP_Q_PTR_SHIFT = 3, EDMA_CMD_OFS = 0x28, @@ -208,14 +219,44 @@ enum { EDMA_DS = (1 << 1), ATA_RST = (1 << 2), + EDMA_IORDY_TMOUT = 0x34, + EDMA_ARB_CFG = 0x38, + /* Host private flags (hp_flags) */ MV_HP_FLAG_MSI = (1 << 0), + MV_HP_ERRATA_50XXB0 = (1 << 1), + MV_HP_ERRATA_50XXB2 = (1 << 2), + MV_HP_ERRATA_60X1B2 = (1 << 3), + MV_HP_ERRATA_60X1C0 = (1 << 4), + MV_HP_50XX = (1 << 5), /* Port private flags (pp_flags) */ MV_PP_FLAG_EDMA_EN = (1 << 0), MV_PP_FLAG_EDMA_DS_ACT = (1 << 1), }; +#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX) +#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0) + +enum { + /* Our DMA boundary is determined by an ePRD being unable to handle + * anything larger than 64KB + */ + MV_DMA_BOUNDARY = 0xffffU, + + EDMA_REQ_Q_BASE_LO_MASK = 0xfffffc00U, + + EDMA_RSP_Q_BASE_LO_MASK = 0xffffff00U, +}; + +enum chip_type { + chip_504x, + chip_508x, + chip_5080, + chip_604x, + chip_608x, +}; + /* Command ReQuest Block: 32B */ struct mv_crqb { u32 sg_addr; @@ -252,14 +293,37 @@ struct mv_port_priv { u32 pp_flags; }; +struct mv_port_signal { + u32 amps; + u32 pre; +}; + +struct mv_host_priv; +struct mv_hw_ops { + void (*phy_errata)(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port); + void (*enable_leds)(struct mv_host_priv *hpriv, void __iomem *mmio); + void (*read_preamp)(struct mv_host_priv *hpriv, int idx, + void __iomem *mmio); + int (*reset_hc)(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int n_hc); + void (*reset_flash)(struct mv_host_priv *hpriv, void __iomem *mmio); + void (*reset_bus)(struct pci_dev *pdev, void __iomem *mmio); +}; + struct mv_host_priv { u32 hp_flags; + struct mv_port_signal signal[8]; + const struct mv_hw_ops *ops; }; static void mv_irq_clear(struct ata_port *ap); static u32 mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in); static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in); +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val); static void mv_phy_reset(struct ata_port *ap); +static void __mv_phy_reset(struct ata_port *ap, int can_sleep); static void mv_host_stop(struct ata_host_set *host_set); static int mv_port_start(struct ata_port *ap); static void mv_port_stop(struct ata_port *ap); @@ -270,6 +334,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, static void mv_eng_timeout(struct ata_port *ap); static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); +static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port); +static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); +static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, + void __iomem *mmio); +static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int n_hc); +static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); +static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio); + +static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port); +static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio); +static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, + void __iomem *mmio); +static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int n_hc); +static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio); +static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio); +static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port_no); +static void mv_stop_and_reset(struct ata_port *ap); + static struct scsi_host_template mv_sht = { .module = THIS_MODULE, .name = DRV_NAME, @@ -278,7 +365,7 @@ static struct scsi_host_template mv_sht = { .eh_strategy_handler = ata_scsi_error, .can_queue = MV_USE_Q_DEPTH, .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = MV_MAX_SG_CT, + .sg_tablesize = MV_MAX_SG_CT / 2, .max_sectors = ATA_MAX_SECTORS, .cmd_per_lun = ATA_SHT_CMD_PER_LUN, .emulated = ATA_SHT_EMULATED, @@ -290,7 +377,34 @@ static struct scsi_host_template mv_sht = { .ordered_flush = 1, }; -static const struct ata_port_operations mv_ops = { +static const struct ata_port_operations mv5_ops = { + .port_disable = ata_port_disable, + + .tf_load = ata_tf_load, + .tf_read = ata_tf_read, + .check_status = ata_check_status, + .exec_command = ata_exec_command, + .dev_select = ata_std_dev_select, + + .phy_reset = mv_phy_reset, + + .qc_prep = mv_qc_prep, + .qc_issue = mv_qc_issue, + + .eng_timeout = mv_eng_timeout, + + .irq_handler = mv_interrupt, + .irq_clear = mv_irq_clear, + + .scr_read = mv5_scr_read, + .scr_write = mv5_scr_write, + + .port_start = mv_port_start, + .port_stop = mv_port_stop, + .host_stop = mv_host_stop, +}; + +static const struct ata_port_operations mv6_ops = { .port_disable = ata_port_disable, .tf_load = ata_tf_load, @@ -322,43 +436,52 @@ static struct ata_port_info mv_port_info[] = { .sht = &mv_sht, .host_flags = MV_COMMON_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ - .port_ops = &mv_ops, + .udma_mask = 0x7f, /* udma0-6 */ + .port_ops = &mv5_ops, }, { /* chip_508x */ .sht = &mv_sht, .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = 0, /* 0x7f (udma0-6 disabled for now) */ - .port_ops = &mv_ops, + .udma_mask = 0x7f, /* udma0-6 */ + .port_ops = &mv5_ops, + }, + { /* chip_5080 */ + .sht = &mv_sht, + .host_flags = (MV_COMMON_FLAGS | MV_FLAG_DUAL_HC), + .pio_mask = 0x1f, /* pio0-4 */ + .udma_mask = 0x7f, /* udma0-6 */ + .port_ops = &mv5_ops, }, { /* chip_604x */ .sht = &mv_sht, .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &mv_ops, + .port_ops = &mv6_ops, }, { /* chip_608x */ .sht = &mv_sht, - .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | + .host_flags = (MV_COMMON_FLAGS | MV_6XXX_FLAGS | MV_FLAG_DUAL_HC), .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 */ - .port_ops = &mv_ops, + .port_ops = &mv6_ops, }, }; -static struct pci_device_id mv_pci_tbl[] = { +static const struct pci_device_id mv_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5040), 0, 0, chip_504x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5041), 0, 0, chip_504x}, - {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_508x}, + {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5080), 0, 0, chip_5080}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5081), 0, 0, chip_508x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6040), 0, 0, chip_604x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6041), 0, 0, chip_604x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6080), 0, 0, chip_608x}, {PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x6081), 0, 0, chip_608x}, + + {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x0241), 0, 0, chip_604x}, {} /* terminate list */ }; @@ -369,6 +492,24 @@ static struct pci_driver mv_pci_driver = { .remove = ata_pci_remove_one, }; +static const struct mv_hw_ops mv5xxx_ops = { + .phy_errata = mv5_phy_errata, + .enable_leds = mv5_enable_leds, + .read_preamp = mv5_read_preamp, + .reset_hc = mv5_reset_hc, + .reset_flash = mv5_reset_flash, + .reset_bus = mv5_reset_bus, +}; + +static const struct mv_hw_ops mv6xxx_ops = { + .phy_errata = mv6_phy_errata, + .enable_leds = mv6_enable_leds, + .read_preamp = mv6_read_preamp, + .reset_hc = mv6_reset_hc, + .reset_flash = mv6_reset_flash, + .reset_bus = mv_reset_pci_bus, +}; + /* * Functions */ @@ -384,11 +525,27 @@ static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc) return (base + MV_SATAHC0_REG_BASE + (hc * MV_SATAHC_REG_SZ)); } +static inline unsigned int mv_hc_from_port(unsigned int port) +{ + return port >> MV_PORT_HC_SHIFT; +} + +static inline unsigned int mv_hardport_from_port(unsigned int port) +{ + return port & MV_PORT_MASK; +} + +static inline void __iomem *mv_hc_base_from_port(void __iomem *base, + unsigned int port) +{ + return mv_hc_base(base, mv_hc_from_port(port)); +} + static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port) { - return (mv_hc_base(base, port >> MV_PORT_HC_SHIFT) + - MV_SATAHC_ARBTR_REG_SZ + - ((port & MV_PORT_MASK) * MV_PORT_REG_SZ)); + return mv_hc_base_from_port(base, port) + + MV_SATAHC_ARBTR_REG_SZ + + (mv_hardport_from_port(port) * MV_PORT_REG_SZ); } static inline void __iomem *mv_ap_base(struct ata_port *ap) @@ -396,9 +553,9 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap) return mv_port_base(ap->host_set->mmio_base, ap->port_no); } -static inline int mv_get_hc_count(unsigned long hp_flags) +static inline int mv_get_hc_count(unsigned long host_flags) { - return ((hp_flags & MV_FLAG_DUAL_HC) ? 2 : 1); + return ((host_flags & MV_FLAG_DUAL_HC) ? 2 : 1); } static void mv_irq_clear(struct ata_port *ap) @@ -450,7 +607,7 @@ static void mv_stop_dma(struct ata_port *ap) } else { assert(!(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS))); } - + /* now properly wait for the eDMA to stop */ for (i = 1000; i > 0; i--) { reg = readl(port_mmio + EDMA_CMD_OFS); @@ -501,7 +658,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, struct pci_dev *pdev) { #ifdef ATA_DEBUG - void __iomem *hc_base = mv_hc_base(mmio_base, + void __iomem *hc_base = mv_hc_base(mmio_base, port >> MV_PORT_HC_SHIFT); void __iomem *port_base; int start_port, num_ports, p, start_hc, num_hcs, hc; @@ -515,7 +672,7 @@ static void mv_dump_all_regs(void __iomem *mmio_base, int port, start_port = port; num_ports = num_hcs = 1; } - DPRINTK("All registers for port(s) %u-%u:\n", start_port, + DPRINTK("All registers for port(s) %u-%u:\n", start_port, num_ports > 1 ? num_ports - 1 : start_port); if (NULL != pdev) { @@ -583,70 +740,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) } /** - * mv_global_soft_reset - Perform the 6xxx global soft reset - * @mmio_base: base address of the HBA - * - * This routine only applies to 6xxx parts. - * - * LOCKING: - * Inherited from caller. - */ -static int mv_global_soft_reset(void __iomem *mmio_base) -{ - void __iomem *reg = mmio_base + PCI_MAIN_CMD_STS_OFS; - int i, rc = 0; - u32 t; - - /* Following procedure defined in PCI "main command and status - * register" table. - */ - t = readl(reg); - writel(t | STOP_PCI_MASTER, reg); - - for (i = 0; i < 1000; i++) { - udelay(1); - t = readl(reg); - if (PCI_MASTER_EMPTY & t) { - break; - } - } - if (!(PCI_MASTER_EMPTY & t)) { - printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); - rc = 1; - goto done; - } - - /* set reset */ - i = 5; - do { - writel(t | GLOB_SFT_RST, reg); - t = readl(reg); - udelay(1); - } while (!(GLOB_SFT_RST & t) && (i-- > 0)); - - if (!(GLOB_SFT_RST & t)) { - printk(KERN_ERR DRV_NAME ": can't set global reset\n"); - rc = 1; - goto done; - } - - /* clear reset and *reenable the PCI master* (not mentioned in spec) */ - i = 5; - do { - writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg); - t = readl(reg); - udelay(1); - } while ((GLOB_SFT_RST & t) && (i-- > 0)); - - if (GLOB_SFT_RST & t) { - printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); - rc = 1; - } -done: - return rc; -} - -/** * mv_host_stop - Host specific cleanup/stop routine. * @host_set: host data structure * @@ -699,7 +792,7 @@ static int mv_port_start(struct ata_port *ap) goto err_out; memset(pp, 0, sizeof(*pp)); - mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, + mem = dma_alloc_coherent(dev, MV_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) goto err_out_pp; @@ -709,7 +802,7 @@ static int mv_port_start(struct ata_port *ap) if (rc) goto err_out_priv; - /* First item in chunk of DMA memory: + /* First item in chunk of DMA memory: * 32-slot command request table (CRQB), 32 bytes each in size */ pp->crqb = mem; @@ -717,7 +810,7 @@ static int mv_port_start(struct ata_port *ap) mem += MV_CRQB_Q_SZ; mem_dma += MV_CRQB_Q_SZ; - /* Second item: + /* Second item: * 32-slot command response table (CRPB), 8 bytes each in size */ pp->crpb = mem; @@ -731,18 +824,18 @@ static int mv_port_start(struct ata_port *ap) pp->sg_tbl = mem; pp->sg_tbl_dma = mem_dma; - writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | + writelfl(EDMA_CFG_Q_DEPTH | EDMA_CFG_RD_BRST_EXT | EDMA_CFG_WR_BUFF_LEN, port_mmio + EDMA_CFG_OFS); writel((pp->crqb_dma >> 16) >> 16, port_mmio + EDMA_REQ_Q_BASE_HI_OFS); - writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, + writelfl(pp->crqb_dma & EDMA_REQ_Q_BASE_LO_MASK, port_mmio + EDMA_REQ_Q_IN_PTR_OFS); writelfl(0, port_mmio + EDMA_REQ_Q_OUT_PTR_OFS); writelfl(0, port_mmio + EDMA_RSP_Q_IN_PTR_OFS); writel((pp->crpb_dma >> 16) >> 16, port_mmio + EDMA_RSP_Q_BASE_HI_OFS); - writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, + writelfl(pp->crpb_dma & EDMA_RSP_Q_BASE_LO_MASK, port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); pp->req_producer = pp->rsp_consumer = 0; @@ -803,20 +896,30 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg; ata_for_each_sg(sg, qc) { - u32 sg_len; dma_addr_t addr; + u32 sg_len, len, offset; addr = sg_dma_address(sg); sg_len = sg_dma_len(sg); - pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); - pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); - assert(0 == (sg_len & ~MV_DMA_BOUNDARY)); - pp->sg_tbl[i].flags_size = cpu_to_le32(sg_len); - if (ata_sg_is_last(sg, qc)) - pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); + while (sg_len) { + offset = addr & MV_DMA_BOUNDARY; + len = sg_len; + if ((offset + sg_len) > 0x10000) + len = 0x10000 - offset; + + pp->sg_tbl[i].addr = cpu_to_le32(addr & 0xffffffff); + pp->sg_tbl[i].addr_hi = cpu_to_le32((addr >> 16) >> 16); + pp->sg_tbl[i].flags_size = cpu_to_le32(len); + + sg_len -= len; + addr += len; + + if (!sg_len && ata_sg_is_last(sg, qc)) + pp->sg_tbl[i].flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); - i++; + i++; + } } } @@ -857,7 +960,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) } /* the req producer index should be the same as we remember it */ - assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> + assert(((readl(mv_ap_base(qc->ap) + EDMA_REQ_Q_IN_PTR_OFS) >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == pp->req_producer); @@ -869,9 +972,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) assert(MV_MAX_Q_DEPTH > qc->tag); flags |= qc->tag << CRQB_TAG_SHIFT; - pp->crqb[pp->req_producer].sg_addr = + pp->crqb[pp->req_producer].sg_addr = cpu_to_le32(pp->sg_tbl_dma & 0xffffffff); - pp->crqb[pp->req_producer].sg_addr_hi = + pp->crqb[pp->req_producer].sg_addr_hi = cpu_to_le32((pp->sg_tbl_dma >> 16) >> 16); pp->crqb[pp->req_producer].ctrl_flags = cpu_to_le16(flags); @@ -894,7 +997,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) #ifdef LIBATA_NCQ /* FIXME: remove this line when NCQ added */ case ATA_CMD_FPDMA_READ: case ATA_CMD_FPDMA_WRITE: - mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0); + mv_crqb_pack_cmd(cw++, tf->hob_feature, ATA_REG_FEATURE, 0); mv_crqb_pack_cmd(cw++, tf->feature, ATA_REG_FEATURE, 0); break; #endif /* FIXME: remove this line when NCQ added */ @@ -960,7 +1063,7 @@ static int mv_qc_issue(struct ata_queued_cmd *qc) pp->req_producer); /* until we do queuing, the queue should be empty at this point */ assert(((in_ptr >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == - ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> + ((readl(port_mmio + EDMA_REQ_Q_OUT_PTR_OFS) >> EDMA_REQ_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK)); mv_inc_q_index(&pp->req_producer); /* now incr producer index */ @@ -997,15 +1100,15 @@ static u8 mv_get_crpb_status(struct ata_port *ap) out_ptr = readl(port_mmio + EDMA_RSP_Q_OUT_PTR_OFS); /* the response consumer index should be the same as we remember it */ - assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + assert(((out_ptr >> EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == pp->rsp_consumer); /* increment our consumer index... */ pp->rsp_consumer = mv_inc_q_index(&pp->rsp_consumer); - + /* and, until we do NCQ, there should only be 1 CRPB waiting */ - assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> - EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == + assert(((readl(port_mmio + EDMA_RSP_Q_IN_PTR_OFS) >> + EDMA_RSP_Q_PTR_SHIFT) & MV_MAX_Q_DEPTH_MASK) == pp->rsp_consumer); /* write out our inc'd consumer index so EDMA knows we're caught up */ @@ -1053,7 +1156,7 @@ static void mv_err_intr(struct ata_port *ap) /* check for fatal here and recover if needed */ if (EDMA_ERR_FATAL & edma_err_cause) { - mv_phy_reset(ap); + mv_stop_and_reset(ap); } } @@ -1118,6 +1221,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, handled++; } + if (ap && + (ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) + continue; + err_mask = ac_err_mask(ata_status); shift = port << 1; /* (port * 2) */ @@ -1129,14 +1236,15 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, err_mask |= AC_ERR_OTHER; handled++; } - + if (handled && ap) { qc = ata_qc_from_tag(ap, ap->active_tag); if (NULL != qc) { VPRINTK("port %u IRQ found for qc, " "ata_status 0x%x\n", port,ata_status); /* mark qc status appropriately */ - ata_qc_complete(qc, err_mask); + if (!(qc->tf.ctl & ATA_NIEN)) + ata_qc_complete(qc, err_mask); } } } @@ -1144,7 +1252,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, } /** - * mv_interrupt - + * mv_interrupt - * @irq: unused * @dev_instance: private data; in this case the host structure * @regs: unused @@ -1154,7 +1262,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant, * routine to handle. Also check for PCI errors which are only * reported here. * - * LOCKING: + * LOCKING: * This routine holds the host_set lock while processing pending * interrupts. */ @@ -1200,8 +1308,422 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, return IRQ_RETVAL(handled); } +static void __iomem *mv5_phy_base(void __iomem *mmio, unsigned int port) +{ + void __iomem *hc_mmio = mv_hc_base_from_port(mmio, port); + unsigned long ofs = (mv_hardport_from_port(port) + 1) * 0x100UL; + + return hc_mmio + ofs; +} + +static unsigned int mv5_scr_offset(unsigned int sc_reg_in) +{ + unsigned int ofs; + + switch (sc_reg_in) { + case SCR_STATUS: + case SCR_ERROR: + case SCR_CONTROL: + ofs = sc_reg_in * sizeof(u32); + break; + default: + ofs = 0xffffffffU; + break; + } + return ofs; +} + +static u32 mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in) +{ + void __iomem *mmio = mv5_phy_base(ap->host_set->mmio_base, ap->port_no); + unsigned int ofs = mv5_scr_offset(sc_reg_in); + + if (ofs != 0xffffffffU) + return readl(mmio + ofs); + else + return (u32) ofs; +} + +static void mv5_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val) +{ + void __iomem *mmio = mv5_phy_base(ap->host_set->mmio_base, ap->port_no); + unsigned int ofs = mv5_scr_offset(sc_reg_in); + + if (ofs != 0xffffffffU) + writelfl(val, mmio + ofs); +} + +static void mv5_reset_bus(struct pci_dev *pdev, void __iomem *mmio) +{ + u8 rev_id; + int early_5080; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + + early_5080 = (pdev->device == 0x5080) && (rev_id == 0); + + if (!early_5080) { + u32 tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL); + tmp |= (1 << 0); + writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); + } + + mv_reset_pci_bus(pdev, mmio); +} + +static void mv5_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) +{ + writel(0x0fcfffff, mmio + MV_FLASH_CTL); +} + +static void mv5_read_preamp(struct mv_host_priv *hpriv, int idx, + void __iomem *mmio) +{ + void __iomem *phy_mmio = mv5_phy_base(mmio, idx); + u32 tmp; + + tmp = readl(phy_mmio + MV5_PHY_MODE); + + hpriv->signal[idx].pre = tmp & 0x1800; /* bits 12:11 */ + hpriv->signal[idx].amps = tmp & 0xe0; /* bits 7:5 */ +} + +static void mv5_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) +{ + u32 tmp; + + writel(0, mmio + MV_GPIO_PORT_CTL); + + /* FIXME: handle MV_HP_ERRATA_50XXB2 errata */ + + tmp = readl(mmio + MV_PCI_EXP_ROM_BAR_CTL); + tmp |= ~(1 << 0); + writel(tmp, mmio + MV_PCI_EXP_ROM_BAR_CTL); +} + +static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port) +{ + void __iomem *phy_mmio = mv5_phy_base(mmio, port); + const u32 mask = (1<<12) | (1<<11) | (1<<7) | (1<<6) | (1<<5); + u32 tmp; + int fix_apm_sq = (hpriv->hp_flags & MV_HP_ERRATA_50XXB0); + + if (fix_apm_sq) { + tmp = readl(phy_mmio + MV5_LT_MODE); + tmp |= (1 << 19); + writel(tmp, phy_mmio + MV5_LT_MODE); + + tmp = readl(phy_mmio + MV5_PHY_CTL); + tmp &= ~0x3; + tmp |= 0x1; + writel(tmp, phy_mmio + MV5_PHY_CTL); + } + + tmp = readl(phy_mmio + MV5_PHY_MODE); + tmp &= ~mask; + tmp |= hpriv->signal[port].pre; + tmp |= hpriv->signal[port].amps; + writel(tmp, phy_mmio + MV5_PHY_MODE); +} + + +#undef ZERO +#define ZERO(reg) writel(0, port_mmio + (reg)) +static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port) +{ + void __iomem *port_mmio = mv_port_base(mmio, port); + + writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS); + + mv_channel_reset(hpriv, mmio, port); + + ZERO(0x028); /* command */ + writel(0x11f, port_mmio + EDMA_CFG_OFS); + ZERO(0x004); /* timer */ + ZERO(0x008); /* irq err cause */ + ZERO(0x00c); /* irq err mask */ + ZERO(0x010); /* rq bah */ + ZERO(0x014); /* rq inp */ + ZERO(0x018); /* rq outp */ + ZERO(0x01c); /* respq bah */ + ZERO(0x024); /* respq outp */ + ZERO(0x020); /* respq inp */ + ZERO(0x02c); /* test control */ + writel(0xbc, port_mmio + EDMA_IORDY_TMOUT); +} +#undef ZERO + +#define ZERO(reg) writel(0, hc_mmio + (reg)) +static void mv5_reset_one_hc(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int hc) +{ + void __iomem *hc_mmio = mv_hc_base(mmio, hc); + u32 tmp; + + ZERO(0x00c); + ZERO(0x010); + ZERO(0x014); + ZERO(0x018); + + tmp = readl(hc_mmio + 0x20); + tmp &= 0x1c1c1c1c; + tmp |= 0x03030303; + writel(tmp, hc_mmio + 0x20); +} +#undef ZERO + +static int mv5_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int n_hc) +{ + unsigned int hc, port; + + for (hc = 0; hc < n_hc; hc++) { + for (port = 0; port < MV_PORTS_PER_HC; port++) + mv5_reset_hc_port(hpriv, mmio, + (hc * MV_PORTS_PER_HC) + port); + + mv5_reset_one_hc(hpriv, mmio, hc); + } + + return 0; +} + +#undef ZERO +#define ZERO(reg) writel(0, mmio + (reg)) +static void mv_reset_pci_bus(struct pci_dev *pdev, void __iomem *mmio) +{ + u32 tmp; + + tmp = readl(mmio + MV_PCI_MODE); + tmp &= 0xff00ffff; + writel(tmp, mmio + MV_PCI_MODE); + + ZERO(MV_PCI_DISC_TIMER); + ZERO(MV_PCI_MSI_TRIGGER); + writel(0x000100ff, mmio + MV_PCI_XBAR_TMOUT); + ZERO(HC_MAIN_IRQ_MASK_OFS); + ZERO(MV_PCI_SERR_MASK); + ZERO(PCI_IRQ_CAUSE_OFS); + ZERO(PCI_IRQ_MASK_OFS); + ZERO(MV_PCI_ERR_LOW_ADDRESS); + ZERO(MV_PCI_ERR_HIGH_ADDRESS); + ZERO(MV_PCI_ERR_ATTRIBUTE); + ZERO(MV_PCI_ERR_COMMAND); +} +#undef ZERO + +static void mv6_reset_flash(struct mv_host_priv *hpriv, void __iomem *mmio) +{ + u32 tmp; + + mv5_reset_flash(hpriv, mmio); + + tmp = readl(mmio + MV_GPIO_PORT_CTL); + tmp &= 0x3; + tmp |= (1 << 5) | (1 << 6); + writel(tmp, mmio + MV_GPIO_PORT_CTL); +} + +/** + * mv6_reset_hc - Perform the 6xxx global soft reset + * @mmio: base address of the HBA + * + * This routine only applies to 6xxx parts. + * + * LOCKING: + * Inherited from caller. + */ +static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int n_hc) +{ + void __iomem *reg = mmio + PCI_MAIN_CMD_STS_OFS; + int i, rc = 0; + u32 t; + + /* Following procedure defined in PCI "main command and status + * register" table. + */ + t = readl(reg); + writel(t | STOP_PCI_MASTER, reg); + + for (i = 0; i < 1000; i++) { + udelay(1); + t = readl(reg); + if (PCI_MASTER_EMPTY & t) { + break; + } + } + if (!(PCI_MASTER_EMPTY & t)) { + printk(KERN_ERR DRV_NAME ": PCI master won't flush\n"); + rc = 1; + goto done; + } + + /* set reset */ + i = 5; + do { + writel(t | GLOB_SFT_RST, reg); + t = readl(reg); + udelay(1); + } while (!(GLOB_SFT_RST & t) && (i-- > 0)); + + if (!(GLOB_SFT_RST & t)) { + printk(KERN_ERR DRV_NAME ": can't set global reset\n"); + rc = 1; + goto done; + } + + /* clear reset and *reenable the PCI master* (not mentioned in spec) */ + i = 5; + do { + writel(t & ~(GLOB_SFT_RST | STOP_PCI_MASTER), reg); + t = readl(reg); + udelay(1); + } while ((GLOB_SFT_RST & t) && (i-- > 0)); + + if (GLOB_SFT_RST & t) { + printk(KERN_ERR DRV_NAME ": can't clear global reset\n"); + rc = 1; + } +done: + return rc; +} + +static void mv6_read_preamp(struct mv_host_priv *hpriv, int idx, + void __iomem *mmio) +{ + void __iomem *port_mmio; + u32 tmp; + + tmp = readl(mmio + MV_RESET_CFG); + if ((tmp & (1 << 0)) == 0) { + hpriv->signal[idx].amps = 0x7 << 8; + hpriv->signal[idx].pre = 0x1 << 5; + return; + } + + port_mmio = mv_port_base(mmio, idx); + tmp = readl(port_mmio + PHY_MODE2); + + hpriv->signal[idx].amps = tmp & 0x700; /* bits 10:8 */ + hpriv->signal[idx].pre = tmp & 0xe0; /* bits 7:5 */ +} + +static void mv6_enable_leds(struct mv_host_priv *hpriv, void __iomem *mmio) +{ + writel(0x00000060, mmio + MV_GPIO_PORT_CTL); +} + +static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port) +{ + void __iomem *port_mmio = mv_port_base(mmio, port); + + u32 hp_flags = hpriv->hp_flags; + int fix_phy_mode2 = + hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); + int fix_phy_mode4 = + hp_flags & (MV_HP_ERRATA_60X1B2 | MV_HP_ERRATA_60X1C0); + u32 m2, tmp; + + if (fix_phy_mode2) { + m2 = readl(port_mmio + PHY_MODE2); + m2 &= ~(1 << 16); + m2 |= (1 << 31); + writel(m2, port_mmio + PHY_MODE2); + + udelay(200); + + m2 = readl(port_mmio + PHY_MODE2); + m2 &= ~((1 << 16) | (1 << 31)); + writel(m2, port_mmio + PHY_MODE2); + + udelay(200); + } + + /* who knows what this magic does */ + tmp = readl(port_mmio + PHY_MODE3); + tmp &= ~0x7F800000; + tmp |= 0x2A800000; + writel(tmp, port_mmio + PHY_MODE3); + + if (fix_phy_mode4) { + u32 m4; + + m4 = readl(port_mmio + PHY_MODE4); + + if (hp_flags & MV_HP_ERRATA_60X1B2) + tmp = readl(port_mmio + 0x310); + + m4 = (m4 & ~(1 << 1)) | (1 << 0); + + writel(m4, port_mmio + PHY_MODE4); + + if (hp_flags & MV_HP_ERRATA_60X1B2) + writel(tmp, port_mmio + 0x310); + } + + /* Revert values of pre-emphasis and signal amps to the saved ones */ + m2 = readl(port_mmio + PHY_MODE2); + + m2 &= ~MV_M2_PREAMP_MASK; + m2 |= hpriv->signal[port].amps; + m2 |= hpriv->signal[port].pre; + m2 &= ~(1 << 16); + + writel(m2, port_mmio + PHY_MODE2); +} + +static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio, + unsigned int port_no) +{ + void __iomem *port_mmio = mv_port_base(mmio, port_no); + + writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); + + if (IS_60XX(hpriv)) { + u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); + ifctl |= (1 << 12) | (1 << 7); + writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); + } + + udelay(25); /* allow reset propagation */ + + /* Spec never mentions clearing the bit. Marvell's driver does + * clear the bit, however. + */ + writelfl(0, port_mmio + EDMA_CMD_OFS); + + hpriv->ops->phy_errata(hpriv, mmio, port_no); + + if (IS_50XX(hpriv)) + mdelay(1); +} + +static void mv_stop_and_reset(struct ata_port *ap) +{ + struct mv_host_priv *hpriv = ap->host_set->private_data; + void __iomem *mmio = ap->host_set->mmio_base; + + mv_stop_dma(ap); + + mv_channel_reset(hpriv, mmio, ap->port_no); + + __mv_phy_reset(ap, 0); +} + +static inline void __msleep(unsigned int msec, int can_sleep) +{ + if (can_sleep) + msleep(msec); + else + mdelay(msec); +} + /** - * mv_phy_reset - Perform eDMA reset followed by COMRESET + * __mv_phy_reset - Perform eDMA reset followed by COMRESET * @ap: ATA channel to manipulate * * Part of this is taken from __sata_phy_reset and modified to @@ -1211,41 +1733,47 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance, * Inherited from caller. This is coded to safe to call at * interrupt level, i.e. it does not sleep. */ -static void mv_phy_reset(struct ata_port *ap) +static void __mv_phy_reset(struct ata_port *ap, int can_sleep) { + struct mv_port_priv *pp = ap->private_data; + struct mv_host_priv *hpriv = ap->host_set->private_data; void __iomem *port_mmio = mv_ap_base(ap); struct ata_taskfile tf; struct ata_device *dev = &ap->device[0]; unsigned long timeout; + int retry = 5; + u32 sstatus; VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio); - mv_stop_dma(ap); - - writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS); - udelay(25); /* allow reset propagation */ - - /* Spec never mentions clearing the bit. Marvell's driver does - * clear the bit, however. - */ - writelfl(0, port_mmio + EDMA_CMD_OFS); - - VPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " + DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x " "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); - /* proceed to init communications via the scr_control reg */ + /* Issue COMRESET via SControl */ +comreset_retry: scr_write_flush(ap, SCR_CONTROL, 0x301); - mdelay(1); + __msleep(1, can_sleep); + scr_write_flush(ap, SCR_CONTROL, 0x300); - timeout = jiffies + (HZ * 1); + __msleep(20, can_sleep); + + timeout = jiffies + msecs_to_jiffies(200); do { - mdelay(10); - if ((scr_read(ap, SCR_STATUS) & 0xf) != 1) + sstatus = scr_read(ap, SCR_STATUS) & 0x3; + if ((sstatus == 3) || (sstatus == 0)) break; + + __msleep(1, can_sleep); } while (time_before(jiffies, timeout)); - VPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " + /* work around errata */ + if (IS_60XX(hpriv) && + (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) && + (retry-- > 0)) + goto comreset_retry; + + DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x " "SCtrl 0x%08x\n", mv_scr_read(ap, SCR_STATUS), mv_scr_read(ap, SCR_ERROR), mv_scr_read(ap, SCR_CONTROL)); @@ -1259,6 +1787,21 @@ static void mv_phy_reset(struct ata_port *ap) } ap->cbl = ATA_CBL_SATA; + /* even after SStatus reflects that device is ready, + * it seems to take a while for link to be fully + * established (and thus Status no longer 0x80/0x7F), + * so we poll a bit for that, here. + */ + retry = 20; + while (1) { + u8 drv_stat = ata_check_status(ap); + if ((drv_stat != 0x80) && (drv_stat != 0x7f)) + break; + __msleep(500, can_sleep); + if (retry-- <= 0) + break; + } + tf.lbah = readb((void __iomem *) ap->ioaddr.lbah_addr); tf.lbam = readb((void __iomem *) ap->ioaddr.lbam_addr); tf.lbal = readb((void __iomem *) ap->ioaddr.lbal_addr); @@ -1269,9 +1812,19 @@ static void mv_phy_reset(struct ata_port *ap) VPRINTK("Port disabled post-sig: No device present.\n"); ata_port_disable(ap); } + + writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS); + + pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN; + VPRINTK("EXIT\n"); } +static void mv_phy_reset(struct ata_port *ap) +{ + __mv_phy_reset(ap, 1); +} + /** * mv_eng_timeout - Routine called by libata when SCSI times out I/O * @ap: ATA channel to manipulate @@ -1289,16 +1842,16 @@ static void mv_eng_timeout(struct ata_port *ap) printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); DPRINTK("All regs @ start of eng_timeout\n"); - mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, + mv_dump_all_regs(ap->host_set->mmio_base, ap->port_no, to_pci_dev(ap->host_set->dev)); qc = ata_qc_from_tag(ap, ap->active_tag); printk(KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n", - ap->host_set->mmio_base, ap, qc, qc->scsicmd, + ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); mv_err_intr(ap); - mv_phy_reset(ap); + mv_stop_and_reset(ap); if (!qc) { printk(KERN_ERR "ata%u: BUG: timeout without command\n", @@ -1334,17 +1887,17 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) unsigned long shd_base = (unsigned long) port_mmio + SHD_BLK_OFS; unsigned serr_ofs; - /* PIO related setup + /* PIO related setup */ port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA); - port->error_addr = + port->error_addr = port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR); port->nsect_addr = shd_base + (sizeof(u32) * ATA_REG_NSECT); port->lbal_addr = shd_base + (sizeof(u32) * ATA_REG_LBAL); port->lbam_addr = shd_base + (sizeof(u32) * ATA_REG_LBAM); port->lbah_addr = shd_base + (sizeof(u32) * ATA_REG_LBAH); port->device_addr = shd_base + (sizeof(u32) * ATA_REG_DEVICE); - port->status_addr = + port->status_addr = port->command_addr = shd_base + (sizeof(u32) * ATA_REG_STATUS); /* special case: control/altstatus doesn't have ATA_REG_ address */ port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS; @@ -1360,14 +1913,92 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) /* unmask all EDMA error interrupts */ writelfl(~0, port_mmio + EDMA_ERR_IRQ_MASK_OFS); - VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", + VPRINTK("EDMA cfg=0x%08x EDMA IRQ err cause/mask=0x%08x/0x%08x\n", readl(port_mmio + EDMA_CFG_OFS), readl(port_mmio + EDMA_ERR_IRQ_CAUSE_OFS), readl(port_mmio + EDMA_ERR_IRQ_MASK_OFS)); } +static int mv_chip_id(struct pci_dev *pdev, struct mv_host_priv *hpriv, + unsigned int board_idx) +{ + u8 rev_id; + u32 hp_flags = hpriv->hp_flags; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id); + + switch(board_idx) { + case chip_5080: + hpriv->ops = &mv5xxx_ops; + hp_flags |= MV_HP_50XX; + + switch (rev_id) { + case 0x1: + hp_flags |= MV_HP_ERRATA_50XXB0; + break; + case 0x3: + hp_flags |= MV_HP_ERRATA_50XXB2; + break; + default: + dev_printk(KERN_WARNING, &pdev->dev, + "Applying 50XXB2 workarounds to unknown rev\n"); + hp_flags |= MV_HP_ERRATA_50XXB2; + break; + } + break; + + case chip_504x: + case chip_508x: + hpriv->ops = &mv5xxx_ops; + hp_flags |= MV_HP_50XX; + + switch (rev_id) { + case 0x0: + hp_flags |= MV_HP_ERRATA_50XXB0; + break; + case 0x3: + hp_flags |= MV_HP_ERRATA_50XXB2; + break; + default: + dev_printk(KERN_WARNING, &pdev->dev, + "Applying B2 workarounds to unknown rev\n"); + hp_flags |= MV_HP_ERRATA_50XXB2; + break; + } + break; + + case chip_604x: + case chip_608x: + hpriv->ops = &mv6xxx_ops; + + switch (rev_id) { + case 0x7: + hp_flags |= MV_HP_ERRATA_60X1B2; + break; + case 0x9: + hp_flags |= MV_HP_ERRATA_60X1C0; + break; + default: + dev_printk(KERN_WARNING, &pdev->dev, + "Applying B2 workarounds to unknown rev\n"); + hp_flags |= MV_HP_ERRATA_60X1B2; + break; + } + break; + + default: + printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx); + return 1; + } + + hpriv->hp_flags = hp_flags; + + return 0; +} + /** - * mv_host_init - Perform some early initialization of the host. + * mv_init_host - Perform some early initialization of the host. + * @pdev: host PCI device * @probe_ent: early data struct representing the host * * If possible, do an early global reset of the host. Then do @@ -1376,23 +2007,48 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio) * LOCKING: * Inherited from caller. */ -static int mv_host_init(struct ata_probe_ent *probe_ent) +static int mv_init_host(struct pci_dev *pdev, struct ata_probe_ent *probe_ent, + unsigned int board_idx) { int rc = 0, n_hc, port, hc; void __iomem *mmio = probe_ent->mmio_base; - void __iomem *port_mmio; + struct mv_host_priv *hpriv = probe_ent->private_data; - if ((MV_FLAG_GLBL_SFT_RST & probe_ent->host_flags) && - mv_global_soft_reset(probe_ent->mmio_base)) { - rc = 1; + /* global interrupt mask */ + writel(0, mmio + HC_MAIN_IRQ_MASK_OFS); + + rc = mv_chip_id(pdev, hpriv, board_idx); + if (rc) goto done; - } n_hc = mv_get_hc_count(probe_ent->host_flags); probe_ent->n_ports = MV_PORTS_PER_HC * n_hc; + for (port = 0; port < probe_ent->n_ports; port++) + hpriv->ops->read_preamp(hpriv, port, mmio); + + rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc); + if (rc) + goto done; + + hpriv->ops->reset_flash(hpriv, mmio); + hpriv->ops->reset_bus(pdev, mmio); + hpriv->ops->enable_leds(hpriv, mmio); + for (port = 0; port < probe_ent->n_ports; port++) { - port_mmio = mv_port_base(mmio, port); + if (IS_60XX(hpriv)) { + void __iomem *port_mmio = mv_port_base(mmio, port); + + u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL); + ifctl |= (1 << 12); + writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL); + } + + hpriv->ops->phy_errata(hpriv, mmio, port); + } + + for (port = 0; port < probe_ent->n_ports; port++) { + void __iomem *port_mmio = mv_port_base(mmio, port); mv_port_init(&probe_ent->port[port], port_mmio); } @@ -1416,11 +2072,12 @@ static int mv_host_init(struct ata_probe_ent *probe_ent) writelfl(~HC_MAIN_MASKED_IRQS, mmio + HC_MAIN_IRQ_MASK_OFS); VPRINTK("HC MAIN IRQ cause/mask=0x%08x/0x%08x " - "PCI int cause/mask=0x%08x/0x%08x\n", + "PCI int cause/mask=0x%08x/0x%08x\n", readl(mmio + HC_MAIN_IRQ_CAUSE_OFS), readl(mmio + HC_MAIN_IRQ_MASK_OFS), readl(mmio + PCI_IRQ_CAUSE_OFS), readl(mmio + PCI_IRQ_MASK_OFS)); + done: return rc; } @@ -1456,7 +2113,7 @@ static void mv_print_info(struct ata_probe_ent *probe_ent) dev_printk(KERN_INFO, &pdev->dev, "%u slots %u ports %s mode IRQ via %s\n", - (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, + (unsigned)MV_MAX_Q_DEPTH, probe_ent->n_ports, scc_s, (MV_HP_FLAG_MSI & hpriv->hp_flags) ? "MSI" : "INTx"); } @@ -1526,7 +2183,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->private_data = hpriv; /* initialize adapter */ - rc = mv_host_init(probe_ent); + rc = mv_init_host(pdev, probe_ent, board_idx); if (rc) { goto err_out_hpriv; } diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 37a4fae..4954896 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c @@ -137,7 +137,7 @@ enum nv_host_type CK804 }; -static struct pci_device_id nv_pci_tbl[] = { +static const struct pci_device_id nv_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NFORCE2 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA, diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 9edc9d9..2691625 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -46,7 +46,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_promise" -#define DRV_VERSION "1.02" +#define DRV_VERSION "1.03" enum { @@ -70,6 +70,9 @@ enum { PDC_HAS_PATA = (1 << 1), /* PDC20375 has PATA */ PDC_RESET = (1 << 11), /* HDMA reset */ + + PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | + ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI, }; @@ -162,8 +165,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_2037x */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -173,8 +175,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_20319 */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SATA, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -184,8 +185,7 @@ static struct ata_port_info pdc_port_info[] = { /* board_20619 */ { .sht = &pdc_ata_sht, - .host_flags = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | - ATA_FLAG_MMIO | ATA_FLAG_SLAVE_POSS, + .host_flags = PDC_COMMON_FLAGS | ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -193,7 +193,7 @@ static struct ata_port_info pdc_port_info[] = { }, }; -static struct pci_device_id pdc_ata_pci_tbl[] = { +static const struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index d274ab2..a8987f5 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -41,7 +41,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_qstor" -#define DRV_VERSION "0.04" +#define DRV_VERSION "0.05" enum { QS_PORTS = 4, @@ -184,7 +184,7 @@ static struct ata_port_info qs_port_info[] = { }, }; -static struct pci_device_id qs_ata_pci_tbl[] = { +static const struct pci_device_id qs_ata_pci_tbl[] = { { PCI_VENDOR_ID_PDC, 0x2068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2068_idx }, @@ -268,7 +268,7 @@ static void qs_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) writel(val, (void __iomem *)(ap->ioaddr.scr_addr + (sc_reg * 8))); } -static void qs_fill_sg(struct ata_queued_cmd *qc) +static unsigned int qs_fill_sg(struct ata_queued_cmd *qc) { struct scatterlist *sg; struct ata_port *ap = qc->ap; @@ -296,6 +296,8 @@ static void qs_fill_sg(struct ata_queued_cmd *qc) (unsigned long long)addr, len); nelem++; } + + return nelem; } static void qs_qc_prep(struct ata_queued_cmd *qc) @@ -304,6 +306,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) u8 dflags = QS_DF_PORD, *buf = pp->pkt; u8 hflags = QS_HF_DAT | QS_HF_IEN | QS_HF_VLD; u64 addr; + unsigned int nelem; VPRINTK("ENTER\n"); @@ -313,7 +316,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) return; } - qs_fill_sg(qc); + nelem = qs_fill_sg(qc); if ((qc->tf.flags & ATA_TFLAG_WRITE)) hflags |= QS_HF_DIRO; @@ -324,7 +327,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) buf[ 0] = QS_HCB_HDR; buf[ 1] = hflags; *(__le32 *)(&buf[ 4]) = cpu_to_le32(qc->nsect * ATA_SECT_SIZE); - *(__le32 *)(&buf[ 8]) = cpu_to_le32(qc->n_elem); + *(__le32 *)(&buf[ 8]) = cpu_to_le32(nelem); addr = ((u64)pp->pkt_dma) + QS_CPB_BYTES; *(__le64 *)(&buf[16]) = cpu_to_le64(addr); diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index d0e3c3c..3609186 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -87,7 +87,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); static void sil_post_set_mode (struct ata_port *ap); -static struct pci_device_id sil_pci_tbl[] = { +static const struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index 4682a50..e0d6f19 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -5,17 +5,6 @@ * * Based on preview driver from Silicon Image. * - * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support - * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make - * those work. Enabling those shouldn't be difficult. Basic - * structure is all there (in libata-dev tree). If you have any - * information about this hardware, please contact me or linux-ide. - * Info is needed on... - * - * - How to issue tagged commands and turn on sactive on issue accordingly. - * - Where to put an ATAPI command and how to tell the device to send it. - * - How to enable/use 64bit. - * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any @@ -42,7 +31,7 @@ #include <asm/io.h> #define DRV_NAME "sata_sil24" -#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */ +#define DRV_VERSION "0.23" /* * Port request block (PRB) 32 bytes @@ -139,6 +128,7 @@ enum { PORT_CS_DEV_RST = (1 << 1), /* device reset */ PORT_CS_INIT = (1 << 2), /* port initialize */ PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */ + PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */ PORT_CS_RESUME = (1 << 6), /* port resume */ PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */ PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */ @@ -188,11 +178,29 @@ enum { PORT_CERR_XFR_PCIPERR = 35, /* PSD ecode 11 - PCI prity err during transfer */ PORT_CERR_SENDSERVICE = 36, /* FIS received while sending service */ + /* bits of PRB control field */ + PRB_CTRL_PROTOCOL = (1 << 0), /* override def. ATA protocol */ + PRB_CTRL_PACKET_READ = (1 << 4), /* PACKET cmd read */ + PRB_CTRL_PACKET_WRITE = (1 << 5), /* PACKET cmd write */ + PRB_CTRL_NIEN = (1 << 6), /* Mask completion irq */ + PRB_CTRL_SRST = (1 << 7), /* Soft reset request (ign BSY?) */ + + /* PRB protocol field */ + PRB_PROT_PACKET = (1 << 0), + PRB_PROT_TCQ = (1 << 1), + PRB_PROT_NCQ = (1 << 2), + PRB_PROT_READ = (1 << 3), + PRB_PROT_WRITE = (1 << 4), + PRB_PROT_TRANSPARENT = (1 << 5), + /* * Other constants */ SGE_TRM = (1 << 31), /* Last SGE in chain */ - PRB_SOFT_RST = (1 << 7), /* Soft reset request (ign BSY?) */ + SGE_LNK = (1 << 30), /* linked list + Points to SGT, not SGE */ + SGE_DRD = (1 << 29), /* discard data read (/dev/null) + data address ignored */ /* board id */ BID_SIL3124 = 0, @@ -202,11 +210,22 @@ enum { IRQ_STAT_4PORTS = 0xf, }; -struct sil24_cmd_block { +struct sil24_ata_block { struct sil24_prb prb; struct sil24_sge sge[LIBATA_MAX_PRD]; }; +struct sil24_atapi_block { + struct sil24_prb prb; + u8 cdb[16]; + struct sil24_sge sge[LIBATA_MAX_PRD - 1]; +}; + +union sil24_cmd_block { + struct sil24_ata_block ata; + struct sil24_atapi_block atapi; +}; + /* * ap->private_data * @@ -214,7 +233,7 @@ struct sil24_cmd_block { * here from the previous interrupt. */ struct sil24_port_priv { - struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */ + union sil24_cmd_block *cmd_block; /* 32 cmd blocks */ dma_addr_t cmd_block_dma; /* DMA base addr for them */ struct ata_taskfile tf; /* Cached taskfile registers */ }; @@ -225,6 +244,7 @@ struct sil24_host_priv { void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */ }; +static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev); static u8 sil24_check_status(struct ata_port *ap); static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); @@ -240,7 +260,7 @@ static void sil24_port_stop(struct ata_port *ap); static void sil24_host_stop(struct ata_host_set *host_set); static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static struct pci_device_id sil24_pci_tbl[] = { +static const struct pci_device_id sil24_pci_tbl[] = { { 0x1095, 0x3124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3124 }, { 0x1095, 0x3132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3132 }, { 0x1095, 0x3131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, BID_SIL3131 }, @@ -278,6 +298,8 @@ static struct scsi_host_template sil24_sht = { static const struct ata_port_operations sil24_ops = { .port_disable = ata_port_disable, + .dev_config = sil24_dev_config, + .check_status = sil24_check_status, .check_altstatus = sil24_check_status, .dev_select = ata_noop_dev_select, @@ -314,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = { { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -325,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = { { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -336,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = { { .sht = &sil24_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | + ATA_FLAG_SRST | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1), .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ @@ -345,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = { }, }; +static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev) +{ + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; + + if (ap->cdb_len == 16) + writel(PORT_CS_CDB16, port + PORT_CTRL_STAT); + else + writel(PORT_CS_CDB16, port + PORT_CTRL_CLR); +} + static inline void sil24_update_tf(struct ata_port *ap) { struct sil24_port_priv *pp = ap->private_data; @@ -396,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf) *tf = pp->tf; } -static void sil24_phy_reset(struct ata_port *ap) +static int sil24_issue_SRST(struct ata_port *ap) { - __sata_phy_reset(ap); + void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr; + struct sil24_port_priv *pp = ap->private_data; + struct sil24_prb *prb = &pp->cmd_block[0].ata.prb; + dma_addr_t paddr = pp->cmd_block_dma; + u32 irq_enable, irq_stat; + int cnt; + + /* temporarily turn off IRQs during SRST */ + irq_enable = readl(port + PORT_IRQ_ENABLE_SET); + writel(irq_enable, port + PORT_IRQ_ENABLE_CLR); + /* - * No ATAPI yet. Just unconditionally indicate ATA device. - * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA - * and libata core will ignore the device. + * XXX: Not sure whether the following sleep is needed or not. + * The original driver had it. So.... */ - if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) - ap->device[0].class = ATA_DEV_ATA; + msleep(10); + + prb->ctrl = PRB_CTRL_SRST; + prb->fis[1] = 0; /* no PM yet */ + + writel((u32)paddr, port + PORT_CMD_ACTIVATE); + + for (cnt = 0; cnt < 100; cnt++) { + irq_stat = readl(port + PORT_IRQ_STAT); + writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */ + + irq_stat >>= PORT_IRQ_RAW_SHIFT; + if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR)) + break; + + msleep(1); + } + + /* restore IRQs */ + writel(irq_enable, port + PORT_IRQ_ENABLE_SET); + + if (!(irq_stat & PORT_IRQ_COMPLETE)) + return -1; + + /* update TF */ + sil24_update_tf(ap); + return 0; +} + +static void sil24_phy_reset(struct ata_port *ap) +{ + struct sil24_port_priv *pp = ap->private_data; + + __sata_phy_reset(ap); + if (ap->flags & ATA_FLAG_PORT_DISABLED) + return; + + if (sil24_issue_SRST(ap) < 0) { + printk(KERN_ERR DRV_NAME + " ata%u: SRST failed, disabling port\n", ap->id); + ap->ops->port_disable(ap); + return; + } + + ap->device->class = ata_dev_classify(&pp->tf); } static inline void sil24_fill_sg(struct ata_queued_cmd *qc, - struct sil24_cmd_block *cb) + struct sil24_sge *sge) { - struct sil24_sge *sge = cb->sge; struct scatterlist *sg; unsigned int idx = 0; @@ -432,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct sil24_port_priv *pp = ap->private_data; - struct sil24_cmd_block *cb = pp->cmd_block + qc->tag; - struct sil24_prb *prb = &cb->prb; + union sil24_cmd_block *cb = pp->cmd_block + qc->tag; + struct sil24_prb *prb; + struct sil24_sge *sge; switch (qc->tf.protocol) { case ATA_PROT_PIO: case ATA_PROT_DMA: case ATA_PROT_NODATA: + prb = &cb->ata.prb; + sge = cb->ata.sge; + prb->ctrl = 0; + break; + + case ATA_PROT_ATAPI: + case ATA_PROT_ATAPI_DMA: + case ATA_PROT_ATAPI_NODATA: + prb = &cb->atapi.prb; + sge = cb->atapi.sge; + memset(cb->atapi.cdb, 0, 32); + memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len); + + if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { + if (qc->tf.flags & ATA_TFLAG_WRITE) + prb->ctrl = PRB_CTRL_PACKET_WRITE; + else + prb->ctrl = PRB_CTRL_PACKET_READ; + } else + prb->ctrl = 0; + break; + default: - /* ATAPI isn't supported yet */ + prb = NULL; /* shut up, gcc */ + sge = NULL; BUG(); } ata_tf_to_fis(&qc->tf, prb->fis, 0); if (qc->flags & ATA_QCFLAG_DMAMAP) - sil24_fill_sg(qc, cb); + sil24_fill_sg(qc, sge); } static int sil24_qc_issue(struct ata_queued_cmd *qc) @@ -467,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap) /* unused */ } +static int __sil24_restart_controller(void __iomem *port) +{ + u32 tmp; + int cnt; + + writel(PORT_CS_INIT, port + PORT_CTRL_STAT); + + /* Max ~10ms */ + for (cnt = 0; cnt < 10000; cnt++) { + tmp = readl(port + PORT_CTRL_STAT); + if (tmp & PORT_CS_RDY) + return 0; + udelay(1); + } + + return -1; +} + +static void sil24_restart_controller(struct ata_port *ap) +{ + if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr)) + printk(KERN_ERR DRV_NAME + " ata%u: failed to restart controller\n", ap->id); +} + static int __sil24_reset_controller(void __iomem *port) { int cnt; @@ -486,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port) if (tmp & PORT_CS_DEV_RST) return -1; - return 0; + + if (tmp & PORT_CS_RDY) + return 0; + + return __sil24_restart_controller(port); } static void sil24_reset_controller(struct ata_port *ap) @@ -548,9 +684,15 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) if (serror) writel(serror, port + PORT_SERROR); - printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" - " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", - ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); + /* + * Don't log ATAPI device errors. They're supposed to happen + * and any serious errors will be logged using sense data by + * the SCSI layer. + */ + if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB) + printk("ata%u: error interrupt on port%d\n" + " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", + ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) { /* @@ -558,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) */ sil24_update_tf(ap); err_mask = ac_err_mask(pp->tf.command); + sil24_restart_controller(ap); } else { /* * Other errors. libata currently doesn't have any @@ -565,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat) * ATA_ERR. */ err_mask = AC_ERR_OTHER; + sil24_reset_controller(ap); } if (qc) ata_qc_complete(qc, err_mask); - - sil24_reset_controller(ap); } static inline void sil24_host_intr(struct ata_port *ap) @@ -646,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap) { struct device *dev = ap->host_set->dev; struct sil24_port_priv *pp; - struct sil24_cmd_block *cb; + union sil24_cmd_block *cb; size_t cb_size = sizeof(*cb); dma_addr_t cb_dma; int rc = -ENOMEM; @@ -687,6 +829,7 @@ static void sil24_port_stop(struct ata_port *ap) struct sil24_port_priv *pp = ap->private_data; sil24_cblk_free(pp, dev); + ata_pad_free(ap, dev); kfree(pp); } diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 42d7c4e..32e1262 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -67,7 +67,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg); static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static struct pci_device_id sis_pci_tbl[] = { +static const struct pci_device_id sis_pci_tbl[] = { { PCI_VENDOR_ID_SI, 0x180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, { PCI_VENDOR_ID_SI, 0x181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, { PCI_VENDOR_ID_SI, 0x182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sis_180 }, diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 9895d1c..6e7f7c8 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c @@ -54,7 +54,7 @@ #endif /* CONFIG_PPC_OF */ #define DRV_NAME "sata_svw" -#define DRV_VERSION "1.06" +#define DRV_VERSION "1.07" /* Taskfile registers offsets */ #define K2_SATA_TF_CMD_OFFSET 0x00 @@ -466,7 +466,7 @@ err_out: * 0x24a is device ID for BCM5785 (aka HT1000) HT southbridge integrated SATA * controller * */ -static struct pci_device_id k2_sata_pci_tbl[] = { +static const struct pci_device_id k2_sata_pci_tbl[] = { { 0x1166, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, { 0x1166, 0x0241, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, { 0x1166, 0x0242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 }, diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index d5a3878..ac7b0d8 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -46,7 +46,7 @@ #include "sata_promise.h" #define DRV_NAME "sata_sx4" -#define DRV_VERSION "0.7" +#define DRV_VERSION "0.8" enum { @@ -220,7 +220,8 @@ static struct ata_port_info pdc_port_info[] = { { .sht = &pdc_sata_sht, .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_SRST | ATA_FLAG_MMIO, + ATA_FLAG_SRST | ATA_FLAG_MMIO | + ATA_FLAG_NO_ATAPI, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ @@ -229,7 +230,7 @@ static struct ata_port_info pdc_port_info[] = { }; -static struct pci_device_id pdc_sata_pci_tbl[] = { +static const struct pci_device_id pdc_sata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x6622, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20621 }, { } /* terminate list */ diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index cf0baaa..b2422a0 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c @@ -55,7 +55,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); static u32 uli_scr_read (struct ata_port *ap, unsigned int sc_reg); static void uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static struct pci_device_id uli_pci_tbl[] = { +static const struct pci_device_id uli_pci_tbl[] = { { PCI_VENDOR_ID_AL, 0x5289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5289 }, { PCI_VENDOR_ID_AL, 0x5287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5287 }, { PCI_VENDOR_ID_AL, 0x5281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, uli_5281 }, diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index ab19d2b..c762156 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c @@ -75,7 +75,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg); static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); -static struct pci_device_id svia_pci_tbl[] = { +static const struct pci_device_id svia_pci_tbl[] = { { 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 }, { 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 }, diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index ce8a2fd..fcfa486 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -47,7 +47,7 @@ #include <linux/libata.h> #define DRV_NAME "sata_vsc" -#define DRV_VERSION "1.0" +#define DRV_VERSION "1.1" /* Interrupt register offsets (from chip base address) */ #define VSC_SATA_INT_STAT_OFFSET 0x00 @@ -400,7 +400,7 @@ err_out: * 0x8086/0x3200 is the Intel 31244, which is supposed to be identical * compatibility is untested as of yet */ -static struct pci_device_id vsc_sata_pci_tbl[] = { +static const struct pci_device_id vsc_sata_pci_tbl[] = { { 0x1725, 0x7174, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, { 0x8086, 0x3200, PCI_ANY_ID, PCI_ANY_ID, 0x10600, 0xFFFFFF, 0 }, { } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 0be60bb..180676d 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -265,10 +265,10 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask) spin_lock_irqsave(&dev->list_lock, flags); list_add_tail(&cmd->list, &dev->cmd_list); spin_unlock_irqrestore(&dev->list_lock, flags); + cmd->jiffies_at_alloc = jiffies; } else put_device(&dev->sdev_gendev); - cmd->jiffies_at_alloc = jiffies; return cmd; } EXPORT_SYMBOL(scsi_get_command); diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index b61fb12..3ded9da 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -178,7 +178,7 @@ struct sdebug_queued_cmd { }; static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; -static Scsi_Host_Template sdebug_driver_template = { +static struct scsi_host_template sdebug_driver_template = { .proc_info = scsi_debug_proc_info, .name = "SCSI DEBUG", .info = scsi_debug_info, diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 0c5b02d..c0ae9e9 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -417,43 +417,20 @@ static int scsi_eh_completed_normally(struct scsi_cmnd *scmd) } /** - * scsi_eh_times_out - timeout function for error handling. - * @scmd: Cmd that is timing out. - * - * Notes: - * During error handling, the kernel thread will be sleeping waiting - * for some action to complete on the device. our only job is to - * record that it timed out, and to wake up the thread. - **/ -static void scsi_eh_times_out(struct scsi_cmnd *scmd) -{ - scmd->eh_eflags |= SCSI_EH_REC_TIMEOUT; - SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd:%p\n", __FUNCTION__, - scmd)); - - up(scmd->device->host->eh_action); -} - -/** * scsi_eh_done - Completion function for error handling. * @scmd: Cmd that is done. **/ static void scsi_eh_done(struct scsi_cmnd *scmd) { - /* - * if the timeout handler is already running, then just set the - * flag which says we finished late, and return. we have no - * way of stopping the timeout handler from running, so we must - * always defer to it. - */ - if (del_timer(&scmd->eh_timeout)) { - scmd->request->rq_status = RQ_SCSI_DONE; + struct completion *eh_action; - SCSI_LOG_ERROR_RECOVERY(3, printk("%s scmd: %p result: %x\n", - __FUNCTION__, scmd, scmd->result)); + SCSI_LOG_ERROR_RECOVERY(3, + printk("%s scmd: %p result: %x\n", + __FUNCTION__, scmd, scmd->result)); - up(scmd->device->host->eh_action); - } + eh_action = scmd->device->host->eh_action; + if (eh_action) + complete(eh_action); } /** @@ -461,10 +438,6 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) * @scmd: SCSI Cmd to send. * @timeout: Timeout for cmd. * - * Notes: - * The initialization of the structures is quite a bit different in - * this case, and furthermore, there is a different completion handler - * vs scsi_dispatch_cmd. * Return value: * SUCCESS or FAILED or NEEDS_RETRY **/ @@ -472,24 +445,16 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; - DECLARE_MUTEX_LOCKED(sem); + DECLARE_COMPLETION(done); + unsigned long timeleft; unsigned long flags; - int rtn = SUCCESS; + int rtn; - /* - * we will use a queued command if possible, otherwise we will - * emulate the queuing and calling of completion function ourselves. - */ if (sdev->scsi_level <= SCSI_2) scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | (sdev->lun << 5 & 0xe0); - scsi_add_timer(scmd, timeout, scsi_eh_times_out); - - /* - * set up the semaphore so we wait for the command to complete. - */ - shost->eh_action = &sem; + shost->eh_action = &done; scmd->request->rq_status = RQ_SCSI_BUSY; spin_lock_irqsave(shost->host_lock, flags); @@ -497,47 +462,29 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) shost->hostt->queuecommand(scmd, scsi_eh_done); spin_unlock_irqrestore(shost->host_lock, flags); - down(&sem); - scsi_log_completion(scmd, SUCCESS); + timeleft = wait_for_completion_timeout(&done, timeout); + scmd->request->rq_status = RQ_SCSI_DONE; shost->eh_action = NULL; - /* - * see if timeout. if so, tell the host to forget about it. - * in other words, we don't want a callback any more. - */ - if (scmd->eh_eflags & SCSI_EH_REC_TIMEOUT) { - scmd->eh_eflags &= ~SCSI_EH_REC_TIMEOUT; - - /* - * as far as the low level driver is - * concerned, this command is still active, so - * we must give the low level driver a chance - * to abort it. (db) - * - * FIXME(eric) - we are not tracking whether we could - * abort a timed out command or not. not sure how - * we should treat them differently anyways. - */ - if (shost->hostt->eh_abort_handler) - shost->hostt->eh_abort_handler(scmd); - - scmd->request->rq_status = RQ_SCSI_DONE; - rtn = FAILED; - } + scsi_log_completion(scmd, SUCCESS); - SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n", - __FUNCTION__, scmd, rtn)); + SCSI_LOG_ERROR_RECOVERY(3, + printk("%s: scmd: %p, timeleft: %ld\n", + __FUNCTION__, scmd, timeleft)); /* - * now examine the actual status codes to see whether the command - * actually did complete normally. + * If there is time left scsi_eh_done got called, and we will + * examine the actual status codes to see whether the command + * actually did complete normally, else tell the host to forget + * about this command. */ - if (rtn == SUCCESS) { + if (timeleft) { rtn = scsi_eh_completed_normally(scmd); SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scsi_eh_completed_normally %x\n", __FUNCTION__, rtn)); + switch (rtn) { case SUCCESS: case NEEDS_RETRY: @@ -547,6 +494,15 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) rtn = FAILED; break; } + } else { + /* + * FIXME(eric) - we are not tracking whether we could + * abort a timed out command or not. not sure how + * we should treat them differently anyways. + */ + if (shost->hostt->eh_abort_handler) + shost->hostt->eh_abort_handler(scmd); + rtn = FAILED; } return rtn; @@ -1571,50 +1527,41 @@ static void scsi_unjam_host(struct Scsi_Host *shost) } /** - * scsi_error_handler - Handle errors/timeouts of SCSI cmds. + * scsi_error_handler - SCSI error handler thread * @data: Host for which we are running. * * Notes: - * This is always run in the context of a kernel thread. The idea is - * that we start this thing up when the kernel starts up (one per host - * that we detect), and it immediately goes to sleep and waits for some - * event (i.e. failure). When this takes place, we have the job of - * trying to unjam the bus and restarting things. + * This is the main error handling loop. This is run as a kernel thread + * for every SCSI host and handles all error handling activity. **/ int scsi_error_handler(void *data) { - struct Scsi_Host *shost = (struct Scsi_Host *) data; - int rtn; + struct Scsi_Host *shost = data; current->flags |= PF_NOFREEZE; - /* - * Note - we always use TASK_INTERRUPTIBLE even if the module - * was loaded as part of the kernel. The reason is that - * UNINTERRUPTIBLE would cause this thread to be counted in - * the load average as a running process, and an interruptible - * wait doesn't. + * We use TASK_INTERRUPTIBLE so that the thread is not + * counted against the load average as a running process. + * We never actually get interrupted because kthread_run + * disables singal delivery for the created thread. */ set_current_state(TASK_INTERRUPTIBLE); while (!kthread_should_stop()) { if (shost->host_failed == 0 || shost->host_failed != shost->host_busy) { - SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" - " scsi_eh_%d" - " sleeping\n", - shost->host_no)); + SCSI_LOG_ERROR_RECOVERY(1, + printk("Error handler scsi_eh_%d sleeping\n", + shost->host_no)); schedule(); set_current_state(TASK_INTERRUPTIBLE); continue; } __set_current_state(TASK_RUNNING); - SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler" - " scsi_eh_%d waking" - " up\n",shost->host_no)); - - shost->eh_active = 1; + SCSI_LOG_ERROR_RECOVERY(1, + printk("Error handler scsi_eh_%d waking up\n", + shost->host_no)); /* * We have a host that is failing for some reason. Figure out @@ -1622,12 +1569,10 @@ int scsi_error_handler(void *data) * If we fail, we end up taking the thing offline. */ if (shost->hostt->eh_strategy_handler) - rtn = shost->hostt->eh_strategy_handler(shost); + shost->hostt->eh_strategy_handler(shost); else scsi_unjam_host(shost); - shost->eh_active = 0; - /* * Note - if the above fails completely, the action is to take * individual devices offline and flush the queue of any @@ -1638,15 +1583,10 @@ int scsi_error_handler(void *data) scsi_restart_operations(shost); set_current_state(TASK_INTERRUPTIBLE); } - __set_current_state(TASK_RUNNING); - SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d" - " exiting\n",shost->host_no)); - - /* - * Make sure that nobody tries to wake us up again. - */ + SCSI_LOG_ERROR_RECOVERY(1, + printk("Error handler scsi_eh_%d exiting\n", shost->host_no)); shost->ehandler = NULL; return 0; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index e40c8b6..dc249cb 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -254,55 +254,6 @@ void scsi_do_req(struct scsi_request *sreq, const void *cmnd, } EXPORT_SYMBOL(scsi_do_req); -/* This is the end routine we get to if a command was never attached - * to the request. Simply complete the request without changing - * rq_status; this will cause a DRIVER_ERROR. */ -static void scsi_wait_req_end_io(struct request *req) -{ - BUG_ON(!req->waiting); - - complete(req->waiting); -} - -void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, - unsigned bufflen, int timeout, int retries) -{ - DECLARE_COMPLETION(wait); - int write = (sreq->sr_data_direction == DMA_TO_DEVICE); - struct request *req; - - req = blk_get_request(sreq->sr_device->request_queue, write, - __GFP_WAIT); - if (bufflen && blk_rq_map_kern(sreq->sr_device->request_queue, req, - buffer, bufflen, __GFP_WAIT)) { - sreq->sr_result = DRIVER_ERROR << 24; - blk_put_request(req); - return; - } - - req->flags |= REQ_NOMERGE; - req->waiting = &wait; - req->end_io = scsi_wait_req_end_io; - req->cmd_len = COMMAND_SIZE(((u8 *)cmnd)[0]); - req->sense = sreq->sr_sense_buffer; - req->sense_len = 0; - memcpy(req->cmd, cmnd, req->cmd_len); - req->timeout = timeout; - req->flags |= REQ_BLOCK_PC; - req->rq_disk = NULL; - blk_insert_request(sreq->sr_device->request_queue, req, - sreq->sr_data_direction == DMA_TO_DEVICE, NULL); - wait_for_completion(&wait); - sreq->sr_request->waiting = NULL; - sreq->sr_result = req->errors; - if (req->errors) - sreq->sr_result |= (DRIVER_ERROR << 24); - - blk_put_request(req); -} - -EXPORT_SYMBOL(scsi_wait_req); - /** * scsi_execute - insert request and wait for the result * @sdev: scsi device @@ -591,10 +542,17 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) void scsi_next_command(struct scsi_cmnd *cmd) { - struct request_queue *q = cmd->device->request_queue; + struct scsi_device *sdev = cmd->device; + struct request_queue *q = sdev->request_queue; + + /* need to hold a reference on the device before we let go of the cmd */ + get_device(&sdev->sdev_gendev); scsi_put_command(cmd); scsi_run_queue(q); + + /* ok to remove device now */ + put_device(&sdev->sdev_gendev); } void scsi_run_host_queues(struct Scsi_Host *shost) @@ -1127,6 +1085,26 @@ static void scsi_generic_done(struct scsi_cmnd *cmd) scsi_io_completion(cmd, cmd->result == 0 ? cmd->bufflen : 0, 0); } +void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd, int retries) +{ + struct request *req = cmd->request; + + BUG_ON(sizeof(req->cmd) > sizeof(cmd->cmnd)); + memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); + cmd->cmd_len = req->cmd_len; + if (!req->data_len) + cmd->sc_data_direction = DMA_NONE; + else if (rq_data_dir(req) == WRITE) + cmd->sc_data_direction = DMA_TO_DEVICE; + else + cmd->sc_data_direction = DMA_FROM_DEVICE; + + cmd->transfersize = req->data_len; + cmd->allowed = retries; + cmd->timeout_per_command = req->timeout; +} +EXPORT_SYMBOL_GPL(scsi_setup_blk_pc_cmnd); + static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct scsi_device *sdev = q->queuedata; @@ -1262,18 +1240,7 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) goto kill; } } else { - memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd)); - cmd->cmd_len = req->cmd_len; - if (rq_data_dir(req) == WRITE) - cmd->sc_data_direction = DMA_TO_DEVICE; - else if (req->data_len) - cmd->sc_data_direction = DMA_FROM_DEVICE; - else - cmd->sc_data_direction = DMA_NONE; - - cmd->transfersize = req->data_len; - cmd->allowed = 3; - cmd->timeout_per_command = req->timeout; + scsi_setup_blk_pc_cmnd(cmd, 3); cmd->done = scsi_generic_done; } } diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index d05f778..d632d9e 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h @@ -22,7 +22,6 @@ struct Scsi_Host; * Scsi Error Handler Flags */ #define SCSI_EH_CANCEL_CMD 0x0001 /* Cancel this cmd */ -#define SCSI_EH_REC_TIMEOUT 0x0002 /* EH retry timed out */ #define SCSI_SENSE_VALID(scmd) \ (((scmd)->sense_buffer[0] & 0x70) == 0x70) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 7eb3a2d..4e6709f 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -9,7 +9,7 @@ * global variable (boot or module load time) settings. * * A specific LUN is scanned via an INQUIRY command; if the LUN has a - * device attached, a Scsi_Device is allocated and setup for it. + * device attached, a scsi_device is allocated and setup for it. * * For every id of every channel on the given host: * @@ -17,7 +17,7 @@ * device or storage attached to LUN 0): * * If LUN 0 has a device attached, allocate and setup a - * Scsi_Device for it. + * scsi_device for it. * * If target is SCSI-3 or up, issue a REPORT LUN, and scan * all of the LUNs returned by the REPORT LUN; else, @@ -266,8 +266,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, /* * if LLDD reports slave not present, don't clutter * console with alloc failure messages - - */ if (ret == -ENXIO) display_failure_msg = 0; @@ -279,7 +277,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, out_device_destroy: transport_destroy_device(&sdev->sdev_gendev); - scsi_free_queue(sdev->request_queue); put_device(&sdev->sdev_gendev); out: if (display_failure_msg) @@ -403,6 +400,36 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, return found_target; } +struct work_queue_wrapper { + struct work_struct work; + struct scsi_target *starget; +}; + +static void scsi_target_reap_work(void *data) { + struct work_queue_wrapper *wqw = (struct work_queue_wrapper *)data; + struct scsi_target *starget = wqw->starget; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + unsigned long flags; + + kfree(wqw); + + spin_lock_irqsave(shost->host_lock, flags); + + if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { + list_del_init(&starget->siblings); + spin_unlock_irqrestore(shost->host_lock, flags); + transport_remove_device(&starget->dev); + device_del(&starget->dev); + transport_destroy_device(&starget->dev); + put_device(&starget->dev); + return; + + } + spin_unlock_irqrestore(shost->host_lock, flags); + + return; +} + /** * scsi_target_reap - check to see if target is in use and destroy if not * @@ -414,19 +441,18 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, */ void scsi_target_reap(struct scsi_target *starget) { - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + struct work_queue_wrapper *wqw = + kzalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); - if (--starget->reap_ref == 0 && list_empty(&starget->devices)) { - list_del_init(&starget->siblings); - spin_unlock_irqrestore(shost->host_lock, flags); - device_del(&starget->dev); - transport_unregister_device(&starget->dev); - put_device(&starget->dev); + if (!wqw) { + starget_printk(KERN_ERR, starget, + "Failed to allocate memory in scsi_reap_target()\n"); return; } - spin_unlock_irqrestore(shost->host_lock, flags); + + INIT_WORK(&wqw->work, scsi_target_reap_work, wqw); + wqw->starget = starget; + schedule_work(&wqw->work); } /** @@ -441,7 +467,7 @@ void scsi_target_reap(struct scsi_target *starget) * * If the INQUIRY is successful, zero is returned and the * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length - * are copied to the Scsi_Device any flags value is stored in *@bflags. + * are copied to the scsi_device any flags value is stored in *@bflags. **/ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, int result_len, int *bflags) @@ -509,8 +535,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, /* * Get any flags for this device. * - * XXX add a bflags to Scsi_Device, and replace the - * corresponding bit fields in Scsi_Device, so bflags + * XXX add a bflags to scsi_device, and replace the + * corresponding bit fields in scsi_device, so bflags * need not be passed as an argument. */ *bflags = scsi_get_device_flags(sdev, &inq_result[8], @@ -592,21 +618,21 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, } /** - * scsi_add_lun - allocate and fully initialze a Scsi_Device - * @sdevscan: holds information to be stored in the new Scsi_Device - * @sdevnew: store the address of the newly allocated Scsi_Device + * scsi_add_lun - allocate and fully initialze a scsi_device + * @sdevscan: holds information to be stored in the new scsi_device + * @sdevnew: store the address of the newly allocated scsi_device * @inq_result: holds the result of a previous INQUIRY to the LUN * @bflags: black/white list flag * * Description: - * Allocate and initialize a Scsi_Device matching sdevscan. Optionally + * Allocate and initialize a scsi_device matching sdevscan. Optionally * set fields based on values in *@bflags. If @sdevnew is not - * NULL, store the address of the new Scsi_Device in *@sdevnew (needed + * NULL, store the address of the new scsi_device in *@sdevnew (needed * when scanning a particular LUN). * * Return: - * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device - * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized + * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device + * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) { @@ -674,7 +700,7 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) * * The above is vague, as it implies that we could treat 001 and * 011 the same. Stay compatible with previous code, and create a - * Scsi_Device for a PQ of 1 + * scsi_device for a PQ of 1 * * Don't set the device offline here; rather let the upper * level drivers eval the PQ to decide whether they should @@ -784,8 +810,8 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev) * scsi_probe_and_add_lun - probe a LUN, if a LUN is found add it * @starget: pointer to target device structure * @lun: LUN of target device - * @sdevscan: probe the LUN corresponding to this Scsi_Device - * @sdevnew: store the value of any new Scsi_Device allocated + * @sdevscan: probe the LUN corresponding to this scsi_device + * @sdevnew: store the value of any new scsi_device allocated * @bflagsp: store bflags here if not NULL * * Description: @@ -793,10 +819,10 @@ static inline void scsi_destroy_sdev(struct scsi_device *sdev) * allocate and set it up by calling scsi_add_lun. * * Return: - * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device + * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device * SCSI_SCAN_TARGET_PRESENT: target responded, but no device is * attached at the LUN - * SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized + * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_probe_and_add_lun(struct scsi_target *starget, uint lun, int *bflagsp, @@ -1046,7 +1072,7 @@ EXPORT_SYMBOL(int_to_scsilun); /** * scsi_report_lun_scan - Scan using SCSI REPORT LUN results - * @sdevscan: scan the host, channel, and id of this Scsi_Device + * @sdevscan: scan the host, channel, and id of this scsi_device * * Description: * If @sdevscan is for a SCSI-3 or up device, send a REPORT LUN @@ -1074,6 +1100,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, struct scsi_sense_hdr sshdr; struct scsi_device *sdev; struct Scsi_Host *shost = dev_to_shost(&starget->dev); + int ret = 0; /* * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. @@ -1169,8 +1196,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, /* * The device probably does not support a REPORT LUN command */ - kfree(lun_data); - return 1; + ret = 1; + goto out_err; } /* @@ -1238,6 +1265,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, } } + out_err: kfree(lun_data); out: scsi_device_put(sdev); @@ -1246,7 +1274,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * the sdev we used didn't appear in the report luns scan */ scsi_destroy_sdev(sdev); - return 0; + return ret; } struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, @@ -1472,16 +1500,16 @@ void scsi_forget_host(struct Scsi_Host *shost) /* * Function: scsi_get_host_dev() * - * Purpose: Create a Scsi_Device that points to the host adapter itself. + * Purpose: Create a scsi_device that points to the host adapter itself. * - * Arguments: SHpnt - Host that needs a Scsi_Device + * Arguments: SHpnt - Host that needs a scsi_device * * Lock status: None assumed. * - * Returns: The Scsi_Device or NULL + * Returns: The scsi_device or NULL * * Notes: - * Attach a single Scsi_Device to the Scsi_Host - this should + * Attach a single scsi_device to the Scsi_Host - this should * be made to look like a "pseudo-device" that points to the * HA itself. * @@ -1518,7 +1546,7 @@ EXPORT_SYMBOL(scsi_get_host_dev); * * Purpose: Free a scsi_device that points to the host adapter itself. * - * Arguments: SHpnt - Host that needs a Scsi_Device + * Arguments: SHpnt - Host that needs a scsi_device * * Lock status: None assumed. * diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 72a6550..4634929 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -691,16 +691,19 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) void __scsi_remove_device(struct scsi_device *sdev) { + struct device *dev = &sdev->sdev_gendev; + if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) return; class_device_unregister(&sdev->sdev_classdev); - device_del(&sdev->sdev_gendev); + transport_remove_device(dev); + device_del(dev); scsi_device_set_state(sdev, SDEV_DEL); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - transport_unregister_device(&sdev->sdev_gendev); - put_device(&sdev->sdev_gendev); + transport_destroy_device(dev); + put_device(dev); } /** diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 6cd5931..2a1a99a 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -105,6 +105,7 @@ static struct { { FC_PORTSTATE_LINKDOWN, "Linkdown" }, { FC_PORTSTATE_ERROR, "Error" }, { FC_PORTSTATE_LOOPBACK, "Loopback" }, + { FC_PORTSTATE_DELETED, "Deleted" }, }; fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) #define FC_PORTSTATE_MAX_NAMELEN 20 @@ -211,6 +212,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) #define FC_MGMTSRVR_PORTID 0x00000a +static void fc_shost_remove_rports(void *data); static void fc_timeout_deleted_rport(void *data); static void fc_scsi_scan_rport(void *data); static void fc_rport_terminate(struct fc_rport *rport); @@ -318,6 +320,8 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev, fc_host_next_rport_number(shost) = 0; fc_host_next_target_id(shost) = 0; + fc_host_flags(shost) = 0; + INIT_WORK(&fc_host_rport_del_work(shost), fc_shost_remove_rports, shost); return 0; } @@ -387,6 +391,7 @@ show_fc_rport_##field (struct class_device *cdev, char *buf) \ struct fc_internal *i = to_fc_internal(shost->transportt); \ if ((i->f->get_rport_##field) && \ !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ + (rport->port_state == FC_PORTSTATE_DELETED) || \ (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ i->f->get_rport_##field(rport); \ return snprintf(buf, sz, format_string, cast rport->field); \ @@ -402,6 +407,7 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \ struct Scsi_Host *shost = rport_to_shost(rport); \ struct fc_internal *i = to_fc_internal(shost->transportt); \ if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ + (rport->port_state == FC_PORTSTATE_DELETED) || \ (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ return -EBUSY; \ val = simple_strtoul(buf, NULL, 0); \ @@ -519,6 +525,7 @@ store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, struct Scsi_Host *shost = rport_to_shost(rport); struct fc_internal *i = to_fc_internal(shost->transportt); if ((rport->port_state == FC_PORTSTATE_BLOCKED) || + (rport->port_state == FC_PORTSTATE_DELETED) || (rport->port_state == FC_PORTSTATE_NOTPRESENT)) return -EBUSY; val = simple_strtoul(buf, NULL, 0); @@ -1769,7 +1776,7 @@ fc_timeout_deleted_rport(void *data) rport->maxframe_size = -1; rport->supported_classes = FC_COS_UNSPECIFIED; rport->roles = FC_RPORT_ROLE_UNKNOWN; - rport->port_state = FC_PORTSTATE_NOTPRESENT; + rport->port_state = FC_PORTSTATE_DELETED; /* remove the identifiers that aren't used in the consisting binding */ switch (fc_host_tgtid_bind_type(shost)) { @@ -1789,14 +1796,23 @@ fc_timeout_deleted_rport(void *data) break; } - spin_unlock_irqrestore(shost->host_lock, flags); - /* * As this only occurs if the remote port (scsi target) * went away and didn't come back - we'll remove * all attached scsi devices. + * + * We'll schedule the shost work item to perform the actual removal + * to avoid recursion in the different flush calls if we perform + * the removal in each target - and there are lots of targets + * whose timeouts fire at the same time. */ - fc_rport_tgt_remove(rport); + + if ( !(fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED)) { + fc_host_flags(shost) |= FC_SHOST_RPORT_DEL_SCHEDULED; + scsi_queue_work(shost, &fc_host_rport_del_work(shost)); + } + + spin_unlock_irqrestore(shost->host_lock, flags); } /** @@ -1818,6 +1834,41 @@ fc_scsi_scan_rport(void *data) } +/** + * fc_shost_remove_rports - called to remove all rports that are marked + * as in a deleted (not connected) state. + * + * @data: shost whose rports are to be looked at + **/ +static void +fc_shost_remove_rports(void *data) +{ + struct Scsi_Host *shost = (struct Scsi_Host *)data; + struct fc_rport *rport, *next_rport; + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + while (fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED) { + + fc_host_flags(shost) &= ~FC_SHOST_RPORT_DEL_SCHEDULED; + +restart_search: + list_for_each_entry_safe(rport, next_rport, + &fc_host_rport_bindings(shost), peers) { + if (rport->port_state == FC_PORTSTATE_DELETED) { + rport->port_state = FC_PORTSTATE_NOTPRESENT; + spin_unlock_irqrestore(shost->host_lock, flags); + fc_rport_tgt_remove(rport); + spin_lock_irqsave(shost->host_lock, flags); + goto restart_search; + } + } + + } + spin_unlock_irqrestore(shost->host_lock, flags); +} + + MODULE_AUTHOR("Martin Hicks"); MODULE_DESCRIPTION("FC Transport Attributes"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 49fd18c..e08462d 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -249,7 +249,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) } static void* -mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) +mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) { struct mempool_zone *zone = pool_data; diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 718a2bc..38a53b5 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -812,12 +812,10 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) if (!scsi_device_sync(sdev) && !scsi_device_dt(sdev)) return; - /* see if the device has an echo buffer. If it does we can - * do the SPI pattern write tests */ - - len = 0; - if (scsi_device_dt(sdev)) - len = spi_dv_device_get_echo_buffer(sdev, buffer); + /* len == -1 is the signal that we need to ascertain the + * presence of an echo buffer before trying to use it. len == + * 0 means we don't have an echo buffer */ + len = -1; retry: @@ -840,11 +838,23 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer) if (spi_min_period(starget) == 8) DV_SET(pcomp_en, 1); } + /* Do the read only INQUIRY tests */ + spi_dv_retrain(sdev, buffer, buffer + sdev->inquiry_len, + spi_dv_device_compare_inquiry); + /* See if we actually managed to negotiate and sustain DT */ + if (i->f->get_dt) + i->f->get_dt(starget); + + /* see if the device has an echo buffer. If it does we can do + * the SPI pattern write tests. Because of some broken + * devices, we *only* try this on a device that has actually + * negotiated DT */ + + if (len == -1 && spi_dt(starget)) + len = spi_dv_device_get_echo_buffer(sdev, buffer); - if (len == 0) { + if (len <= 0) { starget_printk(KERN_INFO, starget, "Domain Validation skipping write tests\n"); - spi_dv_retrain(sdev, buffer, buffer + len, - spi_dv_device_compare_inquiry); return; } diff --git a/drivers/scsi/scsi_typedefs.h b/drivers/scsi/scsi_typedefs.h index 6c43132..29f038b 100644 --- a/drivers/scsi/scsi_typedefs.h +++ b/drivers/scsi/scsi_typedefs.h @@ -1,6 +1,3 @@ -typedef struct scsi_host_template Scsi_Host_Template; -typedef struct scsi_device Scsi_Device; typedef struct scsi_cmnd Scsi_Cmnd; typedef struct scsi_request Scsi_Request; -typedef struct scsi_pointer Scsi_Pointer; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index bb5b242..03fcbab 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -245,24 +245,10 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) * SG_IO from block layer already setup, just copy cdb basically */ if (blk_pc_request(rq)) { - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; - - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else if (rq->data_len) - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - else - SCpnt->sc_data_direction = DMA_NONE; - - this_count = rq->data_len; + scsi_setup_blk_pc_cmnd(SCpnt, SD_PASSTHROUGH_RETRIES); if (rq->timeout) timeout = rq->timeout; - SCpnt->transfersize = rq->data_len; - SCpnt->allowed = SD_PASSTHROUGH_RETRIES; goto queue; } @@ -769,20 +755,16 @@ static void sd_end_flush(request_queue_t *q, struct request *flush_rq) static int sd_prepare_flush(request_queue_t *q, struct request *rq) { struct scsi_device *sdev = q->queuedata; - struct scsi_disk *sdkp = scsi_disk_get_from_dev(&sdev->sdev_gendev); - int ret = 0; + struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev); - if (sdkp) { - if (sdkp->WCE) { - memset(rq->cmd, 0, sizeof(rq->cmd)); - rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; - rq->timeout = SD_TIMEOUT; - rq->cmd[0] = SYNCHRONIZE_CACHE; - ret = 1; - } - scsi_disk_put(sdkp); - } - return ret; + if (!sdkp || !sdkp->WCE) + return 0; + + memset(rq->cmd, 0, sizeof(rq->cmd)); + rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER; + rq->timeout = SD_TIMEOUT; + rq->cmd[0] = SYNCHRONIZE_CACHE; + return 1; } static void sd_rescan(struct device *dev) diff --git a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c index a0cace9..0ff83dd 100644 --- a/drivers/scsi/seagate.c +++ b/drivers/scsi/seagate.c @@ -418,7 +418,7 @@ static inline void borken_wait (void) #define ULOOP( i ) for (clock = i*8;;) #define TIMEOUT (!(clock--)) -int __init seagate_st0x_detect (Scsi_Host_Template * tpnt) +int __init seagate_st0x_detect (struct scsi_host_template * tpnt) { struct Scsi_Host *instance; int i, j; @@ -1649,7 +1649,7 @@ static int seagate_st0x_release(struct Scsi_Host *shost) return 0; } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .detect = seagate_st0x_detect, .release = seagate_st0x_release, .info = seagate_st0x_info, diff --git a/drivers/scsi/seagate.h b/drivers/scsi/seagate.h index 8889ff1a..fb5f380 100644 --- a/drivers/scsi/seagate.h +++ b/drivers/scsi/seagate.h @@ -9,7 +9,7 @@ #ifndef _SEAGATE_H #define SEAGATE_H -static int seagate_st0x_detect(Scsi_Host_Template *); +static int seagate_st0x_detect(struct scsi_host_template *); static int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int seagate_st0x_abort(Scsi_Cmnd *); diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 72ec594..b55c2a8 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1860,9 +1860,11 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages, unlock_page(pages[j]); */ res = 0; out_unmap: - if (res > 0) + if (res > 0) { for (j=0; j < res; j++) page_cache_release(pages[j]); + res = 0; + } kfree(pages); return res; } @@ -1878,8 +1880,6 @@ st_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_pages, for (i=0; i < nr_pages; i++) { struct page *page = sgl[i].page; - /* XXX: just for debug. Remove when PageReserved is removed */ - BUG_ON(PageReserved(page)); if (dirtied) SetPageDirty(page); /* unlock_page(page); */ diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index f37147f..bf2ceb5 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -217,7 +217,7 @@ static inline void init_hpc_chain(struct hpc_data *hd) } static struct Scsi_Host * __init sgiwd93_setup_scsi( - Scsi_Host_Template *SGIblows, int unit, int irq, + struct scsi_host_template *SGIblows, int unit, int irq, struct hpc3_scsiregs *hregs, unsigned char *wdregs) { struct ip22_hostdata *hdata; @@ -265,7 +265,7 @@ out_unregister: return NULL; } -int __init sgiwd93_detect(Scsi_Host_Template *SGIblows) +int __init sgiwd93_detect(struct scsi_host_template *SGIblows) { int found = 0; @@ -324,7 +324,7 @@ static int sgiwd93_bus_reset(Scsi_Cmnd *cmd) * arguments not with pointers. So this is going to blow up beautyfully * on 64-bit systems with memory outside the compat address spaces. */ -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "SGIWD93", .name = "SGI WD93", .detect = sgiwd93_detect, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d68cea7..fb4012b 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -320,25 +320,11 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) * these are already setup, just copy cdb basically */ if (SCpnt->request->flags & REQ_BLOCK_PC) { - struct request *rq = SCpnt->request; + scsi_setup_blk_pc_cmnd(SCpnt, MAX_RETRIES); - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; - - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - if (!rq->data_len) - SCpnt->sc_data_direction = DMA_NONE; - else if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - - this_count = rq->data_len; - if (rq->timeout) - timeout = rq->timeout; + if (SCpnt->timeout_per_command) + timeout = SCpnt->timeout_per_command; - SCpnt->transfersize = rq->data_len; goto queue; } diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 770c432..dd592f6 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -4194,27 +4194,10 @@ static void st_intr(struct scsi_cmnd *SCpnt) */ static int st_init_command(struct scsi_cmnd *SCpnt) { - struct request *rq; - if (!(SCpnt->request->flags & REQ_BLOCK_PC)) return 0; - rq = SCpnt->request; - if (sizeof(rq->cmd) > sizeof(SCpnt->cmnd)) - return 0; - - memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd)); - SCpnt->cmd_len = rq->cmd_len; - - if (rq_data_dir(rq) == WRITE) - SCpnt->sc_data_direction = DMA_TO_DEVICE; - else if (rq->data_len) - SCpnt->sc_data_direction = DMA_FROM_DEVICE; - else - SCpnt->sc_data_direction = DMA_NONE; - - SCpnt->timeout_per_command = rq->timeout; - SCpnt->transfersize = rq->data_len; + scsi_setup_blk_pc_cmnd(SCpnt, 0); SCpnt->done = st_intr; return 1; } @@ -4509,6 +4492,7 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa if (res > 0) { for (j=0; j < res; j++) page_cache_release(pages[j]); + res = 0; } kfree(pages); return res; @@ -4524,8 +4508,6 @@ static int sgl_unmap_user_pages(struct scatterlist *sgl, const unsigned int nr_p for (i=0; i < nr_pages; i++) { struct page *page = sgl[i].page; - /* XXX: just for debug. Remove when PageReserved is removed */ - BUG_ON(PageReserved(page)); if (dirtied) SetPageDirty(page); /* FIXME: cache flush missing for rw==READ diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 7e19589..c041bfd 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -257,7 +257,7 @@ */ static struct Scsi_Host *first_instance = NULL; -static Scsi_Host_Template *the_template = NULL; +static struct scsi_host_template *the_template = NULL; /* Macros ease life... :-) */ #define SETUP_HOSTDATA(in) \ diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index e3ea99f..8371734 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -185,7 +185,7 @@ static inline void sun3_udc_write(unsigned short val, unsigned char reg) static struct Scsi_Host *default_instance; /* - * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt) + * Function : int sun3scsi_detect(struct scsi_host_template * tpnt) * * Purpose : initializes mac NCR5380 driver based on the * command line / compile time port and irq definitions. @@ -196,7 +196,7 @@ static struct Scsi_Host *default_instance; * */ -int sun3scsi_detect(Scsi_Host_Template * tpnt) +int sun3scsi_detect(struct scsi_host_template * tpnt) { unsigned long ioaddr; static int called = 0; @@ -621,7 +621,7 @@ static int sun3scsi_dma_finish(int write_flag) #include "sun3_NCR5380.c" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = SUN3_SCSI_NAME, .detect = sun3scsi_detect, .release = sun3scsi_release, diff --git a/drivers/scsi/sun3_scsi.h b/drivers/scsi/sun3_scsi.h index 155282b..834dab4 100644 --- a/drivers/scsi/sun3_scsi.h +++ b/drivers/scsi/sun3_scsi.h @@ -48,7 +48,7 @@ #define IOBASE_SUN3_VMESCSI 0xff200000 static int sun3scsi_abort (Scsi_Cmnd *); -static int sun3scsi_detect (Scsi_Host_Template *); +static int sun3scsi_detect (struct scsi_host_template *); static const char *sun3scsi_info (struct Scsi_Host *); static int sun3scsi_bus_reset(Scsi_Cmnd *); static int sun3scsi_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index 9acb5dd..008a82a 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c @@ -127,7 +127,7 @@ static inline void sun3scsi_write(int reg, int value) static struct Scsi_Host *default_instance; /* - * Function : int sun3scsi_detect(Scsi_Host_Template * tpnt) + * Function : int sun3scsi_detect(struct scsi_host_template * tpnt) * * Purpose : initializes mac NCR5380 driver based on the * command line / compile time port and irq definitions. @@ -138,7 +138,7 @@ static struct Scsi_Host *default_instance; * */ -static int sun3scsi_detect(Scsi_Host_Template * tpnt) +static int sun3scsi_detect(struct scsi_host_template * tpnt) { unsigned long ioaddr, irq = 0; static int called = 0; @@ -564,7 +564,7 @@ static int sun3scsi_dma_finish(int write_flag) #include "sun3_NCR5380.c" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = SUN3_SCSI_NAME, .detect = sun3scsi_detect, .release = sun3scsi_release, diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index 09d7639..cc990be 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c @@ -47,7 +47,7 @@ static void dma_advance_sg (Scsi_Cmnd *sp); /* Detecting ESP chips on the machine. This is the simple and easy * version. */ -int sun3x_esp_detect(Scsi_Host_Template *tpnt) +int sun3x_esp_detect(struct scsi_host_template *tpnt) { struct NCR_ESP *esp; struct ConfigDev *esp_dev; @@ -367,7 +367,7 @@ static int sun3x_esp_release(struct Scsi_Host *instance) } -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "sun3x_esp", .proc_info = &esp_proc_info, .name = "Sun ESP 100/100a/200", diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index 93dc7b6..8640253 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c @@ -633,7 +633,7 @@ static void sym53c416_probe(void) } } -int __init sym53c416_detect(Scsi_Host_Template *tpnt) +int __init sym53c416_detect(struct scsi_host_template *tpnt) { unsigned long flags; struct Scsi_Host * shpnt = NULL; @@ -849,7 +849,7 @@ module_param_array(sym53c416_3, uint, NULL, 0); #endif -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .proc_name = "sym53c416", .name = "Symbios Logic 53c416", .detect = sym53c416_detect, diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h index fd6b120..77860d0 100644 --- a/drivers/scsi/sym53c416.h +++ b/drivers/scsi/sym53c416.h @@ -22,7 +22,7 @@ #define SYM53C416_SCSI_ID 7 -static int sym53c416_detect(Scsi_Host_Template *); +static int sym53c416_detect(struct scsi_host_template *); static const char *sym53c416_info(struct Scsi_Host *); static int sym53c416_release(struct Scsi_Host *); static int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index d76766c..7fc0b97 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -2086,6 +2086,7 @@ static void sym2_set_dt(struct scsi_target *starget, int dt) tp->tgoal.check_nego = 1; } +#if 0 static void sym2_set_iu(struct scsi_target *starget, int iu) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -2111,7 +2112,7 @@ static void sym2_set_qas(struct scsi_target *starget, int qas) tp->tgoal.qas = 0; tp->tgoal.check_nego = 1; } - +#endif static struct spi_function_template sym2_transport_functions = { .set_offset = sym2_set_offset, @@ -2122,10 +2123,12 @@ static struct spi_function_template sym2_transport_functions = { .show_width = 1, .set_dt = sym2_set_dt, .show_dt = 1, +#if 0 .set_iu = sym2_set_iu, .show_iu = 1, .set_qas = sym2_set_qas, .show_qas = 1, +#endif .get_signalling = sym2_get_signalling, }; diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index a7420ca..1564ca2 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -1405,7 +1405,6 @@ static void sym_check_goals(struct sym_hcb *np, struct scsi_target *starget, goal->iu = 0; goal->dt = 0; goal->qas = 0; - goal->period = 0; goal->offset = 0; return; } @@ -1465,7 +1464,8 @@ static int sym_prepare_nego(struct sym_hcb *np, struct sym_ccb *cp, u_char *msgp * Many devices implement PPR in a buggy way, so only use it if we * really want to. */ - if (goal->iu || goal->dt || goal->qas || (goal->period < 0xa)) { + if (goal->offset && + (goal->iu || goal->dt || goal->qas || (goal->period < 0xa))) { nego = NS_PPR; } else if (spi_width(starget) != goal->width) { nego = NS_WIDE; diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c index f4b780e..21305fc 100644 --- a/drivers/scsi/t128.c +++ b/drivers/scsi/t128.c @@ -183,7 +183,7 @@ void __init t128_setup(char *str, int *ints){ } /* - * Function : int t128_detect(Scsi_Host_Template * tpnt) + * Function : int t128_detect(struct scsi_host_template * tpnt) * * Purpose : detects and initializes T128,T128F, or T228 controllers * that were autoprobed, overridden on the LILO command line, @@ -195,7 +195,7 @@ void __init t128_setup(char *str, int *ints){ * */ -int __init t128_detect(Scsi_Host_Template * tpnt){ +int __init t128_detect(struct scsi_host_template * tpnt){ static int current_override = 0, current_base = 0; struct Scsi_Host *instance; unsigned long base; @@ -430,7 +430,7 @@ MODULE_LICENSE("GPL"); #include "NCR5380.c" -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "Trantor T128/T128F/T228", .detect = t128_detect, .release = t128_release, diff --git a/drivers/scsi/t128.h b/drivers/scsi/t128.h index 596f3a3..646e840 100644 --- a/drivers/scsi/t128.h +++ b/drivers/scsi/t128.h @@ -95,7 +95,7 @@ static int t128_abort(Scsi_Cmnd *); static int t128_biosparam(struct scsi_device *, struct block_device *, sector_t, int*); -static int t128_detect(Scsi_Host_Template *); +static int t128_detect(struct scsi_host_template *); static int t128_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int t128_bus_reset(Scsi_Cmnd *); diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 1ce29ba..33cd90f 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c @@ -282,7 +282,7 @@ * clustering is enabled. ENABLE_CLUSTERING provides a performance increase * up to 50% on sequential access. * - * Since the Scsi_Host_Template structure is shared among all 14F and 34F, + * Since the struct scsi_host_template structure is shared among all 14F and 34F, * the last setting of use_clustering is in effect for all of these boards. * * Here a sample configuration using two U14F boards: diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c index 486551b..e681681 100644 --- a/drivers/scsi/ultrastor.c +++ b/drivers/scsi/ultrastor.c @@ -343,7 +343,7 @@ static void log_ultrastor_abort(struct ultrastor_config *config, } #endif -static int ultrastor_14f_detect(Scsi_Host_Template * tpnt) +static int ultrastor_14f_detect(struct scsi_host_template * tpnt) { size_t i; unsigned char in_byte, version_byte = 0; @@ -525,7 +525,7 @@ out_release_port: return FALSE; } -static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) +static int ultrastor_24f_detect(struct scsi_host_template * tpnt) { int i; struct Scsi_Host * shpnt = NULL; @@ -637,7 +637,7 @@ static int ultrastor_24f_detect(Scsi_Host_Template * tpnt) return FALSE; } -static int ultrastor_detect(Scsi_Host_Template * tpnt) +static int ultrastor_detect(struct scsi_host_template * tpnt) { tpnt->proc_name = "ultrastor"; return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt); @@ -1184,7 +1184,7 @@ static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id, MODULE_LICENSE("GPL"); -static Scsi_Host_Template driver_template = { +static struct scsi_host_template driver_template = { .name = "UltraStor 14F/24F/34F", .detect = ultrastor_detect, .release = ultrastor_release, diff --git a/drivers/scsi/ultrastor.h b/drivers/scsi/ultrastor.h index 0a0f8df..da759a1 100644 --- a/drivers/scsi/ultrastor.h +++ b/drivers/scsi/ultrastor.h @@ -13,7 +13,7 @@ #ifndef _ULTRASTOR_H #define _ULTRASTOR_H -static int ultrastor_detect(Scsi_Host_Template *); +static int ultrastor_detect(struct scsi_host_template *); static const char *ultrastor_info(struct Scsi_Host * shpnt); static int ultrastor_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *)); static int ultrastor_abort(Scsi_Cmnd *); |