reverted: --- b/Documentation/scsi/ChangeLog.megaraid 2004-10-01 19:21:44 -07:00 +++ a/Documentation/scsi/ChangeLog.megaraid 2004-10-01 19:21:44 -07:00 @@ -1,11 +1,3 @@ -Release Date : Mon Sep 27 22:15:07 EDT 2004 - Atul Mukker -Current Version : 2.20.4.0 (scsi module), 2.20.2.0 (cmm module) -Older Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module) - -i. Fix data corruption. Because of a typo in the driver, the IO packets - were wrongly shared by the ioctl path. This causes a whole IO command - to be replaced by an incoming ioctl command. - Release Date : Tue Aug 24 09:43:35 EDT 2004 - Atul Mukker Current Version : 2.20.3.1 (scsi module), 2.20.2.0 (cmm module) Older Version : 2.20.3.0 (scsi module), 2.20.2.0 (cmm module) reverted: --- b/Documentation/scsi/scsi_mid_low_api.txt 2004-10-01 19:21:44 -07:00 +++ a/Documentation/scsi/scsi_mid_low_api.txt 2004-10-01 19:21:44 -07:00 @@ -8,11 +8,11 @@ SCSI lower level drivers. Lower level drivers (LLDs) are variously called host bus adapter (HBA) drivers and host drivers (HD). A "host" in this context is a bridge between a computer IO bus (e.g. PCI or ISA) and a +single SCSI initiator device on a SCSI transport. An "initiator" device +(SCSI terminology) sends SCSI commands to "target" SCSI devices (e.g. +disks). There can be many LLDs in a running system, but only one per +hardware type. Most LLDs can control one or more SCSI HBAs. Some HBAs +contain multiple hosts. -single SCSI initiator port on a SCSI transport. An "initiator" port -(SCSI terminology, see SAM-3 at http://www.t10.org) sends SCSI commands -to "target" SCSI ports (e.g. disks). There can be many LLDs in a running -system, but only one per hardware type. Most LLDs can control one or more -SCSI HBAs. Some HBAs contain multiple hosts. In some cases the SCSI transport is an external bus that already has its own subsystem in Linux (e.g. USB and ieee1394). In such cases the @@ -370,7 +370,6 @@ names all start with "scsi_". Summary: - scsi_activate_tcq - turn on tag command queueing scsi_add_device - creates new scsi device (lu) instance scsi_add_host - perform sysfs registration and SCSI bus scan. scsi_add_timer - (re-)start timer on a SCSI command. @@ -378,7 +377,6 @@ scsi_assign_lock - replace default host_lock with given lock scsi_bios_ptable - return copy of block device's partition table scsi_block_requests - prevent further commands being queued to given host - scsi_deactivate_tcq - turn off tag command queueing scsi_delete_timer - cancel timer on a SCSI command. scsi_host_alloc - return a new scsi_host instance whose refcount==1 scsi_host_get - increments Scsi_Host instance's refcount @@ -399,24 +397,6 @@ Details: /** - * scsi_activate_tcq - turn on tag command queueing ("ordered" task attribute) - * @sdev: device to turn on TCQ for - * @depth: queue depth - * - * Returns nothing - * - * Might block: no - * - * Notes: Eventually, it is hoped depth would be the maximum depth - * the device could cope with and the real queue depth - * would be adjustable from 0 to depth. - * - * Defined (inline) in: include/scsi/scsi_tcq.h - **/ -void scsi_activate_tcq(struct scsi_device *sdev, int depth) - - -/** * scsi_add_device - creates new scsi device (lu) instance * @shost: pointer to scsi host instance * @channel: channel number (rarely other than 0) @@ -482,10 +462,10 @@ /** + * scsi_adjust_queue_depth - change the queue depth on a SCSI device - * scsi_adjust_queue_depth - allow LLD to change queue depth on a SCSI device * @sdev: pointer to SCSI device to change queue depth on * @tagged: 0 - no tagged queuing + * MSG_SIMPLE_TAG - simple (unordered) tagged queuing - * MSG_SIMPLE_TAG - simple tagged queuing * MSG_ORDERED_TAG - ordered tagged queuing * @tags Number of tags allowed if tagged queuing enabled, * or number of commands the LLD can queue up @@ -499,7 +479,7 @@ * LLD. [Specifically during and after slave_configure() and prior to * slave_destroy().] Can safely be invoked from interrupt code. Actual * queue depth change may be delayed until the next command is being + * processed. - * processed. See also scsi_activate_tcq() and scsi_deactivate_tcq(). * * Defined in: drivers/scsi/scsi.c [see source code for more notes] * @@ -555,20 +535,6 @@ /** - * scsi_deactivate_tcq - turn off tag command queueing - * @sdev: device to turn off TCQ for - * @depth: queue depth (stored in sdev) - * - * Returns nothing - * - * Might block: no - * - * Defined (inline) in: include/scsi/scsi_tcq.h - **/ -void scsi_deactivate_tcq(struct scsi_device *sdev, int depth) - - -/** * scsi_delete_timer - cancel timer on a SCSI command. * @scmd: pointer to scsi command instance * @@ -1549,4 +1515,4 @@ Douglas Gilbert dgilbert at interlog dot com +25th August 2004 -21st September 2004 reverted: --- b/drivers/message/fusion/mptbase.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/message/fusion/mptbase.c 2004-10-01 19:21:44 -07:00 @@ -137,6 +137,8 @@ struct proc_dir_entry *mpt_proc_root_dir; +DmpServices_t *DmpService; + #define WHOINIT_UNKNOWN 0xAA /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ @@ -167,9 +169,7 @@ */ static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r); static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); + -static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, - u32 *req, int replyBytes, u16 *u16reply, int maxwait, - int sleepFlag); static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag); static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev); static void mpt_adapter_disable(MPT_ADAPTER *ioc); @@ -437,7 +437,7 @@ /* Put Request back on FreeQ! */ spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR); - list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); #ifdef MFCNT ioc->mfcnt--; #endif @@ -533,7 +533,7 @@ del_timer(&pCfg->timer); spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_DEL_ITEM(&pCfg->linkage); - list_del(&pCfg->linkage); spin_unlock_irqrestore(&ioc->FreeQlock, flags); /* @@ -819,12 +819,11 @@ return NULL; spin_lock_irqsave(&ioc->FreeQlock, flags); + if (! Q_IS_EMPTY(&ioc->FreeQ)) { - if (!list_empty(&ioc->FreeQ)) { int req_offset; + mf = ioc->FreeQ.head; + Q_DEL_ITEM(&mf->u.frame.linkage); - mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, - u.frame.linkage.list); - list_del(&mf->u.frame.linkage.list); mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */ req_offset = (u8 *)mf - (u8 *)ioc->req_frames; /* u16! */ @@ -920,7 +919,7 @@ /* Put Request back on FreeQ! */ spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->FreeQ, &mf->u.frame.linkage, MPT_FRAME_HDR); - list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); #ifdef MFCNT ioc->mfcnt--; #endif @@ -958,6 +957,41 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** + * mpt_add_chain - Place a chain SGE at address pAddr. + * @pAddr: virtual address for SGE + * @next: nextChainOffset value (u32's) + * @length: length of next SGL segment + * @dma_addr: Physical address + * + * This routine places a MPT request frame back on the MPT adapter's + * FreeQ. + */ +void +mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr) +{ + if (sizeof(dma_addr_t) == sizeof(u64)) { + SGEChain64_t *pChain = (SGEChain64_t *) pAddr; + u32 tmp = dma_addr & 0xFFFFFFFF; + + pChain->Length = cpu_to_le16(length); + pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); + + pChain->NextChainOffset = next; + + pChain->Address.Low = cpu_to_le32(tmp); + tmp = (u32) ((u64)dma_addr >> 32); + pChain->Address.High = cpu_to_le32(tmp); + } else { + SGEChain32_t *pChain = (SGEChain32_t *) pAddr; + pChain->Length = cpu_to_le16(length); + pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); + pChain->NextChainOffset = next; + pChain->Address = cpu_to_le32(dma_addr); + } +} + +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ +/** * mpt_send_handshake_request - Send MPT request via doorbell * handshake method. * @handle: Handle of registered MPT protocol driver @@ -1164,7 +1198,7 @@ /* Initialize the running configQ head. */ + Q_INIT(&ioc->configQ, Q_ITEM); - INIT_LIST_HEAD(&ioc->configQ); /* Find lookup slot. */ INIT_LIST_HEAD(&ioc->list); @@ -3558,14 +3592,14 @@ /* Initialize the free chain Q. */ + Q_INIT(&ioc->FreeChainQ, MPT_FRAME_HDR); - INIT_LIST_HEAD(&ioc->FreeChainQ); /* Post the chain buffers to the FreeChainQ. */ mem = (u8 *)ioc->ChainBuffer; for (i=0; i < num_chain; i++) { mf = (MPT_FRAME_HDR *) mem; + Q_ADD_TAIL(&ioc->FreeChainQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR); - list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ); mem += ioc->req_sz; } @@ -3575,13 +3609,12 @@ mem = (u8 *) ioc->req_frames; spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR); - INIT_LIST_HEAD(&ioc->FreeQ); for (i = 0; i < ioc->req_depth; i++) { mf = (MPT_FRAME_HDR *) mem; /* Queue REQUESTs *internally*! */ + Q_ADD_TAIL(&ioc->FreeQ.head, &mf->u.frame.linkage, MPT_FRAME_HDR); - list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); - mem += ioc->req_sz; } spin_unlock_irqrestore(&ioc->FreeQlock, flags); @@ -3655,7 +3688,7 @@ * * Returns 0 for success, non-zero for failure. */ +int -static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) { @@ -4870,7 +4903,7 @@ /* Add to end of Q, set timer and then issue this command */ spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM); - list_add_tail(&pCfg->linkage, &ioc->configQ); spin_unlock_irqrestore(&ioc->FreeQlock, flags); add_timer(&pCfg->timer); @@ -4981,7 +5014,7 @@ /* Add to end of Q, set timer and then issue this command */ spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->configQ.head, &pCfg->linkage, Q_ITEM); - list_add_tail(&pCfg->linkage, &ioc->configQ); spin_unlock_irqrestore(&ioc->FreeQlock, flags); add_timer(&pCfg->timer); @@ -5048,8 +5081,13 @@ * the FIFO's are primed. */ spin_lock_irqsave(&ioc->FreeQlock, flags); + if (! Q_IS_EMPTY(&ioc->configQ)){ + pCfg = (CONFIGPARMS *)ioc->configQ.head; + do { + del_timer(&pCfg->timer); + pCfg = (CONFIGPARMS *) (pCfg->linkage.forw); + } while (pCfg != (CONFIGPARMS *)&ioc->configQ); + } - list_for_each_entry(pCfg, &ioc->configQ, linkage) - del_timer(&pCfg->timer); spin_unlock_irqrestore(&ioc->FreeQlock, flags); } else { @@ -5059,12 +5097,19 @@ * Flush the Q, and wake up all suspended threads. */ spin_lock_irqsave(&ioc->FreeQlock, flags); + if (! Q_IS_EMPTY(&ioc->configQ)){ + pCfg = (CONFIGPARMS *)ioc->configQ.head; + do { + pNext = (CONFIGPARMS *) pCfg->linkage.forw; + + Q_DEL_ITEM(&pCfg->linkage); + + pCfg->status = MPT_CONFIG_ERROR; + pCfg->wait_done = 1; + wake_up(&mpt_waitq); - list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) { - list_del(&pCfg->linkage); + pCfg = pNext; + } while (pCfg != (CONFIGPARMS *)&ioc->configQ); - pCfg->status = MPT_CONFIG_ERROR; - pCfg->wait_done = 1; - wake_up(&mpt_waitq); } spin_unlock_irqrestore(&ioc->FreeQlock, flags); } @@ -5202,6 +5247,9 @@ case MPTCTL_DRIVER: if (!ctl++) drvname = "ioctl"; break; + case MPTDMP_DRIVER: + if (!dmp++) drvname = "DMP"; + break; } if (drvname) @@ -5882,6 +5930,7 @@ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ EXPORT_SYMBOL(ioc_list); EXPORT_SYMBOL(mpt_proc_root_dir); +EXPORT_SYMBOL(DmpService); EXPORT_SYMBOL(mpt_register); EXPORT_SYMBOL(mpt_deregister); EXPORT_SYMBOL(mpt_event_register); @@ -5894,7 +5943,9 @@ EXPORT_SYMBOL(mpt_put_msg_frame); EXPORT_SYMBOL(mpt_free_msg_frame); EXPORT_SYMBOL(mpt_add_sge); +EXPORT_SYMBOL(mpt_add_chain); EXPORT_SYMBOL(mpt_send_handshake_request); +EXPORT_SYMBOL(mpt_handshake_req_reply_wait); EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_print_ioc_summary); @@ -5948,6 +5999,8 @@ MptEvHandlers[i] = NULL; MptResetHandlers[i] = NULL; } + + DmpService = NULL; /* NEW! 20010120 -sralston * Register ourselves (mptbase) in order to facilitate reverted: --- b/drivers/message/fusion/mptbase.h 2004-10-01 19:21:43 -07:00 +++ a/drivers/message/fusion/mptbase.h 2004-10-01 19:21:43 -07:00 @@ -83,8 +83,8 @@ #define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR #endif +#define MPT_LINUX_VERSION_COMMON "3.01.16" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.16" -#define MPT_LINUX_VERSION_COMMON "3.01.17" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.17" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ @@ -206,6 +206,7 @@ MPTSCSIH_DRIVER, /* MPT SCSI host (initiator) class */ MPTLAN_DRIVER, /* MPT LAN class */ MPTSTM_DRIVER, /* MPT SCSI target mode class */ + MPTDMP_DRIVER, /* MPT Dynamic Multi-pathing class */ MPTUNKNOWN_DRIVER } MPT_DRIVER_CLASS; @@ -225,7 +226,8 @@ typedef union _MPT_FRAME_TRACKER { struct { + struct _MPT_FRAME_HDR *forw; + struct _MPT_FRAME_HDR *back; - struct list_head list; u32 arg1; u32 pad; void *argp1; @@ -288,6 +290,15 @@ #define MPT_REQ_MSGFLAGS_DROPME 0x80 +/* Used for tracking the free request frames + * and free reply frames. + */ +typedef struct _MPT_Q_TRACKER { + MPT_FRAME_HDR *head; + MPT_FRAME_HDR *tail; +} MPT_Q_TRACKER; + + typedef struct _MPT_SGL_HDR { SGESimple32_t sge[1]; } MPT_SGL_HDR; @@ -297,6 +308,16 @@ } MPT_SGL64_HDR; +typedef struct _Q_ITEM { + struct _Q_ITEM *forw; + struct _Q_ITEM *back; +} Q_ITEM; + +typedef struct _Q_TRACKER { + struct _Q_ITEM *head; + struct _Q_ITEM *tail; +} Q_TRACKER; + /* * Chip-specific stuff... FC929 delineates break between * FC and Parallel SCSI parts. Do NOT re-order. @@ -347,6 +368,27 @@ /* * Dynamic Multi-Pathing specific stuff... */ +#define DMP_MAX_PATHS 8 + +typedef struct _PathInfo { + u8 ioc; + u8 target; + u8 pad; + u8 pflags; +} PathInfo; + +#define PATHINFO_FLAGS_OWNED 0x01 +#define PATHINFO_FLAGS_EXISTS 0x02 +#define PATHINFO_FLAGS_AVAILABLE 0x04 +#define PATHINFO_FLAGS_SECONDARY 0x08 + +#define PFLAGS_EXISTS_AND_AVAIL (PATHINFO_FLAGS_EXISTS|PATHINFO_FLAGS_AVAILABLE) +#define PFLAGS_AVAIL_AND_OWNED (PATHINFO_FLAGS_AVAILABLE|PATHINFO_FLAGS_OWNED) + +typedef struct _ScsiCmndTracker { + void *head; + void *tail; +} ScsiCmndTracker; /* VirtDevice negoFlags field */ #define MPT_TARGET_NO_NEGO_WIDE 0x01 @@ -356,9 +398,14 @@ /* * VirtDevice - FC LUN device or SCSI target device + * (used to be FCSCSI_TARGET) */ typedef struct _VirtDevice { + struct _VirtDevice *forw; + struct _VirtDevice *back; struct scsi_device *device; + rwlock_t VdevLock; + int ref_cnt; u8 tflags; u8 ioc_id; u8 target_id; @@ -371,8 +418,17 @@ u8 type; /* byte 0 of Inquiry data */ u8 cflags; /* controller flags */ u8 rsvd1raid; + int npaths; u16 fc_phys_lun; u16 fc_xlat_lun; + int stall_detected; + PathInfo path[DMP_MAX_PATHS]; + struct timer_list stall_timer; + struct timer_list retry_timer; + struct timer_list gone_timer; + ScsiCmndTracker WaitQ; + ScsiCmndTracker SentQ; + ScsiCmndTracker DoneQ; u32 num_luns; u32 luns[8]; /* Max LUNs is 256 */ u8 pad[4]; @@ -396,6 +452,14 @@ #define MPT_TARGET_FLAGS_VALID_56 0x10 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED 0x20 +typedef struct _VirtDevTracker { + struct _VirtDevice *head; + struct _VirtDevice *tail; + rwlock_t VlistLock; + int pad; +} VirtDevTracker; + + /* * /proc/mpt interface */ @@ -511,6 +575,8 @@ */ typedef struct _MPT_ADAPTER { + struct _MPT_ADAPTER *forw; + struct _MPT_ADAPTER *back; int id; /* Unique adapter id N {0,1,2,...} */ int pci_irq; /* This irq */ char name[MPT_NAME_LENGTH]; /* "iocN" */ @@ -541,7 +607,7 @@ int *ChainToChain; u8 *ChainBuffer; dma_addr_t ChainBufferDMA; + MPT_Q_TRACKER FreeChainQ; - struct list_head FreeChainQ; spinlock_t FreeChainQlock; CHIP_TYPE chip_type; /* We (host driver) get to manage our own RequestQueue! */ @@ -551,7 +617,7 @@ int req_depth; /* Number of request frames */ int req_sz; /* Request frame size (bytes) */ spinlock_t FreeQlock; + MPT_Q_TRACKER FreeQ; - struct list_head FreeQ; /* Pool of SCSI sense buffers for commands coming from * the SCSI mid-layer. We have one 256 byte sense buffer * for each REQ entry. @@ -582,7 +648,7 @@ struct _mpt_ioctl_events *events; /* pointer to event log */ u8 *cached_fw; /* Pointer to FW */ dma_addr_t cached_fw_dma; + Q_TRACKER configQ; /* linked list of config. requests */ - struct list_head configQ; /* linked list of config. requests */ int hs_reply_idx; #ifndef MFCNT u32 pad0; @@ -609,6 +675,12 @@ struct net_device *netdev; } MPT_ADAPTER; + +typedef struct _MPT_ADAPTER_TRACKER { + MPT_ADAPTER *head; + MPT_ADAPTER *tail; +} MPT_ADAPTER_TRACKER; + /* * New return value convention: * 1 = Ok to free associated request frame @@ -830,6 +902,41 @@ #define MPT_INDEX_2_RFPTR(ioc,idx) \ (MPT_FRAME_HDR*)( (u8*)(ioc)->reply_frames + (ioc)->req_sz * (idx) ) +#define Q_INIT(q,type) (q)->head = (q)->tail = (type*)(q) +#define Q_IS_EMPTY(q) ((Q_ITEM*)(q)->head == (Q_ITEM*)(q)) + +#define Q_ADD_TAIL(qt,i,type) { \ + Q_TRACKER *_qt = (Q_TRACKER*)(qt); \ + Q_ITEM *oldTail = _qt->tail; \ + (i)->forw = (type*)_qt; \ + (i)->back = (type*)oldTail; \ + oldTail->forw = (Q_ITEM*)(i); \ + _qt->tail = (Q_ITEM*)(i); \ +} + +#define Q_ADD_HEAD(qt,i,type) { \ + Q_TRACKER *_qt = (Q_TRACKER*)(qt); \ + Q_ITEM *oldHead = _qt->head; \ + (i)->forw = (type*)oldHead; \ + (i)->back = (type*)_qt; \ + oldHead->back = (Q_ITEM*)(i); \ + _qt->head = (Q_ITEM*)(i); \ +} + +#define Q_DEL_ITEM(i) { \ + Q_ITEM *_forw = (Q_ITEM*)(i)->forw; \ + Q_ITEM *_back = (Q_ITEM*)(i)->back; \ + _back->forw = _forw; \ + _forw->back = _back; \ +} + +#define SWAB4(value) \ + (u32)( (((value) & 0x000000ff) << 24) \ + | (((value) & 0x0000ff00) << 8) \ + | (((value) & 0x00ff0000) >> 8) \ + | (((value) & 0xff000000) >> 24) ) + + #if defined(MPT_DEBUG) || defined(MPT_DEBUG_MSG_FRAME) #define DBG_DUMP_REPLY_FRAME(mfp) \ { u32 *m = (u32 *)(mfp); \ @@ -910,11 +1017,13 @@ /* Pool of memory for holding SCpnts before doing * OS callbacks. freeQ is the free pool. */ + MPT_Q_TRACKER taskQ; /* TM request Q */ + int taskQcnt; u8 tmPending; u8 resetPending; u8 is_spi; /* Parallel SCSI i/f */ u8 negoNvram; /* DV disabled, nego NVRAM */ + u8 is_multipath; /* Multi-path compatible */ - u8 pad1; u8 tmState; u8 rsvd[2]; MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/ @@ -935,12 +1044,32 @@ /* Forward decl, a strange C thing, to prevent gcc compiler warnings */ struct scsi_cmnd; +/* + * DMP service layer structure / API interface + */ +typedef struct _DmpServices { + VirtDevTracker VdevList; + struct semaphore *Daemon; + int (*ScsiPathSelect) + (struct scsi_cmnd *, MPT_SCSI_HOST **hd, int *target, int *lun); + int (*DmpIoDoneChk) + (MPT_SCSI_HOST *, struct scsi_cmnd *, + SCSIIORequest_t *, + SCSIIOReply_t *); + void (*mptscsih_scanVlist) + (MPT_SCSI_HOST *, int portnum); + int (*ScsiAbort) + (struct scsi_cmnd *); + int (*ScsiBusReset) + (struct scsi_cmnd *); +} DmpServices_t; + /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* * Generic structure passed to the base mpt_config function. */ typedef struct _x_config_parms { + Q_ITEM linkage; /* linked list */ - struct list_head linkage; /* linked list */ struct timer_list timer; /* timer function for this request */ ConfigPageHeader_t *hdr; dma_addr_t physAddr; @@ -970,8 +1099,10 @@ extern void mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf); extern void mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr); +extern void mpt_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr); extern int mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag); +extern int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait, int sleepFlag); extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp); extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); @@ -988,12 +1119,20 @@ */ extern struct list_head ioc_list; extern struct proc_dir_entry *mpt_proc_root_dir; +extern DmpServices_t *DmpService; extern int mpt_lan_index; /* needed by mptlan.c */ extern int mpt_stm_index; /* needed by mptstm.c */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ + +/* + * More (public) macros... + */ +#ifndef offsetof +#define offsetof(t, m) ((size_t) (&((t *)0)->m)) +#endif #if defined(__alpha__) || defined(__sparc_v9__) || defined(__ia64__) || defined(__x86_64__) #define CAST_U32_TO_PTR(x) ((void *)(u64)x) reverted: --- b/drivers/message/fusion/mptscsih.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/message/fusion/mptscsih.c 2004-10-01 19:21:44 -07:00 @@ -340,18 +340,19 @@ dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n", ioc->name)); spin_lock_irqsave(&ioc->FreeQlock, flags); + if (!Q_IS_EMPTY(&ioc->FreeChainQ)) { + - if (!list_empty(&ioc->FreeChainQ)) { int offset; + chainBuf = ioc->FreeChainQ.head; + Q_DEL_ITEM(&chainBuf->u.frame.linkage); - chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR, - u.frame.linkage.list); - list_del(&chainBuf->u.frame.linkage.list); offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer; chain_idx = offset / ioc->req_sz; rc = SUCCESS; dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n", ioc->name, *retIndex, chainBuf)); + } + else { - } else { rc = FAILED; chain_idx = MPT_HOST_NO_CHAIN; dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n", @@ -359,7 +360,9 @@ } spin_unlock_irqrestore(&ioc->FreeQlock, flags); + *retIndex = chain_idx; + return rc; } /* mptscsih_getFreeChainBuffer() */ @@ -1192,7 +1195,12 @@ hd->ioc = ioc; if ((int)ioc->chip_type > (int)FC929) + hd->is_spi = 1; + + if (DmpService && (ioc->chip_type == FC919 || + ioc->chip_type == FC929)) { + hd->is_multipath = 1; + } - hd->is_spi = 1; /* SCSI needs scsi_cmnd lookup table! * (with size equal to req_depth*PtrSz!) @@ -1210,6 +1218,12 @@ dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", ioc->name, hd->ScsiLookup, sz)); + /* Initialize this Scsi_Host + * internal task Q. + */ + Q_INIT(&hd->taskQ, MPT_FRAME_HDR); + hd->taskQcnt = 0; + /* Allocate memory for the device structures. * A non-Null pointer at an offset * indicates a device exists. @@ -2088,9 +2102,9 @@ chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer + (chain_idx * ioc->req_sz)); - spin_lock_irqsave(&ioc->FreeQlock, flags); + Q_ADD_TAIL(&ioc->FreeChainQ.head, + &chain->u.frame.linkage, MPT_FRAME_HDR); - list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ); spin_unlock_irqrestore(&ioc->FreeQlock, flags); dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n", @@ -2650,6 +2664,8 @@ if (hd->tmPtr) { del_timer(&hd->TMtimer); } + dtmprintk((MYIOC_s_WARN_FMT "taskQcnt (%d)\n", + ioc->name, hd->taskQcnt)); } else { dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name)); @@ -2782,6 +2798,10 @@ return -ENOMEM; } else { memset(vdev, 0, sizeof(VirtDevice)); + rwlock_init(&vdev->VdevLock); + Q_INIT(&vdev->WaitQ, void); + Q_INIT(&vdev->SentQ, void); + Q_INIT(&vdev->DoneQ, void); vdev->tflags = MPT_TARGET_FLAGS_Q_YES; vdev->ioc_id = hd->ioc->id; vdev->target_id = device->id; @@ -2867,40 +2887,6 @@ return; } -static void -mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd, - VirtDevice *pTarget, int qdepth) -{ - int max_depth; - int tagged; - - if ( hd->is_spi ) { - if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { - if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) - max_depth = 1; - else if (((pTarget->inq_data[0] & 0x1f) == 0x00) && - (pTarget->minSyncFactor <= MPT_ULTRA160 )) - max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; - else - max_depth = MPT_SCSI_CMD_PER_DEV_LOW; - } else { - /* error case - No Inq. Data */ - max_depth = 1; - } - } else - max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; - - if (qdepth > max_depth) - qdepth = max_depth; - if (qdepth == 1) - tagged = 0; - else - tagged = MSG_SIMPLE_TAG; - - scsi_adjust_queue_depth(device, tagged, qdepth); -} - - /* * OS entry point to adjust the queue_depths on a per-device basis. * Called once per device the bus scan. Use it to force the queue_depth @@ -2950,7 +2936,24 @@ mptscsih_initTarget(hd, device->channel, device->id, device->lun, device->inquiry, device->inquiry_len ); + scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, + MPT_SCSI_CMD_PER_DEV_HIGH); + if ( hd->is_spi ) { + if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { + if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) + scsi_adjust_queue_depth(device, 0, 1); + else if (((pTarget->inq_data[0] & 0x1f) == 0x00) + && (pTarget->minSyncFactor <= MPT_ULTRA160 )) + scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, + MPT_SCSI_CMD_PER_DEV_HIGH); + else + scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, + MPT_SCSI_CMD_PER_DEV_LOW); + } else { + /* error case - No Inq. Data */ + scsi_adjust_queue_depth(device, 0, 1); + } + } - mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH); dsprintk((MYIOC_s_INFO_FMT "Queue depth=%d, tflags=%x\n", @@ -2970,25 +2973,6 @@ return 0; } -static ssize_t -mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count) -{ - int depth; - struct scsi_device *sdev = to_scsi_device(dev); - MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata; - VirtDevice *pTarget; - - depth = simple_strtoul(buf, NULL, 0); - if (depth == 0) - return -EINVAL; - pTarget = hd->Targets[sdev->id]; - if (pTarget == NULL) - return -EINVAL; - mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata, - pTarget, depth); - return count; -} - /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /* @@ -3013,6 +2997,8 @@ pReq = (SCSIIORequest_t *) mf; index = (int) pReq->TargetID; target = hd->Targets[index]; + if (hd->is_multipath && sc->device->hostdata) + target = (VirtDevice *) sc->device->hostdata; if (sense_count) { u8 *sense_data; @@ -3316,19 +3302,6 @@ return 1; /* currently means nothing really */ } -static struct device_attribute mptscsih_queue_depth_attr = { - .attr = { - .name = "queue_depth", - .mode = S_IWUSR, - }, - .store = mptscsih_store_queue_depth, -}; - -static struct device_attribute *mptscsih_dev_attrs[] = { - &mptscsih_queue_depth_attr, - NULL, -}; - static struct scsi_host_template driver_template = { .proc_name = "mptscsih", .proc_info = mptscsih_proc_info, @@ -3349,7 +3322,6 @@ .max_sectors = 8192, .cmd_per_lun = 7, .use_clustering = ENABLE_CLUSTERING, - .sdev_attrs = mptscsih_dev_attrs, }; /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ diff -u b/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- b/drivers/scsi/3w-xxxx.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/3w-xxxx.c 2004-10-01 19:23:17 -07:00 @@ -207,7 +207,7 @@ #include "3w-xxxx.h" /* Globals */ -#define TW_DRIVER_VERSION "1.26.02.000" +static const char *tw_driver_version="1.26.02.000"; static TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; static int tw_device_extension_count = 0; static int twe_major = -1; @@ -216,7 +216,6 @@ MODULE_AUTHOR("AMCC"); MODULE_DESCRIPTION("3ware Storage Controller Linux Driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(TW_DRIVER_VERSION); /* Function prototypes */ static int tw_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_reset); @@ -224,7 +223,7 @@ /* Functions */ /* This function will check the status register for unexpected bits */ -static int tw_check_bits(u32 status_reg_value) +int tw_check_bits(u32 status_reg_value) { if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) { dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value); @@ -493,7 +492,7 @@ "Max sector count: %4d\n" "SCSI Host Resets: %4d\n" "AEN's: %4d\n", - TW_DRIVER_VERSION, + tw_driver_version, tw_dev->posted_request_count, tw_dev->max_posted_request_count, tw_dev->pending_request_count, @@ -885,7 +884,7 @@ /* This function handles ioctl for the character device */ static int tw_chrdev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int request_id; + int error, request_id; dma_addr_t dma_handle; unsigned short tw_aen_code; unsigned long flags; @@ -906,7 +905,8 @@ return -EINTR; /* First copy down the buffer length */ - if (copy_from_user(&data_buffer_length, argp, sizeof(unsigned int))) + error = copy_from_user(&data_buffer_length, argp, sizeof(unsigned int)); + if (error) goto out; /* Check size */ @@ -919,7 +919,7 @@ data_buffer_length_adjusted = (data_buffer_length + 511) & ~511; /* Now allocate ioctl buf memory */ - cpu_addr = dma_alloc_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle, GFP_KERNEL); + cpu_addr = pci_alloc_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, &dma_handle); if (cpu_addr == NULL) { retval = -ENOMEM; goto out; @@ -928,7 +928,8 @@ tw_ioctl = (TW_New_Ioctl *)cpu_addr; /* Now copy down the entire ioctl */ - if (copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1)) + error = copy_from_user(tw_ioctl, argp, data_buffer_length + sizeof(TW_New_Ioctl) - 1); + if (error) goto out2; passthru = (TW_Passthru *)&tw_ioctl->firmware_command; @@ -1041,12 +1042,12 @@ } /* Now copy the response to userspace */ - if (copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1)) - goto out2; - retval = 0; + error = copy_to_user(argp, tw_ioctl, sizeof(TW_New_Ioctl) + data_buffer_length - 1); + if (error == 0) + retval = 0; out2: /* Now free ioctl buf memory */ - dma_free_coherent(&tw_dev->tw_pci_dev->dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); + pci_free_consistent(tw_dev->tw_pci_dev, data_buffer_length_adjusted+sizeof(TW_New_Ioctl) - 1, cpu_addr, dma_handle); out: up(&tw_dev->ioctl_sem); return retval; @@ -1543,7 +1544,7 @@ request_buffer[4] = 31; /* Additional length */ memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */ sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id); - memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3); + memcpy(&request_buffer[32], tw_driver_version, 3); param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; if (param == NULL) { @@ -2483,7 +2484,7 @@ /* This function is called on driver initialization */ static int __init tw_init(void) { - printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", TW_DRIVER_VERSION); + printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version); return pci_module_init(&tw_driver); } /* End tw_init() */ diff -u b/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c --- b/drivers/scsi/BusLogic.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/BusLogic.c 2004-10-01 19:23:17 -07:00 @@ -2344,8 +2344,6 @@ Remove Host Adapter from the list of registered BusLogic Host Adapters. */ list_del(&HostAdapter->host_list); - - scsi_host_put(Host); return 0; } @@ -2621,7 +2619,7 @@ /* Acquire exclusive access to Host Adapter. */ - spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, ProcessorFlags); + BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags); /* Handle Interrupts appropriately for each Host Adapter type. */ @@ -2689,7 +2687,7 @@ /* Release exclusive access to Host Adapter. */ - spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, ProcessorFlags); + BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags); return IRQ_HANDLED; } @@ -2777,9 +2775,9 @@ */ CCB = BusLogic_AllocateCCB(HostAdapter); if (CCB == NULL) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_ReleaseHostAdapterLock(HostAdapter); BusLogic_Delay(1); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_AcquireHostAdapterLock(HostAdapter); CCB = BusLogic_AllocateCCB(HostAdapter); if (CCB == NULL) { Command->result = DID_ERROR << 16; @@ -2903,10 +2901,10 @@ error as a Host Adapter Hard Reset should be initiated soon. */ if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_ReleaseHostAdapterLock(HostAdapter); BusLogic_Warning("Unable to write Outgoing Mailbox - " "Pausing for 1 second\n", HostAdapter); BusLogic_Delay(1); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_AcquireHostAdapterLock(HostAdapter); if (!BusLogic_WriteOutgoingMailbox(HostAdapter, BusLogic_MailboxStartCommand, CCB)) { BusLogic_Warning("Still unable to write Outgoing Mailbox - " "Host Adapter Dead?\n", HostAdapter); BusLogic_DeallocateCCB(CCB); @@ -3044,9 +3042,9 @@ */ if (HardReset) { - spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_ReleaseHostAdapterLock(HostAdapter); BusLogic_Delay(HostAdapter->BusSettleTime); - spin_lock_irq(HostAdapter->SCSI_Host->host_lock); + BusLogic_AcquireHostAdapterLock(HostAdapter); } for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) { diff -u b/drivers/scsi/BusLogic.h b/drivers/scsi/BusLogic.h --- b/drivers/scsi/BusLogic.h 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/BusLogic.h 2004-10-01 19:23:16 -07:00 @@ -1169,6 +1169,46 @@ unsigned char ProductRevisionLevel[4]; /* Bytes 32-35 */ }; +/* + BusLogic_AcquireHostAdapterLock acquires exclusive access to Host Adapter. +*/ + +static inline void BusLogic_AcquireHostAdapterLock(struct BusLogic_HostAdapter *HostAdapter) +{ + spin_lock_irq(HostAdapter->SCSI_Host->host_lock); +} + +/* + BusLogic_ReleaseHostAdapterLock releases exclusive access to Host Adapter. +*/ + +static inline void BusLogic_ReleaseHostAdapterLock(struct BusLogic_HostAdapter *HostAdapter) +{ + spin_unlock_irq(HostAdapter->SCSI_Host->host_lock); +} + + +/* + BusLogic_AcquireHostAdapterLockIH acquires exclusive access to Host Adapter, + but is only called from the interrupt handler. +*/ + +static inline void BusLogic_AcquireHostAdapterLockIH(struct BusLogic_HostAdapter *HostAdapter, unsigned long *ProcessorFlags) +{ + spin_lock_irqsave(HostAdapter->SCSI_Host->host_lock, *ProcessorFlags); +} + + +/* + BusLogic_ReleaseHostAdapterLockIH releases exclusive access to Host Adapter, + but is only called from the interrupt handler. +*/ + +static inline void BusLogic_ReleaseHostAdapterLockIH(struct BusLogic_HostAdapter *HostAdapter, unsigned long *ProcessorFlags) +{ + spin_unlock_irqrestore(HostAdapter->SCSI_Host->host_lock, *ProcessorFlags); +} + /* Define functions to provide an abstraction for reading and writing the diff -u b/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- b/drivers/scsi/Kconfig 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/Kconfig 2004-10-01 19:23:17 -07:00 @@ -313,8 +313,8 @@ module will be called aha1740. config SCSI_AACRAID - tristate "Adaptec AACRAID support" - depends on SCSI && PCI + tristate "Adaptec AACRAID support (EXPERIMENTAL)" + depends on EXPERIMENTAL && SCSI && PCI source "drivers/scsi/aic7xxx/Kconfig.aic7xxx" @@ -783,7 +783,7 @@ config SCSI_INITIO tristate "Initio 9100U(W) support" - depends on PCI && SCSI + depends on PCI && SCSI && BROKEN help This is support for the Initio 91XXU(W) SCSI host adapter. Please read the SCSI-HOWTO, available from @@ -1222,7 +1222,7 @@ module will be called qlogicfas. config SCSI_QLOGIC_ISP - tristate "Qlogic ISP SCSI support (old driver)" + tristate "Qlogic ISP SCSI support" depends on PCI && SCSI ---help--- This driver works for all QLogic PCI SCSI host adapters (IQ-PCI, @@ -1239,9 +1239,6 @@ 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 @@ -1260,21 +1257,14 @@ qlogicfc driver. This is required on some platforms. config SCSI_QLOGIC_1280 - tristate "Qlogic QLA 1240/1x80/1x160 SCSI support" + tristate "Qlogic QLA 1280 SCSI support" depends on PCI && SCSI help - Say Y if you have a QLogic ISP1240/1x80/1x160 SCSI host adapter. + Say Y if you have a QLogic ISP1x80/1x160 SCSI host adapter. 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" - 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 reverted: --- b/drivers/scsi/Makefile 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/Makefile 2004-10-01 19:21:44 -07:00 @@ -149,6 +149,7 @@ sd_mod-objs := sd.o sr_mod-objs := sr.o sr_ioctl.o sr_vendor.o initio-objs := ini9100u.o i91uscsi.o +a100u2w-objs := inia100.o i60uscsi.o ncr53c8xx-flags-$(CONFIG_SCSI_ZALON) \ := -DCONFIG_NCR53C8XX_PREFETCH -DSCSI_NCR_BIG_ENDIAN \ -DCONFIG_SCSI_NCR53C8XX_NO_WORD_TRANSFERS reverted: --- b/drivers/scsi/a100u2w.c 2004-10-01 19:21:44 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,1202 +0,0 @@ -/* - * Initio A100 device driver for Linux. - * - * Copyright (c) 1994-1998 Initio Corporation - * Copyright (c) 2003-2004 Christoph Hellwig - * All rights reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * -------------------------------------------------------------------------- - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Where this Software is combined with software released under the terms of - * the GNU General Public License ("GPL") and the terms of the GPL would require the - * combined work to also be released under the terms of the GPL, the terms - * and conditions of this License will apply in addition to those of the - * GPL with the exception of any terms or conditions of this License that - * conflict with, or are expressly prohibited by, the GPL. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Revision History: - * 07/02/98 hl - v.91n Initial drivers. - * 09/14/98 hl - v1.01 Support new Kernel. - * 09/22/98 hl - v1.01a Support reset. - * 09/24/98 hl - v1.01b Fixed reset. - * 10/05/98 hl - v1.02 split the source code and release. - * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up - * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause - * 08/08/99 bv - v1.02c Use waitForPause again. - * 06/25/02 Doug Ledford - v1.02d - * - Remove limit on number of controllers - * - Port to DMA mapping API - * - Clean up interrupt handler registration - * - Fix memory leaks - * - Fix allocation of scsi host structs and private data - * 11/18/03 Christoph Hellwig - * - Port to new probing API - * - Fix some more leaks in init failure cases - * 9/28/04 Christoph Hellwig - * - merge the two source files - * - remove internal queueing code - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "a100u2w.h" - - -#define JIFFIES_TO_MS(t) ((t) * 1000 / HZ) -#define MS_TO_JIFFIES(j) ((j * HZ) / 1000) - -static ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); -static void inia100SCBPost(BYTE * pHcb, BYTE * pScb); - -static NVRAM nvram, *nvramp = &nvram; -static UCHAR dftNvRam[64] = -{ -/*----------header -------------*/ - 0x01, /* 0x00: Sub System Vendor ID 0 */ - 0x11, /* 0x01: Sub System Vendor ID 1 */ - 0x60, /* 0x02: Sub System ID 0 */ - 0x10, /* 0x03: Sub System ID 1 */ - 0x00, /* 0x04: SubClass */ - 0x01, /* 0x05: Vendor ID 0 */ - 0x11, /* 0x06: Vendor ID 1 */ - 0x60, /* 0x07: Device ID 0 */ - 0x10, /* 0x08: Device ID 1 */ - 0x00, /* 0x09: Reserved */ - 0x00, /* 0x0A: Reserved */ - 0x01, /* 0x0B: Revision of Data Structure */ - /* -- Host Adapter Structure --- */ - 0x01, /* 0x0C: Number Of SCSI Channel */ - 0x01, /* 0x0D: BIOS Configuration 1 */ - 0x00, /* 0x0E: BIOS Configuration 2 */ - 0x00, /* 0x0F: BIOS Configuration 3 */ - /* --- SCSI Channel 0 Configuration --- */ - 0x07, /* 0x10: H/A ID */ - 0x83, /* 0x11: Channel Configuration */ - 0x20, /* 0x12: MAX TAG per target */ - 0x0A, /* 0x13: SCSI Reset Recovering time */ - 0x00, /* 0x14: Channel Configuration4 */ - 0x00, /* 0x15: Channel Configuration5 */ - /* SCSI Channel 0 Target Configuration */ - /* 0x16-0x25 */ - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - /* --- SCSI Channel 1 Configuration --- */ - 0x07, /* 0x26: H/A ID */ - 0x83, /* 0x27: Channel Configuration */ - 0x20, /* 0x28: MAX TAG per target */ - 0x0A, /* 0x29: SCSI Reset Recovering time */ - 0x00, /* 0x2A: Channel Configuration4 */ - 0x00, /* 0x2B: Channel Configuration5 */ - /* SCSI Channel 1 Target Configuration */ - /* 0x2C-0x3B */ - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, - 0x00, /* 0x3C: Reserved */ - 0x00, /* 0x3D: Reserved */ - 0x00, /* 0x3E: Reserved */ - 0x00 /* 0x3F: Checksum */ -}; - - -/***************************************************************************/ -static void waitForPause(unsigned amount) -{ - ULONG the_time = jiffies + MS_TO_JIFFIES(amount); - while (time_before_eq(jiffies, the_time)) - cpu_relax(); -} - -/***************************************************************************/ -static UCHAR waitChipReady(ORC_HCS * hcsp) -{ - int i; - - for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ - if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP) /* Wait HOSTSTOP set */ - return 1; - waitForPause(100); /* wait 100ms before try again */ - } - return 0; -} - -/***************************************************************************/ -static UCHAR waitFWReady(ORC_HCS * hcsp) -{ - int i; - - for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ - if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) /* Wait READY set */ - return 1; - waitForPause(100); /* wait 100ms before try again */ - } - return 0; -} - -/***************************************************************************/ -static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp) -{ - int i; - - for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ - if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST)) /* Wait SCSIRST done */ - return 1; - waitForPause(100); /* wait 100ms before try again */ - } - return 0; -} - -/***************************************************************************/ -static UCHAR waitHDOoff(ORC_HCS * hcsp) -{ - int i; - - for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ - if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO)) /* Wait HDO off */ - return 1; - waitForPause(100); /* wait 100ms before try again */ - } - return 0; -} - -/***************************************************************************/ -static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData) -{ - int i; - - for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ - if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI) - return 1; /* Wait HDI set */ - waitForPause(100); /* wait 100ms before try again */ - } - return 0; -} - -/***************************************************************************/ -static unsigned short get_FW_version(ORC_HCS * hcsp) -{ - UCHAR bData; - union { - unsigned short sVersion; - unsigned char cVersion[2]; - } Version; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION); - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - if (waitHDIset(hcsp, &bData) == 0) /* Wait HDI set */ - return 0; - Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); - ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ - - if (waitHDIset(hcsp, &bData) == 0) /* Wait HDI set */ - return 0; - Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); - ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ - - return (Version.sVersion); -} - -/***************************************************************************/ -static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value) -{ - ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM); /* Write command */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, value); /* Write value */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - return 1; -} - -/***************************************************************************/ -static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn) -{ - unsigned char bData; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM); /* Write command */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - if (waitHDIset(hcsp, &bData) == 0) /* Wait HDI set */ - return 0; - *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA); - ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ - - return 1; -} - -/***************************************************************************/ -static void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp) -{ - scbp->SCB_Status = ORCSCB_POST; - ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx); - return; -} - - -/*********************************************************************** - Read SCSI H/A configuration parameters from serial EEPROM -************************************************************************/ -static int se2_rd_all(ORC_HCS * hcsp) -{ - int i; - UCHAR *np, chksum = 0; - - np = (UCHAR *) nvramp; - for (i = 0; i < 64; i++, np++) { /* <01> */ - if (get_NVRAM(hcsp, (unsigned char) i, np) == 0) - return -1; -// *np++ = get_NVRAM(hcsp, (unsigned char ) i); - } - -/*------ Is ckecksum ok ? ------*/ - np = (UCHAR *) nvramp; - for (i = 0; i < 63; i++) - chksum += *np++; - - if (nvramp->CheckSum != (UCHAR) chksum) - return -1; - return 1; -} - -/************************************************************************ - Update SCSI H/A configuration parameters from serial EEPROM -*************************************************************************/ -static void se2_update_all(ORC_HCS * hcsp) -{ /* setup default pattern */ - int i; - UCHAR *np, *np1, chksum = 0; - - /* Calculate checksum first */ - np = (UCHAR *) dftNvRam; - for (i = 0; i < 63; i++) - chksum += *np++; - *np = chksum; - - np = (UCHAR *) dftNvRam; - np1 = (UCHAR *) nvramp; - for (i = 0; i < 64; i++, np++, np1++) { - if (*np != *np1) { - set_NVRAM(hcsp, (unsigned char) i, *np); - } - } - return; -} - -/************************************************************************* - Function name : read_eeprom -**************************************************************************/ -static void read_eeprom(ORC_HCS * hcsp) -{ - if (se2_rd_all(hcsp) != 1) { - se2_update_all(hcsp); /* setup default pattern */ - se2_rd_all(hcsp); /* load again */ - } -} - - -/***************************************************************************/ -static UCHAR load_FW(ORC_HCS * hcsp) -{ - U32 dData; - USHORT wBIOSAddress; - USHORT i; - UCHAR *pData, bData; - - - bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG); - ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */ - ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00); - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00); - if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) { - ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ - return 0; - } - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01); - if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) { - ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ - return 0; - } - ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */ - pData = (UCHAR *) & dData; - dData = 0; /* Initial FW address to 0 */ - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10); - *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11); - *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12); - *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ - ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2)); - ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */ - - wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */ - for (i = 0, pData = (UCHAR *) & dData; /* Download the code */ - i < 0x1000; /* Firmware code size = 4K */ - i++, wBIOSAddress++) { - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); - *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ - if ((i % 4) == 3) { - ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */ - pData = (UCHAR *) & dData; - } - } - - ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */ - wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */ - for (i = 0, pData = (UCHAR *) & dData; /* Check the code */ - i < 0x1000; /* Firmware code size = 4K */ - i++, wBIOSAddress++) { - ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); - *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ - if ((i % 4) == 3) { - if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) { - ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ - ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */ - return 0; - } - pData = (UCHAR *) & dData; - } - } - ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ - ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ - return 1; -} - -/***************************************************************************/ -static void setup_SCBs(ORC_HCS * hcsp) -{ - ORC_SCB *pVirScb; - int i; - ESCB *pVirEscb; - dma_addr_t pPhysEscb; - - /* Setup SCB HCS_Base and SCB Size registers */ - ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, ORC_MAXQUEUE); /* Total number of SCBs */ - /* SCB HCS_Base address 0 */ - ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); - /* SCB HCS_Base address 1 */ - ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray); - - /* setup scatter list address with one buffer */ - pVirScb = hcsp->HCS_virScbArray; - pVirEscb = hcsp->HCS_virEscbArray; - - for (i = 0; i < ORC_MAXQUEUE; i++) { - pPhysEscb = (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); - pVirScb->SCB_SGPAddr = (U32) pPhysEscb; - pVirScb->SCB_SensePAddr = (U32) pPhysEscb; - pVirScb->SCB_EScb = pVirEscb; - pVirScb->SCB_ScbIdx = i; - pVirScb++; - pVirEscb++; - } - - return; -} - -/***************************************************************************/ -static void initAFlag(ORC_HCS * hcsp) -{ - UCHAR i, j; - - for (i = 0; i < MAX_CHANNELS; i++) { - for (j = 0; j < 8; j++) { - hcsp->BitAllocFlag[i][j] = 0xffffffff; - } - } -} - -/***************************************************************************/ -static int init_orchid(ORC_HCS * hcsp) -{ - UBYTE *readBytep; - USHORT revision; - UCHAR i; - - initAFlag(hcsp); - ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */ - if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */ - revision = get_FW_version(hcsp); - if (revision == 0xFFFF) { - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ - if (waitChipReady(hcsp) == 0) - return (-1); - load_FW(hcsp); /* Download FW */ - setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */ - if (waitFWReady(hcsp) == 0) - return (-1); - /* Wait for firmware ready */ - } else { - setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ - } - } else { /* Orchid is not Ready */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ - if (waitChipReady(hcsp) == 0) - return (-1); - load_FW(hcsp); /* Download FW */ - setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */ - - /* clear HOSTSTOP */ - if (waitFWReady(hcsp) == 0) /* Wait for firmware ready */ - return (-1); - } - -/*------------- get serial EEProm settting -------*/ - - read_eeprom(hcsp); - - if (nvramp->Revision != 1) - return (-1); - - hcsp->HCS_SCSI_ID = nvramp->SCSI0Id; - hcsp->HCS_BIOS = nvramp->BIOSConfig1; - hcsp->HCS_MaxTar = MAX_TARGETS; - readBytep = (UCHAR *) & (nvramp->Target00Config); - for (i = 0; i < 16; readBytep++, i++) { - hcsp->TargetFlag[i] = *readBytep; - hcsp->MaximumTags[i] = ORC_MAXTAGS; - } /* for */ - - if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ - hcsp->HCS_Flags |= HCF_SCSI_RESET; - } - ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */ - return (0); -} - -/***************************************************************************** - Function name : orc_reset_scsi_bus - Description : Reset registers, reset a hanging bus and - kill active and disconnected commands for target w/o soft reset - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int orc_reset_scsi_bus(ORC_HCS * pHCB) -{ /* I need Host Control Block Information */ - ULONG flags; - - spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); - - initAFlag(pHCB); - /* reset scsi bus */ - ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST); - if (waitSCSIRSTdone(pHCB) == 0) { - spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); - return FAILED; - } else { - spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); - return SUCCESS; - } -} - -/***************************************************************************** - Function name : orc_device_reset - Description : Reset registers, reset a hanging bus and - kill active and disconnected commands for target w/o soft reset - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int orc_device_reset(ORC_HCS * pHCB, struct scsi_cmnd *SCpnt, unsigned int target) -{ /* I need Host Control Block Information */ - ORC_SCB *pScb; - ESCB *pVirEscb; - ORC_SCB *pVirScb; - UCHAR i; - ULONG flags; - - spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); - pScb = (ORC_SCB *) NULL; - pVirEscb = (ESCB *) NULL; - - /* setup scatter list address with one buffer */ - pVirScb = pHCB->HCS_virScbArray; - - initAFlag(pHCB); - /* device reset */ - for (i = 0; i < ORC_MAXQUEUE; i++) { - pVirEscb = pVirScb->SCB_EScb; - if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) - break; - pVirScb++; - } - - if (i == ORC_MAXQUEUE) { - printk("Unable to Reset - No SCB Found\n"); - spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); - return FAILED; - } - if ((pScb = orc_alloc_scb(pHCB)) == NULL) { - spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); - return FAILED; - } - pScb->SCB_Opcode = ORC_BUSDEVRST; - pScb->SCB_Target = target; - pScb->SCB_HaStat = 0; - pScb->SCB_TaStat = 0; - pScb->SCB_Status = 0x0; - pScb->SCB_Link = 0xFF; - pScb->SCB_Reserved0 = 0; - pScb->SCB_Reserved1 = 0; - pScb->SCB_XferLen = 0; - pScb->SCB_SGLen = 0; - - pVirEscb->SCB_Srb = NULL; - pVirEscb->SCB_Srb = SCpnt; - orc_exec_scb(pHCB, pScb); /* Start execute SCB */ - spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); - return SUCCESS; -} - - -/***************************************************************************/ -static ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp) -{ - ORC_SCB *pTmpScb; - UCHAR Ch; - ULONG idx; - UCHAR index; - UCHAR i; - - Ch = hcsp->HCS_Index; - for (i = 0; i < 8; i++) { - for (index = 0; index < 32; index++) { - if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) { - hcsp->BitAllocFlag[Ch][i] &= ~(1 << index); - break; - } - } - idx = index + 32 * i; - pTmpScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB))); - return (pTmpScb); - } - return (NULL); -} - -static ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp) -{ - ORC_SCB *pTmpScb; - ULONG flags; - - spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); - pTmpScb = __orc_alloc_scb(hcsp); - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); - return (pTmpScb); -} - - -/***************************************************************************/ -static void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) -{ - ULONG flags; - UCHAR Index; - UCHAR i; - UCHAR Ch; - - spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); - Ch = hcsp->HCS_Index; - Index = scbp->SCB_ScbIdx; - i = Index / 32; - Index %= 32; - hcsp->BitAllocFlag[Ch][i] |= (1 << Index); - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); -} - -/***************************************************************************** - Function name : abort_SCB - Description : Abort a queued command. - (commands that are on the bus can't be aborted easily) - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb) -{ - unsigned char bData, bStatus; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */ - ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); - if (waitHDOoff(hcsp) == 0) /* Wait HDO off */ - return 0; - - if (waitHDIset(hcsp, &bData) == 0) /* Wait HDI set */ - return 0; - bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA); - ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ - - if (bStatus == 1) /* 0 - Successfully */ - return 0; /* 1 - Fail */ - return 1; -} - -/***************************************************************************** - Function name : inia100_abort - Description : Abort a queued command. - (commands that are on the bus can't be aborted easily) - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int orc_abort_srb(ORC_HCS * hcsp, struct scsi_cmnd *SCpnt) -{ - ESCB *pVirEscb; - ORC_SCB *pVirScb; - UCHAR i; - ULONG flags; - - spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); - - pVirScb = hcsp->HCS_virScbArray; - - for (i = 0; i < ORC_MAXQUEUE; i++, pVirScb++) { - pVirEscb = pVirScb->SCB_EScb; - if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) { - if (pVirScb->SCB_TagMsg == 0) { - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); - return FAILED; - } else { - if (abort_SCB(hcsp, pVirScb)) { - pVirEscb->SCB_Srb = NULL; - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); - return SUCCESS; - } else { - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); - return FAILED; - } - } - } - } - spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); - return FAILED; -} - -/*********************************************************************** - Routine Description: - This is the interrupt service routine for the Orchid SCSI adapter. - It reads the interrupt register to determine if the adapter is indeed - the source of the interrupt and clears the interrupt at the device. - Arguments: - HwDeviceExtension - HBA miniport driver's adapter data storage - Return Value: -***********************************************************************/ -static void orc_interrupt( - ORC_HCS * hcsp -) -{ - BYTE bScbIdx; - ORC_SCB *pScb; - - if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) { - return; // 0; - - } - do { - bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE); - - pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx)); - pScb->SCB_Status = 0x0; - - inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb); - } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT)); - return; //1; - -} /* End of I1060Interrupt() */ - -/***************************************************************************** - Function name : inia100BuildSCB - Description : - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * SCpnt) -{ /* Create corresponding SCB */ - struct scatterlist *pSrbSG; - ORC_SG *pSG; /* Pointer to SG list */ - int i, count_sg; - ESCB *pEScb; - - pEScb = pSCB->SCB_EScb; - pEScb->SCB_Srb = SCpnt; - pSG = NULL; - - pSCB->SCB_Opcode = ORC_EXECSCSI; - pSCB->SCB_Flags = SCF_NO_DCHK; /* Clear done bit */ - pSCB->SCB_Target = SCpnt->device->id; - pSCB->SCB_Lun = SCpnt->device->lun; - pSCB->SCB_Reserved0 = 0; - pSCB->SCB_Reserved1 = 0; - pSCB->SCB_SGLen = 0; - - if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) { - pSG = (ORC_SG *) & pEScb->ESCB_SGList[0]; - if (SCpnt->use_sg) { - pSrbSG = (struct scatterlist *) SCpnt->request_buffer; - count_sg = pci_map_sg(pHCB->pdev, pSrbSG, SCpnt->use_sg, - SCpnt->sc_data_direction); - pSCB->SCB_SGLen = (U32) (count_sg * 8); - for (i = 0; i < count_sg; i++, pSG++, pSrbSG++) { - pSG->SG_Ptr = (U32) sg_dma_address(pSrbSG); - pSG->SG_Len = (U32) sg_dma_len(pSrbSG); - } - } else if (SCpnt->request_bufflen != 0) {/* Non SG */ - pSCB->SCB_SGLen = 0x8; - SCpnt->SCp.dma_handle = pci_map_single(pHCB->pdev, - SCpnt->request_buffer, - SCpnt->request_bufflen, - SCpnt->sc_data_direction); - pSG->SG_Ptr = (U32) SCpnt->SCp.dma_handle; - pSG->SG_Len = (U32) SCpnt->request_bufflen; - } else { - pSCB->SCB_SGLen = 0; - pSG->SG_Ptr = 0; - pSG->SG_Len = 0; - } - } - pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr; - pSCB->SCB_HaStat = 0; - pSCB->SCB_TaStat = 0; - pSCB->SCB_Link = 0xFF; - pSCB->SCB_SenseLen = SENSE_SIZE; - pSCB->SCB_CDBLen = SCpnt->cmd_len; - if (pSCB->SCB_CDBLen >= IMAX_CDB) { - printk("max cdb length= %x\b", SCpnt->cmd_len); - pSCB->SCB_CDBLen = IMAX_CDB; - } - pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; - if (SCpnt->device->tagged_supported) { /* Tag Support */ - pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ - } else { - pSCB->SCB_TagMsg = 0; /* No tag support */ - } - memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen); - return; -} - -/***************************************************************************** - Function name : inia100_queue - Description : Queue a command and setup interrupts for a free bus. - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int inia100_queue(struct scsi_cmnd * SCpnt, void (*done) (struct scsi_cmnd *)) -{ - register ORC_SCB *pSCB; - ORC_HCS *pHCB; /* Point to Host adapter control block */ - - pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; - SCpnt->scsi_done = done; - /* Get free SCSI control block */ - if ((pSCB = orc_alloc_scb(pHCB)) == NULL) - return SCSI_MLQUEUE_HOST_BUSY; - - inia100BuildSCB(pHCB, pSCB, SCpnt); - orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ - - return (0); -} - -/***************************************************************************** - Function name : inia100_abort - Description : Abort a queued command. - (commands that are on the bus can't be aborted easily) - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int inia100_abort(struct scsi_cmnd * SCpnt) -{ - ORC_HCS *hcsp; - - hcsp = (ORC_HCS *) SCpnt->device->host->hostdata; - return orc_abort_srb(hcsp, SCpnt); -} - -/***************************************************************************** - Function name : inia100_reset - Description : Reset registers, reset a hanging bus and - kill active and disconnected commands for target w/o soft reset - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int inia100_bus_reset(struct scsi_cmnd * SCpnt) -{ /* I need Host Control Block Information */ - ORC_HCS *pHCB; - pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; - return orc_reset_scsi_bus(pHCB); -} - -/***************************************************************************** - Function name : inia100_device_reset - Description : Reset the device - Input : pHCB - Pointer to host adapter structure - Output : None. - Return : pSRB - Pointer to SCSI request block. -*****************************************************************************/ -static int inia100_device_reset(struct scsi_cmnd * SCpnt) -{ /* I need Host Control Block Information */ - ORC_HCS *pHCB; - pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; - return orc_device_reset(pHCB, SCpnt, SCpnt->device->id); - -} - -/***************************************************************************** - Function name : inia100SCBPost - Description : This is callback routine be called when orc finish one - SCSI command. - Input : pHCB - Pointer to host adapter control block. - pSCB - Pointer to SCSI control block. - Output : None. - Return : None. -*****************************************************************************/ -static void inia100SCBPost(BYTE * pHcb, BYTE * pScb) -{ - struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */ - ORC_HCS *pHCB; - ORC_SCB *pSCB; - ESCB *pEScb; - - pHCB = (ORC_HCS *) pHcb; - pSCB = (ORC_SCB *) pScb; - pEScb = pSCB->SCB_EScb; - if ((pSRB = (struct scsi_cmnd *) pEScb->SCB_Srb) == 0) { - printk("inia100SCBPost: SRB pointer is empty\n"); - orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ - return; - } - pEScb->SCB_Srb = NULL; - - switch (pSCB->SCB_HaStat) { - case 0x0: - case 0xa: /* Linked command complete without error and linked normally */ - case 0xb: /* Linked command complete without error interrupt generated */ - pSCB->SCB_HaStat = 0; - break; - - case 0x11: /* Selection time out-The initiator selection or target - reselection was not complete within the SCSI Time out period */ - pSCB->SCB_HaStat = DID_TIME_OUT; - break; - - case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus - phase sequence was requested by the target. The host adapter - will generate a SCSI Reset Condition, notifying the host with - a SCRD interrupt */ - pSCB->SCB_HaStat = DID_RESET; - break; - - case 0x1a: /* SCB Aborted. 07/21/98 */ - pSCB->SCB_HaStat = DID_ABORT; - break; - - case 0x12: /* Data overrun/underrun-The target attempted to transfer more data - than was allocated by the Data Length field or the sum of the - Scatter / Gather Data Length fields. */ - case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ - case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */ - - default: - printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); - pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ - break; - } - - if (pSCB->SCB_TaStat == 2) { /* Check condition */ - memcpy((unsigned char *) &pSRB->sense_buffer[0], - (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE); - } - pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); - - if (pSRB->use_sg) { - pci_unmap_sg(pHCB->pdev, - (struct scatterlist *)pSRB->request_buffer, - pSRB->use_sg, pSRB->sc_data_direction); - } else if (pSRB->request_bufflen != 0) { - pci_unmap_single(pHCB->pdev, pSRB->SCp.dma_handle, - pSRB->request_bufflen, - pSRB->sc_data_direction); - } - - pSRB->scsi_done(pSRB); /* Notify system DONE */ - - orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ -} - -/* - * Interrupt handler (main routine of the driver) - */ -static irqreturn_t inia100_intr(int irqno, void *devid, struct pt_regs *regs) -{ - struct Scsi_Host *host = (struct Scsi_Host *)devid; - ORC_HCS *pHcb = (ORC_HCS *)host->hostdata; - unsigned long flags; - - spin_lock_irqsave(host->host_lock, flags); - orc_interrupt(pHcb); - spin_unlock_irqrestore(host->host_lock, flags); - - return IRQ_HANDLED; -} - -static struct scsi_host_template inia100_template = { - .proc_name = "inia100", - .name = inia100_REVID, - .queuecommand = inia100_queue, - .eh_abort_handler = inia100_abort, - .eh_bus_reset_handler = inia100_bus_reset, - .eh_device_reset_handler = inia100_device_reset, - .can_queue = 1, - .this_id = 1, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, - .use_clustering = ENABLE_CLUSTERING, -}; - -static int __devinit inia100_probe_one(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct Scsi_Host *shost; - ORC_HCS *pHCB; - unsigned long port, bios; - int error = -ENODEV; - u32 sz; - unsigned long dBiosAdr; - char *pbBiosAdr; - - if (pci_enable_device(pdev)) - goto out; - if (pci_set_dma_mask(pdev, 0xffffffffULL)) { - printk(KERN_WARNING "Unable to set 32bit DMA " - "on inia100 adapter, ignoring.\n"); - goto out_disable_device; - } - - pci_set_master(pdev); - - port = pci_resource_start(pdev, 0); - if (!request_region(port, 256, "inia100")) { - printk(KERN_WARNING "inia100: io port 0x%lx, is busy.\n", port); - goto out_disable_device; - } - - /* <02> read from base address + 0x50 offset to get the bios balue. */ - bios = ORC_RDWORD(port, 0x50); - - - shost = scsi_host_alloc(&inia100_template, sizeof(ORC_HCS)); - if (!shost) - goto out_release_region; - - pHCB = (ORC_HCS *)shost->hostdata; - pHCB->pdev = pdev; - pHCB->HCS_Base = port; - pHCB->HCS_BIOS = bios; - pHCB->BitAllocFlagLock = SPIN_LOCK_UNLOCKED; - - /* Get total memory needed for SCB */ - sz = ORC_MAXQUEUE * sizeof(ORC_SCB); - pHCB->HCS_virScbArray = pci_alloc_consistent(pdev, sz, - &pHCB->HCS_physScbArray); - if (!pHCB->HCS_virScbArray) { - printk("inia100: SCB memory allocation error\n"); - goto out_host_put; - } - memset(pHCB->HCS_virScbArray, 0, sz); - - /* Get total memory needed for ESCB */ - sz = ORC_MAXQUEUE * sizeof(ESCB); - pHCB->HCS_virEscbArray = pci_alloc_consistent(pdev, sz, - &pHCB->HCS_physEscbArray); - if (!pHCB->HCS_virEscbArray) { - printk("inia100: ESCB memory allocation error\n"); - goto out_free_scb_array; - } - memset(pHCB->HCS_virEscbArray, 0, sz); - - dBiosAdr = pHCB->HCS_BIOS; - dBiosAdr = (dBiosAdr << 4); - pbBiosAdr = phys_to_virt(dBiosAdr); - if (init_orchid(pHCB)) { /* Initialize orchid chip */ - printk("inia100: initial orchid fail!!\n"); - goto out_free_escb_array; - } - - shost->io_port = pHCB->HCS_Base; - shost->n_io_port = 0xff; - shost->can_queue = ORC_MAXQUEUE; - shost->unique_id = shost->io_port; - shost->max_id = pHCB->HCS_MaxTar; - shost->max_lun = 16; - shost->irq = pHCB->HCS_Intr = pdev->irq; - shost->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ - shost->sg_tablesize = TOTAL_SG_ENTRY; - - /* Initial orc chip */ - error = request_irq(pdev->irq, inia100_intr, SA_SHIRQ, - "inia100", shost); - if (error < 0) { - printk(KERN_WARNING "inia100: unable to get irq %d\n", - pdev->irq); - goto out_free_escb_array; - } - - pci_set_drvdata(pdev, shost); - - error = scsi_add_host(shost, &pdev->dev); - if (error) - goto out_free_irq; - - scsi_scan_host(shost); - return 0; - - out_free_irq: - free_irq(shost->irq, shost); - out_free_escb_array: - pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB), - pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray); - out_free_scb_array: - pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB), - pHCB->HCS_virScbArray, pHCB->HCS_physScbArray); - out_host_put: - scsi_host_put(shost); - out_release_region: - release_region(port, 256); - out_disable_device: - pci_disable_device(pdev); - out: - return error; -} - -static void __devexit inia100_remove_one(struct pci_dev *pdev) -{ - struct Scsi_Host *shost = pci_get_drvdata(pdev); - ORC_HCS *pHCB = (ORC_HCS *)shost->hostdata; - - scsi_remove_host(shost); - - free_irq(shost->irq, shost); - pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB), - pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray); - pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB), - pHCB->HCS_virScbArray, pHCB->HCS_physScbArray); - release_region(shost->io_port, 256); - - scsi_host_put(shost); -} - -static struct pci_device_id inia100_pci_tbl[] = { - {PCI_VENDOR_ID_INIT, 0x1060, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} -}; -MODULE_DEVICE_TABLE(pci, inia100_pci_tbl); - -static struct pci_driver inia100_pci_driver = { - .name = "inia100", - .id_table = inia100_pci_tbl, - .probe = inia100_probe_one, - .remove = __devexit_p(inia100_remove_one), -}; - -static int __init inia100_init(void) -{ - return pci_module_init(&inia100_pci_driver); -} - -static void __exit inia100_exit(void) -{ - pci_unregister_driver(&inia100_pci_driver); -} - -MODULE_DESCRIPTION("Initio A100U2W SCSI driver"); -MODULE_AUTHOR("Initio Corporation"); -MODULE_LICENSE("Dual BSD/GPL"); - -module_init(inia100_init); -module_exit(inia100_exit); reverted: --- b/drivers/scsi/a100u2w.h 2004-10-01 19:21:43 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,416 +0,0 @@ -/* - * Initio A100 device driver for Linux. - * - * Copyright (c) 1994-1998 Initio Corporation - * All rights reserved. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * -------------------------------------------------------------------------- - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Where this Software is combined with software released under the terms of - * the GNU General Public License ("GPL") and the terms of the GPL would require the - * combined work to also be released under the terms of the GPL, the terms - * and conditions of this License will apply in addition to those of the - * GPL with the exception of any terms or conditions of this License that - * conflict with, or are expressly prohibited by, the GPL. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Revision History: - * 06/18/98 HL, Initial production Version 1.02 - * 12/19/98 bv, Use spinlocks for 2.1.95 and up - * 06/25/02 Doug Ledford - * - This and the i60uscsi.h file are almost identical, - * merged them into a single header used by both .c files. - */ - -#define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02d" - -#define ULONG unsigned long -#define USHORT unsigned short -#define UCHAR unsigned char -#define BYTE unsigned char -#define WORD unsigned short -#define DWORD unsigned long -#define UBYTE unsigned char -#define UWORD unsigned short -#define UDWORD unsigned long -#define U32 u32 - -#if 1 -#define ORC_MAXQUEUE 245 -#define ORC_MAXTAGS 64 -#else -#define ORC_MAXQUEUE 25 -#define ORC_MAXTAGS 8 -#endif - -#define TOTAL_SG_ENTRY 32 -#define MAX_TARGETS 16 -#define IMAX_CDB 15 -#define SENSE_SIZE 14 - -/************************************************************************/ -/* Scatter-Gather Element Structure */ -/************************************************************************/ -typedef struct ORC_SG_Struc { - U32 SG_Ptr; /* Data Pointer */ - U32 SG_Len; /* Data Length */ -} ORC_SG; - -/* SCSI related definition */ -#define DISC_NOT_ALLOW 0x80 /* Disconnect is not allowed */ -#define DISC_ALLOW 0xC0 /* Disconnect is allowed */ - - -#define ORC_OFFSET_SCB 16 -#define ORC_MAX_SCBS 250 -#define MAX_CHANNELS 2 -#define MAX_ESCB_ELE 64 -#define TCF_DRV_255_63 0x0400 - -/********************************************************/ -/* Orchid Host Command Set */ -/********************************************************/ -#define ORC_CMD_NOP 0x00 /* Host command - NOP */ -#define ORC_CMD_VERSION 0x01 /* Host command - Get F/W version */ -#define ORC_CMD_ECHO 0x02 /* Host command - ECHO */ -#define ORC_CMD_SET_NVM 0x03 /* Host command - Set NVRAM */ -#define ORC_CMD_GET_NVM 0x04 /* Host command - Get NVRAM */ -#define ORC_CMD_GET_BUS_STATUS 0x05 /* Host command - Get SCSI bus status */ -#define ORC_CMD_ABORT_SCB 0x06 /* Host command - Abort SCB */ -#define ORC_CMD_ISSUE_SCB 0x07 /* Host command - Issue SCB */ - -/********************************************************/ -/* Orchid Register Set */ -/********************************************************/ -#define ORC_GINTS 0xA0 /* Global Interrupt Status */ -#define QINT 0x04 /* Reply Queue Interrupt */ -#define ORC_GIMSK 0xA1 /* Global Interrupt MASK */ -#define MQINT 0x04 /* Mask Reply Queue Interrupt */ -#define ORC_GCFG 0xA2 /* Global Configure */ -#define EEPRG 0x01 /* Enable EEPROM programming */ -#define ORC_GSTAT 0xA3 /* Global status */ -#define WIDEBUS 0x10 /* Wide SCSI Devices connected */ -#define ORC_HDATA 0xA4 /* Host Data */ -#define ORC_HCTRL 0xA5 /* Host Control */ -#define SCSIRST 0x80 /* SCSI bus reset */ -#define HDO 0x40 /* Host data out */ -#define HOSTSTOP 0x02 /* Host stop RISC engine */ -#define DEVRST 0x01 /* Device reset */ -#define ORC_HSTUS 0xA6 /* Host Status */ -#define HDI 0x02 /* Host data in */ -#define RREADY 0x01 /* RISC engine is ready to receive */ -#define ORC_NVRAM 0xA7 /* Nvram port address */ -#define SE2CS 0x008 -#define SE2CLK 0x004 -#define SE2DO 0x002 -#define SE2DI 0x001 -#define ORC_PQUEUE 0xA8 /* Posting queue FIFO */ -#define ORC_PQCNT 0xA9 /* Posting queue FIFO Cnt */ -#define ORC_RQUEUE 0xAA /* Reply queue FIFO */ -#define ORC_RQUEUECNT 0xAB /* Reply queue FIFO Cnt */ -#define ORC_FWBASEADR 0xAC /* Firmware base address */ - -#define ORC_EBIOSADR0 0xB0 /* External Bios address */ -#define ORC_EBIOSADR1 0xB1 /* External Bios address */ -#define ORC_EBIOSADR2 0xB2 /* External Bios address */ -#define ORC_EBIOSDATA 0xB3 /* External Bios address */ - -#define ORC_SCBSIZE 0xB7 /* SCB size register */ -#define ORC_SCBBASE0 0xB8 /* SCB base address 0 */ -#define ORC_SCBBASE1 0xBC /* SCB base address 1 */ - -#define ORC_RISCCTL 0xE0 /* RISC Control */ -#define PRGMRST 0x002 -#define DOWNLOAD 0x001 -#define ORC_PRGMCTR0 0xE2 /* RISC program counter */ -#define ORC_PRGMCTR1 0xE3 /* RISC program counter */ -#define ORC_RISCRAM 0xEC /* RISC RAM data port 4 bytes */ - -typedef struct orc_extended_scb { /* Extended SCB */ - ORC_SG ESCB_SGList[TOTAL_SG_ENTRY]; /*0 Start of SG list */ - struct scsi_cmnd *SCB_Srb; /*50 SRB Pointer */ -} ESCB; - -/*********************************************************************** - SCSI Control Block -************************************************************************/ -typedef struct orc_scb { /* Scsi_Ctrl_Blk */ - UBYTE SCB_Opcode; /*00 SCB command code&residual */ - UBYTE SCB_Flags; /*01 SCB Flags */ - UBYTE SCB_Target; /*02 Target Id */ - UBYTE SCB_Lun; /*03 Lun */ - U32 SCB_Reserved0; /*04 Reserved for ORCHID must 0 */ - U32 SCB_XferLen; /*08 Data Transfer Length */ - U32 SCB_Reserved1; /*0C Reserved for ORCHID must 0 */ - U32 SCB_SGLen; /*10 SG list # * 8 */ - U32 SCB_SGPAddr; /*14 SG List Buf physical Addr */ - U32 SCB_SGPAddrHigh; /*18 SG Buffer high physical Addr */ - UBYTE SCB_HaStat; /*1C Host Status */ - UBYTE SCB_TaStat; /*1D Target Status */ - UBYTE SCB_Status; /*1E SCB status */ - UBYTE SCB_Link; /*1F Link pointer, default 0xFF */ - UBYTE SCB_SenseLen; /*20 Sense Allocation Length */ - UBYTE SCB_CDBLen; /*21 CDB Length */ - UBYTE SCB_Ident; /*22 Identify */ - UBYTE SCB_TagMsg; /*23 Tag Message */ - UBYTE SCB_CDB[IMAX_CDB]; /*24 SCSI CDBs */ - UBYTE SCB_ScbIdx; /*3C Index for this ORCSCB */ - U32 SCB_SensePAddr; /*34 Sense Buffer physical Addr */ - - ESCB *SCB_EScb; /*38 Extended SCB Pointer */ -#ifndef ALPHA - UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use */ -#endif -} ORC_SCB; - -/* Opcodes of ORCSCB_Opcode */ -#define ORC_EXECSCSI 0x00 /* SCSI initiator command with residual */ -#define ORC_BUSDEVRST 0x01 /* SCSI Bus Device Reset */ - -/* Status of ORCSCB_Status */ -#define ORCSCB_COMPLETE 0x00 /* SCB request completed */ -#define ORCSCB_POST 0x01 /* SCB is posted by the HOST */ - -/* Bit Definition for ORCSCB_Flags */ -#define SCF_DISINT 0x01 /* Disable HOST interrupt */ -#define SCF_DIR 0x18 /* Direction bits */ -#define SCF_NO_DCHK 0x00 /* Direction determined by SCSI */ -#define SCF_DIN 0x08 /* From Target to Initiator */ -#define SCF_DOUT 0x10 /* From Initiator to Target */ -#define SCF_NO_XF 0x18 /* No data transfer */ -#define SCF_POLL 0x40 - -/* Error Codes for ORCSCB_HaStat */ -#define HOST_SEL_TOUT 0x11 -#define HOST_DO_DU 0x12 -#define HOST_BUS_FREE 0x13 -#define HOST_BAD_PHAS 0x14 -#define HOST_INV_CMD 0x16 -#define HOST_SCSI_RST 0x1B -#define HOST_DEV_RST 0x1C - - -/* Error Codes for ORCSCB_TaStat */ -#define TARGET_CHK_COND 0x02 -#define TARGET_BUSY 0x08 -#define TARGET_TAG_FULL 0x28 - - -/*********************************************************************** - Target Device Control Structure -**********************************************************************/ - -typedef struct ORC_Tar_Ctrl_Struc { - UBYTE TCS_DrvDASD; /* 6 */ - UBYTE TCS_DrvSCSI; /* 7 */ - UBYTE TCS_DrvHead; /* 8 */ - UWORD TCS_DrvFlags; /* 4 */ - UBYTE TCS_DrvSector; /* 7 */ -} ORC_TCS; - -/* Bit Definition for TCF_DrvFlags */ -#define TCS_DF_NODASD_SUPT 0x20 /* Suppress OS/2 DASD Mgr support */ -#define TCS_DF_NOSCSI_SUPT 0x40 /* Suppress OS/2 SCSI Mgr support */ - - -/*********************************************************************** - Host Adapter Control Structure -************************************************************************/ -typedef struct ORC_Ha_Ctrl_Struc { - USHORT HCS_Base; /* 00 */ - UBYTE HCS_Index; /* 02 */ - UBYTE HCS_Intr; /* 04 */ - UBYTE HCS_SCSI_ID; /* 06 H/A SCSI ID */ - UBYTE HCS_BIOS; /* 07 BIOS configuration */ - - UBYTE HCS_Flags; /* 0B */ - UBYTE HCS_HAConfig1; /* 1B SCSI0MAXTags */ - UBYTE HCS_MaxTar; /* 1B SCSI0MAXTags */ - - USHORT HCS_Units; /* Number of units this adapter */ - USHORT HCS_AFlags; /* Adapter info. defined flags */ - ULONG HCS_Timeout; /* Adapter timeout value */ - ORC_SCB *HCS_virScbArray; /* 28 Virtual Pointer to SCB array */ - dma_addr_t HCS_physScbArray; /* Scb Physical address */ - ESCB *HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */ - dma_addr_t HCS_physEscbArray; /* scatter list Physical address */ - UBYTE TargetFlag[16]; /* 30 target configuration, TCF_EN_TAG */ - UBYTE MaximumTags[16]; /* 40 ORC_MAX_SCBS */ - UBYTE ActiveTags[16][16]; /* 50 */ - ORC_TCS HCS_Tcs[16]; /* 28 */ - U32 BitAllocFlag[MAX_CHANNELS][8]; /* Max STB is 256, So 256/32 */ - spinlock_t BitAllocFlagLock; - struct pci_dev *pdev; -} ORC_HCS; - -/* Bit Definition for HCS_Flags */ - -#define HCF_SCSI_RESET 0x01 /* SCSI BUS RESET */ -#define HCF_PARITY 0x02 /* parity card */ -#define HCF_LVDS 0x10 /* parity card */ - -/* Bit Definition for TargetFlag */ - -#define TCF_EN_255 0x08 -#define TCF_EN_TAG 0x10 -#define TCF_BUSY 0x20 -#define TCF_DISCONNECT 0x40 -#define TCF_SPIN_UP 0x80 - -/* Bit Definition for HCS_AFlags */ -#define HCS_AF_IGNORE 0x01 /* Adapter ignore */ -#define HCS_AF_DISABLE_RESET 0x10 /* Adapter disable reset */ -#define HCS_AF_DISABLE_ADPT 0x80 /* Adapter disable */ - -typedef struct _NVRAM { -/*----------header ---------------*/ - UCHAR SubVendorID0; /* 00 - Sub Vendor ID */ - UCHAR SubVendorID1; /* 00 - Sub Vendor ID */ - UCHAR SubSysID0; /* 02 - Sub System ID */ - UCHAR SubSysID1; /* 02 - Sub System ID */ - UCHAR SubClass; /* 04 - Sub Class */ - UCHAR VendorID0; /* 05 - Vendor ID */ - UCHAR VendorID1; /* 05 - Vendor ID */ - UCHAR DeviceID0; /* 07 - Device ID */ - UCHAR DeviceID1; /* 07 - Device ID */ - UCHAR Reserved0[2]; /* 09 - Reserved */ - UCHAR Revision; /* 0B - Revision of data structure */ - /* ----Host Adapter Structure ---- */ - UCHAR NumOfCh; /* 0C - Number of SCSI channel */ - UCHAR BIOSConfig1; /* 0D - BIOS configuration 1 */ - UCHAR BIOSConfig2; /* 0E - BIOS boot channel&target ID */ - UCHAR BIOSConfig3; /* 0F - BIOS configuration 3 */ - /* ----SCSI channel Structure ---- */ - /* from "CTRL-I SCSI Host Adapter SetUp menu " */ - UCHAR SCSI0Id; /* 10 - Channel 0 SCSI ID */ - UCHAR SCSI0Config; /* 11 - Channel 0 SCSI configuration */ - UCHAR SCSI0MaxTags; /* 12 - Channel 0 Maximum tags */ - UCHAR SCSI0ResetTime; /* 13 - Channel 0 Reset recovering time */ - UCHAR ReservedforChannel0[2]; /* 14 - Reserved */ - - /* ----SCSI target Structure ---- */ - /* from "CTRL-I SCSI device SetUp menu " */ - UCHAR Target00Config; /* 16 - Channel 0 Target 0 config */ - UCHAR Target01Config; /* 17 - Channel 0 Target 1 config */ - UCHAR Target02Config; /* 18 - Channel 0 Target 2 config */ - UCHAR Target03Config; /* 19 - Channel 0 Target 3 config */ - UCHAR Target04Config; /* 1A - Channel 0 Target 4 config */ - UCHAR Target05Config; /* 1B - Channel 0 Target 5 config */ - UCHAR Target06Config; /* 1C - Channel 0 Target 6 config */ - UCHAR Target07Config; /* 1D - Channel 0 Target 7 config */ - UCHAR Target08Config; /* 1E - Channel 0 Target 8 config */ - UCHAR Target09Config; /* 1F - Channel 0 Target 9 config */ - UCHAR Target0AConfig; /* 20 - Channel 0 Target A config */ - UCHAR Target0BConfig; /* 21 - Channel 0 Target B config */ - UCHAR Target0CConfig; /* 22 - Channel 0 Target C config */ - UCHAR Target0DConfig; /* 23 - Channel 0 Target D config */ - UCHAR Target0EConfig; /* 24 - Channel 0 Target E config */ - UCHAR Target0FConfig; /* 25 - Channel 0 Target F config */ - - UCHAR SCSI1Id; /* 26 - Channel 1 SCSI ID */ - UCHAR SCSI1Config; /* 27 - Channel 1 SCSI configuration */ - UCHAR SCSI1MaxTags; /* 28 - Channel 1 Maximum tags */ - UCHAR SCSI1ResetTime; /* 29 - Channel 1 Reset recovering time */ - UCHAR ReservedforChannel1[2]; /* 2A - Reserved */ - - /* ----SCSI target Structure ---- */ - /* from "CTRL-I SCSI device SetUp menu " */ - UCHAR Target10Config; /* 2C - Channel 1 Target 0 config */ - UCHAR Target11Config; /* 2D - Channel 1 Target 1 config */ - UCHAR Target12Config; /* 2E - Channel 1 Target 2 config */ - UCHAR Target13Config; /* 2F - Channel 1 Target 3 config */ - UCHAR Target14Config; /* 30 - Channel 1 Target 4 config */ - UCHAR Target15Config; /* 31 - Channel 1 Target 5 config */ - UCHAR Target16Config; /* 32 - Channel 1 Target 6 config */ - UCHAR Target17Config; /* 33 - Channel 1 Target 7 config */ - UCHAR Target18Config; /* 34 - Channel 1 Target 8 config */ - UCHAR Target19Config; /* 35 - Channel 1 Target 9 config */ - UCHAR Target1AConfig; /* 36 - Channel 1 Target A config */ - UCHAR Target1BConfig; /* 37 - Channel 1 Target B config */ - UCHAR Target1CConfig; /* 38 - Channel 1 Target C config */ - UCHAR Target1DConfig; /* 39 - Channel 1 Target D config */ - UCHAR Target1EConfig; /* 3A - Channel 1 Target E config */ - UCHAR Target1FConfig; /* 3B - Channel 1 Target F config */ - UCHAR reserved[3]; /* 3C - Reserved */ - /* ---------- CheckSum ---------- */ - UCHAR CheckSum; /* 3F - Checksum of NVRam */ -} NVRAM, *PNVRAM; - -/* Bios Configuration for nvram->BIOSConfig1 */ -#define NBC_BIOSENABLE 0x01 /* BIOS enable */ -#define NBC_CDROM 0x02 /* Support bootable CDROM */ -#define NBC_REMOVABLE 0x04 /* Support removable drive */ - -/* Bios Configuration for nvram->BIOSConfig2 */ -#define NBB_TARGET_MASK 0x0F /* Boot SCSI target ID number */ -#define NBB_CHANL_MASK 0xF0 /* Boot SCSI channel number */ - -/* Bit definition for nvram->SCSIConfig */ -#define NCC_BUSRESET 0x01 /* Reset SCSI bus at power up */ -#define NCC_PARITYCHK 0x02 /* SCSI parity enable */ -#define NCC_LVDS 0x10 /* Enable LVDS */ -#define NCC_ACTTERM1 0x20 /* Enable active terminator 1 */ -#define NCC_ACTTERM2 0x40 /* Enable active terminator 2 */ -#define NCC_AUTOTERM 0x80 /* Enable auto termination */ - -/* Bit definition for nvram->TargetxConfig */ -#define NTC_PERIOD 0x07 /* Maximum Sync. Speed */ -#define NTC_1GIGA 0x08 /* 255 head / 63 sectors (64/32) */ -#define NTC_NO_SYNC 0x10 /* NO SYNC. NEGO */ -#define NTC_NO_WIDESYNC 0x20 /* NO WIDE SYNC. NEGO */ -#define NTC_DISC_ENABLE 0x40 /* Enable SCSI disconnect */ -#define NTC_SPINUP 0x80 /* Start disk drive */ - -/* Default NVRam values */ -#define NBC_DEFAULT (NBC_ENABLE) -#define NCC_DEFAULT (NCC_BUSRESET | NCC_AUTOTERM | NCC_PARITYCHK) -#define NCC_MAX_TAGS 0x20 /* Maximum tags per target */ -#define NCC_RESET_TIME 0x0A /* SCSI RESET recovering time */ -#define NTC_DEFAULT (NTC_1GIGA | NTC_NO_WIDESYNC | NTC_DISC_ENABLE) - -#define ORC_RD(x,y) (UCHAR)(inb( (int)((ULONG)((ULONG)x+(UCHAR)y)) )) -#define ORC_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) -#define ORC_RDLONG(x,y) (long)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) - -#define ORC_WR( adr,data) outb( (UCHAR)(data), (int)(adr)) -#define ORC_WRSHORT(adr,data) outw( (UWORD)(data), (int)(adr)) -#define ORC_WRLONG( adr,data) outl( (ULONG)(data), (int)(adr)) reverted: --- b/drivers/scsi/aacraid/aachba.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aacraid/aachba.c 2004-10-01 19:21:44 -07:00 @@ -131,10 +131,47 @@ u8 inqd_prl[4]; /* Product Revision Level */ }; +struct sense_data { + u8 error_code; /* 70h (current errors), 71h(deferred errors) */ + u8 valid:1; /* A valid bit of one indicates that the information */ + /* field contains valid information as defined in the + * SCSI-2 Standard. + */ + u8 segment_number; /* Only used for COPY, COMPARE, or COPY AND VERIFY Commands */ + u8 sense_key:4; /* Sense Key */ + u8 reserved:1; + u8 ILI:1; /* Incorrect Length Indicator */ + u8 EOM:1; /* End Of Medium - reserved for random access devices */ + u8 filemark:1; /* Filemark - reserved for random access devices */ + + u8 information[4]; /* for direct-access devices, contains the unsigned + * logical block address or residue associated with + * the sense key + */ + u8 add_sense_len; /* number of additional sense bytes to follow this field */ + u8 cmnd_info[4]; /* not used */ + u8 ASC; /* Additional Sense Code */ + u8 ASCQ; /* Additional Sense Code Qualifier */ + u8 FRUC; /* Field Replaceable Unit Code - not used */ + u8 bit_ptr:3; /* indicates which byte of the CDB or parameter data + * was in error + */ + u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that + * the bit_ptr field has valid value + */ + u8 reserved2:2; + u8 CD:1; /* command data bit: 1- illegal parameter in CDB. + * 0- illegal parameter in data. + */ + u8 SKSV:1; + u8 field_ptr[2]; /* byte of the CDB or parameter data in error */ +}; + /* * M O D U L E G L O B A L S */ +static struct sense_data sense_data[MAXIMUM_NUM_CONTAINERS]; static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* sgmap); static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* psg); static int aac_send_srb_fib(struct scsi_cmnd* scsicmd); @@ -156,80 +193,6 @@ static int nondasd = -1; static int dacmode = -1; -static int commit = -1; - -/** - * aac_get_config_status - check the adapter configuration - * @common: adapter to query - * - * Query config status, and commit the configuration if needed. - */ -int aac_get_config_status(struct aac_dev *dev) -{ - int status = 0; - struct fib * fibptr; - - if (!(fibptr = fib_alloc(dev))) - return -ENOMEM; - - fib_init(fibptr); - { - struct aac_get_config_status *dinfo; - dinfo = (struct aac_get_config_status *) fib_data(fibptr); - - dinfo->command = cpu_to_le32(VM_ContainerConfig); - dinfo->type = cpu_to_le32(CT_GET_CONFIG_STATUS); - dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data)); - } - - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_get_config_status), - FsaNormal, - 1, 1, - NULL, NULL); - if (status < 0 ) { - printk(KERN_WARNING "aac_get_config_status: SendFIB failed.\n"); - } else { - struct aac_get_config_status_resp *reply - = (struct aac_get_config_status_resp *) fib_data(fibptr); - dprintk((KERN_WARNING - "aac_get_config_status: response=%d status=%d action=%d\n", - reply->response, reply->status, reply->data.action)); - if ((reply->response != ST_OK) - || (reply->status != CT_OK) - || (reply->data.action > CFACT_PAUSE)) { - printk(KERN_WARNING "aac_get_config_status: Will not issue the Commit Configuration\n"); - status = -EINVAL; - } - } - fib_complete(fibptr); - /* Send a CT_COMMIT_CONFIG to enable discovery of devices */ - if (status >= 0) { - if (commit == 1) { - struct aac_commit_config * dinfo; - fib_init(fibptr); - dinfo = (struct aac_commit_config *) fib_data(fibptr); - - dinfo->command = cpu_to_le32(VM_ContainerConfig); - dinfo->type = cpu_to_le32(CT_COMMIT_CONFIG); - - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_commit_config), - FsaNormal, - 1, 1, - NULL, NULL); - fib_complete(fibptr); - } else if (commit == 0) { - printk(KERN_WARNING - "aac_get_config_status: Foreign device configurations are being ignored\n"); - } - } - fib_free(fibptr); - return status; -} - /** * aac_get_containers - list containers * @common: adapter to probe @@ -238,57 +201,21 @@ */ int aac_get_containers(struct aac_dev *dev) { + struct fsa_scsi_hba *fsa_dev_ptr; - struct fsa_dev_info *fsa_dev_ptr; u32 index; int status = 0; + struct aac_query_mount *dinfo; + struct aac_mount *dresp; struct fib * fibptr; unsigned instance; - struct aac_get_container_count *dinfo; - struct aac_get_container_count_resp *dresp; - int maximum_num_containers = MAXIMUM_NUM_CONTAINERS; + fsa_dev_ptr = &(dev->fsa_dev); instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) return -ENOMEM; + for (index = 0; index < MAXIMUM_NUM_CONTAINERS; index++) { - fib_init(fibptr); - dinfo = (struct aac_get_container_count *) fib_data(fibptr); - dinfo->command = cpu_to_le32(VM_ContainerConfig); - dinfo->type = cpu_to_le32(CT_GET_CONTAINER_COUNT); - - status = fib_send(ContainerCommand, - fibptr, - sizeof (struct aac_get_container_count), - FsaNormal, - 1, 1, - NULL, NULL); - if (status >= 0) { - dresp = (struct aac_get_container_count_resp *)fib_data(fibptr); - maximum_num_containers = dresp->ContainerSwitchEntries; - fib_complete(fibptr); - } - - if (maximum_num_containers < MAXIMUM_NUM_CONTAINERS) - maximum_num_containers = MAXIMUM_NUM_CONTAINERS; - - fsa_dev_ptr = (struct fsa_dev_info *) kmalloc( - sizeof(*fsa_dev_ptr) * maximum_num_containers, GFP_KERNEL); - if (!fsa_dev_ptr) { - fib_free(fibptr); - return -ENOMEM; - } - memset(fsa_dev_ptr, 0, sizeof(*fsa_dev_ptr) * maximum_num_containers); - - dev->fsa_dev = fsa_dev_ptr; - dev->maximum_num_containers = maximum_num_containers; - - for (index = 0; index < dev->maximum_num_containers; index++) { - struct aac_query_mount *dinfo; - struct aac_mount *dresp; - - fsa_dev_ptr[index].devname[0] = '\0'; - fib_init(fibptr); dinfo = (struct aac_query_mount *) fib_data(fibptr); @@ -308,20 +235,14 @@ } dresp = (struct aac_mount *)fib_data(fibptr); - dprintk ((KERN_DEBUG - "VM_NameServe cid=%d status=%d vol=%d state=%d cap=%u\n", - (int)index, (int)le32_to_cpu(dresp->status), - (int)le32_to_cpu(dresp->mnt[0].vol), - (int)le32_to_cpu(dresp->mnt[0].state), - (unsigned)le32_to_cpu(dresp->mnt[0].capacity))); if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr->valid[index] = 1; + fsa_dev_ptr->type[index] = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr->size[index] = le32_to_cpu(dresp->mnt[0].capacity); - fsa_dev_ptr[index].valid = 1; - fsa_dev_ptr[index].type = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr[index].size = le32_to_cpu(dresp->mnt[0].capacity); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr->ro[index] = 1; - fsa_dev_ptr[index].ro = 1; } fib_complete(fibptr); /* @@ -341,19 +262,19 @@ * @cid: container identifier * * Queries the controller about the given volume. The volume information + * is updated in the struct fsa_scsi_hba structure rather than returned. - * is updated in the struct fsa_dev_info structure rather than returned. */ static int probe_container(struct aac_dev *dev, int cid) { + struct fsa_scsi_hba *fsa_dev_ptr; - struct fsa_dev_info *fsa_dev_ptr; int status; struct aac_query_mount *dinfo; struct aac_mount *dresp; struct fib * fibptr; unsigned instance; + fsa_dev_ptr = &(dev->fsa_dev); - fsa_dev_ptr = dev->fsa_dev; instance = dev->scsi_host_ptr->unique_id; if (!(fibptr = fib_alloc(dev))) @@ -383,11 +304,11 @@ if ((le32_to_cpu(dresp->status) == ST_OK) && (le32_to_cpu(dresp->mnt[0].vol) != CT_NONE) && (le32_to_cpu(dresp->mnt[0].state) != FSCS_HIDDEN)) { + fsa_dev_ptr->valid[cid] = 1; + fsa_dev_ptr->type[cid] = le32_to_cpu(dresp->mnt[0].vol); + fsa_dev_ptr->size[cid] = le32_to_cpu(dresp->mnt[0].capacity); - fsa_dev_ptr[cid].valid = 1; - fsa_dev_ptr[cid].type = le32_to_cpu(dresp->mnt[0].vol); - fsa_dev_ptr[cid].size = le32_to_cpu(dresp->mnt[0].capacity); if (le32_to_cpu(dresp->mnt[0].state) & FSCS_READONLY) + fsa_dev_ptr->ro[cid] = 1; - fsa_dev_ptr[cid].ro = 1; } error: @@ -650,15 +571,12 @@ else { printk(KERN_WARNING "read_callback: read failed, status = %d\n", readreply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &sense_data[cid], - set_sense((u8 *) &dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); + memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data)); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) - ? sizeof(scsicmd->sense_buffer) - : sizeof(dev->fsa_dev[cid].sense_data)); } fib_complete(fibptr); fib_free(fibptr); @@ -699,13 +617,12 @@ else { printk(KERN_WARNING "write_callback: write failed, status = %d\n", writereply->status); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &sense_data[cid], - set_sense((u8 *) &dev->fsa_dev[cid].sense_data, HARDWARE_ERROR, SENCODE_INTERNAL_TARGET_FAILURE, ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0, 0, 0); + memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data)); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - sizeof(struct sense_data)); } fib_complete(fibptr); @@ -947,11 +864,11 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd) { u32 cid = 0; + int ret; struct Scsi_Host *host = scsicmd->device->host; struct aac_dev *dev = (struct aac_dev *)host->hostdata; + struct fsa_scsi_hba *fsa_dev_ptr = &dev->fsa_dev; - struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev; int cardtype = dev->cardtype; - int ret; /* * If the bus, id or lun is out of range, return fail @@ -960,7 +877,7 @@ */ if (scsicmd->device->id != host->this_id) { if ((scsicmd->device->channel == 0) ){ + if( (scsicmd->device->id >= MAXIMUM_NUM_CONTAINERS) || (scsicmd->device->lun != 0)){ - if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ scsicmd->result = DID_NO_CONNECT << 16; __aac_io_done(scsicmd); return 0; @@ -971,7 +888,7 @@ * If the target container doesn't exist, it may have * been newly created */ + if (fsa_dev_ptr->valid[cid] == 0) { - if ((fsa_dev_ptr[cid].valid & 1) == 0) { switch (scsicmd->cmnd[0]) { case INQUIRY: case READ_CAPACITY: @@ -979,7 +896,7 @@ spin_unlock_irq(host->host_lock); probe_container(dev, cid); spin_lock_irq(host->host_lock); + if (fsa_dev_ptr->valid[cid] == 0) { - if (fsa_dev_ptr[cid].valid == 0) { scsicmd->result = DID_NO_CONNECT << 16; __aac_io_done(scsicmd); return 0; @@ -992,7 +909,7 @@ * If the target container still doesn't exist, * return failure */ + if (fsa_dev_ptr->valid[cid] == 0) { - if (fsa_dev_ptr[cid].valid == 0) { scsicmd->result = DID_BAD_TARGET << 16; __aac_io_done(scsicmd); return 0; @@ -1015,15 +932,12 @@ { dprintk((KERN_WARNING "Only INQUIRY & TUR command supported for controller, rcvd = 0x%x.\n", scsicmd->cmnd[0])); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &sense_data[cid], - set_sense((u8 *) &dev->fsa_dev[cid].sense_data, ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND, ASENCODE_INVALID_COMMAND, 0, 0, 0, 0); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) - ? sizeof(scsicmd->sense_buffer) - : sizeof(dev->fsa_dev[cid].sense_data)); __aac_io_done(scsicmd); + memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof(struct sense_data)); return 0; } @@ -1048,7 +962,7 @@ * Set the Vendor, Product, and Revision Level * see: .c i.e. aac.c */ + setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr->type[cid]); - setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type); if (scsicmd->device->id == host->this_id) inq_data_ptr->inqd_pdt = INQD_PDT_PROC; /* Processor device */ else @@ -1059,14 +973,11 @@ } case READ_CAPACITY: { + int capacity; - u32 capacity; char *cp; dprintk((KERN_DEBUG "READ CAPACITY command.\n")); + capacity = fsa_dev_ptr->size[cid] - 1; - if (fsa_dev_ptr[cid].size <= 0x100000000) - capacity = fsa_dev_ptr[cid].size - 1; - else - capacity = (u32)-1; cp = scsicmd->request_buffer; cp[0] = (capacity >> 24) & 0xff; cp[1] = (capacity >> 16) & 0xff; @@ -1121,8 +1032,8 @@ } case REQUEST_SENSE: dprintk((KERN_DEBUG "REQUEST SENSE command.\n")); + memcpy(scsicmd->sense_buffer, &sense_data[cid], sizeof (struct sense_data)); + memset(&sense_data[cid], 0, sizeof (struct sense_data)); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, sizeof (struct sense_data)); - memset(&dev->fsa_dev[cid].sense_data, 0, sizeof (struct sense_data)); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; __aac_io_done(scsicmd); return 0; @@ -1130,9 +1041,9 @@ case ALLOW_MEDIUM_REMOVAL: dprintk((KERN_DEBUG "LOCK command.\n")); if (scsicmd->cmnd[4]) + fsa_dev_ptr->locked[cid] = 1; - fsa_dev_ptr[cid].locked = 1; else + fsa_dev_ptr->locked[cid] = 0; - fsa_dev_ptr[cid].locked = 0; scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; __aac_io_done(scsicmd); @@ -1164,7 +1075,7 @@ spin_unlock_irq(host->host_lock); if (scsicmd->request->rq_disk) + memcpy(fsa_dev_ptr->devname[cid], - memcpy(fsa_dev_ptr[cid].devname, scsicmd->request->rq_disk->disk_name, 8); @@ -1184,13 +1095,11 @@ */ printk(KERN_WARNING "Unhandled SCSI Command: 0x%x.\n", scsicmd->cmnd[0]); scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION; + set_sense((u8 *) &sense_data[cid], - set_sense((u8 *) &dev->fsa_dev[cid].sense_data, ILLEGAL_REQUEST, SENCODE_INVALID_COMMAND, + ASENCODE_INVALID_COMMAND, 0, 0, 0, 0); + memcpy(scsicmd->sense_buffer, &sense_data[cid], + sizeof(struct sense_data)); - ASENCODE_INVALID_COMMAND, 0, 0, 0, 0); - memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data, - (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer)) - ? sizeof(scsicmd->sense_buffer) - : sizeof(dev->fsa_dev[cid].sense_data)); __aac_io_done(scsicmd); return 0; } @@ -1199,16 +1108,16 @@ static int query_disk(struct aac_dev *dev, void __user *arg) { struct aac_query_disk qd; + struct fsa_scsi_hba *fsa_dev_ptr; - struct fsa_dev_info *fsa_dev_ptr; + fsa_dev_ptr = &(dev->fsa_dev); - fsa_dev_ptr = dev->fsa_dev; if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk))) return -EFAULT; if (qd.cnum == -1) qd.cnum = ID_LUN_TO_CONTAINER(qd.id, qd.lun); else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) { + if (qd.cnum < 0 || qd.cnum >= MAXIMUM_NUM_CONTAINERS) - if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers) return -EINVAL; qd.instance = dev->scsi_host_ptr->host_no; qd.bus = 0; @@ -1217,17 +1126,16 @@ } else return -EINVAL; + qd.valid = fsa_dev_ptr->valid[qd.cnum]; + qd.locked = fsa_dev_ptr->locked[qd.cnum]; + qd.deleted = fsa_dev_ptr->deleted[qd.cnum]; - qd.valid = fsa_dev_ptr[qd.cnum].valid; - qd.locked = fsa_dev_ptr[qd.cnum].locked; - qd.deleted = fsa_dev_ptr[qd.cnum].deleted; + if (fsa_dev_ptr->devname[qd.cnum][0] == '\0') - if (fsa_dev_ptr[qd.cnum].devname[0] == '\0') qd.unmapped = 1; else qd.unmapped = 0; + strlcpy(qd.name, fsa_dev_ptr->devname[qd.cnum], sizeof(qd.name)); - strlcpy(qd.name, fsa_dev_ptr[qd.cnum].devname, - min(sizeof(qd.name), sizeof(fsa_dev_ptr[qd.cnum].devname) + 1)); if (copy_to_user(arg, &qd, sizeof (struct aac_query_disk))) return -EFAULT; @@ -1237,49 +1145,49 @@ static int force_delete_disk(struct aac_dev *dev, void __user *arg) { struct aac_delete_disk dd; + struct fsa_scsi_hba *fsa_dev_ptr; - struct fsa_dev_info *fsa_dev_ptr; + fsa_dev_ptr = &(dev->fsa_dev); - fsa_dev_ptr = dev->fsa_dev; if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) return -EFAULT; + if (dd.cnum >= MAXIMUM_NUM_CONTAINERS) - if (dd.cnum >= dev->maximum_num_containers) return -EINVAL; /* * Mark this container as being deleted. */ + fsa_dev_ptr->deleted[dd.cnum] = 1; - fsa_dev_ptr[dd.cnum].deleted = 1; /* * Mark the container as no longer valid */ + fsa_dev_ptr->valid[dd.cnum] = 0; - fsa_dev_ptr[dd.cnum].valid = 0; return 0; } static int delete_disk(struct aac_dev *dev, void __user *arg) { struct aac_delete_disk dd; + struct fsa_scsi_hba *fsa_dev_ptr; - struct fsa_dev_info *fsa_dev_ptr; + fsa_dev_ptr = &(dev->fsa_dev); - fsa_dev_ptr = dev->fsa_dev; if (copy_from_user(&dd, arg, sizeof (struct aac_delete_disk))) return -EFAULT; + if (dd.cnum >= MAXIMUM_NUM_CONTAINERS) - if (dd.cnum >= dev->maximum_num_containers) return -EINVAL; /* * If the container is locked, it can not be deleted by the API. */ + if (fsa_dev_ptr->locked[dd.cnum]) - if (fsa_dev_ptr[dd.cnum].locked) return -EBUSY; else { /* * Mark the container as no longer being valid. */ + fsa_dev_ptr->valid[dd.cnum] = 0; + fsa_dev_ptr->devname[dd.cnum][0] = '\0'; - fsa_dev_ptr[dd.cnum].valid = 0; - fsa_dev_ptr[dd.cnum].devname[0] = '\0'; return 0; } } reverted: --- b/drivers/scsi/aacraid/aacraid.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aacraid/aacraid.h 2004-10-01 19:21:44 -07:00 @@ -7,6 +7,7 @@ *----------------------------------------------------------------------------*/ #define MAXIMUM_NUM_CONTAINERS 32 +#define MAXIMUM_NUM_ADAPTERS 8 #define AAC_NUM_FIB (256 + 64) #define AAC_NUM_IO_FIB 100 @@ -56,7 +57,6 @@ #define CT_VOLUME_OF_MIRRORS 12 /* volume of mirror */ #define CT_PSEUDO_RAID 13 /* really raid4 */ #define CT_LAST_VOLUME_TYPE 14 -#define CT_OK 218 /* * Types of objects addressable in some fashion by the client. @@ -662,53 +662,14 @@ struct list_head fib_list; // this holds fibs and their attachd hw_fibs }; +struct fsa_scsi_hba { + u32 size[MAXIMUM_NUM_CONTAINERS]; + u32 type[MAXIMUM_NUM_CONTAINERS]; + u8 valid[MAXIMUM_NUM_CONTAINERS]; + u8 ro[MAXIMUM_NUM_CONTAINERS]; + u8 locked[MAXIMUM_NUM_CONTAINERS]; + u8 deleted[MAXIMUM_NUM_CONTAINERS]; + char devname[MAXIMUM_NUM_CONTAINERS][8]; -struct sense_data { - u8 error_code; /* 70h (current errors), 71h(deferred errors) */ - u8 valid:1; /* A valid bit of one indicates that the information */ - /* field contains valid information as defined in the - * SCSI-2 Standard. - */ - u8 segment_number; /* Only used for COPY, COMPARE, or COPY AND VERIFY Commands */ - u8 sense_key:4; /* Sense Key */ - u8 reserved:1; - u8 ILI:1; /* Incorrect Length Indicator */ - u8 EOM:1; /* End Of Medium - reserved for random access devices */ - u8 filemark:1; /* Filemark - reserved for random access devices */ - - u8 information[4]; /* for direct-access devices, contains the unsigned - * logical block address or residue associated with - * the sense key - */ - u8 add_sense_len; /* number of additional sense bytes to follow this field */ - u8 cmnd_info[4]; /* not used */ - u8 ASC; /* Additional Sense Code */ - u8 ASCQ; /* Additional Sense Code Qualifier */ - u8 FRUC; /* Field Replaceable Unit Code - not used */ - u8 bit_ptr:3; /* indicates which byte of the CDB or parameter data - * was in error - */ - u8 BPV:1; /* bit pointer valid (BPV): 1- indicates that - * the bit_ptr field has valid value - */ - u8 reserved2:2; - u8 CD:1; /* command data bit: 1- illegal parameter in CDB. - * 0- illegal parameter in data. - */ - u8 SKSV:1; - u8 field_ptr[2]; /* byte of the CDB or parameter data in error */ -}; - -struct fsa_dev_info { - u64 last; - u64 size; - u32 type; - u16 queue_depth; - u8 valid; - u8 ro; - u8 locked; - u8 deleted; - char devname[8]; - struct sense_data sense_data; }; struct fib { @@ -810,7 +771,7 @@ struct aac_dev { + struct aac_dev *next; - struct list_head entry; const char *name; int id; @@ -853,8 +814,7 @@ size_t comm_size; struct Scsi_Host *scsi_host_ptr; + struct fsa_scsi_hba fsa_dev; - int maximum_num_containers; - struct fsa_dev_info *fsa_dev; pid_t thread_pid; int cardtype; @@ -1209,71 +1169,6 @@ }; /* - * Query for Container Configuration Status - */ - -#define CT_GET_CONFIG_STATUS 147 -struct aac_get_config_status { - u32 command; /* VM_ContainerConfig */ - u32 type; /* CT_GET_CONFIG_STATUS */ - u32 parm1; - u32 parm2; - u32 parm3; - u32 parm4; - u32 parm5; - u32 count; /* sizeof(((struct aac_get_config_status_resp *)NULL)->data) */ -}; - -#define CFACT_CONTINUE 0 -#define CFACT_PAUSE 1 -#define CFACT_ABORT 2 -struct aac_get_config_status_resp { - u32 response; /* ST_OK */ - u32 dummy0; - u32 status; /* CT_OK */ - u32 parm1; - u32 parm2; - u32 parm3; - u32 parm4; - u32 parm5; - struct { - u32 action; /* CFACT_CONTINUE, CFACT_PAUSE or CFACT_ABORT */ - u16 flags; - s16 count; - } data; -}; - -/* - * Accept the configuration as-is - */ - -#define CT_COMMIT_CONFIG 152 - -struct aac_commit_config { - u32 command; /* VM_ContainerConfig */ - u32 type; /* CT_COMMIT_CONFIG */ -}; - -/* - * Query for Container Configuration Count - */ - -#define CT_GET_CONTAINER_COUNT 4 -struct aac_get_container_count { - u32 command; /* VM_ContainerConfig */ - u32 type; /* CT_GET_CONTAINER_COUNT */ -}; - -struct aac_get_container_count_resp { - u32 response; /* ST_OK */ - u32 dummy0; - u32 MaxContainers; - u32 ContainerSwitchEntries; - u32 MaxPartitions; -}; - - -/* * Query for "mountable" objects, ie, objects that are typically * associated with a drive letter on the client (host) side. */ @@ -1548,7 +1443,6 @@ int fib_complete(struct fib * context); #define fib_data(fibctx) ((void *)(fibctx)->hw_fib->data) struct aac_dev *aac_init_adapter(struct aac_dev *dev); -int aac_get_config_status(struct aac_dev *dev); int aac_get_containers(struct aac_dev *dev); int aac_scsi_cmd(struct scsi_cmnd *cmd); int aac_dev_ioctl(struct aac_dev *dev, int cmd, void __user *arg); reverted: --- b/drivers/scsi/aacraid/linit.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aacraid/linit.c 2004-10-01 19:21:44 -07:00 @@ -65,7 +65,8 @@ MODULE_LICENSE("GPL"); MODULE_VERSION(AAC_DRIVER_VERSION); +struct aac_dev *aac_devices[MAXIMUM_NUM_ADAPTERS]; +static unsigned aac_count; -static LIST_HEAD(aac_devices); static int aac_cfg_major = -1; /* @@ -451,18 +452,11 @@ static int aac_cfg_open(struct inode *inode, struct file *file) { - struct aac_dev *aac; unsigned minor = iminor(inode); - int err = -ENODEV; - - list_for_each_entry(aac, &aac_devices, entry) { - if (aac->id == minor) { - file->private_data = aac; - err = 0; - break; - } - } + if (minor >= aac_count) + return -ENODEV; + file->private_data = aac_devices[minor]; return 0; } @@ -521,18 +515,10 @@ { unsigned index = id->driver_data; struct Scsi_Host *shost; + struct fsa_scsi_hba *fsa_dev_ptr; struct aac_dev *aac; + int container; - struct list_head *insert = &aac_devices; int error = -ENODEV; - int unique_id = 0; - - list_for_each_entry(aac, &aac_devices, entry) { - if (aac->id > unique_id) { - insert = &aac->entry; - break; - } - unique_id++; - } if (pci_enable_device(pdev)) goto out; @@ -551,13 +537,16 @@ pci_set_master(pdev); + /* Increment the host adapter count */ + aac_count++; + shost = scsi_host_alloc(&aac_driver_template, sizeof(struct aac_dev)); if (!shost) goto out_disable_pdev; shost->irq = pdev->irq; shost->base = pci_resource_start(pdev, 0); + shost->unique_id = aac_count - 1; - shost->unique_id = unique_id; aac = (struct aac_dev *)shost->hostdata; aac->scsi_host_ptr = shost; @@ -565,13 +554,17 @@ aac->name = aac_driver_template.name; aac->id = shost->unique_id; aac->cardtype = index; - INIT_LIST_HEAD(&aac->entry); aac->fibs = kmalloc(sizeof(struct fib) * AAC_NUM_FIB, GFP_KERNEL); if (!aac->fibs) goto out_free_host; spin_lock_init(&aac->fib_lock); + /* Initialize the ordinal number of the device to -1 */ + fsa_dev_ptr = &aac->fsa_dev; + for (container = 0; container < MAXIMUM_NUM_CONTAINERS; container++) + fsa_dev_ptr->devname[container][0] = '\0'; + if ((*aac_drivers[index].init)(aac)) goto out_free_fibs; @@ -596,32 +589,26 @@ else shost->max_channel = 1; - aac_get_config_status(aac); aac_get_containers(aac); + aac_devices[aac_count-1] = aac; - list_add(&aac->entry, insert); - - shost->max_id = aac->maximum_num_containers; - if (shost->max_id < MAXIMUM_NUM_CONTAINERS) - shost->max_id = MAXIMUM_NUM_CONTAINERS; - else - shost->this_id = shost->max_id; /* * dmb - we may need to move the setting of these parms somewhere else once * we get a fib that can report the actual numbers */ + shost->max_id = MAXIMUM_NUM_CONTAINERS; shost->max_lun = AAC_MAX_LUN; - pci_set_drvdata(pdev, shost); - error = scsi_add_host(shost, &pdev->dev); if (error) goto out_deinit; + + pci_set_drvdata(pdev, shost); scsi_scan_host(shost); return 0; + out_deinit: -out_deinit: kill_proc(aac->thread_pid, SIGKILL, 0); wait_for_completion(&aac->aif_completion); @@ -633,11 +620,11 @@ iounmap((void * )aac->regs.sa); out_free_fibs: kfree(aac->fibs); - kfree(aac->fsa_dev); out_free_host: scsi_host_put(shost); out_disable_pdev: pci_disable_device(pdev); + aac_count--; out: return error; } @@ -666,7 +653,15 @@ scsi_host_put(shost); pci_disable_device(pdev); + /* + * We don't decrement aac_count here because adapters can be unplugged + * in a different order than they were detected. If we're ever going + * to overflow MAXIMUM_NUM_ADAPTERS we'll have to consider using a + * bintmap of free aac_devices slots. + */ +#if 0 + aac_count--; +#endif - list_del(&aac->entry); } static struct pci_driver aac_pci_driver = { reverted: --- b/drivers/scsi/advansys.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/advansys.c 2004-10-01 19:21:44 -07:00 @@ -796,7 +796,6 @@ #include #include -#include #include #include #include "advansys.h" reverted: --- b/drivers/scsi/aic7xxx/aic79xx.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic79xx.h 2004-10-01 19:21:44 -07:00 @@ -549,7 +549,7 @@ struct map_node { bus_dmamap_t dmamap; + bus_addr_t physaddr; - dma_addr_t physaddr; uint8_t *vaddr; SLIST_ENTRY(map_node) links; }; @@ -626,8 +626,8 @@ struct map_node *sense_map; void *sg_list; uint8_t *sense_data; + bus_addr_t sg_list_busaddr; + bus_addr_t sense_busaddr; - dma_addr_t sg_list_busaddr; - dma_addr_t sense_busaddr; u_int sg_count;/* How full ahd_dma_seg is */ #define AHD_MAX_LQ_CRC_ERRORS 5 u_int crc_retry_count; @@ -1198,7 +1198,7 @@ bus_dma_tag_t parent_dmat; bus_dma_tag_t shared_data_dmat; bus_dmamap_t shared_data_dmamap; + bus_addr_t shared_data_busaddr; - dma_addr_t shared_data_busaddr; /* Information saved through suspend/resume cycles */ struct ahd_suspend_state suspend_state; reverted: --- b/drivers/scsi/aic7xxx/aic79xx_core.c 2004-10-01 19:21:43 -07:00 +++ a/drivers/scsi/aic7xxx/aic79xx_core.c 2004-10-01 19:21:43 -07:00 @@ -5493,9 +5493,9 @@ static void ahd_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { + bus_addr_t *baddr; - dma_addr_t *baddr; + baddr = (bus_addr_t *)arg; - baddr = (dma_addr_t *)arg; *baddr = segs->ds_addr; } @@ -5926,9 +5926,9 @@ struct map_node *sense_map; uint8_t *segs; uint8_t *sense_data; + bus_addr_t hscb_busaddr; + bus_addr_t sg_busaddr; + bus_addr_t sense_busaddr; - dma_addr_t hscb_busaddr; - dma_addr_t sg_busaddr; - dma_addr_t sense_busaddr; int newcount; int i; @@ -6161,7 +6161,7 @@ { uint8_t *base_vaddr; uint8_t *next_vaddr; + bus_addr_t next_baddr; - dma_addr_t next_baddr; size_t driver_data_size; int i; int error; @@ -6205,7 +6205,7 @@ if (ahd_dma_tag_create(ahd, ahd->parent_dmat, /*alignment*/1, /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, /*lowaddr*/ahd->flags & AHD_39BIT_ADDRESSING + ? (bus_addr_t)0x7FFFFFFFFFULL - ? (dma_addr_t)0x7FFFFFFFFFULL : BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, reverted: --- b/drivers/scsi/aic7xxx/aic79xx_inline.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic79xx_inline.h 2004-10-01 19:21:44 -07:00 @@ -231,7 +231,7 @@ /*********************** Scatter Gather List Handling *************************/ static __inline void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, - void *sgptr, dma_addr_t addr, bus_size_t len, int last); static __inline void ahd_setup_scb_common(struct ahd_softc *ahd, struct scb *scb); @@ -242,10 +242,10 @@ static __inline void * ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb, + void *sgptr, bus_addr_t addr, bus_size_t len, int last) - void *sgptr, dma_addr_t addr, bus_size_t len, int last) { scb->sg_count++; + if (sizeof(bus_addr_t) > 4 - if (sizeof(dma_addr_t) > 4 && (ahd->flags & AHD_64BIT_ADDRESSING) != 0) { struct ahd_dma64_seg *sg; @@ -361,7 +361,7 @@ static __inline void * ahd_sg_bus_to_virt(struct ahd_softc *ahd, struct scb *scb, uint32_t sg_busaddr) { + bus_addr_t sg_offset; - dma_addr_t sg_offset; /* sg_list_phys points to entry 1, not 0 */ sg_offset = sg_busaddr - (scb->sg_list_busaddr - ahd_sg_size(ahd)); @@ -371,7 +371,7 @@ static __inline uint32_t ahd_sg_virt_to_bus(struct ahd_softc *ahd, struct scb *scb, void *sg) { + bus_addr_t sg_offset; - dma_addr_t sg_offset; /* sg_list_phys points to entry 1, not 0 */ sg_offset = ((uint8_t *)sg - (uint8_t *)scb->sg_list) diff -u b/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c --- b/drivers/scsi/aic7xxx/aic79xx_osm.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c 2004-10-01 19:23:16 -07:00 @@ -52,7 +52,9 @@ */ #include "aiclib.c" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #include /* __setup */ +#endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include "sd.h" /* For geometry detection */ @@ -66,6 +68,14 @@ */ spinlock_t ahd_list_spinlock; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +struct proc_dir_entry proc_scsi_aic79xx = { + PROC_SCSI_AIC79XX, 7, "aic79xx", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* For dynamic sglist size calculation. */ u_int ahd_linux_nseg; @@ -551,7 +561,7 @@ static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, struct ahd_dma_seg *sg, - dma_addr_t addr, bus_size_t len); + bus_addr_t addr, bus_size_t len); static __inline void ahd_schedule_completeq(struct ahd_softc *ahd) @@ -569,20 +579,31 @@ static __inline void ahd_schedule_runq(struct ahd_softc *ahd) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_schedule(&ahd->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahd_runq_tasklet((unsigned long)ahd); +#endif } static __inline void ahd_setup_runq_tasklet(struct ahd_softc *ahd) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_init(&ahd->platform_data->runq_tasklet, ahd_runq_tasklet, (unsigned long)ahd); +#endif } static __inline void ahd_teardown_runq_tasklet(struct ahd_softc *ahd) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_kill(&ahd->platform_data->runq_tasklet); +#endif } static __inline struct ahd_linux_device* @@ -713,7 +734,7 @@ static __inline int ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, - struct ahd_dma_seg *sg, dma_addr_t addr, bus_size_t len) + struct ahd_dma_seg *sg, bus_addr_t addr, bus_size_t len) { int consumed; @@ -725,7 +746,7 @@ sg->addr = ahd_htole32(addr & 0xFFFFFFFF); scb->platform_data->xfer_len += len; - if (sizeof(dma_addr_t) > 4 + if (sizeof(bus_addr_t) > 4 && (ahd->flags & AHD_39BIT_ADDRESSING) != 0) len |= (addr >> 8) & AHD_SG_HIGH_ADDR_MASK; @@ -869,7 +890,11 @@ "aic79xx: insmod or else it might trash certain memory areas.\n"); #endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) template->proc_name = "aic79xx"; +#else + template->proc_dir = &proc_scsi_aic79xx; +#endif /* * Initialize our softc list lock prior to @@ -1676,27 +1701,35 @@ { struct ahd_softc* ahd; struct ahd_linux_device *dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) u_long flags; +#endif ahd = (struct ahd_softc *)data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ahd_lock(ahd, &flags); +#endif while ((dev = ahd_linux_next_device_to_run(ahd)) != NULL) { TAILQ_REMOVE(&ahd->platform_data->device_runq, dev, links); dev->flags &= ~AHD_DEV_ON_RUN_LIST; ahd_linux_check_device_queue(ahd, dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* Yeild to our interrupt handler */ ahd_unlock(ahd, &flags); ahd_lock(ahd, &flags); +#endif } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ahd_unlock(ahd, &flags); +#endif } /******************************** Bus DMA *************************************/ int ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, bus_size_t alignment, bus_size_t boundary, - dma_addr_t lowaddr, dma_addr_t highaddr, + bus_addr_t lowaddr, bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) @@ -1733,6 +1766,7 @@ { bus_dmamap_t map; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); if (map == NULL) return (ENOMEM); @@ -1744,7 +1778,7 @@ * our dma mask when doing allocations. */ if (ahd->dev_softc != NULL) - if (pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF)) { + if (ahd_pci_set_dma_mask(ahd->dev_softc, 0xFFFFFFFF)) { printk(KERN_WARNING "aic79xx: No suitable DMA available.\n"); kfree(map); return (ENODEV); @@ -1752,12 +1786,22 @@ *vaddr = pci_alloc_consistent(ahd->dev_softc, dmat->maxsize, &map->bus_addr); if (ahd->dev_softc != NULL) - if (pci_set_dma_mask(ahd->dev_softc, + if (ahd_pci_set_dma_mask(ahd->dev_softc, ahd->platform_data->hw_dma_mask)) { printk(KERN_WARNING "aic79xx: No suitable DMA available.\n"); kfree(map); return (ENODEV); } +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessible via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif if (*vaddr == NULL) return (ENOMEM); *mapp = map; @@ -1768,8 +1812,12 @@ ahd_dmamem_free(struct ahd_softc *ahd, bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) pci_free_consistent(ahd->dev_softc, dmat->maxsize, vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif } int @@ -1783,7 +1831,12 @@ */ bus_dma_segment_t stack_sg; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) stack_sg.ds_addr = map->bus_addr; +#else +#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif stack_sg.ds_len = dmat->maxsize; cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); return (0); @@ -2015,7 +2068,9 @@ return 1; } +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) __setup("aic79xx=", aic79xx_setup); +#endif uint32_t aic79xx_verbose; @@ -2058,7 +2113,8 @@ ahd_set_name(ahd, new_name); } host->unique_id = ahd->unit; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) scsi_set_pci_device(host, ahd->dev_softc); #endif ahd_linux_setup_user_rd_strm_settings(ahd); @@ -2210,9 +2266,15 @@ ahd->platform_data->completeq_timer.data = (u_long)ahd; ahd->platform_data->completeq_timer.function = (ahd_linux_callback_t *)ahd_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) init_MUTEX_LOCKED(&ahd->platform_data->eh_sem); init_MUTEX_LOCKED(&ahd->platform_data->dv_sem); init_MUTEX_LOCKED(&ahd->platform_data->dv_cmd_sem); +#else + ahd->platform_data->eh_sem = MUTEX_LOCKED; + ahd->platform_data->dv_sem = MUTEX_LOCKED; + ahd->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif ahd_setup_runq_tasklet(ahd); ahd->seltime = (aic79xx_seltime & 0x3) << 4; return (0); @@ -2272,10 +2334,13 @@ base_addr = (u_long)ahd->bshs[0].maddr; base_addr &= PAGE_MASK; iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(ahd->platform_data->mem_busaddr, 0x1000); +#endif } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* * In 2.4 we detach from the scsi midlayer before the PCI * layer invokes our remove callback. No per-instance @@ -4065,7 +4130,7 @@ cmd->use_sg, dir); scb->platform_data->xfer_len = 0; for (sg = scb->sg_list; nseg > 0; nseg--, cur_seg++) { - dma_addr_t addr; + bus_addr_t addr; bus_size_t len; addr = sg_dma_address(cur_seg); @@ -4076,7 +4141,7 @@ } } else if (cmd->request_bufflen != 0) { void *sg; - dma_addr_t addr; + bus_addr_t addr; int dir; sg = scb->sg_list; @@ -4310,7 +4375,7 @@ WARN_ON(lun != CAM_LUN_WILDCARD); scsi_report_device_reset(ahd->platform_data->host, channel - 'A', target); -#else +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) Scsi_Device *scsi_dev; /* @@ -4331,10 +4396,12 @@ break; } case AC_BUS_RESET: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahd->platform_data->host != NULL) { scsi_report_bus_reset(ahd->platform_data->host, channel - 'A'); } +#endif break; default: panic("ahd_send_async: Unexpected async event"); reverted: --- b/drivers/scsi/aic7xxx/aic79xx_osm.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic79xx_osm.h 2004-10-01 19:21:44 -07:00 @@ -53,9 +53,17 @@ #include #include +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #include /* For tasklet support. */ #include #include +#else +#include +#endif /* Core SCSI definitions */ #define AIC_LIB_PREFIX ahd @@ -136,6 +144,11 @@ /***************************** Bus Space/DMA **********************************/ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17) +typedef dma_addr_t bus_addr_t; +#else +typedef uint32_t bus_addr_t; +#endif typedef uint32_t bus_size_t; typedef enum { @@ -150,7 +163,7 @@ typedef struct bus_dma_segment { + bus_addr_t ds_addr; - dma_addr_t ds_addr; bus_size_t ds_len; } bus_dma_segment_t; @@ -164,11 +177,11 @@ struct ahd_linux_dmamap { + bus_addr_t bus_addr; - dma_addr_t bus_addr; }; typedef struct ahd_linux_dmamap* bus_dmamap_t; +typedef int bus_dma_filter_t(void*, bus_addr_t); -typedef int bus_dma_filter_t(void*, dma_addr_t); typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); #define BUS_DMA_WAITOK 0x0 @@ -185,7 +198,7 @@ int ahd_dma_tag_create(struct ahd_softc *, bus_dma_tag_t /*parent*/, bus_size_t /*alignment*/, bus_size_t /*boundary*/, + bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/, - dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/, bus_dma_filter_t*/*filter*/, void */*filterarg*/, bus_size_t /*maxsize*/, int /*nsegments*/, bus_size_t /*maxsegsz*/, int /*flags*/, @@ -267,7 +280,11 @@ } /***************************** SMP support ************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) #include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) +#include +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) #define AHD_SCSI_HAS_HOST_LOCK 1 @@ -492,8 +509,11 @@ struct scb_platform_data { struct ahd_linux_device *dev; + bus_addr_t buf_busaddr; - dma_addr_t buf_busaddr; uint32_t xfer_len; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) + uint32_t resid; /* Transfer residual */ +#endif uint32_t sense_resid; /* Auto-Sense residual */ ahd_linux_scb_flags flags; }; @@ -523,7 +543,9 @@ struct ahd_completeq completeq; spinlock_t spin_lock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct tasklet_struct runq_tasklet; +#endif u_int qfrozen; pid_t dv_pid; struct timer_list completeq_timer; @@ -540,7 +562,7 @@ uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ + bus_addr_t hw_dma_mask; - dma_addr_t hw_dma_mask; ahd_linux_softc_flags flags; }; @@ -837,7 +859,9 @@ #define PCIXM_STATUS_MAXCRDS 0x1C00 /* Maximum Cumulative Read Size */ #define PCIXM_STATUS_RCVDSCEM 0x2000 /* Received a Split Comp w/Error msg */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) extern struct pci_driver aic79xx_pci_driver; +#endif typedef enum { @@ -941,6 +965,25 @@ ahd_inb(ahd, INTSTAT); } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0) +#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg) +#define pci_unmap_sg(pdev, sg_list, nseg, direction) +#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address)) +#define sg_dma_len(sg) ((sg)->length) +#define pci_map_single(pdev, buffer, bufflen, direction) \ + (VIRT_TO_BUS(buffer)) +#define pci_unmap_single(pdev, buffer, buflen, direction) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahd_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahd_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif /**************************** Proc FS Support *********************************/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) int ahd_linux_proc_info(char *, char **, off_t, int, int, int); @@ -1048,13 +1091,35 @@ static __inline int ahd_get_transfer_dir(struct scb *scb) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40) return (scb->io_ctx->sc_data_direction); +#else + if (scb->io_ctx->bufflen == 0) + return (CAM_DIR_NONE); + + switch(scb->io_ctx->cmnd[0]) { + case 0x08: /* READ(6) */ + case 0x28: /* READ(10) */ + case 0xA8: /* READ(12) */ + return (CAM_DIR_IN); + case 0x0A: /* WRITE(6) */ + case 0x2A: /* WRITE(10) */ + case 0xAA: /* WRITE(12) */ + return (CAM_DIR_OUT); + default: + return (CAM_DIR_NONE); + } +#endif } static __inline void ahd_set_residual(struct scb *scb, u_long resid) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) scb->io_ctx->resid = resid; +#else + scb->platform_data->resid = resid; +#endif } static __inline @@ -1066,7 +1131,11 @@ static __inline u_long ahd_get_residual(struct scb *scb) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) return (scb->io_ctx->resid); +#else + return (scb->platform_data->resid); +#endif } static __inline diff -u b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c --- b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c 2004-10-01 19:23:16 -07:00 @@ -42,6 +42,12 @@ #include "aic79xx_osm.h" #include "aic79xx_inline.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +struct pci_device_id +{ +}; +#endif + static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static int ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, @@ -49,6 +55,7 @@ static int ahd_linux_pci_reserve_mem_region(struct ahd_softc *ahd, u_long *bus_addr, uint8_t **maddr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static void ahd_linux_pci_dev_remove(struct pci_dev *pdev); /* We do our own ID filtering. So, grab all SCSI storage class devices. */ @@ -96,6 +103,7 @@ } ahd_list_unlock(&l); } +#endif /* !LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) */ static int ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -144,39 +152,42 @@ ahd = ahd_alloc(NULL, name); if (ahd == NULL) return (-ENOMEM); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (pci_enable_device(pdev)) { ahd_free(ahd); return (-ENODEV); } pci_set_master(pdev); - if (sizeof(dma_addr_t) > 4) { + if (sizeof(bus_addr_t) > 4) { uint64_t memsize; - dma_addr_t mask_64bit; - dma_addr_t mask_39bit; + bus_addr_t mask_64bit; + bus_addr_t mask_39bit; memsize = ahd_linux_get_memsize(); - mask_64bit = (dma_addr_t)0xFFFFFFFFFFFFFFFFULL; - mask_39bit = (dma_addr_t)0x7FFFFFFFFFULL; + mask_64bit = (bus_addr_t)0xFFFFFFFFFFFFFFFFULL; + mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL; if (memsize >= 0x8000000000ULL - && pci_set_dma_mask(pdev, mask_64bit) == 0) { + && ahd_pci_set_dma_mask(pdev, mask_64bit) == 0) { ahd->flags |= AHD_64BIT_ADDRESSING; ahd->platform_data->hw_dma_mask = mask_64bit; } else if (memsize > 0x80000000 - && pci_set_dma_mask(pdev, mask_39bit) == 0) { + && ahd_pci_set_dma_mask(pdev, mask_39bit) == 0) { ahd->flags |= AHD_39BIT_ADDRESSING; ahd->platform_data->hw_dma_mask = mask_39bit; } } else { - pci_set_dma_mask(pdev, 0xFFFFFFFF); + ahd_pci_set_dma_mask(pdev, 0xFFFFFFFF); ahd->platform_data->hw_dma_mask = 0xFFFFFFFF; } +#endif ahd->dev_softc = pci; error = ahd_pci_config(ahd, entry); if (error != 0) { ahd_free(ahd); return (-error); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahd); if (aic79xx_detect_complete) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) @@ -187,13 +198,38 @@ return (-ENODEV); #endif } +#endif return (0); } int ahd_linux_pci_init(void) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) return (pci_module_init(&aic79xx_pci_driver)); +#else + struct pci_dev *pdev; + u_int class; + int found; + + /* If we don't have a PCI bus, we can't find any adapters. */ + if (pci_present() == 0) + return (0); + + found = 0; + pdev = NULL; + class = PCI_CLASS_STORAGE_SCSI << 8; + while ((pdev = pci_find_class(class, pdev)) != NULL) { + ahd_dev_softc_t pci; + int error; + + pci = pdev; + error = ahd_linux_pci_dev_probe(pdev, /*pci_devid*/NULL); + if (error == 0) + found++; + } + return (found); +#endif } void @@ -206,6 +242,7 @@ ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base, u_long *base2) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) *base = pci_resource_start(ahd->dev_softc, 0); /* * This is really the 3rd bar and should be at index 2, @@ -213,14 +250,28 @@ * bars. */ *base2 = pci_resource_start(ahd->dev_softc, 3); +#else + *base = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR0, 4); + *base2 = ahd_pci_read_config(ahd->dev_softc, AHD_PCI_IOADDR1, 4); + *base &= PCI_BASE_ADDRESS_IO_MASK; + *base2 &= PCI_BASE_ADDRESS_IO_MASK; +#endif if (*base == 0 || *base2 == 0) return (ENOMEM); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + if (check_region(*base, 256) != 0 + || check_region(*base2, 256) != 0) + return (ENOMEM); + request_region(*base, 256, "aic79xx"); + request_region(*base2, 256, "aic79xx"); +#else if (request_region(*base, 256, "aic79xx") == 0) return (ENOMEM); if (request_region(*base2, 256, "aic79xx") == 0) { release_region(*base2, 256); return (ENOMEM); } +#endif return (0); } @@ -241,18 +292,29 @@ return (ENOMEM); error = 0; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) start = pci_resource_start(ahd->dev_softc, 1); base_page = start & PAGE_MASK; base_offset = start - base_page; +#else + start = ahd_pci_read_config(ahd->dev_softc, PCIR_MAPS+4, 4); + base_offset = start & PCI_BASE_ADDRESS_MEM_MASK; + base_page = base_offset & PAGE_MASK; + base_offset -= base_page; +#endif if (start != 0) { *bus_addr = start; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) if (request_mem_region(start, 0x1000, "aic79xx") == 0) error = ENOMEM; +#endif if (error == 0) { *maddr = ioremap_nocache(base_page, base_offset + 256); if (*maddr == NULL) { error = ENOMEM; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(start, 0x1000); +#endif } else *maddr += base_offset; } @@ -294,8 +356,10 @@ ahd_get_pci_slot(ahd->dev_softc), ahd_get_pci_function(ahd->dev_softc)); iounmap((void *)((u_long)maddr & PAGE_MASK)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(ahd->platform_data->mem_busaddr, 0x1000); +#endif ahd->bshs[0].maddr = NULL; maddr = NULL; } else @@ -350,3 +414,36 @@ { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_power_state(ahd->dev_softc, new_state); +#else + uint32_t cap; + u_int cap_offset; + + /* + * Traverse the capability list looking for + * the power management capability. + */ + cap = 0; + cap_offset = ahd_pci_read_config(ahd->dev_softc, + PCIR_CAP_PTR, /*bytes*/1); + while (cap_offset != 0) { + + cap = ahd_pci_read_config(ahd->dev_softc, + cap_offset, /*bytes*/4); + if ((cap & 0xFF) == 1 + && ((cap >> 16) & 0x3) > 0) { + uint32_t pm_control; + + pm_control = ahd_pci_read_config(ahd->dev_softc, + cap_offset + 4, + /*bytes*/4); + pm_control &= ~0x3; + pm_control |= new_state; + ahd_pci_write_config(ahd->dev_softc, + cap_offset + 4, + pm_control, /*bytes*/2); + break; + } + cap_offset = (cap >> 8) & 0xFF; + } +#endif } reverted: --- b/drivers/scsi/aic7xxx/aic7xxx.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic7xxx.h 2004-10-01 19:21:44 -07:00 @@ -521,7 +521,7 @@ struct sg_map_node { bus_dmamap_t sg_dmamap; + bus_addr_t sg_physaddr; - dma_addr_t sg_physaddr; struct ahc_dma_seg* sg_vaddr; SLIST_ENTRY(sg_map_node) links; }; @@ -584,7 +584,7 @@ struct scb_platform_data *platform_data; struct sg_map_node *sg_map; struct ahc_dma_seg *sg_list; + bus_addr_t sg_list_phys; - dma_addr_t sg_list_phys; u_int sg_count;/* How full ahc_dma_seg is */ }; @@ -611,10 +611,10 @@ */ bus_dma_tag_t hscb_dmat; /* dmat for our hardware SCB array */ bus_dmamap_t hscb_dmamap; + bus_addr_t hscb_busaddr; - dma_addr_t hscb_busaddr; bus_dma_tag_t sense_dmat; bus_dmamap_t sense_dmamap; + bus_addr_t sense_busaddr; - dma_addr_t sense_busaddr; bus_dma_tag_t sg_dmat; /* dmat for our sg segments */ SLIST_HEAD(, sg_map_node) sg_maps; uint8_t numscbs; @@ -1069,14 +1069,14 @@ bus_dma_tag_t parent_dmat; bus_dma_tag_t shared_data_dmat; bus_dmamap_t shared_data_dmamap; + bus_addr_t shared_data_busaddr; - dma_addr_t shared_data_busaddr; /* * Bus address of the one byte buffer used to * work-around a DMA bug for chips <= aic7880 * in target mode. */ + bus_addr_t dma_bug_buf; - dma_addr_t dma_bug_buf; /* Number of enabled target mode device on this card */ u_int enabled_luns; reverted: --- b/drivers/scsi/aic7xxx/aic7xxx_core.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic7xxx_core.c 2004-10-01 19:21:44 -07:00 @@ -4199,9 +4199,9 @@ static void ahc_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) { + bus_addr_t *baddr; - dma_addr_t *baddr; + baddr = (bus_addr_t *)arg; - baddr = (dma_addr_t *)arg; *baddr = segs->ds_addr; } @@ -4456,7 +4456,7 @@ struct scb_data *scb_data; struct scb *next_scb; struct sg_map_node *sg_map; + bus_addr_t physaddr; - dma_addr_t physaddr; struct ahc_dma_seg *segs; int newcount; int i; @@ -4820,7 +4820,7 @@ if (ahc_dma_tag_create(ahc, ahc->parent_dmat, /*alignment*/1, /*boundary*/BUS_SPACE_MAXADDR_32BIT + 1, /*lowaddr*/ahc->flags & AHC_39BIT_ADDRESSING + ? (bus_addr_t)0x7FFFFFFFFFULL - ? (dma_addr_t)0x7FFFFFFFFFULL : BUS_SPACE_MAXADDR_32BIT, /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, /*filterarg*/NULL, diff -u b/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c --- b/drivers/scsi/aic7xxx/aic7xxx_osm.c 2004-10-01 19:21:43 -07:00 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c 2004-10-01 19:23:16 -07:00 @@ -129,7 +129,10 @@ */ #include "aiclib.c" +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) #include /* __setup */ +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) #include "sd.h" /* For geometry detection */ @@ -149,6 +152,14 @@ u_int ahc_linux_nseg; #endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +struct proc_dir_entry proc_scsi_aic7xxx = { + PROC_SCSI_AIC7XXX, 7, "aic7xxx", + S_IFDIR | S_IRUGO | S_IXUGO, 2, + 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; +#endif + /* * Set this to the delay in seconds after SCSI bus reset. * Note, we honor this only for the initial bus reset. @@ -561,7 +572,7 @@ static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, struct ahc_dma_seg *sg, - dma_addr_t addr, bus_size_t len); + bus_addr_t addr, bus_size_t len); static __inline void ahc_schedule_completeq(struct ahc_softc *ahc) @@ -579,7 +590,14 @@ static __inline void ahc_schedule_runq(struct ahc_softc *ahc) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_schedule(&ahc->platform_data->runq_tasklet); +#else + /* + * Tasklets are not available, so run inline. + */ + ahc_runq_tasklet((unsigned long)ahc); +#endif } static __inline struct ahc_linux_device* @@ -710,7 +728,7 @@ static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, - struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len) + struct ahc_dma_seg *sg, bus_addr_t addr, bus_size_t len) { int consumed; @@ -722,7 +740,7 @@ sg->addr = ahc_htole32(addr & 0xFFFFFFFF); scb->platform_data->xfer_len += len; - if (sizeof(dma_addr_t) > 4 + if (sizeof(bus_addr_t) > 4 && (ahc->flags & AHC_39BIT_ADDRESSING) != 0) len |= (addr >> 8) & AHC_SG_HIGH_ADDR_MASK; @@ -859,7 +877,11 @@ "aic7xxx: insmod or else it might trash certain memory areas.\n"); #endif +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) template->proc_name = "aic7xxx"; +#else + template->proc_dir = &proc_scsi_aic7xxx; +#endif /* * Initialize our softc list lock prior to @@ -1301,20 +1323,28 @@ { struct ahc_softc* ahc; struct ahc_linux_device *dev; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) u_long flags; +#endif ahc = (struct ahc_softc *)data; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ahc_lock(ahc, &flags); +#endif while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); dev->flags &= ~AHC_DEV_ON_RUN_LIST; ahc_linux_check_device_queue(ahc, dev); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) /* Yeild to our interrupt handler */ ahc_unlock(ahc, &flags); ahc_lock(ahc, &flags); +#endif } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) ahc_unlock(ahc, &flags); +#endif } /******************************** Macros **************************************/ @@ -1327,7 +1357,7 @@ int ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, bus_size_t alignment, bus_size_t boundary, - dma_addr_t lowaddr, dma_addr_t highaddr, + bus_addr_t lowaddr, bus_addr_t highaddr, bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, int nsegments, bus_size_t maxsegsz, int flags, bus_dma_tag_t *ret_tag) @@ -1364,6 +1394,7 @@ { bus_dmamap_t map; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); if (map == NULL) return (ENOMEM); @@ -1375,7 +1406,7 @@ * our dma mask when doing allocations. */ if (ahc->dev_softc != NULL) - if (pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) { + if (ahc_pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) { printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); kfree(map); return (ENODEV); @@ -1383,12 +1414,22 @@ *vaddr = pci_alloc_consistent(ahc->dev_softc, dmat->maxsize, &map->bus_addr); if (ahc->dev_softc != NULL) - if (pci_set_dma_mask(ahc->dev_softc, + if (ahc_pci_set_dma_mask(ahc->dev_softc, ahc->platform_data->hw_dma_mask)) { printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); kfree(map); return (ENODEV); } +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) */ + /* + * At least in 2.2.14, malloc is a slab allocator so all + * allocations are aligned. We assume for these kernel versions + * that all allocations will be bellow 4Gig, physically contiguous, + * and accessible via DMA by the controller. + */ + map = NULL; /* No additional information to store */ + *vaddr = malloc(dmat->maxsize, M_DEVBUF, M_NOWAIT); +#endif if (*vaddr == NULL) return (ENOMEM); *mapp = map; @@ -1399,8 +1440,12 @@ ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) pci_free_consistent(ahc->dev_softc, dmat->maxsize, vaddr, map->bus_addr); +#else + free(vaddr, M_DEVBUF); +#endif } int @@ -1414,7 +1459,12 @@ */ bus_dma_segment_t stack_sg; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) stack_sg.ds_addr = map->bus_addr; +#else +#define VIRT_TO_BUS(a) (uint32_t)virt_to_bus((void *)(a)) + stack_sg.ds_addr = VIRT_TO_BUS(buf); +#endif stack_sg.ds_len = dmat->maxsize; cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); return (0); @@ -1425,10 +1475,9 @@ { /* * The map may is NULL in our < 2.3.X implementation. - * Now it's 2.6.5, but just in case... */ - BUG_ON(map == NULL); - free(map, M_DEVBUF); + if (map != NULL) + free(map, M_DEVBUF); } int @@ -1644,7 +1693,9 @@ return 1; } +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) __setup("aic7xxx=", aic7xxx_setup); +#endif uint32_t aic7xxx_verbose; @@ -1687,7 +1738,8 @@ ahc_set_name(ahc, new_name); } host->unique_id = ahc->unit; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) scsi_set_pci_device(host, ahc->dev_softc); #endif ahc_linux_initialize_scsi_bus(ahc); @@ -1873,11 +1925,19 @@ ahc->platform_data->completeq_timer.data = (u_long)ahc; ahc->platform_data->completeq_timer.function = (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); init_MUTEX_LOCKED(&ahc->platform_data->dv_sem); init_MUTEX_LOCKED(&ahc->platform_data->dv_cmd_sem); +#else + ahc->platform_data->eh_sem = MUTEX_LOCKED; + ahc->platform_data->dv_sem = MUTEX_LOCKED; + ahc->platform_data->dv_cmd_sem = MUTEX_LOCKED; +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, (unsigned long)ahc); +#endif ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; if (aic7xxx_pci_parity == 0) @@ -1896,7 +1956,9 @@ if (ahc->platform_data != NULL) { del_timer_sync(&ahc->platform_data->completeq_timer); ahc_linux_kill_dv_thread(ahc); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) tasklet_kill(&ahc->platform_data->runq_tasklet); +#endif if (ahc->platform_data->host != NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) scsi_remove_host(ahc->platform_data->host); @@ -1937,10 +1999,13 @@ base_addr = (u_long)ahc->bsh.maddr; base_addr &= PAGE_MASK; iounmap((void *)base_addr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) release_mem_region(ahc->platform_data->mem_busaddr, 0x1000); +#endif } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \ + LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* * In 2.4 we detach from the scsi midlayer before the PCI * layer invokes our remove callback. No per-instance @@ -3686,7 +3751,7 @@ * a transfer crosses a 32bit page. */ while (cur_seg < end_seg) { - dma_addr_t addr; + bus_addr_t addr; bus_size_t len; int consumed; @@ -3715,7 +3780,7 @@ scb->hscb->datacnt = scb->sg_list->len; } else if (cmd->request_bufflen != 0) { struct ahc_dma_seg *sg; - dma_addr_t addr; + bus_addr_t addr; sg = scb->sg_list; addr = pci_map_single(ahc->dev_softc, @@ -3999,7 +4064,7 @@ WARN_ON(lun != CAM_LUN_WILDCARD); scsi_report_device_reset(ahc->platform_data->host, channel - 'A', target); -#else +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) Scsi_Device *scsi_dev; /* @@ -4020,10 +4085,12 @@ break; } case AC_BUS_RESET: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) if (ahc->platform_data->host != NULL) { scsi_report_bus_reset(ahc->platform_data->host, channel - 'A'); } +#endif break; default: panic("ahc_send_async: Unexpected async event"); reverted: --- b/drivers/scsi/aic7xxx/aic7xxx_osm.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic7xxx_osm.h 2004-10-01 19:21:44 -07:00 @@ -70,9 +70,17 @@ #include #include +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) #include /* For tasklet support. */ #include #include +#else +#include +#endif /* Core SCSI definitions */ #define AIC_LIB_PREFIX ahc @@ -148,6 +156,11 @@ /***************************** Bus Space/DMA **********************************/ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,2,17) +typedef dma_addr_t bus_addr_t; +#else +typedef uint32_t bus_addr_t; +#endif typedef uint32_t bus_size_t; typedef enum { @@ -162,7 +175,7 @@ typedef struct bus_dma_segment { + bus_addr_t ds_addr; - dma_addr_t ds_addr; bus_size_t ds_len; } bus_dma_segment_t; @@ -176,11 +189,11 @@ struct ahc_linux_dmamap { + bus_addr_t bus_addr; - dma_addr_t bus_addr; }; typedef struct ahc_linux_dmamap* bus_dmamap_t; +typedef int bus_dma_filter_t(void*, bus_addr_t); -typedef int bus_dma_filter_t(void*, dma_addr_t); typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); #define BUS_DMA_WAITOK 0x0 @@ -197,7 +210,7 @@ int ahc_dma_tag_create(struct ahc_softc *, bus_dma_tag_t /*parent*/, bus_size_t /*alignment*/, bus_size_t /*boundary*/, + bus_addr_t /*lowaddr*/, bus_addr_t /*highaddr*/, - dma_addr_t /*lowaddr*/, dma_addr_t /*highaddr*/, bus_dma_filter_t*/*filter*/, void */*filterarg*/, bus_size_t /*maxsize*/, int /*nsegments*/, bus_size_t /*maxsegsz*/, int /*flags*/, @@ -279,7 +292,11 @@ } /***************************** SMP support ************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,17) #include +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,93) +#include +#endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) #define AHC_SCSI_HAS_HOST_LOCK 1 @@ -498,8 +515,11 @@ struct scb_platform_data { struct ahc_linux_device *dev; + bus_addr_t buf_busaddr; - dma_addr_t buf_busaddr; uint32_t xfer_len; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) + uint32_t resid; /* Transfer residual */ +#endif uint32_t sense_resid; /* Auto-Sense residual */ ahc_linux_scb_flags flags; }; @@ -529,7 +549,9 @@ struct ahc_completeq completeq; spinlock_t spin_lock; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) struct tasklet_struct runq_tasklet; +#endif u_int qfrozen; pid_t dv_pid; struct timer_list completeq_timer; @@ -545,7 +567,7 @@ uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ + bus_addr_t hw_dma_mask; - dma_addr_t hw_dma_mask; ahc_linux_softc_flags flags; }; @@ -797,7 +819,9 @@ #define PCIR_SUBVEND_0 0x2c #define PCIR_SUBDEV_0 0x2e +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) extern struct pci_driver aic7xxx_pci_driver; +#endif typedef enum { @@ -930,6 +954,25 @@ ahc_inb(ahc, INTSTAT); } +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,3,0) +#define pci_map_sg(pdev, sg_list, nseg, direction) (nseg) +#define pci_unmap_sg(pdev, sg_list, nseg, direction) +#define sg_dma_address(sg) (VIRT_TO_BUS((sg)->address)) +#define sg_dma_len(sg) ((sg)->length) +#define pci_map_single(pdev, buffer, bufflen, direction) \ + (VIRT_TO_BUS(buffer)) +#define pci_unmap_single(pdev, buffer, buflen, direction) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3) +#define ahc_pci_set_dma_mask pci_set_dma_mask +#else +/* + * Always "return" 0 for success. + */ +#define ahc_pci_set_dma_mask(dev_softc, mask) \ + (((dev_softc)->dma_mask = mask) && 0) +#endif /**************************** Proc FS Support *********************************/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) int ahc_linux_proc_info(char *, char **, off_t, int, int, int); @@ -1037,13 +1080,35 @@ static __inline int ahc_get_transfer_dir(struct scb *scb) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,40) return (scb->io_ctx->sc_data_direction); +#else + if (scb->io_ctx->bufflen == 0) + return (CAM_DIR_NONE); + + switch(scb->io_ctx->cmnd[0]) { + case 0x08: /* READ(6) */ + case 0x28: /* READ(10) */ + case 0xA8: /* READ(12) */ + return (CAM_DIR_IN); + case 0x0A: /* WRITE(6) */ + case 0x2A: /* WRITE(10) */ + case 0xAA: /* WRITE(12) */ + return (CAM_DIR_OUT); + default: + return (CAM_DIR_NONE); + } +#endif } static __inline void ahc_set_residual(struct scb *scb, u_long resid) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) scb->io_ctx->resid = resid; +#else + scb->platform_data->resid = resid; +#endif } static __inline @@ -1055,7 +1120,11 @@ static __inline u_long ahc_get_residual(struct scb *scb) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) return (scb->io_ctx->resid); +#else + return (scb->platform_data->resid); +#endif } static __inline reverted: --- b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c 2004-10-01 19:21:44 -07:00 @@ -40,7 +40,6 @@ */ #include "aic7xxx_osm.h" -#include "aic7xxx_pci.h" #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) struct pci_device_id @@ -58,77 +57,16 @@ #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) static void ahc_linux_pci_dev_remove(struct pci_dev *pdev); +/* We do our own ID filtering. So, grab all SCSI storage class devices. */ static struct pci_device_id ahc_linux_pci_id_table[] = { + { + 0x9004, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 + }, + { + 0x9005, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, + PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 + }, -#define LINUXID(x,s) (unsigned)((((x) >> s) & 0xffff) ?: PCI_ANY_ID) -#define ID(x) \ - { \ - LINUXID(x,32), LINUXID(x,48), LINUXID(x,0), LINUXID(x,16), \ - PCI_CLASS_STORAGE_SCSI << 8, 0xFFFF00, 0 \ - } -#define ID4(x,y) \ - ID(x | ((y+0)<<48)), ID(x | ((y+1)<<48)), ID(x | ((y+2)<<48)), \ - ID(x | ((y+3)<<48)) -#define ID16(x) ID4(x,0ULL), ID4(x,4ULL), ID4(x,8ULL), ID4(x,12ULL) - ID(ID_AHA_2902_04_10_15_20C_30C), - ID(ID_AHA_2930CU), - ID(ID_AHA_1480A & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2940), - ID(ID_AHA_3940), - ID(ID_AHA_398X), - ID(ID_AHA_2944), - ID(ID_AHA_3944), - ID(ID_AHA_4944), - ID(ID_AHA_2940U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_3940U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2944U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_3944U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_398XU & ID_DEV_VENDOR_MASK), - ID(ID_AHA_4944U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2930U & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK), - ID(ID_AHA_2930U2), - ID(ID_AHA_2940U2B), - ID(ID_AHA_2940U2_OEM), - ID(ID_AHA_2940U2), - ID(ID_AHA_2950U2B), - ID(ID_AIC7890_ARO), - ID(ID_AAA_131U2), - ID(ID_AHA_29160), - ID(ID_AHA_29160_CPQ), - ID(ID_AHA_29160N), - ID(ID_AHA_29160C), - ID(ID_AHA_29160B), - ID(ID_AHA_19160B), - ID(ID_AIC7892_ARO), - ID(ID_AHA_2940U_DUAL), - ID(ID_AHA_3940AU), - ID(ID_AHA_3944AU), - ID(ID_AIC7895_ARO), - ID(ID_AHA_3950U2B_0), - ID(ID_AHA_3950U2B_1), - ID(ID_AHA_3950U2D_0), - ID(ID_AHA_3950U2D_1), - ID(ID_AIC7896_ARO), - ID(ID_AHA_3960D), - ID(ID_AHA_3960D_CPQ), - ID(ID_AIC7899_ARO), - ID(ID_AIC7850 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7855 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7859 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7860 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7870 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7880 & ID_DEV_VENDOR_MASK), - ID16(ID_AIC7890), - ID16(ID_AIC7892), - ID(ID_AIC7895 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7896), - ID(ID_AIC7899), - ID(ID_AIC7810 & ID_DEV_VENDOR_MASK), - ID(ID_AIC7815 & ID_DEV_VENDOR_MASK), { 0 } }; @@ -170,7 +108,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { char buf[80]; + bus_addr_t mask_39bit; - dma_addr_t mask_39bit; struct ahc_softc *ahc; ahc_dev_softc_t pci; struct ahc_pci_identity *entry; @@ -221,14 +159,14 @@ } pci_set_master(pdev); + mask_39bit = (bus_addr_t)0x7FFFFFFFFFULL; + if (sizeof(bus_addr_t) > 4 - mask_39bit = 0x7FFFFFFFFFULL; - if (sizeof(dma_addr_t) > 4 && ahc_linux_get_memsize() > 0x80000000 + && ahc_pci_set_dma_mask(pdev, mask_39bit) == 0) { - && pci_set_dma_mask(pdev, mask_39bit) == 0) { ahc->flags |= AHC_39BIT_ADDRESSING; ahc->platform_data->hw_dma_mask = mask_39bit; } else { + if (ahc_pci_set_dma_mask(pdev, 0xFFFFFFFF)) { - if (pci_set_dma_mask(pdev, 0xFFFFFFFF)) { printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); return (-ENODEV); } reverted: --- b/drivers/scsi/aic7xxx/aic7xxx_pci.c 2004-10-01 19:21:43 -07:00 +++ a/drivers/scsi/aic7xxx/aic7xxx_pci.c 2004-10-01 19:21:43 -07:00 @@ -54,10 +54,100 @@ #include #endif -#include "aic7xxx_pci.h" - #define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */ #define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */ + +static __inline uint64_t +ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) +{ + uint64_t id; + + id = subvendor + | (subdevice << 16) + | ((uint64_t)vendor << 32) + | ((uint64_t)device << 48); + + return (id); +} + +#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull +#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull +#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull +#define ID_9005_SISL_MASK 0x000FFFFF00000000ull +#define ID_9005_SISL_ID 0x0005900500000000ull +#define ID_AIC7850 0x5078900400000000ull +#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull +#define ID_AIC7855 0x5578900400000000ull +#define ID_AIC7859 0x3860900400000000ull +#define ID_AHA_2930CU 0x3860900438699004ull +#define ID_AIC7860 0x6078900400000000ull +#define ID_AIC7860C 0x6078900478609004ull +#define ID_AHA_1480A 0x6075900400000000ull +#define ID_AHA_2940AU_0 0x6178900400000000ull +#define ID_AHA_2940AU_1 0x6178900478619004ull +#define ID_AHA_2940AU_CN 0x2178900478219004ull +#define ID_AHA_2930C_VAR 0x6038900438689004ull + +#define ID_AIC7870 0x7078900400000000ull +#define ID_AHA_2940 0x7178900400000000ull +#define ID_AHA_3940 0x7278900400000000ull +#define ID_AHA_398X 0x7378900400000000ull +#define ID_AHA_2944 0x7478900400000000ull +#define ID_AHA_3944 0x7578900400000000ull +#define ID_AHA_4944 0x7678900400000000ull + +#define ID_AIC7880 0x8078900400000000ull +#define ID_AIC7880_B 0x8078900478809004ull +#define ID_AHA_2940U 0x8178900400000000ull +#define ID_AHA_3940U 0x8278900400000000ull +#define ID_AHA_2944U 0x8478900400000000ull +#define ID_AHA_3944U 0x8578900400000000ull +#define ID_AHA_398XU 0x8378900400000000ull +#define ID_AHA_4944U 0x8678900400000000ull +#define ID_AHA_2940UB 0x8178900478819004ull +#define ID_AHA_2930U 0x8878900478889004ull +#define ID_AHA_2940U_PRO 0x8778900478879004ull +#define ID_AHA_2940U_CN 0x0078900478009004ull + +#define ID_AIC7895 0x7895900478959004ull +#define ID_AIC7895_ARO 0x7890900478939004ull +#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull +#define ID_AHA_2940U_DUAL 0x7895900478919004ull +#define ID_AHA_3940AU 0x7895900478929004ull +#define ID_AHA_3944AU 0x7895900478949004ull + +#define ID_AIC7890 0x001F9005000F9005ull +#define ID_AIC7890_ARO 0x00139005000F9005ull +#define ID_AAA_131U2 0x0013900500039005ull +#define ID_AHA_2930U2 0x0011900501819005ull +#define ID_AHA_2940U2B 0x00109005A1009005ull +#define ID_AHA_2940U2_OEM 0x0010900521809005ull +#define ID_AHA_2940U2 0x00109005A1809005ull +#define ID_AHA_2950U2B 0x00109005E1009005ull + +#define ID_AIC7892 0x008F9005FFFF9005ull +#define ID_AIC7892_ARO 0x00839005FFFF9005ull +#define ID_AHA_29160 0x00809005E2A09005ull +#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull +#define ID_AHA_29160N 0x0080900562A09005ull +#define ID_AHA_29160C 0x0080900562209005ull +#define ID_AHA_29160B 0x00809005E2209005ull +#define ID_AHA_19160B 0x0081900562A19005ull + +#define ID_AIC7896 0x005F9005FFFF9005ull +#define ID_AIC7896_ARO 0x00539005FFFF9005ull +#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull +#define ID_AHA_3950U2B_1 0x00509005F5009005ull +#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull +#define ID_AHA_3950U2D_1 0x00519005B5009005ull + +#define ID_AIC7899 0x00CF9005FFFF9005ull +#define ID_AIC7899_ARO 0x00C39005FFFF9005ull +#define ID_AHA_3960D 0x00C09005F6209005ull +#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull + +#define ID_AIC7810 0x1078900400000000ull +#define ID_AIC7815 0x7815900400000000ull #define DEVID_9005_TYPE(id) ((id) & 0xF) #define DEVID_9005_TYPE_HBA 0x0 /* Standard Card */ reverted: --- b/drivers/scsi/aic7xxx/aic7xxx_pci.h 2004-10-01 19:21:44 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,92 +0,0 @@ - -static __inline uint64_t -ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) -{ - uint64_t id; - - id = subvendor - | (subdevice << 16) - | ((uint64_t)vendor << 32) - | ((uint64_t)device << 48); - - return (id); -} - -#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull -#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull -#define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull -#define ID_9005_SISL_MASK 0x000FFFFF00000000ull -#define ID_9005_SISL_ID 0x0005900500000000ull -#define ID_AIC7850 0x5078900400000000ull -#define ID_AHA_2902_04_10_15_20C_30C 0x5078900478509004ull -#define ID_AIC7855 0x5578900400000000ull -#define ID_AIC7859 0x3860900400000000ull -#define ID_AHA_2930CU 0x3860900438699004ull -#define ID_AIC7860 0x6078900400000000ull -#define ID_AIC7860C 0x6078900478609004ull -#define ID_AHA_1480A 0x6075900400000000ull -#define ID_AHA_2940AU_0 0x6178900400000000ull -#define ID_AHA_2940AU_1 0x6178900478619004ull -#define ID_AHA_2940AU_CN 0x2178900478219004ull -#define ID_AHA_2930C_VAR 0x6038900438689004ull - -#define ID_AIC7870 0x7078900400000000ull -#define ID_AHA_2940 0x7178900400000000ull -#define ID_AHA_3940 0x7278900400000000ull -#define ID_AHA_398X 0x7378900400000000ull -#define ID_AHA_2944 0x7478900400000000ull -#define ID_AHA_3944 0x7578900400000000ull -#define ID_AHA_4944 0x7678900400000000ull - -#define ID_AIC7880 0x8078900400000000ull -#define ID_AIC7880_B 0x8078900478809004ull -#define ID_AHA_2940U 0x8178900400000000ull -#define ID_AHA_3940U 0x8278900400000000ull -#define ID_AHA_2944U 0x8478900400000000ull -#define ID_AHA_3944U 0x8578900400000000ull -#define ID_AHA_398XU 0x8378900400000000ull -#define ID_AHA_4944U 0x8678900400000000ull -#define ID_AHA_2940UB 0x8178900478819004ull -#define ID_AHA_2930U 0x8878900478889004ull -#define ID_AHA_2940U_PRO 0x8778900478879004ull -#define ID_AHA_2940U_CN 0x0078900478009004ull - -#define ID_AIC7895 0x7895900478959004ull -#define ID_AIC7895_ARO 0x7890900478939004ull -#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull -#define ID_AHA_2940U_DUAL 0x7895900478919004ull -#define ID_AHA_3940AU 0x7895900478929004ull -#define ID_AHA_3944AU 0x7895900478949004ull - -#define ID_AIC7890 0x001F9005000F9005ull -#define ID_AIC7890_ARO 0x00139005000F9005ull -#define ID_AAA_131U2 0x0013900500039005ull -#define ID_AHA_2930U2 0x0011900501819005ull -#define ID_AHA_2940U2B 0x00109005A1009005ull -#define ID_AHA_2940U2_OEM 0x0010900521809005ull -#define ID_AHA_2940U2 0x00109005A1809005ull -#define ID_AHA_2950U2B 0x00109005E1009005ull - -#define ID_AIC7892 0x008F9005FFFF9005ull -#define ID_AIC7892_ARO 0x00839005FFFF9005ull -#define ID_AHA_29160 0x00809005E2A09005ull -#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull -#define ID_AHA_29160N 0x0080900562A09005ull -#define ID_AHA_29160C 0x0080900562209005ull -#define ID_AHA_29160B 0x00809005E2209005ull -#define ID_AHA_19160B 0x0081900562A19005ull - -#define ID_AIC7896 0x005F9005FFFF9005ull -#define ID_AIC7896_ARO 0x00539005FFFF9005ull -#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull -#define ID_AHA_3950U2B_1 0x00509005F5009005ull -#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull -#define ID_AHA_3950U2D_1 0x00519005B5009005ull - -#define ID_AIC7899 0x00CF9005FFFF9005ull -#define ID_AIC7899_ARO 0x00C39005FFFF9005ull -#define ID_AHA_3960D 0x00C09005F6209005ull -#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull - -#define ID_AIC7810 0x1078900400000000ull -#define ID_AIC7815 0x7815900400000000ull reverted: --- b/drivers/scsi/aic7xxx/cam.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/aic7xxx/cam.h 2004-10-01 19:21:44 -07:00 @@ -85,6 +85,12 @@ CAM_STATUS_MASK = 0x3F } cam_status; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0) +#define SCSI_DATA_READ 1 +#define SCSI_DATA_WRITE 2 +#define SCSI_DATA_NONE 3 +#endif + /* * Definitions for the asynchronous callback CCB fields. */ reverted: --- /dev/null Wed Dec 31 16:00:00 196900 +++ a/drivers/scsi/i60uscsi.c 2004-10-01 19:21:43 -07:00 @@ -0,0 +1,805 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU General Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************* + * + * module: i60uscsi.c + * DESCRIPTION: + * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host + * adapters + * + * 07/02/98 hl - v.91n Initial drivers. + * 09/14/98 hl - v1.01 Support new Kernel. + * 09/22/98 hl - v1.01a Support reset. + * 09/24/98 hl - v1.01b Fixed reset. + * 10/05/98 hl - v1.02 split the source code and release. + * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up + * 01/31/99 bv - v1.02b Use mdelay instead of waitForPause + * 08/08/99 bv - v1.02c Use waitForPause again. + * 06/25/02 Doug Ledford - v1.02d + * - Remove limit on number of controllers + * - Port to DMA mapping API + * - Clean up interrupt handler registration + * - Fix memory leaks + * - Fix allocation of scsi host structs and private data + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "scsi.h" +#include +#include "inia100.h" + +#define JIFFIES_TO_MS(t) ((t) * 1000 / HZ) +#define MS_TO_JIFFIES(j) ((j * HZ) / 1000) + +/* ---- INTERNAL FUNCTIONS ---- */ +static UCHAR waitChipReady(ORC_HCS * hcsp); +static UCHAR waitFWReady(ORC_HCS * hcsp); +static UCHAR waitFWReady(ORC_HCS * hcsp); +static UCHAR waitSCSIRSTdone(ORC_HCS * hcsp); +static UCHAR waitHDOoff(ORC_HCS * hcsp); +static UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData); +static unsigned short get_FW_version(ORC_HCS * hcsp); +static UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value); +static UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn); +static int se2_rd_all(ORC_HCS * hcsp); +static void se2_update_all(ORC_HCS * hcsp); /* setup default pattern */ +static void read_eeprom(ORC_HCS * hcsp); +static UCHAR load_FW(ORC_HCS * hcsp); +static void setup_SCBs(ORC_HCS * hcsp); +static void initAFlag(ORC_HCS * hcsp); +ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); + +/* ---- EXTERNAL FUNCTIONS ---- */ +extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb); + +NVRAM nvram, *nvramp = &nvram; +static UCHAR dftNvRam[64] = +{ +/*----------header -------------*/ + 0x01, /* 0x00: Sub System Vendor ID 0 */ + 0x11, /* 0x01: Sub System Vendor ID 1 */ + 0x60, /* 0x02: Sub System ID 0 */ + 0x10, /* 0x03: Sub System ID 1 */ + 0x00, /* 0x04: SubClass */ + 0x01, /* 0x05: Vendor ID 0 */ + 0x11, /* 0x06: Vendor ID 1 */ + 0x60, /* 0x07: Device ID 0 */ + 0x10, /* 0x08: Device ID 1 */ + 0x00, /* 0x09: Reserved */ + 0x00, /* 0x0A: Reserved */ + 0x01, /* 0x0B: Revision of Data Structure */ + /* -- Host Adapter Structure --- */ + 0x01, /* 0x0C: Number Of SCSI Channel */ + 0x01, /* 0x0D: BIOS Configuration 1 */ + 0x00, /* 0x0E: BIOS Configuration 2 */ + 0x00, /* 0x0F: BIOS Configuration 3 */ + /* --- SCSI Channel 0 Configuration --- */ + 0x07, /* 0x10: H/A ID */ + 0x83, /* 0x11: Channel Configuration */ + 0x20, /* 0x12: MAX TAG per target */ + 0x0A, /* 0x13: SCSI Reset Recovering time */ + 0x00, /* 0x14: Channel Configuration4 */ + 0x00, /* 0x15: Channel Configuration5 */ + /* SCSI Channel 0 Target Configuration */ + /* 0x16-0x25 */ + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + /* --- SCSI Channel 1 Configuration --- */ + 0x07, /* 0x26: H/A ID */ + 0x83, /* 0x27: Channel Configuration */ + 0x20, /* 0x28: MAX TAG per target */ + 0x0A, /* 0x29: SCSI Reset Recovering time */ + 0x00, /* 0x2A: Channel Configuration4 */ + 0x00, /* 0x2B: Channel Configuration5 */ + /* SCSI Channel 1 Target Configuration */ + /* 0x2C-0x3B */ + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, 0xC8, + 0x00, /* 0x3C: Reserved */ + 0x00, /* 0x3D: Reserved */ + 0x00, /* 0x3E: Reserved */ + 0x00 /* 0x3F: Checksum */ +}; + + +/***************************************************************************/ +static void waitForPause(unsigned amount) +{ + ULONG the_time = jiffies + MS_TO_JIFFIES(amount); + while (time_before_eq(jiffies, the_time)) + cpu_relax(); +} + +/***************************************************************************/ +UCHAR waitChipReady(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ + if (ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HOSTSTOP) /* Wait HOSTSTOP set */ + return (TRUE); + waitForPause(100); /* wait 100ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitFWReady(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ + if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) /* Wait READY set */ + return (TRUE); + waitForPause(100); /* wait 100ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitSCSIRSTdone(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ + if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & SCSIRST)) /* Wait SCSIRST done */ + return (TRUE); + waitForPause(100); /* wait 100ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitHDOoff(ORC_HCS * hcsp) +{ + int i; + + for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ + if (!(ORC_RD(hcsp->HCS_Base, ORC_HCTRL) & HDO)) /* Wait HDO off */ + return (TRUE); + waitForPause(100); /* wait 100ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +UCHAR waitHDIset(ORC_HCS * hcsp, UCHAR * pData) +{ + int i; + + for (i = 0; i < 10; i++) { /* Wait 1 second for report timeout */ + if ((*pData = ORC_RD(hcsp->HCS_Base, ORC_HSTUS)) & HDI) + return (TRUE); /* Wait HDI set */ + waitForPause(100); /* wait 100ms before try again */ + } + return (FALSE); +} + +/***************************************************************************/ +unsigned short get_FW_version(ORC_HCS * hcsp) +{ + UCHAR bData; + union { + unsigned short sVersion; + unsigned char cVersion[2]; + } Version; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_VERSION); + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + Version.cVersion[0] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + Version.cVersion[1] = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + return (Version.sVersion); +} + +/***************************************************************************/ +UCHAR set_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char value) +{ + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_SET_NVM); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, value); /* Write value */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + return (TRUE); +} + +/***************************************************************************/ +UCHAR get_NVRAM(ORC_HCS * hcsp, unsigned char address, unsigned char *pDataIn) +{ + unsigned char bData; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_GET_NVM); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, address); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + *pDataIn = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + return (TRUE); +} + +/***************************************************************************/ +void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp) +{ + scbp->SCB_Status = ORCSCB_POST; + ORC_WR(hcsp->HCS_Base + ORC_PQUEUE, scbp->SCB_ScbIdx); + return; +} + + +/*********************************************************************** + Read SCSI H/A configuration parameters from serial EEPROM +************************************************************************/ +int se2_rd_all(ORC_HCS * hcsp) +{ + int i; + UCHAR *np, chksum = 0; + + np = (UCHAR *) nvramp; + for (i = 0; i < 64; i++, np++) { /* <01> */ + if (get_NVRAM(hcsp, (unsigned char) i, np) == FALSE) + return -1; +// *np++ = get_NVRAM(hcsp, (unsigned char ) i); + } + +/*------ Is ckecksum ok ? ------*/ + np = (UCHAR *) nvramp; + for (i = 0; i < 63; i++) + chksum += *np++; + + if (nvramp->CheckSum != (UCHAR) chksum) + return -1; + return 1; +} + +/************************************************************************ + Update SCSI H/A configuration parameters from serial EEPROM +*************************************************************************/ +void se2_update_all(ORC_HCS * hcsp) +{ /* setup default pattern */ + int i; + UCHAR *np, *np1, chksum = 0; + + /* Calculate checksum first */ + np = (UCHAR *) dftNvRam; + for (i = 0; i < 63; i++) + chksum += *np++; + *np = chksum; + + np = (UCHAR *) dftNvRam; + np1 = (UCHAR *) nvramp; + for (i = 0; i < 64; i++, np++, np1++) { + if (*np != *np1) { + set_NVRAM(hcsp, (unsigned char) i, *np); + } + } + return; +} + +/************************************************************************* + Function name : read_eeprom +**************************************************************************/ +void read_eeprom(ORC_HCS * hcsp) +{ + if (se2_rd_all(hcsp) != 1) { + se2_update_all(hcsp); /* setup default pattern */ + se2_rd_all(hcsp); /* load again */ + } +} + + +/***************************************************************************/ +UCHAR load_FW(ORC_HCS * hcsp) +{ + U32 dData; + USHORT wBIOSAddress; + USHORT i; + UCHAR *pData, bData; + + + bData = ORC_RD(hcsp->HCS_Base, ORC_GCFG); + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData | EEPRG); /* Enable EEPROM programming */ + ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, 0x00); + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x00); + if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0x55) { + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (FALSE); + } + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x01); + if (ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA) != 0xAA) { + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (FALSE); + } + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Enable SRAM programming */ + pData = (UCHAR *) & dData; + dData = 0; /* Initial FW address to 0 */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x10); + *pData = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x11); + *(pData + 1) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, 0x12); + *(pData + 2) = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + ORC_WR(hcsp->HCS_Base + ORC_EBIOSADR2, *(pData + 2)); + ORC_WRLONG(hcsp->HCS_Base + ORC_FWBASEADR, dData); /* Write FW address */ + + wBIOSAddress = (USHORT) dData; /* FW code locate at BIOS address + ? */ + for (i = 0, pData = (UCHAR *) & dData; /* Download the code */ + i < 0x1000; /* Firmware code size = 4K */ + i++, wBIOSAddress++) { + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); + *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + if ((i % 4) == 3) { + ORC_WRLONG(hcsp->HCS_Base + ORC_RISCRAM, dData); /* Write every 4 bytes */ + pData = (UCHAR *) & dData; + } + } + + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST | DOWNLOAD); /* Reset program count 0 */ + wBIOSAddress -= 0x1000; /* Reset the BIOS adddress */ + for (i = 0, pData = (UCHAR *) & dData; /* Check the code */ + i < 0x1000; /* Firmware code size = 4K */ + i++, wBIOSAddress++) { + ORC_WRSHORT(hcsp->HCS_Base + ORC_EBIOSADR0, wBIOSAddress); + *pData++ = ORC_RD(hcsp->HCS_Base, ORC_EBIOSDATA); /* Read from BIOS */ + if ((i % 4) == 3) { + if (ORC_RDLONG(hcsp->HCS_Base, ORC_RISCRAM) != dData) { + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /*Disable EEPROM programming */ + return (FALSE); + } + pData = (UCHAR *) & dData; + } + } + ORC_WR(hcsp->HCS_Base + ORC_RISCCTL, PRGMRST); /* Reset program to 0 */ + ORC_WR(hcsp->HCS_Base + ORC_GCFG, bData); /* Disable EEPROM programming */ + return (TRUE); +} + +/***************************************************************************/ +void setup_SCBs(ORC_HCS * hcsp) +{ + ORC_SCB *pVirScb; + int i; + ESCB *pVirEscb; + dma_addr_t pPhysEscb; + + /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_SCBSIZE, ORC_MAXQUEUE); /* Total number of SCBs */ + /* SCB HCS_Base address 0 */ + ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE0, hcsp->HCS_physScbArray); + /* SCB HCS_Base address 1 */ + ORC_WRLONG(hcsp->HCS_Base + ORC_SCBBASE1, hcsp->HCS_physScbArray); + + /* setup scatter list address with one buffer */ + pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; + pVirEscb = (ESCB *) hcsp->HCS_virEscbArray; + + for (i = 0; i < ORC_MAXQUEUE; i++) { + pPhysEscb = (hcsp->HCS_physEscbArray + (sizeof(ESCB) * i)); + pVirScb->SCB_SGPAddr = (U32) pPhysEscb; + pVirScb->SCB_SensePAddr = (U32) pPhysEscb; + pVirScb->SCB_EScb = pVirEscb; + pVirScb->SCB_ScbIdx = i; + pVirScb++; + pVirEscb++; + } + + return; +} + +/***************************************************************************/ +static void initAFlag(ORC_HCS * hcsp) +{ + UCHAR i, j; + + for (i = 0; i < MAX_CHANNELS; i++) { + for (j = 0; j < 8; j++) { + hcsp->BitAllocFlag[i][j] = 0xffffffff; + } + } +} + +/***************************************************************************/ +int init_orchid(ORC_HCS * hcsp) +{ + UBYTE *readBytep; + USHORT revision; + UCHAR i; + + initAFlag(hcsp); + ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFF); /* Disable all interrupt */ + if (ORC_RD(hcsp->HCS_Base, ORC_HSTUS) & RREADY) { /* Orchid is ready */ + revision = get_FW_version(hcsp); + if (revision == 0xFFFF) { + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ + if (waitChipReady(hcsp) == FALSE) + return (-1); + load_FW(hcsp); /* Download FW */ + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, 0); /* clear HOSTSTOP */ + if (waitFWReady(hcsp) == FALSE) + return (-1); + /* Wait for firmware ready */ + } else { + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + } + } else { /* Orchid is not Ready */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, DEVRST); /* Reset Host Adapter */ + if (waitChipReady(hcsp) == FALSE) + return (-1); + load_FW(hcsp); /* Download FW */ + setup_SCBs(hcsp); /* Setup SCB HCS_Base and SCB Size registers */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); /* Do Hardware Reset & */ + + /* clear HOSTSTOP */ + if (waitFWReady(hcsp) == FALSE) /* Wait for firmware ready */ + return (-1); + } + +/*------------- get serial EEProm settting -------*/ + + read_eeprom(hcsp); + + if (nvramp->Revision != 1) + return (-1); + + hcsp->HCS_SCSI_ID = nvramp->SCSI0Id; + hcsp->HCS_BIOS = nvramp->BIOSConfig1; + hcsp->HCS_MaxTar = MAX_TARGETS; + readBytep = (UCHAR *) & (nvramp->Target00Config); + for (i = 0; i < 16; readBytep++, i++) { + hcsp->TargetFlag[i] = *readBytep; + hcsp->MaximumTags[i] = ORC_MAXTAGS; + } /* for */ + + if (nvramp->SCSI0Config & NCC_BUSRESET) { /* Reset SCSI bus */ + hcsp->HCS_Flags |= HCF_SCSI_RESET; + } + ORC_WR(hcsp->HCS_Base + ORC_GIMSK, 0xFB); /* enable RP FIFO interrupt */ + return (0); +} + +/***************************************************************************** + Function name : orc_reset_scsi_bus + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_reset_scsi_bus(ORC_HCS * pHCB) +{ /* I need Host Control Block Information */ + ULONG flags; + + spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); + + initAFlag(pHCB); + /* reset scsi bus */ + ORC_WR(pHCB->HCS_Base + ORC_HCTRL, SCSIRST); + if (waitSCSIRSTdone(pHCB) == FALSE) { + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); + return FAILED; + } else { + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); + return SUCCESS; + } +} + +/***************************************************************************** + Function name : orc_device_reset + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_device_reset(ORC_HCS * pHCB, Scsi_Cmnd *SCpnt, unsigned int target) +{ /* I need Host Control Block Information */ + ORC_SCB *pScb; + ESCB *pVirEscb; + ORC_SCB *pVirScb; + UCHAR i; + ULONG flags; + + spin_lock_irqsave(&(pHCB->BitAllocFlagLock), flags); + pScb = (ORC_SCB *) NULL; + pVirEscb = (ESCB *) NULL; + + /* setup scatter list address with one buffer */ + pVirScb = (ORC_SCB *) pHCB->HCS_virScbArray; + + initAFlag(pHCB); + /* device reset */ + for (i = 0; i < ORC_MAXQUEUE; i++) { + pVirEscb = pVirScb->SCB_EScb; + if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) + break; + pVirScb++; + } + + if (i == ORC_MAXQUEUE) { + printk("Unable to Reset - No SCB Found\n"); + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); + return FAILED; + } + if ((pScb = orc_alloc_scb(pHCB)) == NULL) { + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); + return FAILED; + } + pScb->SCB_Opcode = ORC_BUSDEVRST; + pScb->SCB_Target = target; + pScb->SCB_HaStat = 0; + pScb->SCB_TaStat = 0; + pScb->SCB_Status = 0x0; + pScb->SCB_Link = 0xFF; + pScb->SCB_Reserved0 = 0; + pScb->SCB_Reserved1 = 0; + pScb->SCB_XferLen = 0; + pScb->SCB_SGLen = 0; + + pVirEscb->SCB_Srb = NULL; + pVirEscb->SCB_Srb = SCpnt; + orc_exec_scb(pHCB, pScb); /* Start execute SCB */ + spin_unlock_irqrestore(&(pHCB->BitAllocFlagLock), flags); + return SUCCESS; +} + + +/***************************************************************************/ +ORC_SCB *__orc_alloc_scb(ORC_HCS * hcsp) +{ + ORC_SCB *pTmpScb; + UCHAR Ch; + ULONG idx; + UCHAR index; + UCHAR i; + + Ch = hcsp->HCS_Index; + for (i = 0; i < 8; i++) { + for (index = 0; index < 32; index++) { + if ((hcsp->BitAllocFlag[Ch][i] >> index) & 0x01) { + hcsp->BitAllocFlag[Ch][i] &= ~(1 << index); + break; + } + } + idx = index + 32 * i; + pTmpScb = (PVOID) ((ULONG) hcsp->HCS_virScbArray + (idx * sizeof(ORC_SCB))); + return (pTmpScb); + } + return (NULL); +} + +ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp) +{ + ORC_SCB *pTmpScb; + ULONG flags; + + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); + pTmpScb = __orc_alloc_scb(hcsp); + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); + return (pTmpScb); +} + + +/***************************************************************************/ +void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp) +{ + ULONG flags; + UCHAR Index; + UCHAR i; + UCHAR Ch; + + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); + Ch = hcsp->HCS_Index; + Index = scbp->SCB_ScbIdx; + i = Index / 32; + Index %= 32; + hcsp->BitAllocFlag[Ch][i] |= (1 << Index); + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); +} + + +/***************************************************************************/ +void orc_release_dma(ORC_HCS * hcsp, Scsi_Cmnd * SCpnt) +{ + struct scatterlist *pSrbSG; + + if (SCpnt->use_sg) { + pSrbSG = (struct scatterlist *)SCpnt->request_buffer; + pci_unmap_sg(hcsp->pdev, pSrbSG, SCpnt->use_sg, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + } else if (SCpnt->request_bufflen != 0) { + pci_unmap_single(hcsp->pdev, (U32)SCpnt->host_scribble, + SCpnt->request_bufflen, + scsi_to_pci_dma_dir(SCpnt->sc_data_direction)); + } +} + +/***************************************************************************** + Function name : abort_SCB + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb) +{ + unsigned char bData, bStatus; + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, ORC_CMD_ABORT_SCB); /* Write command */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + ORC_WR(hcsp->HCS_Base + ORC_HDATA, pScb->SCB_ScbIdx); /* Write address */ + ORC_WR(hcsp->HCS_Base + ORC_HCTRL, HDO); + if (waitHDOoff(hcsp) == FALSE) /* Wait HDO off */ + return (FALSE); + + if (waitHDIset(hcsp, &bData) == FALSE) /* Wait HDI set */ + return (FALSE); + bStatus = ORC_RD(hcsp->HCS_Base, ORC_HDATA); + ORC_WR(hcsp->HCS_Base + ORC_HSTUS, bData); /* Clear HDI */ + + if (bStatus == 1) /* 0 - Successfully */ + return (FALSE); /* 1 - Fail */ + return (TRUE); +} + +/***************************************************************************** + Function name : inia100_abort + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +int orc_abort_srb(ORC_HCS * hcsp, Scsi_Cmnd *SCpnt) +{ + ESCB *pVirEscb; + ORC_SCB *pVirScb; + UCHAR i; + ULONG flags; + + spin_lock_irqsave(&(hcsp->BitAllocFlagLock), flags); + + pVirScb = (ORC_SCB *) hcsp->HCS_virScbArray; + + for (i = 0; i < ORC_MAXQUEUE; i++, pVirScb++) { + pVirEscb = pVirScb->SCB_EScb; + if ((pVirScb->SCB_Status) && (pVirEscb->SCB_Srb == SCpnt)) { + if (pVirScb->SCB_TagMsg == 0) { + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); + return FAILED; + } else { + if (abort_SCB(hcsp, pVirScb)) { + pVirEscb->SCB_Srb = NULL; + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); + return SUCCESS; + } else { + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); + return FAILED; + } + } + } + } + spin_unlock_irqrestore(&(hcsp->BitAllocFlagLock), flags); + return FAILED; +} + +/*********************************************************************** + Routine Description: + This is the interrupt service routine for the Orchid SCSI adapter. + It reads the interrupt register to determine if the adapter is indeed + the source of the interrupt and clears the interrupt at the device. + Arguments: + HwDeviceExtension - HBA miniport driver's adapter data storage + Return Value: +***********************************************************************/ +void orc_interrupt( + ORC_HCS * hcsp +) +{ + BYTE bScbIdx; + ORC_SCB *pScb; + + if (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT) == 0) { + return; // (FALSE); + + } + do { + bScbIdx = ORC_RD(hcsp->HCS_Base, ORC_RQUEUE); + + pScb = (ORC_SCB *) ((ULONG) hcsp->HCS_virScbArray + (ULONG) (sizeof(ORC_SCB) * bScbIdx)); + pScb->SCB_Status = 0x0; + + inia100SCBPost((BYTE *) hcsp, (BYTE *) pScb); + } while (ORC_RD(hcsp->HCS_Base, ORC_RQUEUECNT)); + return; //(TRUE); + +} /* End of I1060Interrupt() */ reverted: --- b/drivers/scsi/i91uscsi.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/i91uscsi.c 2004-10-01 19:21:44 -07:00 @@ -1,4 +1,5 @@ /************************************************************************** + * Initio 9100 device driver for Linux. * * Copyright (c) 1994-1998 Initio Corporation * Copyright (c) 1998 Bas Vermeulen @@ -83,8 +84,6 @@ #include #include -#include - #include "i91uscsi.h" /*--- external functions --*/ @@ -500,7 +499,7 @@ if (i91u_adpt[i].ADPT_BIOS == wBIOS) { if (i91u_adpt[i].ADPT_BASE == wBASE) { if (i91u_adpt[i].ADPT_Bus != 0xFF) + return (FAILURE); - return 1; } else if (i91u_adpt[i].ADPT_BASE < wBASE) continue; } @@ -516,9 +515,9 @@ i91u_adpt[i].ADPT_BIOS = wBIOS; i91u_adpt[i].ADPT_Bus = bBus; i91u_adpt[i].ADPT_Device = bDevice; + return (SUCCESSFUL); - return 0; } + return (FAILURE); - return 1; } void init_i91uAdapter_table(void) @@ -978,7 +977,7 @@ } /***************************************************************************/ +int tul_abort_srb(HCS * pCurHcb, ULONG srbp) -int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) { ULONG flags; SCB *pTmpScb, *pPrevScb; @@ -1005,7 +1004,7 @@ pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; /* Check Pend queue */ while (pTmpScb != NULL) { /* 07/27/98 */ + if (pTmpScb->SCB_Srb == (unsigned char *) srbp) { - if (pTmpScb->SCB_Srb == srbp) { if (pTmpScb == pCurHcb->HCS_ActScb) { spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); return SCSI_ABORT_BUSY; @@ -1031,7 +1030,7 @@ pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ while (pTmpScb != NULL) { + if (pTmpScb->SCB_Srb == (unsigned char *) srbp) { - if (pTmpScb->SCB_Srb == srbp) { if (pTmpScb == pCurHcb->HCS_ActScb) { spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); @@ -1088,8 +1087,7 @@ } /************************************************************************/ +int tul_device_reset(HCS * pCurHcb, ULONG pSrb, unsigned int target, unsigned int ResetFlags) -int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, - unsigned int target, unsigned int ResetFlags) { ULONG flags; SCB *pScb; @@ -1116,7 +1114,7 @@ } pScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ while (pScb != NULL) { + if (pScb->SCB_Srb == (unsigned char *) pSrb) - if (pScb->SCB_Srb == pSrb) break; pScb = pScb->SCB_NxtScb; } @@ -1138,7 +1136,7 @@ pScb->SCB_Srb = 0; if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { + pScb->SCB_Srb = (unsigned char *) pSrb; - pScb->SCB_Srb = pSrb; } tul_push_pend_scb(pCurHcb, pScb); /* push this SCB to Pending queue */ @@ -1253,7 +1251,7 @@ tulip_scsi(pCurHcb); /* Call tulip_scsi */ while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) { /* find done entry */ + if (pCurScb->SCB_TaStat == QUEUE_FULL) { - if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) { pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] = pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1; pCurScb->SCB_TaStat = 0; @@ -1411,7 +1409,11 @@ } } } else if (pCurScb->SCB_Opcode == AbortCmd) { + ULONG srbp; + + srbp = (ULONG) pCurScb->SCB_Srb; +/* 08/03/98 */ + if (tul_abort_srb(pCurHcb, srbp) != 0) { - if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) { tul_unlink_pend_scb(pCurHcb, pCurScb); reverted: --- b/drivers/scsi/i91uscsi.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/i91uscsi.h 2004-10-01 19:21:44 -07:00 @@ -53,7 +53,6 @@ * **************************************************************************/ - #include #include @@ -68,11 +67,22 @@ #define UDWORD unsigned long #define U32 u32 +#ifndef FAILURE +#define FAILURE (-1) +#endif + #define TOTAL_SG_ENTRY 32 #define MAX_SUPPORTED_ADAPTERS 8 #define MAX_OFFSET 15 #define MAX_TARGETS 16 +#define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ +#define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ +#define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ +#define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ + +#define _I91USCSI_H + typedef struct { unsigned short base; unsigned short vec; @@ -413,7 +423,7 @@ U32 SCB_SGPAddr; /*44 SG List/Sense Buf phy. Addr. */ U32 SCB_SensePtr; /*48 Sense data pointer */ void (*SCB_Post) (BYTE *, BYTE *); /*4C POST routine */ + unsigned char *SCB_Srb; /*50 SRB Pointer */ - struct scsi_cmnd *SCB_Srb; /*50 SRB Pointer */ SG SCB_SGList[TOTAL_SG_ENTRY]; /*54 Start of SG list */ } SCB; @@ -462,7 +472,7 @@ /* Error Codes for SCB_TaStat */ #define TARGET_CHKCOND 0x02 #define TARGET_BUSY 0x08 +#define QUEUE_FULL 0x28 -#define INI_QUEUE_FULL 0x28 /* SCSI MESSAGE */ #define MSG_COMP 0x00 @@ -576,9 +586,11 @@ UBYTE HCS_MaxTags[16]; /* 58 */ UBYTE HCS_ActTags[16]; /* 68 */ TCS HCS_Tcs[MAX_TARGETS]; /* 78 */ + ULONG pSRB_head; /* SRB save queue header */ + ULONG pSRB_tail; /* SRB save queue tail */ spinlock_t HCS_AvailLock; spinlock_t HCS_SemaphLock; + spinlock_t pSRB_lock; /* SRB queue lock */ - struct pci_dev *pci_dev; } HCS; /* Bit Definition for HCB_Config */ @@ -682,6 +694,117 @@ #define DISC_ALLOW 0xC0 /* Disconnect is allowed */ #define SCSICMD_RequestSense 0x03 + +/*----------------------------------------------------------------------*/ +/* PCI */ +/*----------------------------------------------------------------------*/ +#define PCI_FUNCTION_ID 0xB1 +#define PCI_BIOS_PRESENT 0x01 +#define FIND_PCI_DEVICE 0x02 +#define FIND_PCI_CLASS_CODE 0x03 +#define GENERATE_SPECIAL_CYCLE 0x06 +#define READ_CONFIG_BYTE 0x08 +#define READ_CONFIG_WORD 0x09 +#define READ_CONFIG_DWORD 0x0A +#define WRITE_CONFIG_BYTE 0x0B +#define WRITE_CONFIG_WORD 0x0C +#define WRITE_CONFIG_DWORD 0x0D + +#define SUCCESSFUL 0x00 +#define FUNC_NOT_SUPPORTED 0x81 +#define BAD_VENDOR_ID 0x83 /* Bad vendor ID */ +#define DEVICE_NOT_FOUND 0x86 /* PCI device not found */ +#define BAD_REGISTER_NUMBER 0x87 + +#define MAX_PCI_DEVICES 21 /* Maximum devices supportted */ + +#define MAX_PCI_CHANL 4 + +typedef struct _BIOS32_ENTRY_STRUCTURE { + DWORD Signatures; /* Should be "_32_" */ + DWORD BIOS32Entry; /* 32-bit physical address */ + BYTE Revision; /* Revision level, should be 0 */ + BYTE Length; /* Multiply of 16, should be 1 */ + BYTE CheckSum; /* Checksum of whole structure */ + BYTE Reserved[5]; /* Reserved */ +} BIOS32_ENTRY_STRUCTURE, *PBIOS32_ENTRY_STRUCTURE; + +typedef struct { + union { + unsigned int eax; + struct { + unsigned short ax; + } word; + struct { + unsigned char al; + unsigned char ah; + } byte; + } eax; + union { + unsigned int ebx; + struct { + unsigned short bx; + } word; + struct { + unsigned char bl; + unsigned char bh; + } byte; + } ebx; + union { + unsigned int ecx; + struct { + unsigned short cx; + } word; + struct { + unsigned char cl; + unsigned char ch; + } byte; + } ecx; + union { + unsigned int edx; + struct { + unsigned short dx; + } word; + struct { + unsigned char dl; + unsigned char dh; + } byte; + } edx; + union { + unsigned int edi; + struct { + unsigned short di; + } word; + } edi; + union { + unsigned int esi; + struct { + unsigned short si; + } word; + } esi; +} REGS; + +typedef union { /* Union define for mechanism 1 */ + struct { + unsigned char RegNum; + unsigned char FcnNum:3; + unsigned char DeviceNum:5; + unsigned char BusNum; + unsigned char Reserved:7; + unsigned char Enable:1; + } sConfigAdr; + unsigned long lConfigAdr; +} CONFIG_ADR; + +typedef union { /* Union define for mechanism 2 */ + struct { + unsigned char RegNum; + unsigned char DeviceNum; + unsigned short Reserved; + } sHostAdr; + unsigned long lHostAdr; +} HOST_ADR; + typedef struct _HCSinfo { ULONG base; UCHAR vec; @@ -718,22 +841,3 @@ #define SCSI_RESET_BUS_RESET 0x100 #define SCSI_RESET_HOST_RESET 0x200 #define SCSI_RESET_ACTION 0xff - -extern void init_i91uAdapter_table(void); -extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE); -extern int tul_ReturnNumberOfAdapters(void); -extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index); -extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time); -extern SCB *tul_alloc_scb(HCS * pHCB); -extern int tul_abort_srb(HCS * pHCB, struct scsi_cmnd * pSRB); -extern void tul_exec_scb(HCS * pHCB, SCB * pSCB); -extern void tul_release_scb(HCS * pHCB, SCB * pSCB); -extern void tul_stop_bm(HCS * pHCB); -extern int tul_reset_scsi(HCS * pCurHcb, int seconds); -extern int tul_isr(HCS * pHCB); -extern int tul_reset(HCS * pHCB, struct scsi_cmnd * pSRB, unsigned char target); -extern int tul_reset_scsi_bus(HCS * pCurHcb); -extern int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, - unsigned int target, unsigned int ResetFlags); - /* ---- EXTERNAL VARIABLES ---- */ -extern HCS tul_hcs[]; reverted: --- b/drivers/scsi/ini9100u.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/ini9100u.c 2004-10-01 19:21:44 -07:00 @@ -110,6 +110,12 @@ * - Re-add reset_bus support **************************************************************************/ +#define CVT_LINUX_VERSION(V,P,S) (V * 65536 + P * 256 + S) + +#ifndef LINUX_VERSION_CODE +#include +#endif + #include #include #include @@ -126,39 +132,45 @@ #include #include #include + #include +#include "scsi.h" -#include -#include -#include #include +#include "ini9100u.h" -#include +#ifdef DEBUG_i91u +unsigned int i91u_debug = DEBUG_DEFAULT; +#endif -#include "i91uscsi.h" +static Scsi_Host_Template driver_template = { + .proc_name = "INI9100U", + .name = i91u_REVID, + .detect = i91u_detect, + .release = i91u_release, + .queuecommand = i91u_queue, +// .abort = i91u_abort, +// .reset = i91u_reset, + .eh_bus_reset_handler = i91u_bus_reset, + .bios_param = i91u_biosparam, + .can_queue = 1, + .this_id = 1, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = ENABLE_CLUSTERING, +}; +#include "scsi_module.c" -#define SENSE_SIZE 14 +char *i91uCopyright = "Copyright (C) 1996-98"; +char *i91uInitioName = "by Initio Corporation"; +char *i91uProductName = "INI-9X00U/UW"; +char *i91uVersion = "v1.04a"; -#define i91u_MAXQUEUE 2 -#define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" - -#define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ -#define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ -#define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ -#define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ -#define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ -#define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ - -#ifdef DEBUG_i91u -static unsigned int i91u_debug = DEBUG_DEFAULT; -#endif #define TULSZ(sz) (sizeof(sz) / sizeof(sz[0])) #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) +/* set by i91_setup according to the command line */ +static int setup_called = 0; -typedef struct PCI_ID_Struc { - unsigned short vendor_id; - unsigned short device_id; -} PCI_ID; static int tul_num_ch = 4; /* Maximum 4 adapters */ static int tul_num_scb; @@ -169,12 +181,33 @@ static int setup_debug = 0; #endif +static char *setup_str = (char *) NULL; + +static void i91u_panic(char *msg); + static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); /* ---- EXTERNAL FUNCTIONS ---- */ /* Get total number of adapters */ +extern void init_i91uAdapter_table(void); +extern int Addi91u_into_Adapter_table(WORD, WORD, BYTE, BYTE, BYTE); +extern int tul_ReturnNumberOfAdapters(void); +extern void get_tulipPCIConfig(HCS * pHCB, int iChannel_index); +extern int init_tulip(HCS * pHCB, SCB * pSCB, int tul_num_scb, BYTE * pbBiosAdr, int reset_time); +extern SCB *tul_alloc_scb(HCS * pHCB); +extern int tul_abort_srb(HCS * pHCB, Scsi_Cmnd * pSRB); +extern void tul_exec_scb(HCS * pHCB, SCB * pSCB); +extern void tul_release_scb(HCS * pHCB, SCB * pSCB); +extern void tul_stop_bm(HCS * pHCB); +extern int tul_reset_scsi(HCS * pCurHcb, int seconds); +extern int tul_isr(HCS * pHCB); +extern int tul_reset(HCS * pHCB, Scsi_Cmnd * pSRB, unsigned char target); +extern int tul_reset_scsi_bus(HCS * pCurHcb); +extern int tul_device_reset(HCS * pCurHcb, ULONG pSrb, unsigned int target, unsigned int ResetFlags); + /* ---- EXTERNAL VARIABLES ---- */ +extern HCS tul_hcs[]; +const PCI_ID i91u_pci_devices[] = { -static const PCI_ID i91u_pci_devices[] = { { INI_VENDOR_ID, I950_DEVICE_ID }, { INI_VENDOR_ID, I940_DEVICE_ID }, { INI_VENDOR_ID, I935_DEVICE_ID }, @@ -182,6 +215,57 @@ { DMX_VENDOR_ID, I920_DEVICE_ID }, }; +/* + * queue services: + */ +/***************************************************************************** + Function name : i91uAppendSRBToQueue + Description : This function will push current request into save list + Input : pSRB - Pointer to SCSI request block. + pHCB - Pointer to host adapter structure + Output : None. + Return : None. +*****************************************************************************/ +static void i91uAppendSRBToQueue(HCS * pHCB, Scsi_Cmnd * pSRB) +{ + ULONG flags; + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); + + pSRB->host_scribble = NULL; /* Pointer to next */ + + if (pHCB->pSRB_head == NULL) + pHCB->pSRB_head = pSRB; + else + pHCB->pSRB_tail->host_scribble = (char *)pSRB; /* Pointer to next */ + pHCB->pSRB_tail = pSRB; + + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); + return; +} + +/***************************************************************************** + Function name : i91uPopSRBFromQueue + Description : This function will pop current request from save list + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static Scsi_Cmnd *i91uPopSRBFromQueue(HCS * pHCB) +{ + Scsi_Cmnd *pSRB; + ULONG flags; + + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); + + if ((pSRB = pHCB->pSRB_head) != NULL) { + pHCB->pSRB_head = (struct scsi_cmnd *)pHCB->pSRB_head->host_scribble; + pSRB->host_scribble = NULL; + } + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); + + return (pSRB); +} + static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs) { struct Scsi_Host *dev = dev_id; @@ -193,7 +277,22 @@ return IRQ_HANDLED; } +/* called from init/main.c */ + +void i91u_setup(char *str, int *ints) +{ + if (setup_called) + i91u_panic("i91u: i91u_setup called twice.\n"); + + setup_called = ints[0]; + setup_str = str; + +#ifdef DEBUG_i91u + setup_debug = ints[0] >= 1 ? ints[1] : DEBUG_DEFAULT; +#endif +} + +int tul_NewReturnNumberOfAdapters(void) -static int tul_NewReturnNumberOfAdapters(void) { struct pci_dev *pDev = NULL; /* Start from none */ int iAdapters = 0; @@ -232,7 +331,7 @@ return (iAdapters); } +int i91u_detect(Scsi_Host_Template * tpnt) -static int i91u_detect(struct scsi_host_template * tpnt) { HCS *pHCB; struct Scsi_Host *hreg; @@ -241,6 +340,20 @@ ULONG dBiosAdr; BYTE *pbBiosAdr; + tpnt->proc_name = "INI9100U"; + + if (setup_called) { /* Setup by i91u_setup */ + printk("i91u: processing commandline: "); + +#ifdef DEBUG_i91u + if (setup_called > 1) { + printk("\ni91u: %s\n", setup_str); + printk("i91u: usage: i91u[=]\n"); + i91u_panic("i91u panics in line %d", __LINE__); + } + i91u_debug = setup_debug; +#endif + } /* Get total number of adapters in the motherboard */ iAdapters = tul_NewReturnNumberOfAdapters(); if (iAdapters == 0) /* If no tulip founded, return */ @@ -273,6 +386,9 @@ for (i = 0, pHCB = &tul_hcs[0]; /* Get pointer for control block */ i < tul_num_ch; i++, pHCB++) { + pHCB->pSRB_head = NULL; /* Initial SRB save queue */ + pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ + pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ get_tulipPCIConfig(pHCB, i); dBiosAdr = pHCB->HCS_BIOS; @@ -314,7 +430,7 @@ return 1; } +static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, Scsi_Cmnd * SCpnt) -static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt) { /* Create corresponding SCB */ struct scatterlist *pSrbSG; SG *pSG; /* Pointer to SG list */ @@ -382,29 +498,38 @@ } } +/* + * Queue a command and setup interrupts for a free bus. + */ +int i91u_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) -static int i91u_queuecommand(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) { - HCS *pHCB = (HCS *) cmd->device->host->base; register SCB *pSCB; + HCS *pHCB; /* Point to Host adapter control block */ + if (SCpnt->device->lun > 16) { /* 07/22/98 */ - cmd->scsi_done = done; + SCpnt->result = (DID_TIME_OUT << 16); + done(SCpnt); /* Notify system DONE */ + return (0); + } + pHCB = (HCS *) SCpnt->device->host->base; - pSCB = tul_alloc_scb(pHCB); - if (!pSCB) - return SCSI_MLQUEUE_HOST_BUSY; + SCpnt->scsi_done = done; + /* Get free SCSI control block */ + if ((pSCB = tul_alloc_scb(pHCB)) == NULL) { + i91uAppendSRBToQueue(pHCB, SCpnt); /* Buffer this request */ + return (0); + } + i91uBuildSCB(pHCB, pSCB, SCpnt); + tul_exec_scb(pHCB, pSCB); /* Start execute SCB */ + return (0); - i91uBuildSCB(pHCB, pSCB, cmd); - tul_exec_scb(pHCB, pSCB); - return 0; } -#if 0 /* no new EH yet */ /* * Abort a queued command * (commands that are on the bus can't be aborted easily) */ +int i91u_abort(Scsi_Cmnd * SCpnt) -static int i91u_abort(struct scsi_cmnd * SCpnt) { HCS *pHCB; @@ -416,7 +541,7 @@ * Reset registers, reset a hanging bus and * kill active and disconnected commands for target w/o soft reset */ +int i91u_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags) -static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags) { /* I need Host Control Block Information */ HCS *pHCB; @@ -425,11 +550,10 @@ if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) return tul_reset_scsi_bus(pHCB); else + return tul_device_reset(pHCB, (ULONG) SCpnt, SCpnt->device->id, reset_flags); - return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags); } -#endif +int i91u_bus_reset(Scsi_Cmnd * SCpnt) -static int i91u_bus_reset(struct scsi_cmnd * SCpnt) { HCS *pHCB; @@ -441,7 +565,7 @@ /* * Return the "logical geometry" */ +int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev, -static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev, sector_t capacity, int *info_array) { HCS *pHcb; /* Point to Host adapter control block */ @@ -483,7 +607,7 @@ if (cmnd->SCp.ptr) { dma_unmap_single(&pci_dev->dev, (dma_addr_t)((unsigned long)cmnd->SCp.ptr), + SENSE_SIZE, SCSI_DATA_READ); - SENSE_SIZE, DMA_FROM_DEVICE); cmnd->SCp.ptr = NULL; } @@ -514,7 +638,7 @@ *****************************************************************************/ static void i91uSCBPost(BYTE * pHcb, BYTE * pScb) { + Scsi_Cmnd *pSRB; /* Pointer to SCSI request block */ - struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */ HCS *pHCB; SCB *pSCB; @@ -569,36 +693,35 @@ i91u_unmap_cmnd(pHCB->pci_dev, pSRB); pSRB->scsi_done(pSRB); /* Notify system DONE */ + if ((pSRB = i91uPopSRBFromQueue(pHCB)) != NULL) + /* Find the next pending SRB */ + { /* Assume resend will success */ + /* Reuse old SCB */ + i91uBuildSCB(pHCB, pSCB, pSRB); /* Create corresponding SCB */ + tul_exec_scb(pHCB, pSCB); /* Start execute SCB */ + } else { /* No Pending SRB */ + tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ + } + return; +} + +/* + * Dump the current driver status and panic... + */ +static void i91u_panic(char *msg) +{ + printk("\ni91u_panic: %s\n", msg); + panic("i91u panic"); - tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ } /* * Release ressources */ +int i91u_release(struct Scsi_Host *hreg) -static int i91u_release(struct Scsi_Host *hreg) { free_irq(hreg->irq, hreg); release_region(hreg->io_port, 256); return 0; } MODULE_LICENSE("Dual BSD/GPL"); - -static struct scsi_host_template driver_template = { - .proc_name = "INI9100U", - .name = i91u_REVID, - .detect = i91u_detect, - .release = i91u_release, - .queuecommand = i91u_queuecommand, -// .abort = i91u_abort, -// .reset = i91u_reset, - .eh_bus_reset_handler = i91u_bus_reset, - .bios_param = i91u_biosparam, - .can_queue = 1, - .this_id = 1, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 1, - .use_clustering = ENABLE_CLUSTERING, -}; -#include "scsi_module.c" - reverted: --- /dev/null Wed Dec 31 16:00:00 196900 +++ a/drivers/scsi/ini9100u.h 2004-10-01 19:21:44 -07:00 @@ -0,0 +1,251 @@ +/************************************************************************** + * Initio 9100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU General Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************* + * + * Module: ini9100u.h + * Description: INI-9100U/UW LINUX device driver header + * Revision History: + * 06/18/96 Harry Chen, Initial Version 1.00A (Beta) + * 06/23/98 hc - v1.01k + * - Get it work for kernel version >= 2.1.75 + * 12/09/98 bv - v1.03a + * - Removed unused code + * 12/13/98 bv - v1.03b + * - Add spinlocks to HCS structure. + * 21/01/99 bv - v1.03e + * - Added PCI_ID structure + **************************************************************************/ + +#ifndef CVT_LINUX_VERSION +#define CVT_LINUX_VERSION(V,P,S) (((V) * 65536) + ((P) * 256) + (S)) +#endif + +#ifndef LINUX_VERSION_CODE +#include +#endif +#include + +extern int i91u_detect(Scsi_Host_Template *); +extern int i91u_release(struct Scsi_Host *); +extern int i91u_command(Scsi_Cmnd *); +extern int i91u_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *)); +extern int i91u_abort(Scsi_Cmnd *); +extern int i91u_reset(Scsi_Cmnd *, unsigned int); +extern int i91u_bus_reset(Scsi_Cmnd *); +extern int i91u_biosparam(struct scsi_device *, struct block_device *, + sector_t, int *); + +#define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" + +#define VIRT_TO_BUS(i) (unsigned int) virt_to_bus((void *)(i)) +#define ULONG unsigned long +#define USHORT unsigned short +#define UCHAR unsigned char +#define BYTE u8 +#define WORD unsigned short +#define DWORD unsigned long +#define UBYTE u8 +#define UWORD unsigned short +#define UDWORD unsigned long +#define U32 u32 + +#ifndef TRUE +#define TRUE (1) /* boolean true */ +#endif +#ifndef FALSE +#define FALSE (0) /* boolean false */ +#endif +#ifndef FAILURE +#define FAILURE (-1) +#endif + +#define i91u_MAXQUEUE 2 +#define TOTAL_SG_ENTRY 32 +#define MAX_TARGETS 16 +#define SENSE_SIZE 14 + +#define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ +#define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ +#define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ +#define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ +#define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ +#define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ + +/************************************************************************/ +/* Vendor ID/Device ID Pair Structure */ +/************************************************************************/ +typedef struct PCI_ID_Struc { + unsigned short vendor_id; + unsigned short device_id; +} PCI_ID; + +/************************************************************************/ +/* Scatter-Gather Element Structure */ +/************************************************************************/ +typedef struct SG_Struc { + U32 SG_Ptr; /* Data Pointer */ + U32 SG_Len; /* Data Length */ +} SG; + +/*********************************************************************** + SCSI Control Block +************************************************************************/ +typedef struct Scsi_Ctrl_Blk { + U32 SCB_InitioReserved[9]; /* 0 */ + + UBYTE SCB_Opcode; /*24 SCB command code */ + UBYTE SCB_Flags; /*25 SCB Flags */ + UBYTE SCB_Target; /*26 Target Id */ + UBYTE SCB_Lun; /*27 Lun */ + U32 SCB_BufPtr; /*28 Data Buffer Pointer */ + U32 SCB_BufLen; /*2C Data Allocation Length */ + UBYTE SCB_SGLen; /*30 SG list # */ + UBYTE SCB_SenseLen; /*31 Sense Allocation Length */ + UBYTE SCB_HaStat; /*32 */ + UBYTE SCB_TaStat; /*33 */ + UBYTE SCB_CDBLen; /*34 CDB Length */ + UBYTE SCB_Ident; /*35 Identify */ + UBYTE SCB_TagMsg; /*36 Tag Message */ + UBYTE SCB_TagId; /*37 Queue Tag */ + UBYTE SCB_CDB[12]; /*38 */ + U32 SCB_SGPAddr; /*44 SG List/Sense Buf phy. Addr. */ + U32 SCB_SensePtr; /*48 Sense data pointer */ + void (*SCB_Post) (BYTE *, BYTE *); /*4C POST routine */ + Scsi_Cmnd *SCB_Srb; /*50 SRB Pointer */ + SG SCB_SGList[TOTAL_SG_ENTRY]; /*54 Start of SG list */ +} SCB; + +/* Opcodes of SCB_Opcode */ +#define ExecSCSI 0x1 +#define BusDevRst 0x2 +#define AbortCmd 0x3 + +/* Bit Definition for SCB_Flags */ +#define SCF_DONE 0x01 +#define SCF_POST 0x02 +#define SCF_SENSE 0x04 +#define SCF_DIR 0x18 +#define SCF_NO_DCHK 0x00 +#define SCF_DIN 0x08 +#define SCF_DOUT 0x10 +#define SCF_NO_XF 0x18 +#define SCF_POLL 0x40 +#define SCF_SG 0x80 + +/* Error Codes for SCB_HaStat */ +#define HOST_SEL_TOUT 0x11 +#define HOST_DO_DU 0x12 +#define HOST_BUS_FREE 0x13 +#define HOST_BAD_PHAS 0x14 +#define HOST_INV_CMD 0x16 +#define HOST_SCSI_RST 0x1B +#define HOST_DEV_RST 0x1C + +/* Error Codes for SCB_TaStat */ +#define TARGET_CHKCOND 0x02 +#define TARGET_BUSY 0x08 + +/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */ +#define MSG_STAG 0x20 +#define MSG_HTAG 0x21 +#define MSG_OTAG 0x22 + +/*********************************************************************** + Target Device Control Structure +**********************************************************************/ + +typedef struct Tar_Ctrl_Struc { + ULONG TCS_InitioReserved; /* 0 */ + + UWORD TCS_DrvFlags; /* 4 */ + UBYTE TCS_DrvHead; /* 6 */ + UBYTE TCS_DrvSector; /* 7 */ +} TCS; + +/*********************************************************************** + Target Device Control Structure +**********************************************************************/ +/* Bit Definition for TCF_DrvFlags */ +#define TCF_DRV_255_63 0x0400 + +/*********************************************************************** + Host Adapter Control Structure +************************************************************************/ +typedef struct Ha_Ctrl_Struc { + UWORD HCS_Base; /* 00 */ + UWORD HCS_BIOS; /* 02 */ + UBYTE HCS_Intr; /* 04 */ + UBYTE HCS_SCSI_ID; /* 05 */ + UBYTE HCS_MaxTar; /* 06 */ + UBYTE HCS_NumScbs; /* 07 */ + + UBYTE HCS_Flags; /* 08 */ + UBYTE HCS_Index; /* 09 */ + UBYTE HCS_Reserved[2]; /* 0a */ + ULONG HCS_InitioReserved[27]; /* 0C */ + TCS HCS_Tcs[16]; /* 78 -> 16 Targets */ + Scsi_Cmnd *pSRB_head; /* SRB save queue header */ + Scsi_Cmnd *pSRB_tail; /* SRB save queue tail */ + spinlock_t HCS_AvailLock; + spinlock_t HCS_SemaphLock; + spinlock_t pSRB_lock; + struct pci_dev *pci_dev; +} HCS; + +/* Bit Definition for HCB_Flags */ +#define HCF_EXPECT_RESET 0x10 + +/* SCSI related definition */ +#define DISC_NOT_ALLOW 0x80 /* Disconnect is not allowed */ +#define DISC_ALLOW 0xC0 /* Disconnect is allowed */ reverted: --- /dev/null Wed Dec 31 16:00:00 196900 +++ a/drivers/scsi/inia100.c 2004-10-01 19:21:44 -07:00 @@ -0,0 +1,580 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU General Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************** + * + * module: inia100.c + * DESCRIPTION: + * This is the Linux low-level SCSI driver for Initio INIA100 SCSI host + * adapters + * 09/24/98 hl - v1.02 initial production release. + * 12/19/98 bv - v1.02a Use spinlocks for 2.1.95 and up. + * 06/25/02 Doug Ledford - v1.02d + * - Remove limit on number of controllers + * - Port to DMA mapping API + * - Clean up interrupt handler registration + * - Fix memory leaks + * - Fix allocation of scsi host structs and private data + * 18/11/03 Christoph Hellwig + * - Port to new probing API + * - Fix some more leaks in init failure cases + * TODO: + * - use list.h macros for SCB queue + * ( - merge with i60uscsi.c ) + **************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "inia100.h" + +#define ORC_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) + +char *inia100_Copyright = "Copyright (C) 1998-99"; +char *inia100_InitioName = "by Initio Corporation"; +char *inia100_ProductName = "INI-A100U2W"; +char *inia100_Version = "v1.02d"; + +/* ---- EXTERNAL FUNCTIONS ---- */ +extern void inia100SCBPost(BYTE * pHcb, BYTE * pScb); +extern int init_inia100Adapter_table(int); +extern ORC_SCB *orc_alloc_scb(ORC_HCS * hcsp); +extern void orc_exec_scb(ORC_HCS * hcsp, ORC_SCB * scbp); +extern void orc_release_scb(ORC_HCS * hcsp, ORC_SCB * scbp); +extern void orc_release_dma(ORC_HCS * hcsp, struct scsi_cmnd * cmnd); +extern void orc_interrupt(ORC_HCS * hcsp); +extern int orc_device_reset(ORC_HCS * pHCB, struct scsi_cmnd *SCpnt, unsigned int target); +extern int orc_reset_scsi_bus(ORC_HCS * pHCB); +extern int abort_SCB(ORC_HCS * hcsp, ORC_SCB * pScb); +extern int orc_abort_srb(ORC_HCS * hcsp, struct scsi_cmnd *SCpnt); +extern int init_orchid(ORC_HCS * hcsp); + +/***************************************************************************** + Function name : inia100AppendSRBToQueue + Description : This function will push current request into save list + Input : pSRB - Pointer to SCSI request block. + pHCB - Pointer to host adapter structure + Output : None. + Return : None. +*****************************************************************************/ +static void inia100AppendSRBToQueue(ORC_HCS * pHCB, struct scsi_cmnd * pSRB) +{ + ULONG flags; + + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); + + pSRB->SCp.ptr = NULL; /* Pointer to next */ + if (pHCB->pSRB_head == NULL) + pHCB->pSRB_head = pSRB; + else + pHCB->pSRB_tail->SCp.ptr = (char *)pSRB; /* Pointer to next */ + pHCB->pSRB_tail = pSRB; + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); + return; +} + +/***************************************************************************** + Function name : inia100PopSRBFromQueue + Description : This function will pop current request from save list + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static struct scsi_cmnd *inia100PopSRBFromQueue(ORC_HCS * pHCB) +{ + struct scsi_cmnd *pSRB; + ULONG flags; + spin_lock_irqsave(&(pHCB->pSRB_lock), flags); + if ((pSRB = (struct scsi_cmnd *) pHCB->pSRB_head) != NULL) { + pHCB->pSRB_head = (struct scsi_cmnd *) pHCB->pSRB_head->SCp.ptr; + pSRB->SCp.ptr = NULL; + } + spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags); + return (pSRB); +} + +/***************************************************************************** + Function name : inia100BuildSCB + Description : + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static void inia100BuildSCB(ORC_HCS * pHCB, ORC_SCB * pSCB, struct scsi_cmnd * SCpnt) +{ /* Create corresponding SCB */ + struct scatterlist *pSrbSG; + ORC_SG *pSG; /* Pointer to SG list */ + int i, count_sg; + U32 TotalLen; + ESCB *pEScb; + + pEScb = pSCB->SCB_EScb; + pEScb->SCB_Srb = SCpnt; + pSG = NULL; + + pSCB->SCB_Opcode = ORC_EXECSCSI; + pSCB->SCB_Flags = SCF_NO_DCHK; /* Clear done bit */ + pSCB->SCB_Target = SCpnt->device->id; + pSCB->SCB_Lun = SCpnt->device->lun; + pSCB->SCB_Reserved0 = 0; + pSCB->SCB_Reserved1 = 0; + pSCB->SCB_SGLen = 0; + + if ((pSCB->SCB_XferLen = (U32) SCpnt->request_bufflen)) { + pSG = (ORC_SG *) & pEScb->ESCB_SGList[0]; + if (SCpnt->use_sg) { + TotalLen = 0; + pSrbSG = (struct scatterlist *) SCpnt->request_buffer; + count_sg = pci_map_sg(pHCB->pdev, pSrbSG, SCpnt->use_sg, + SCpnt->sc_data_direction); + pSCB->SCB_SGLen = (U32) (count_sg * 8); + for (i = 0; i < count_sg; i++, pSG++, pSrbSG++) { + pSG->SG_Ptr = (U32) sg_dma_address(pSrbSG); + pSG->SG_Len = (U32) sg_dma_len(pSrbSG); + TotalLen += (U32) sg_dma_len(pSrbSG); + } + } else if (SCpnt->request_bufflen != 0) {/* Non SG */ + pSCB->SCB_SGLen = 0x8; + pSG->SG_Ptr = (U32) pci_map_single(pHCB->pdev, + SCpnt->request_buffer, SCpnt->request_bufflen, + SCpnt->sc_data_direction); + SCpnt->host_scribble = (void *)pSG->SG_Ptr; + pSG->SG_Len = (U32) SCpnt->request_bufflen; + } else { + pSCB->SCB_SGLen = 0; + pSG->SG_Ptr = 0; + pSG->SG_Len = 0; + } + } + pSCB->SCB_SGPAddr = (U32) pSCB->SCB_SensePAddr; + pSCB->SCB_HaStat = 0; + pSCB->SCB_TaStat = 0; + pSCB->SCB_Link = 0xFF; + pSCB->SCB_SenseLen = SENSE_SIZE; + pSCB->SCB_CDBLen = SCpnt->cmd_len; + if (pSCB->SCB_CDBLen >= IMAX_CDB) { + printk("max cdb length= %x\b", SCpnt->cmd_len); + pSCB->SCB_CDBLen = IMAX_CDB; + } + pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; + if (SCpnt->device->tagged_supported) { /* Tag Support */ + pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ + } else { + pSCB->SCB_TagMsg = 0; /* No tag support */ + } + memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, pSCB->SCB_CDBLen); + return; +} + +/***************************************************************************** + Function name : inia100_queue + Description : Queue a command and setup interrupts for a free bus. + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static int inia100_queue(struct scsi_cmnd * SCpnt, void (*done) (struct scsi_cmnd *)) +{ + register ORC_SCB *pSCB; + ORC_HCS *pHCB; /* Point to Host adapter control block */ + + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; + SCpnt->scsi_done = done; + /* Get free SCSI control block */ + if ((pSCB = orc_alloc_scb(pHCB)) == NULL) { + inia100AppendSRBToQueue(pHCB, SCpnt); /* Buffer this request */ + /* printk("inia100_entry: can't allocate SCB\n"); */ + return (0); + } + inia100BuildSCB(pHCB, pSCB, SCpnt); + orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ + + return (0); +} + +/***************************************************************************** + Function name : inia100_abort + Description : Abort a queued command. + (commands that are on the bus can't be aborted easily) + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static int inia100_abort(struct scsi_cmnd * SCpnt) +{ + ORC_HCS *hcsp; + + hcsp = (ORC_HCS *) SCpnt->device->host->hostdata; + return orc_abort_srb(hcsp, SCpnt); +} + +/***************************************************************************** + Function name : inia100_reset + Description : Reset registers, reset a hanging bus and + kill active and disconnected commands for target w/o soft reset + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static int inia100_bus_reset(struct scsi_cmnd * SCpnt) +{ /* I need Host Control Block Information */ + ORC_HCS *pHCB; + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; + return orc_reset_scsi_bus(pHCB); +} + +/***************************************************************************** + Function name : inia100_device_reset + Description : Reset the device + Input : pHCB - Pointer to host adapter structure + Output : None. + Return : pSRB - Pointer to SCSI request block. +*****************************************************************************/ +static int inia100_device_reset(struct scsi_cmnd * SCpnt) +{ /* I need Host Control Block Information */ + ORC_HCS *pHCB; + pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; + return orc_device_reset(pHCB, SCpnt, SCpnt->device->id); + +} + +/***************************************************************************** + Function name : inia100SCBPost + Description : This is callback routine be called when orc finish one + SCSI command. + Input : pHCB - Pointer to host adapter control block. + pSCB - Pointer to SCSI control block. + Output : None. + Return : None. +*****************************************************************************/ +void inia100SCBPost(BYTE * pHcb, BYTE * pScb) +{ + struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */ + ORC_HCS *pHCB; + ORC_SCB *pSCB; + ESCB *pEScb; + + pHCB = (ORC_HCS *) pHcb; + pSCB = (ORC_SCB *) pScb; + pEScb = pSCB->SCB_EScb; + if ((pSRB = (struct scsi_cmnd *) pEScb->SCB_Srb) == 0) { + printk("inia100SCBPost: SRB pointer is empty\n"); + orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ + return; + } + pEScb->SCB_Srb = NULL; + + switch (pSCB->SCB_HaStat) { + case 0x0: + case 0xa: /* Linked command complete without error and linked normally */ + case 0xb: /* Linked command complete without error interrupt generated */ + pSCB->SCB_HaStat = 0; + break; + + case 0x11: /* Selection time out-The initiator selection or target + reselection was not complete within the SCSI Time out period */ + pSCB->SCB_HaStat = DID_TIME_OUT; + break; + + case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus + phase sequence was requested by the target. The host adapter + will generate a SCSI Reset Condition, notifying the host with + a SCRD interrupt */ + pSCB->SCB_HaStat = DID_RESET; + break; + + case 0x1a: /* SCB Aborted. 07/21/98 */ + pSCB->SCB_HaStat = DID_ABORT; + break; + + case 0x12: /* Data overrun/underrun-The target attempted to transfer more data + than was allocated by the Data Length field or the sum of the + Scatter / Gather Data Length fields. */ + case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ + case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */ + + default: + printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); + pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ + break; + } + + if (pSCB->SCB_TaStat == 2) { /* Check condition */ + memcpy((unsigned char *) &pSRB->sense_buffer[0], + (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE); + } + pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); + orc_release_dma(pHCB, pSRB); /* release DMA before we call scsi_done */ + pSRB->scsi_done(pSRB); /* Notify system DONE */ + + /* Find the next pending SRB */ + if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) { /* Assume resend will success */ + inia100BuildSCB(pHCB, pSCB, pSRB); /* Create corresponding SCB */ + orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ + } else { + orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ + } + return; +} + +/* + * Interrupt handler (main routine of the driver) + */ +static irqreturn_t inia100_intr(int irqno, void *devid, struct pt_regs *regs) +{ + struct Scsi_Host *host = (struct Scsi_Host *)devid; + ORC_HCS *pHcb = (ORC_HCS *)host->hostdata; + unsigned long flags; + + spin_lock_irqsave(host->host_lock, flags); + orc_interrupt(pHcb); + spin_unlock_irqrestore(host->host_lock, flags); + + return IRQ_HANDLED; +} + +static struct scsi_host_template inia100_template = { + .proc_name = "inia100", + .name = inia100_REVID, + .queuecommand = inia100_queue, + .eh_abort_handler = inia100_abort, + .eh_bus_reset_handler = inia100_bus_reset, + .eh_device_reset_handler = inia100_device_reset, + .can_queue = 1, + .this_id = 1, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 1, + .use_clustering = ENABLE_CLUSTERING, +}; + +static int __devinit inia100_probe_one(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + struct Scsi_Host *shost; + ORC_HCS *pHCB; + unsigned long port, bios; + int error = -ENODEV; + u32 sz; + unsigned long dBiosAdr; + char *pbBiosAdr; + + if (pci_enable_device(pdev)) + goto out; + if (pci_set_dma_mask(pdev, 0xffffffffULL)) { + printk(KERN_WARNING "Unable to set 32bit DMA " + "on inia100 adapter, ignoring.\n"); + goto out_disable_device; + } + + pci_set_master(pdev); + + port = pci_resource_start(pdev, 0); + if (!request_region(port, 256, "inia100")) { + printk(KERN_WARNING "inia100: io port 0x%lx, is busy.\n", port); + goto out_disable_device; + } + + /* <02> read from base address + 0x50 offset to get the bios balue. */ + bios = ORC_RDWORD(port, 0x50); + + + shost = scsi_host_alloc(&inia100_template, sizeof(ORC_HCS)); + if (!shost) + goto out_release_region; + + pHCB = (ORC_HCS *)shost->hostdata; + pHCB->pdev = pdev; + pHCB->HCS_Base = port; + pHCB->HCS_BIOS = bios; + pHCB->pSRB_head = NULL; /* Initial SRB save queue */ + pHCB->pSRB_tail = NULL; /* Initial SRB save queue */ + pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED; /* SRB save queue lock */ + pHCB->BitAllocFlagLock = SPIN_LOCK_UNLOCKED; + + /* Get total memory needed for SCB */ + sz = ORC_MAXQUEUE * sizeof(ORC_SCB); + pHCB->HCS_virScbArray = pci_alloc_consistent(pdev, sz, + &pHCB->HCS_physScbArray); + if (!pHCB->HCS_virScbArray) { + printk("inia100: SCB memory allocation error\n"); + goto out_host_put; + } + memset(pHCB->HCS_virScbArray, 0, sz); + + /* Get total memory needed for ESCB */ + sz = ORC_MAXQUEUE * sizeof(ESCB); + pHCB->HCS_virEscbArray = pci_alloc_consistent(pdev, sz, + &pHCB->HCS_physEscbArray); + if (!pHCB->HCS_virEscbArray) { + printk("inia100: ESCB memory allocation error\n"); + goto out_free_scb_array; + } + memset(pHCB->HCS_virEscbArray, 0, sz); + + dBiosAdr = pHCB->HCS_BIOS; + dBiosAdr = (dBiosAdr << 4); + pbBiosAdr = phys_to_virt(dBiosAdr); + if (init_orchid(pHCB)) { /* Initialize orchid chip */ + printk("inia100: initial orchid fail!!\n"); + goto out_free_escb_array; + } + + shost->io_port = pHCB->HCS_Base; + shost->n_io_port = 0xff; + shost->can_queue = ORC_MAXQUEUE; + shost->unique_id = shost->io_port; + shost->max_id = pHCB->HCS_MaxTar; + shost->max_lun = 16; + shost->irq = pHCB->HCS_Intr = pdev->irq; + shost->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ + shost->sg_tablesize = TOTAL_SG_ENTRY; + + /* Initial orc chip */ + error = request_irq(pdev->irq, inia100_intr, SA_SHIRQ, + "inia100", shost); + if (error < 0) { + printk(KERN_WARNING "inia100: unable to get irq %d\n", + pdev->irq); + goto out_free_escb_array; + } + + pci_set_drvdata(pdev, shost); + + error = scsi_add_host(shost, &pdev->dev); + if (error) + goto out_free_irq; + + scsi_scan_host(shost); + return 0; + + out_free_irq: + free_irq(shost->irq, shost); + out_free_escb_array: + pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB), + pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray); + out_free_scb_array: + pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB), + pHCB->HCS_virScbArray, pHCB->HCS_physScbArray); + out_host_put: + scsi_host_put(shost); + out_release_region: + release_region(port, 256); + out_disable_device: + pci_disable_device(pdev); + out: + return error; +} + +static void __devexit inia100_remove_one(struct pci_dev *pdev) +{ + struct Scsi_Host *shost = pci_get_drvdata(pdev); + ORC_HCS *pHCB = (ORC_HCS *)shost->hostdata; + + scsi_remove_host(shost); + + free_irq(shost->irq, shost); + pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ESCB), + pHCB->HCS_virEscbArray, pHCB->HCS_physEscbArray); + pci_free_consistent(pdev, ORC_MAXQUEUE * sizeof(ORC_SCB), + pHCB->HCS_virScbArray, pHCB->HCS_physScbArray); + release_region(shost->io_port, 256); + + scsi_host_put(shost); +} + +static struct pci_device_id inia100_pci_tbl[] = { + {ORC_VENDOR_ID, ORC_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + {0,} +}; +MODULE_DEVICE_TABLE(pci, inia100_pci_tbl); + +static struct pci_driver inia100_pci_driver = { + .name = "inia100", + .id_table = inia100_pci_tbl, + .probe = inia100_probe_one, + .remove = __devexit_p(inia100_remove_one), +}; + +static int __init inia100_init(void) +{ + return pci_module_init(&inia100_pci_driver); +} + +static void __exit inia100_exit(void) +{ + pci_unregister_driver(&inia100_pci_driver); +} + +MODULE_DESCRIPTION("Initio A100U2W SCSI driver"); +MODULE_AUTHOR("Initio Corporation"); +MODULE_LICENSE("Dual BSD/GPL"); + +module_init(inia100_init); +module_exit(inia100_exit); reverted: --- /dev/null Wed Dec 31 16:00:00 196900 +++ a/drivers/scsi/inia100.h 2004-10-01 19:21:43 -07:00 @@ -0,0 +1,533 @@ +/************************************************************************** + * Initio A100 device driver for Linux. + * + * Copyright (c) 1994-1998 Initio Corporation + * All rights reserved. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * -------------------------------------------------------------------------- + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU General Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + ************************************************************************** + * + * Module: inia100.h + * Description: INI-A100U2W LINUX device driver header + * Revision History: + * 06/18/98 HL, Initial production Version 1.02 + * 12/19/98 bv, Use spinlocks for 2.1.95 and up + * 06/25/02 Doug Ledford + * - This and the i60uscsi.h file are almost identical, + * merged them into a single header used by both .c files. + ****************************************************************************/ + +#include +#include +#include + +#define inia100_REVID "Initio INI-A100U2W SCSI device driver; Revision: 1.02d" + +#define ULONG unsigned long +#define PVOID void * +#define USHORT unsigned short +#define UCHAR unsigned char +#define BYTE unsigned char +#define WORD unsigned short +#define DWORD unsigned long +#define UBYTE unsigned char +#define UWORD unsigned short +#define UDWORD unsigned long +#define U32 u32 + +#ifndef FAILURE +#define FAILURE (-1) +#endif +#if 1 +#define ORC_MAXQUEUE 245 +#define ORC_MAXTAGS 64 +#else +#define ORC_MAXQUEUE 25 +#define ORC_MAXTAGS 8 +#endif + +#define TOTAL_SG_ENTRY 32 +#define MAX_TARGETS 16 +#define IMAX_CDB 15 +#define SENSE_SIZE 14 +#define SUCCESSFUL 0x00 + +#define I920_DEVICE_ID 0x0002 /* Initio's inic-950 product ID */ + +/************************************************************************/ +/* Scatter-Gather Element Structure */ +/************************************************************************/ +typedef struct ORC_SG_Struc { + U32 SG_Ptr; /* Data Pointer */ + U32 SG_Len; /* Data Length */ +} ORC_SG; + +/* SCSI related definition */ +#define DISC_NOT_ALLOW 0x80 /* Disconnect is not allowed */ +#define DISC_ALLOW 0xC0 /* Disconnect is allowed */ + + +#define ORC_OFFSET_SCB 16 +#define ORC_MAX_SCBS 250 +#define MAX_CHANNELS 2 +#define MAX_ESCB_ELE 64 +#define TCF_DRV_255_63 0x0400 + +/********************************************************/ +/* Orchid Configuration Register Set */ +/********************************************************/ +#define ORC_PVID 0x00 /* Vendor ID */ +#define ORC_VENDOR_ID 0x1101 /* Orchid vendor ID */ +#define ORC_PDID 0x02 /* Device ID */ +#define ORC_DEVICE_ID 0x1060 /* Orchid device ID */ +#define ORC_COMMAND 0x04 /* Command */ +#define BUSMS 0x04 /* BUS MASTER Enable */ +#define IOSPA 0x01 /* IO Space Enable */ +#define ORC_STATUS 0x06 /* Status register */ +#define ORC_REVISION 0x08 /* Revision number */ +#define ORC_BASE 0x10 /* Base address */ +#define ORC_BIOS 0x50 /* Expansion ROM base address */ +#define ORC_INT_NUM 0x3C /* Interrupt line */ +#define ORC_INT_PIN 0x3D /* Interrupt pin */ + +/********************************************************/ +/* Orchid Host Command Set */ +/********************************************************/ +#define ORC_CMD_NOP 0x00 /* Host command - NOP */ +#define ORC_CMD_VERSION 0x01 /* Host command - Get F/W version */ +#define ORC_CMD_ECHO 0x02 /* Host command - ECHO */ +#define ORC_CMD_SET_NVM 0x03 /* Host command - Set NVRAM */ +#define ORC_CMD_GET_NVM 0x04 /* Host command - Get NVRAM */ +#define ORC_CMD_GET_BUS_STATUS 0x05 /* Host command - Get SCSI bus status */ +#define ORC_CMD_ABORT_SCB 0x06 /* Host command - Abort SCB */ +#define ORC_CMD_ISSUE_SCB 0x07 /* Host command - Issue SCB */ + +/********************************************************/ +/* Orchid Register Set */ +/********************************************************/ +#define ORC_GINTS 0xA0 /* Global Interrupt Status */ +#define QINT 0x04 /* Reply Queue Interrupt */ +#define ORC_GIMSK 0xA1 /* Global Interrupt MASK */ +#define MQINT 0x04 /* Mask Reply Queue Interrupt */ +#define ORC_GCFG 0xA2 /* Global Configure */ +#define EEPRG 0x01 /* Enable EEPROM programming */ +#define ORC_GSTAT 0xA3 /* Global status */ +#define WIDEBUS 0x10 /* Wide SCSI Devices connected */ +#define ORC_HDATA 0xA4 /* Host Data */ +#define ORC_HCTRL 0xA5 /* Host Control */ +#define SCSIRST 0x80 /* SCSI bus reset */ +#define HDO 0x40 /* Host data out */ +#define HOSTSTOP 0x02 /* Host stop RISC engine */ +#define DEVRST 0x01 /* Device reset */ +#define ORC_HSTUS 0xA6 /* Host Status */ +#define HDI 0x02 /* Host data in */ +#define RREADY 0x01 /* RISC engine is ready to receive */ +#define ORC_NVRAM 0xA7 /* Nvram port address */ +#define SE2CS 0x008 +#define SE2CLK 0x004 +#define SE2DO 0x002 +#define SE2DI 0x001 +#define ORC_PQUEUE 0xA8 /* Posting queue FIFO */ +#define ORC_PQCNT 0xA9 /* Posting queue FIFO Cnt */ +#define ORC_RQUEUE 0xAA /* Reply queue FIFO */ +#define ORC_RQUEUECNT 0xAB /* Reply queue FIFO Cnt */ +#define ORC_FWBASEADR 0xAC /* Firmware base address */ + +#define ORC_EBIOSADR0 0xB0 /* External Bios address */ +#define ORC_EBIOSADR1 0xB1 /* External Bios address */ +#define ORC_EBIOSADR2 0xB2 /* External Bios address */ +#define ORC_EBIOSDATA 0xB3 /* External Bios address */ + +#define ORC_SCBSIZE 0xB7 /* SCB size register */ +#define ORC_SCBBASE0 0xB8 /* SCB base address 0 */ +#define ORC_SCBBASE1 0xBC /* SCB base address 1 */ + +#define ORC_RISCCTL 0xE0 /* RISC Control */ +#define PRGMRST 0x002 +#define DOWNLOAD 0x001 +#define ORC_PRGMCTR0 0xE2 /* RISC program counter */ +#define ORC_PRGMCTR1 0xE3 /* RISC program counter */ +#define ORC_RISCRAM 0xEC /* RISC RAM data port 4 bytes */ + +typedef struct orc_extended_scb { /* Extended SCB */ + ORC_SG ESCB_SGList[TOTAL_SG_ENTRY]; /*0 Start of SG list */ + struct scsi_cmnd *SCB_Srb; /*50 SRB Pointer */ +} ESCB; + +/*********************************************************************** + SCSI Control Block +************************************************************************/ +typedef struct orc_scb { /* Scsi_Ctrl_Blk */ + UBYTE SCB_Opcode; /*00 SCB command code&residual */ + UBYTE SCB_Flags; /*01 SCB Flags */ + UBYTE SCB_Target; /*02 Target Id */ + UBYTE SCB_Lun; /*03 Lun */ + U32 SCB_Reserved0; /*04 Reserved for ORCHID must 0 */ + U32 SCB_XferLen; /*08 Data Transfer Length */ + U32 SCB_Reserved1; /*0C Reserved for ORCHID must 0 */ + U32 SCB_SGLen; /*10 SG list # * 8 */ + U32 SCB_SGPAddr; /*14 SG List Buf physical Addr */ + U32 SCB_SGPAddrHigh; /*18 SG Buffer high physical Addr */ + UBYTE SCB_HaStat; /*1C Host Status */ + UBYTE SCB_TaStat; /*1D Target Status */ + UBYTE SCB_Status; /*1E SCB status */ + UBYTE SCB_Link; /*1F Link pointer, default 0xFF */ + UBYTE SCB_SenseLen; /*20 Sense Allocation Length */ + UBYTE SCB_CDBLen; /*21 CDB Length */ + UBYTE SCB_Ident; /*22 Identify */ + UBYTE SCB_TagMsg; /*23 Tag Message */ + UBYTE SCB_CDB[IMAX_CDB]; /*24 SCSI CDBs */ + UBYTE SCB_ScbIdx; /*3C Index for this ORCSCB */ + U32 SCB_SensePAddr; /*34 Sense Buffer physical Addr */ + + ESCB *SCB_EScb; /*38 Extended SCB Pointer */ +#ifndef ALPHA + UBYTE SCB_Reserved2[4]; /*3E Reserved for Driver use */ +#endif +} ORC_SCB; + +/* Opcodes of ORCSCB_Opcode */ +#define ORC_EXECSCSI 0x00 /* SCSI initiator command with residual */ +#define ORC_BUSDEVRST 0x01 /* SCSI Bus Device Reset */ + +/* Status of ORCSCB_Status */ +#define ORCSCB_COMPLETE 0x00 /* SCB request completed */ +#define ORCSCB_POST 0x01 /* SCB is posted by the HOST */ + +/* Bit Definition for ORCSCB_Flags */ +#define SCF_DISINT 0x01 /* Disable HOST interrupt */ +#define SCF_DIR 0x18 /* Direction bits */ +#define SCF_NO_DCHK 0x00 /* Direction determined by SCSI */ +#define SCF_DIN 0x08 /* From Target to Initiator */ +#define SCF_DOUT 0x10 /* From Initiator to Target */ +#define SCF_NO_XF 0x18 /* No data transfer */ +#define SCF_POLL 0x40 + +/* Error Codes for ORCSCB_HaStat */ +#define HOST_SEL_TOUT 0x11 +#define HOST_DO_DU 0x12 +#define HOST_BUS_FREE 0x13 +#define HOST_BAD_PHAS 0x14 +#define HOST_INV_CMD 0x16 +#define HOST_SCSI_RST 0x1B +#define HOST_DEV_RST 0x1C + + +/* Error Codes for ORCSCB_TaStat */ +#define TARGET_CHK_COND 0x02 +#define TARGET_BUSY 0x08 +#define TARGET_TAG_FULL 0x28 + + +/* Queue tag msg: Simple_quque_tag, Head_of_queue_tag, Ordered_queue_tag */ +#define MSG_STAG 0x20 +#define MSG_HTAG 0x21 +#define MSG_OTAG 0x22 + +#define MSG_IGNOREWIDE 0x23 + +#define MSG_IDENT 0x80 +#define MSG_DISC 0x40 /* Disconnect allowed */ + + +/* SCSI MESSAGE */ +#define MSG_EXTEND 0x01 +#define MSG_SDP 0x02 +#define MSG_ABORT 0x06 +#define MSG_REJ 0x07 +#define MSG_NOP 0x08 +#define MSG_PARITY 0x09 +#define MSG_DEVRST 0x0C +#define MSG_STAG 0x20 + +/*********************************************************************** + Target Device Control Structure +**********************************************************************/ + +typedef struct ORC_Tar_Ctrl_Struc { + UBYTE TCS_DrvDASD; /* 6 */ + UBYTE TCS_DrvSCSI; /* 7 */ + UBYTE TCS_DrvHead; /* 8 */ + UWORD TCS_DrvFlags; /* 4 */ + UBYTE TCS_DrvSector; /* 7 */ +} ORC_TCS, *PORC_TCS; + +/* Bit Definition for TCF_DrvFlags */ +#define TCS_DF_NODASD_SUPT 0x20 /* Suppress OS/2 DASD Mgr support */ +#define TCS_DF_NOSCSI_SUPT 0x40 /* Suppress OS/2 SCSI Mgr support */ + + +/*********************************************************************** + Host Adapter Control Structure +************************************************************************/ +typedef struct ORC_Ha_Ctrl_Struc { + USHORT HCS_Base; /* 00 */ + UBYTE HCS_Index; /* 02 */ + UBYTE HCS_Intr; /* 04 */ + UBYTE HCS_SCSI_ID; /* 06 H/A SCSI ID */ + UBYTE HCS_BIOS; /* 07 BIOS configuration */ + + UBYTE HCS_Flags; /* 0B */ + UBYTE HCS_HAConfig1; /* 1B SCSI0MAXTags */ + UBYTE HCS_MaxTar; /* 1B SCSI0MAXTags */ + + USHORT HCS_Units; /* Number of units this adapter */ + USHORT HCS_AFlags; /* Adapter info. defined flags */ + ULONG HCS_Timeout; /* Adapter timeout value */ + PVOID HCS_virScbArray; /* 28 Virtual Pointer to SCB array */ + dma_addr_t HCS_physScbArray; /* Scb Physical address */ + PVOID HCS_virEscbArray; /* Virtual pointer to ESCB Scatter list */ + dma_addr_t HCS_physEscbArray; /* scatter list Physical address */ + UBYTE TargetFlag[16]; /* 30 target configuration, TCF_EN_TAG */ + UBYTE MaximumTags[16]; /* 40 ORC_MAX_SCBS */ + UBYTE ActiveTags[16][16]; /* 50 */ + ORC_TCS HCS_Tcs[16]; /* 28 */ + U32 BitAllocFlag[MAX_CHANNELS][8]; /* Max STB is 256, So 256/32 */ + spinlock_t BitAllocFlagLock; + struct scsi_cmnd *pSRB_head; + struct scsi_cmnd *pSRB_tail; + spinlock_t pSRB_lock; + struct pci_dev *pdev; +} ORC_HCS; + +/* Bit Definition for HCS_Flags */ + +#define HCF_SCSI_RESET 0x01 /* SCSI BUS RESET */ +#define HCF_PARITY 0x02 /* parity card */ +#define HCF_LVDS 0x10 /* parity card */ + +/* Bit Definition for TargetFlag */ + +#define TCF_EN_255 0x08 +#define TCF_EN_TAG 0x10 +#define TCF_BUSY 0x20 +#define TCF_DISCONNECT 0x40 +#define TCF_SPIN_UP 0x80 + +/* Bit Definition for HCS_AFlags */ +#define HCS_AF_IGNORE 0x01 /* Adapter ignore */ +#define HCS_AF_DISABLE_RESET 0x10 /* Adapter disable reset */ +#define HCS_AF_DISABLE_ADPT 0x80 /* Adapter disable */ + + +/*---------------------------------------*/ +/* TimeOut for RESET to complete (30s) */ +/* */ +/* After a RESET the drive is checked */ +/* every 200ms. */ +/*---------------------------------------*/ +#define DELAYED_RESET_MAX (30*1000L) +#define DELAYED_RESET_INTERVAL 200L + +/*----------------------------------------------*/ +/* TimeOut for IRQ from last interrupt (5s) */ +/*----------------------------------------------*/ +#define IRQ_TIMEOUT_INTERVAL (5*1000L) + +/*----------------------------------------------*/ +/* Retry Delay interval (200ms) */ +/*----------------------------------------------*/ +#define DELAYED_RETRY_INTERVAL 200L + +#define INQUIRY_SIZE 36 +#define CAPACITY_SIZE 8 +#define DEFAULT_SENSE_LEN 14 + +#define DEVICE_NOT_FOUND 0x86 + +/*----------------------------------------------*/ +/* Definition for PCI device */ +/*----------------------------------------------*/ +#define MAX_PCI_DEVICES 21 +#define MAX_PCI_BUSES 8 + +typedef struct Adpt_Struc { + USHORT ADPT_BIOS; /* 0 */ + UBYTE ADPT_BASE; /* 1 */ + UBYTE ADPT_Bus; /* 2 */ + UBYTE ADPT_Device; /* 3 */ + UBYTE ADPT_Reserved[3]; +} JACS, *PJACS; + +typedef struct _NVRAM { +/*----------header ---------------*/ + UCHAR SubVendorID0; /* 00 - Sub Vendor ID */ + UCHAR SubVendorID1; /* 00 - Sub Vendor ID */ + UCHAR SubSysID0; /* 02 - Sub System ID */ + UCHAR SubSysID1; /* 02 - Sub System ID */ + UCHAR SubClass; /* 04 - Sub Class */ + UCHAR VendorID0; /* 05 - Vendor ID */ + UCHAR VendorID1; /* 05 - Vendor ID */ + UCHAR DeviceID0; /* 07 - Device ID */ + UCHAR DeviceID1; /* 07 - Device ID */ + UCHAR Reserved0[2]; /* 09 - Reserved */ + UCHAR Revision; /* 0B - Revision of data structure */ + /* ----Host Adapter Structure ---- */ + UCHAR NumOfCh; /* 0C - Number of SCSI channel */ + UCHAR BIOSConfig1; /* 0D - BIOS configuration 1 */ + UCHAR BIOSConfig2; /* 0E - BIOS boot channel&target ID */ + UCHAR BIOSConfig3; /* 0F - BIOS configuration 3 */ + /* ----SCSI channel Structure ---- */ + /* from "CTRL-I SCSI Host Adapter SetUp menu " */ + UCHAR SCSI0Id; /* 10 - Channel 0 SCSI ID */ + UCHAR SCSI0Config; /* 11 - Channel 0 SCSI configuration */ + UCHAR SCSI0MaxTags; /* 12 - Channel 0 Maximum tags */ + UCHAR SCSI0ResetTime; /* 13 - Channel 0 Reset recovering time */ + UCHAR ReservedforChannel0[2]; /* 14 - Reserved */ + + /* ----SCSI target Structure ---- */ + /* from "CTRL-I SCSI device SetUp menu " */ + UCHAR Target00Config; /* 16 - Channel 0 Target 0 config */ + UCHAR Target01Config; /* 17 - Channel 0 Target 1 config */ + UCHAR Target02Config; /* 18 - Channel 0 Target 2 config */ + UCHAR Target03Config; /* 19 - Channel 0 Target 3 config */ + UCHAR Target04Config; /* 1A - Channel 0 Target 4 config */ + UCHAR Target05Config; /* 1B - Channel 0 Target 5 config */ + UCHAR Target06Config; /* 1C - Channel 0 Target 6 config */ + UCHAR Target07Config; /* 1D - Channel 0 Target 7 config */ + UCHAR Target08Config; /* 1E - Channel 0 Target 8 config */ + UCHAR Target09Config; /* 1F - Channel 0 Target 9 config */ + UCHAR Target0AConfig; /* 20 - Channel 0 Target A config */ + UCHAR Target0BConfig; /* 21 - Channel 0 Target B config */ + UCHAR Target0CConfig; /* 22 - Channel 0 Target C config */ + UCHAR Target0DConfig; /* 23 - Channel 0 Target D config */ + UCHAR Target0EConfig; /* 24 - Channel 0 Target E config */ + UCHAR Target0FConfig; /* 25 - Channel 0 Target F config */ + + UCHAR SCSI1Id; /* 26 - Channel 1 SCSI ID */ + UCHAR SCSI1Config; /* 27 - Channel 1 SCSI configuration */ + UCHAR SCSI1MaxTags; /* 28 - Channel 1 Maximum tags */ + UCHAR SCSI1ResetTime; /* 29 - Channel 1 Reset recovering time */ + UCHAR ReservedforChannel1[2]; /* 2A - Reserved */ + + /* ----SCSI target Structure ---- */ + /* from "CTRL-I SCSI device SetUp menu " */ + UCHAR Target10Config; /* 2C - Channel 1 Target 0 config */ + UCHAR Target11Config; /* 2D - Channel 1 Target 1 config */ + UCHAR Target12Config; /* 2E - Channel 1 Target 2 config */ + UCHAR Target13Config; /* 2F - Channel 1 Target 3 config */ + UCHAR Target14Config; /* 30 - Channel 1 Target 4 config */ + UCHAR Target15Config; /* 31 - Channel 1 Target 5 config */ + UCHAR Target16Config; /* 32 - Channel 1 Target 6 config */ + UCHAR Target17Config; /* 33 - Channel 1 Target 7 config */ + UCHAR Target18Config; /* 34 - Channel 1 Target 8 config */ + UCHAR Target19Config; /* 35 - Channel 1 Target 9 config */ + UCHAR Target1AConfig; /* 36 - Channel 1 Target A config */ + UCHAR Target1BConfig; /* 37 - Channel 1 Target B config */ + UCHAR Target1CConfig; /* 38 - Channel 1 Target C config */ + UCHAR Target1DConfig; /* 39 - Channel 1 Target D config */ + UCHAR Target1EConfig; /* 3A - Channel 1 Target E config */ + UCHAR Target1FConfig; /* 3B - Channel 1 Target F config */ + UCHAR reserved[3]; /* 3C - Reserved */ + /* ---------- CheckSum ---------- */ + UCHAR CheckSum; /* 3F - Checksum of NVRam */ +} NVRAM, *PNVRAM; + +/* Bios Configuration for nvram->BIOSConfig1 */ +#define NBC_BIOSENABLE 0x01 /* BIOS enable */ +#define NBC_CDROM 0x02 /* Support bootable CDROM */ +#define NBC_REMOVABLE 0x04 /* Support removable drive */ + +/* Bios Configuration for nvram->BIOSConfig2 */ +#define NBB_TARGET_MASK 0x0F /* Boot SCSI target ID number */ +#define NBB_CHANL_MASK 0xF0 /* Boot SCSI channel number */ + +/* Bit definition for nvram->SCSIConfig */ +#define NCC_BUSRESET 0x01 /* Reset SCSI bus at power up */ +#define NCC_PARITYCHK 0x02 /* SCSI parity enable */ +#define NCC_LVDS 0x10 /* Enable LVDS */ +#define NCC_ACTTERM1 0x20 /* Enable active terminator 1 */ +#define NCC_ACTTERM2 0x40 /* Enable active terminator 2 */ +#define NCC_AUTOTERM 0x80 /* Enable auto termination */ + +/* Bit definition for nvram->TargetxConfig */ +#define NTC_PERIOD 0x07 /* Maximum Sync. Speed */ +#define NTC_1GIGA 0x08 /* 255 head / 63 sectors (64/32) */ +#define NTC_NO_SYNC 0x10 /* NO SYNC. NEGO */ +#define NTC_NO_WIDESYNC 0x20 /* NO WIDE SYNC. NEGO */ +#define NTC_DISC_ENABLE 0x40 /* Enable SCSI disconnect */ +#define NTC_SPINUP 0x80 /* Start disk drive */ + +/* Default NVRam values */ +#define NBC_DEFAULT (NBC_ENABLE) +#define NCC_DEFAULT (NCC_BUSRESET | NCC_AUTOTERM | NCC_PARITYCHK) +#define NCC_MAX_TAGS 0x20 /* Maximum tags per target */ +#define NCC_RESET_TIME 0x0A /* SCSI RESET recovering time */ +#define NTC_DEFAULT (NTC_1GIGA | NTC_NO_WIDESYNC | NTC_DISC_ENABLE) + +typedef union { /* Union define for mechanism 1 */ + struct { + unsigned char RegNum; + unsigned char FcnNum:3; + unsigned char DeviceNum:5; + unsigned char BusNum; + unsigned char Reserved:7; + unsigned char Enable:1; + } sConfigAdr; + unsigned long lConfigAdr; +} CONFIG_ADR; + +typedef union { /* Union define for mechanism 2 */ + struct { + unsigned char RegNum; + unsigned char DeviceNum; + unsigned short Reserved; + } sHostAdr; + unsigned long lHostAdr; +} HOST_ADR; + +#define ORC_RD(x,y) (UCHAR)(inb( (int)((ULONG)((ULONG)x+(UCHAR)y)) )) +#define ORC_RDLONG(x,y) (long)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) + +#define ORC_WR( adr,data) outb( (UCHAR)(data), (int)(adr)) +#define ORC_WRSHORT(adr,data) outw( (UWORD)(data), (int)(adr)) +#define ORC_WRLONG( adr,data) outl( (ULONG)(data), (int)(adr)) + + + reverted: --- b/drivers/scsi/megaraid/megaraid_mbox.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/megaraid/megaraid_mbox.c 2004-10-01 19:21:44 -07:00 @@ -10,7 +10,7 @@ * 2 of the License, or (at your option) any later version. * * FILE : megaraid_mbox.c + * Version : v2.20.3.1 (August 24 2004) - * Version : v2.20.4 (September 27 2004) * * Authors: * Atul Mukker @@ -197,7 +197,7 @@ * ### global data ### */ static uint8_t megaraid_mbox_version[8] = + { 0x02, 0x20, 0x02, 0x00, 7, 22, 20, 4 }; - { 0x02, 0x20, 0x04, 0x00, 9, 27, 20, 4 }; /* @@ -3562,7 +3562,7 @@ for (i = 0; i < MBOX_MAX_USER_CMDS; i++) { scb = adapter->uscb_list + i; + ccb = raid_dev->ccb_list + i; - ccb = raid_dev->uccb_list + i; scb->ccb = (caddr_t)ccb; ccb->mbox64 = raid_dev->umbox64 + i; reverted: --- b/drivers/scsi/megaraid/megaraid_mbox.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/megaraid/megaraid_mbox.h 2004-10-01 19:21:44 -07:00 @@ -21,8 +21,8 @@ #include "megaraid_ioctl.h" +#define MEGARAID_VERSION "2.20.3.1" +#define MEGARAID_EXT_VERSION "(Release Date: Tue Aug 24 09:43:35 EDT 2004)" -#define MEGARAID_VERSION "2.20.4.0" -#define MEGARAID_EXT_VERSION "(Release Date: Mon Sep 27 22:15:07 EDT 2004)" /* reverted: --- b/drivers/scsi/ncr53c8xx.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/ncr53c8xx.c 2004-10-01 19:21:44 -07:00 @@ -83,6 +83,11 @@ ** ** Supported NCR/SYMBIOS chips: ** 53C720 (Wide, Fast SCSI-2, intfly problems) +** +** Other features: +** Memory mapped IO (linux-1.3.X and above only) +** Module +** Shared IRQ (since linux-1.3.72) */ /* Name and version of the driver */ @@ -119,10 +124,8 @@ #include #include +#include "scsi.h" +#include -#include -#include -#include -#include #include "ncr53c8xx.h" @@ -137,6 +140,7 @@ #define NAME53C "ncr53c" #define NAME53C8XX "ncr53c8xx" +#define DRIVER_SMP_LOCK ncr53c8xx_lock #include "sym53c8xx_comm.h" @@ -312,6 +316,10 @@ #define ScsiResult(host_code, scsi_code) (((host_code) << 16) + ((scsi_code) & 0x7f)) +static void ncr53c8xx_timeout(unsigned long np); +static int ncr53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, + int length, int func); + #define initverbose (driver_setup.verbose) #define bootverbose (np->verbose) @@ -618,10 +626,10 @@ ** CCB queue management. **---------------------------------------------------------------- */ + XPT_QUEHEAD free_ccbq; /* Queue of available CCBs */ + XPT_QUEHEAD busy_ccbq; /* Queue of busy CCBs */ + XPT_QUEHEAD wait_ccbq; /* Queue of waiting for IO CCBs */ + XPT_QUEHEAD skip_ccbq; /* Queue of skipped CCBs */ - struct list_head free_ccbq; /* Queue of available CCBs */ - struct list_head busy_ccbq; /* Queue of busy CCBs */ - struct list_head wait_ccbq; /* Queue of waiting for IO CCBs */ - struct list_head skip_ccbq; /* Queue of skipped CCBs */ u_char actccbs; /* Number of allocated CCBs */ u_char busyccbs; /* CCBs busy for this lun */ u_char queuedccbs; /* CCBs queued to the controller*/ @@ -912,7 +920,7 @@ u_char queued; u_char auto_sense; struct ccb * link_ccb; /* Host adapter CCB chain */ + XPT_QUEHEAD link_ccbq; /* Link to unit CCB queue */ - struct list_head link_ccbq; /* Link to unit CCB queue */ u32 startp; /* Initial data pointer */ u_long magic; /* Free / busy CCB flag */ }; @@ -989,9 +997,9 @@ ** Virtual and physical bus addresses of the chip. **---------------------------------------------------------------- */ + vm_offset_t vaddr; /* Virtual and bus address of */ + vm_offset_t paddr; /* chip's IO registers. */ + vm_offset_t paddr2; /* On-chip RAM bus address. */ - unsigned long vaddr; /* Virtual and bus address of */ - unsigned long paddr; /* chip's IO registers. */ - unsigned long paddr2; /* On-chip RAM bus address. */ volatile /* Pointer to volatile for */ struct ncr_reg *reg; /* memory mapped IO. */ @@ -2818,7 +2826,7 @@ *p++ =PADDR (idle); }; + assert ((u_long)p == (u_long)&scrh->tryloop + sizeof (scrh->tryloop)); - BUG_ON((u_long)p != (u_long)&scrh->tryloop + sizeof (scrh->tryloop)); #ifdef SCSI_NCR_CCB_DONE_SUPPORT @@ -2831,7 +2839,7 @@ *p++ =PADDR (done_end); } + assert ((u_long)p ==(u_long)&scrh->done_queue+sizeof(scrh->done_queue)); - BUG_ON((u_long)p != (u_long)&scrh->done_queue+sizeof(scrh->done_queue)); #endif /* SCSI_NCR_CCB_DONE_SUPPORT */ @@ -2842,8 +2850,7 @@ *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN; *p++ =offsetof (struct dsb, data[i]); }; + assert ((u_long)p == (u_long)&scrh->hdata_in + sizeof (scrh->hdata_in)); - - BUG_ON((u_long)p != (u_long)&scrh->hdata_in + sizeof (scrh->hdata_in)); p = scr->data_in; for (i=MAX_SCATTERH; idata_in + sizeof (scr->data_in)); - - BUG_ON((u_long)p != (u_long)&scr->data_in + sizeof (scr->data_in)); p = scrh->hdata_out; for (i=0; ihdata_out + sizeof (scrh->hdata_out)); - - BUG_ON((u_long)p != (u_long)&scrh->hdata_out + sizeof (scrh->hdata_out)); p = scr->data_out; for (i=MAX_SCATTERH; idata_out + sizeof (scr->data_out)); - BUG_ON((u_long) p != (u_long)&scr->data_out + sizeof (scr->data_out)); } /*========================================================== @@ -2911,7 +2916,7 @@ if (opcode == 0) { printk (KERN_ERR "%s: ERROR0 IN SCRIPT at %d.\n", ncr_name(np), (int) (src-start-1)); + MDELAY (1000); - mdelay(1000); }; if (DEBUG_FLAGS & DEBUG_SCRIPT) @@ -2941,7 +2946,7 @@ if ((tmp1 ^ tmp2) & 3) { printk (KERN_ERR"%s: ERROR1 IN SCRIPT at %d.\n", ncr_name(np), (int) (src-start-1)); + MDELAY (1000); - mdelay(1000); } /* ** If PREFETCH feature not enabled, remove @@ -3031,8 +3036,21 @@ }; } +/*========================================================== +** +** +** Auto configuration: attach and init a host adapter. +** +** +**========================================================== +*/ + /* ** Linux host data structure +** +** The script area is allocated in the host data structure +** because kmalloc() returns NULL during scsi initialisations +** with Linux 1.2.X */ struct host_data { @@ -3825,8 +3843,8 @@ **---------------------------------------------------- */ + direction = scsi_data_direction(cmd); + if (direction != SCSI_DATA_NONE) { - direction = cmd->sc_data_direction; - if (direction != DMA_NONE) { segments = ncr_scatter(np, cp, cp->cmd); if (segments < 0) { ncr_free_ccb(np, cp); @@ -3923,17 +3941,17 @@ **---------------------------------------------------- */ if (!cp->data_len) + direction = SCSI_DATA_NONE; - direction = DMA_NONE; /* + ** If data direction is UNKNOWN, speculate DATA_READ + ** but prepare alternate pointers for WRITE in case - ** If data direction is BIDIRECTIONAL, speculate FROM_DEVICE - ** but prepare alternate pointers for TO_DEVICE in case ** of our speculation will be just wrong. ** SCRIPTS will swap values if needed. */ switch(direction) { + case SCSI_DATA_UNKNOWN: + case SCSI_DATA_WRITE: - case DMA_BIDIRECTIONAL: - case DMA_TO_DEVICE: goalp = NCB_SCRIPT_PHYS (np, data_out2) + 8; if (segments <= MAX_SCATTERL) lastp = goalp - 8 - (segments * 16); @@ -3941,12 +3959,12 @@ lastp = NCB_SCRIPTH_PHYS (np, hdata_out2); lastp -= (segments - MAX_SCATTERL) * 16; } + if (direction != SCSI_DATA_UNKNOWN) - if (direction != DMA_BIDIRECTIONAL) break; cp->phys.header.wgoalp = cpu_to_scr(goalp); cp->phys.header.wlastp = cpu_to_scr(lastp); /* fall through */ + case SCSI_DATA_READ: - case DMA_FROM_DEVICE: goalp = NCB_SCRIPT_PHYS (np, data_in2) + 8; if (segments <= MAX_SCATTERL) lastp = goalp - 8 - (segments * 16); @@ -3956,7 +3974,7 @@ } break; default: + case SCSI_DATA_NONE: - case DMA_NONE: lastp = goalp = NCB_SCRIPT_PHYS (np, no_data); break; } @@ -3968,7 +3986,7 @@ cp->phys.header.lastp = cpu_to_scr(lastp); cp->phys.header.goalp = cpu_to_scr(goalp); + if (direction == SCSI_DATA_UNKNOWN) - if (direction == DMA_BIDIRECTIONAL) cp->phys.header.savep = cpu_to_scr(NCB_SCRIPTH_PHYS (np, data_io)); else @@ -4071,19 +4089,19 @@ static void ncr_start_next_ccb(struct ncb *np, struct lcb *lp, int maxn) { + XPT_QUEHEAD *qp; - struct list_head *qp; struct ccb *cp; if (lp->held_ccb) return; while (maxn-- && lp->queuedccbs < lp->queuedepth) { + qp = xpt_remque_head(&lp->wait_ccbq); - qp = ncr_list_pop(&lp->wait_ccbq); if (!qp) break; ++lp->queuedccbs; + cp = xpt_que_entry(qp, struct ccb, link_ccbq); + xpt_insque_tail(qp, &lp->busy_ccbq); - cp = list_entry(qp, struct ccb, link_ccbq); - list_add_tail(qp, &lp->busy_ccbq); lp->jump_ccb[cp->tag == NO_TAG ? 0 : cp->tag] = cpu_to_scr(CCB_PHYS (cp, restart)); ncr_put_start_queue(np, cp); @@ -4134,7 +4152,7 @@ ncr_name(np), settle_delay); ncr_chip_reset(np, 100); + UDELAY (2000); /* The 895 needs time for the bus mode to settle */ - udelay(2000); /* The 895 needs time for the bus mode to settle */ if (enab_int) OUTW (nc_sien, RST); /* @@ -4143,7 +4161,7 @@ */ OUTB (nc_stest3, TE); OUTB (nc_scntl1, CRST); + UDELAY (200); - udelay(200); if (!driver_setup.bus_check) goto out; @@ -4262,7 +4280,6 @@ return SUCCESS; } -#if 0 /* unused and broken.. */ /*========================================================== ** ** @@ -4343,7 +4360,17 @@ return retv; } + +/*========================================================== +** +** Linux release module stuff. +** +** Called before unloading the module +** Detach the host. +** We have to free resources and halt the NCR chip +** +**========================================================== +*/ -#endif static void ncr_detach(struct ncb *np) { @@ -4368,8 +4395,7 @@ printk("%s: stopping the timer\n", ncr_name(np)); #endif np->release_stage = 1; + for (i = 50 ; i && np->release_stage != 2 ; i--) MDELAY (100); - for (i = 50 ; i && np->release_stage != 2 ; i--) - mdelay(100); if (np->release_stage != 2) printk("%s: the timer seems to be already stopped\n", ncr_name(np)); else np->release_stage = 2; @@ -4510,7 +4536,8 @@ if (lp && lp->held_ccb) { if (cp == lp->held_ccb) { + xpt_que_splice(&lp->skip_ccbq, &lp->wait_ccbq); + xpt_que_init(&lp->skip_ccbq); - list_splice_init(&lp->skip_ccbq, &lp->wait_ccbq); lp->held_ccb = NULL; } } @@ -4721,7 +4748,7 @@ ** requeue awaiting scsi commands for this lun. */ if (lp && lp->queuedccbs < lp->queuedepth && + !xpt_que_empty(&lp->wait_ccbq)) - !list_empty(&lp->wait_ccbq)) ncr_start_next_ccb(np, lp, 2); /* @@ -4758,8 +4785,8 @@ cp->host_status &= ~HS_SKIPMASK; cp->start.schedule.l_paddr = cpu_to_scr(NCB_SCRIPT_PHYS (np, select)); + xpt_remque(&cp->link_ccbq); + xpt_insque_tail(&cp->link_ccbq, &lp->skip_ccbq); - list_del(&cp->link_ccbq); - list_add_tail(&cp->link_ccbq, &lp->skip_ccbq); if (cp->queued) { --lp->queuedccbs; } @@ -4844,7 +4871,7 @@ static void ncr_chip_reset(struct ncb *np, int delay) { OUTB (nc_istat, SRST); + UDELAY (delay); - udelay(delay); OUTB (nc_istat, 0 ); if (np->features & FE_EHP) @@ -4873,7 +4900,7 @@ if (reset) { OUTB (nc_istat, SRST); + UDELAY (100); - udelay(100); } else { OUTB (nc_stest3, TE|CSF); @@ -5188,12 +5215,18 @@ static void ncr_setsync (struct ncb *np, struct ccb *cp, u_char scntl3, u_char sxfer) { + struct scsi_cmnd *cmd; - struct scsi_cmnd *cmd = cp->cmd; struct tcb *tp; u_char target = INB (nc_sdid) & 0x0f; u_char idiv; + assert (cp && cp->cmd); + if (!cp) return; + + cmd = cp->cmd; + if (!cmd) return; + + assert (target == (cmd->device->id & 0xf)); - BUG_ON(target != (cmd->device->id & 0xf)); tp = &np->target[target]; @@ -5266,13 +5299,19 @@ static void ncr_setwide (struct ncb *np, struct ccb *cp, u_char wide, u_char ack) { + struct scsi_cmnd *cmd; - struct scsi_cmnd *cmd = cp->cmd; u16 target = INB (nc_sdid) & 0x0f; struct tcb *tp; u_char scntl3; u_char sxfer; + assert (cp && cp->cmd); + if (!cp) return; + + cmd = cp->cmd; + if (!cmd) return; + + assert (target == (cmd->device->id & 0xf)); - BUG_ON(target != (cmd->device->id & 0xf)); tp = &np->target[target]; tp->widedone = wide+1; @@ -5399,6 +5438,86 @@ } } +/*---------------------------------------------------- +** +** handle user commands +** +**---------------------------------------------------- +*/ + +#ifdef SCSI_NCR_USER_COMMAND_SUPPORT + +static void ncr_usercmd (struct ncb *np) +{ + u_char t; + struct tcb *tp; + + switch (np->user.cmd) { + + case 0: return; + + case UC_SETSYNC: + for (t=0; tuser.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrsync = np->user.data; + ncr_negotiate (np, tp); + }; + break; + + case UC_SETTAGS: + for (t=0; tuser.target>>t)&1)) continue; + np->target[t].usrtags = np->user.data; + for (ln = 0; ln < MAX_LUN; ln++) { + struct lcb *lp = np->target[t].lp[ln]; + if (!lp) + continue; + lp->maxtags = lp->numtags = np->user.data; + ncr_setup_tags (np, t, ln); + } + }; + break; + + case UC_SETDEBUG: +#ifdef SCSI_NCR_DEBUG_INFO_SUPPORT + ncr_debug = np->user.data; +#endif + break; + + case UC_SETORDER: + np->order = np->user.data; + break; + + case UC_SETVERBOSE: + np->verbose = np->user.data; + break; + + case UC_SETWIDE: + for (t=0; tuser.target>>t)&1)) continue; + tp = &np->target[t]; + size = np->user.data; + if (size > np->maxwide) size=np->maxwide; + tp->usrwide = size; + ncr_negotiate (np, tp); + }; + break; + + case UC_SETFLAG: + for (t=0; tuser.target>>t)&1)) continue; + tp = &np->target[t]; + tp->usrflag = np->user.data; + }; + break; + } + np->user.cmd=0; +} +#endif + /*========================================================== ** ** @@ -6234,7 +6353,7 @@ struct scsi_cmnd *cmd = cp->cmd; struct tcb *tp = &np->target[cmd->device->id]; struct lcb *lp = tp->lp[cmd->device->lun]; + XPT_QUEHEAD *qp; - struct list_head *qp; struct ccb * cp2; int disc_cnt = 0; int busy_cnt = 0; @@ -6248,10 +6367,10 @@ ** are before cp and busy ones after. */ if (lp) { + qp = lp->busy_ccbq.blink; - qp = lp->busy_ccbq.prev; while (qp != &lp->busy_ccbq) { + cp2 = xpt_que_entry(qp, struct ccb, link_ccbq); + qp = qp->blink; - cp2 = list_entry(qp, struct ccb, link_ccbq); - qp = qp->prev; ++busy_cnt; if (cp2 == cp) break; @@ -6331,7 +6450,7 @@ /* ** sense data */ + bzero(cp->sense_buf, sizeof(cp->sense_buf)); - memset(cp->sense_buf, 0, sizeof(cp->sense_buf)); cp->phys.sense.addr = cpu_to_scr(CCB_PHYS(cp,sense_buf[0])); cp->phys.sense.size = cpu_to_scr(sizeof(cp->sense_buf)); @@ -6472,8 +6591,7 @@ while (cp && (CCB_PHYS (cp, phys) != dsa)) cp = cp->link_ccb; + assert (cp && cp == np->header.cp); - BUG_ON(!cp); - BUG_ON(cp != np->header.cp); if (!cp || cp != np->header.cp) goto out; @@ -6899,7 +7017,7 @@ ** Lun structure available ? */ if (lp) { + XPT_QUEHEAD *qp; - struct list_head *qp; /* ** Keep from using more tags than we can handle. */ @@ -6909,7 +7027,7 @@ /* ** Allocate a new CCB if needed. */ + if (xpt_que_empty(&lp->free_ccbq)) - if (list_empty(&lp->free_ccbq)) ncr_alloc_ccb(np, tn, ln); /* @@ -6922,15 +7040,16 @@ /* ** Look for free CCB */ + qp = xpt_remque_head(&lp->free_ccbq); - qp = ncr_list_pop(&lp->free_ccbq); if (qp) { + cp = xpt_que_entry(qp, struct ccb, link_ccbq); - cp = list_entry(qp, struct ccb, link_ccbq); if (cp->magic) { PRINT_LUN(np, tn, ln); printk ("ccb free list corrupted (@%p)\n", cp); cp = NULL; + } + else { + xpt_insque_tail(qp, &lp->wait_ccbq); - } else { - list_add_tail(qp, &lp->wait_ccbq); ++lp->busyccbs; } } @@ -7040,8 +7159,10 @@ */ if (lp) { + if (cp != np->ccb) { + xpt_remque(&cp->link_ccbq); + xpt_insque_head(&cp->link_ccbq, &lp->free_ccbq); + } - if (cp != np->ccb) - list_move(&cp->link_ccbq, &lp->free_ccbq); --lp->busyccbs; if (cp->queued) { --lp->queuedccbs; @@ -7079,9 +7200,9 @@ cp->phys.header.cp = cp; /* + ** This allows xpt_remque to work for the default ccb. - ** This allows list_del to work for the default ccb. */ + xpt_que_init(&cp->link_ccbq); - INIT_LIST_HEAD(&cp->link_ccbq); /* ** Initialyze the start and restart launch script. @@ -7125,7 +7246,7 @@ */ lp->actccbs++; np->actccbs++; + bzero (cp, sizeof (*cp)); - memset(cp, 0, sizeof (*cp)); ncr_init_ccb(np, cp); /* @@ -7135,7 +7256,7 @@ cp->link_ccb = np->ccb->link_ccb; np->ccb->link_ccb = cp; + xpt_insque_head(&cp->link_ccbq, &lp->free_ccbq); - list_add(&cp->link_ccbq, &lp->free_ccbq); ncr_setup_tags (np, tn, ln); } @@ -7224,15 +7345,15 @@ ** These assert's should be moved at driver initialisations. */ #ifdef SCSI_NCR_BIG_ENDIAN + assert (( (offsetof(struct ncr_reg, nc_sxfer) ^ + offsetof(struct tcb , sval )) &3) == 3); + assert (( (offsetof(struct ncr_reg, nc_scntl3) ^ + offsetof(struct tcb , wval )) &3) == 3); - BUG_ON(((offsetof(struct ncr_reg, nc_sxfer) ^ - offsetof(struct tcb , sval )) &3) != 3); - BUG_ON(((offsetof(struct ncr_reg, nc_scntl3) ^ - offsetof(struct tcb , wval )) &3) != 3); #else + assert (( (offsetof(struct ncr_reg, nc_sxfer) ^ + offsetof(struct tcb , sval )) &3) == 0); + assert (( (offsetof(struct ncr_reg, nc_scntl3) ^ + offsetof(struct tcb , wval )) &3) == 0); - BUG_ON(((offsetof(struct ncr_reg, nc_sxfer) ^ - offsetof(struct tcb , sval )) &3) != 0); - BUG_ON(((offsetof(struct ncr_reg, nc_scntl3) ^ - offsetof(struct tcb , wval )) &3) != 0); #endif } @@ -7263,7 +7384,7 @@ lp = m_calloc_dma(sizeof(struct lcb), "LCB"); if (!lp) goto fail; + bzero(lp, sizeof(*lp)); - memset(lp, 0, sizeof(*lp)); tp->lp[ln] = lp; /* @@ -7275,10 +7396,10 @@ /* ** Initialize the CCB queue headers. */ + xpt_que_init(&lp->free_ccbq); + xpt_que_init(&lp->busy_ccbq); + xpt_que_init(&lp->wait_ccbq); + xpt_que_init(&lp->skip_ccbq); - INIT_LIST_HEAD(&lp->free_ccbq); - INIT_LIST_HEAD(&lp->busy_ccbq); - INIT_LIST_HEAD(&lp->wait_ccbq); - INIT_LIST_HEAD(&lp->skip_ccbq); /* ** Set max CCBs to 1 and use the default 1 entry @@ -7721,11 +7842,11 @@ if (np->multiplier > 2) { /* Poll bit 5 of stest4 for quadrupler */ int i = 20; while (!(INB(nc_stest4) & LCKFRQ) && --i > 0) + UDELAY (20); - udelay(20); if (!i) printk("%s: the chip cannot lock the frequency\n", ncr_name(np)); } else /* Wait 20 micro-seconds for doubler */ + UDELAY (20); - udelay(20); OUTB(nc_stest3, HSC); /* Halt the scsi clock */ OUTB(nc_scntl3, scntl3); OUTB(nc_stest1, (DBLEN|DBLSEL));/* Select clock multiplier */ @@ -7766,7 +7887,7 @@ OUTB (nc_stime1, gen); /* set to nominal delay of 1<host; + struct ncb *np; + struct tcb *tp; + struct lcb *lp; - struct ncb *np = ((struct host_data *) host->hostdata)->ncb; - struct tcb *tp = &np->target[device->id]; - struct lcb *lp = tp->lp[device->lun]; int numtags, depth_to_use; + np = ((struct host_data *) host->hostdata)->ncb; + tp = &np->target[device->id]; + lp = tp->lp[device->lun]; + /* ** Select queue depth from driver setup. ** Donnot use more than configured by user. @@ -7884,10 +8013,6 @@ ** Since the queue depth is not tunable under Linux, ** we need to know this value in order not to ** announce stupid things to user. - ** - ** XXX(hch): As of Linux 2.6 it certainly _is_ tunable.. - ** In fact we just tuned it, or did I miss - ** something important? :) */ if (lp) { lp->numtags = lp->maxtags = numtags; @@ -7903,7 +8028,11 @@ return 0; } +/* +** Linux entry point of queuecommand() function +*/ + +int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) -static int ncr53c8xx_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) { struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb; unsigned long flags; @@ -7918,7 +8047,7 @@ cmd->__data_mapped = 0; cmd->__data_mapping = 0; + NCR_LOCK_NCB(np, flags); - spin_lock_irqsave(&np->smp_lock, flags); if ((sts = ncr_queue_command(np, cmd)) != DID_OK) { cmd->result = ScsiResult(sts, 0); @@ -7931,7 +8060,7 @@ printk("ncr53c8xx : command successfully queued\n"); #endif + NCR_UNLOCK_NCB(np, flags); - spin_unlock_irqrestore(&np->smp_lock, flags); if (sts != DID_OK) { unmap_scsi_data(np, cmd); @@ -7941,6 +8070,14 @@ return sts; } +/* +** Linux entry point of the interrupt handler. +** Since linux versions > 1.3.70, we trust the kernel for +** passing the internal host descriptor as 'dev_id'. +** Otherwise, we scan the host list and call the interrupt +** routine for each host that uses this IRQ. +*/ + irqreturn_t ncr53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs) { unsigned long flags; @@ -7955,42 +8092,58 @@ if (DEBUG_FLAGS & DEBUG_TINY) printk ("["); + NCR_LOCK_NCB(np, flags); - spin_lock_irqsave(&np->smp_lock, flags); ncr_exception(np); done_list = np->done_list; np->done_list = NULL; + NCR_UNLOCK_NCB(np, flags); - spin_unlock_irqrestore(&np->smp_lock, flags); if (DEBUG_FLAGS & DEBUG_TINY) printk ("]\n"); + if (done_list) { + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); + ncr_flush_done_cmds(done_list); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); + } - if (done_list) - ncr_flush_done_cmds(done_list); return IRQ_HANDLED; } +/* +** Linux entry point of the timer handler +*/ + static void ncr53c8xx_timeout(unsigned long npref) { + struct ncb *np = (struct ncb *) npref; + unsigned long flags; + struct scsi_cmnd *done_list; - struct ncb *np = (struct ncb *) npref; - unsigned long flags; - struct scsi_cmnd *done_list; + NCR_LOCK_NCB(np, flags); + ncr_timeout(np); + done_list = np->done_list; + np->done_list = NULL; + NCR_UNLOCK_NCB(np, flags); - spin_lock_irqsave(&np->smp_lock, flags); - ncr_timeout(np); - done_list = np->done_list; - np->done_list = NULL; - spin_unlock_irqrestore(&np->smp_lock, flags); + if (done_list) { + NCR_LOCK_SCSI_DONE(done_list->device->host, flags); + ncr_flush_done_cmds(done_list); + NCR_UNLOCK_SCSI_DONE(done_list->device->host, flags); + } - if (done_list) - ncr_flush_done_cmds(done_list); } +/* +** Linux entry point of reset() function +*/ + +int ncr53c8xx_bus_reset(struct scsi_cmnd *cmd) -static int ncr53c8xx_bus_reset(struct scsi_cmnd *cmd) { struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; unsigned long flags; struct scsi_cmnd *done_list; + NCR_LOCK_NCB(np, flags); + /* * If the mid-level driver told us reset is synchronous, it seems * that we must call the done() callback for the involved command, @@ -7998,20 +8151,22 @@ * before returning SUCCESS. */ - spin_lock_irqsave(&np->smp_lock, flags); sts = ncr_reset_bus(np, cmd, 1); done_list = np->done_list; np->done_list = NULL; + NCR_UNLOCK_NCB(np, flags); - spin_unlock_irqrestore(&np->smp_lock, flags); ncr_flush_done_cmds(done_list); return sts; } +/* +** Linux entry point of abort() function +*/ + +int ncr53c8xx_abort(struct scsi_cmnd *cmd) -#if 0 /* unused and broken */ -static int ncr53c8xx_abort(struct scsi_cmnd *cmd) { struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb; int sts; @@ -8047,7 +8202,6 @@ return sts; } -#endif /* @@ -8132,23 +8286,291 @@ #undef next_wcmd +#ifdef SCSI_NCR_PROC_INFO_SUPPORT + +/*========================================================================= +** Proc file system stuff +** +** A read operation returns profile information. +** A write operation is a control command. +** The string is parsed in the driver code and the command is passed +** to the ncr_usercmd() function. +**========================================================================= +*/ + +#ifdef SCSI_NCR_USER_COMMAND_SUPPORT + +#define is_digit(c) ((c) >= '0' && (c) <= '9') +#define digit_to_bin(c) ((c) - '0') +#define is_space(c) ((c) == ' ' || (c) == '\t') + +static int skip_spaces(char *ptr, int len) +{ + int cnt, c; + + for (cnt = len; cnt > 0 && (c = *ptr++) && is_space(c); cnt--); + + return (len - cnt); +} + +static int get_int_arg(char *ptr, int len, u_long *pv) +{ + int cnt, c; + u_long v; + + for (v = 0, cnt = len; cnt > 0 && (c = *ptr++) && is_digit(c); cnt--) { + v = (v * 10) + digit_to_bin(c); + } + + if (pv) + *pv = v; + + return (len - cnt); +} + +static int is_keyword(char *ptr, int len, char *verb) -static ssize_t show_ncr53c8xx_revision(struct class_device *dev, char *buf) { + int verb_len = strlen(verb); + + if (len >= strlen(verb) && !memcmp(verb, ptr, verb_len)) + return verb_len; + else + return 0; + +} + +#define SKIP_SPACES(min_spaces) \ + if ((arg_len = skip_spaces(ptr, len)) < (min_spaces)) \ + return -EINVAL; \ + ptr += arg_len; len -= arg_len; + +#define GET_INT_ARG(v) \ + if (!(arg_len = get_int_arg(ptr, len, &(v)))) \ + return -EINVAL; \ + ptr += arg_len; len -= arg_len; + + +/* +** Parse a control command +*/ + +static int ncr_user_command(struct ncb *np, char *buffer, int length) +{ + char *ptr = buffer; + int len = length; + struct usrcmd *uc = &np->user; + int arg_len; + u_long target; + + bzero(uc, sizeof(*uc)); + + if (len > 0 && ptr[len-1] == '\n') + --len; + + if ((arg_len = is_keyword(ptr, len, "setsync")) != 0) + uc->cmd = UC_SETSYNC; + else if ((arg_len = is_keyword(ptr, len, "settags")) != 0) + uc->cmd = UC_SETTAGS; + else if ((arg_len = is_keyword(ptr, len, "setorder")) != 0) + uc->cmd = UC_SETORDER; + else if ((arg_len = is_keyword(ptr, len, "setverbose")) != 0) + uc->cmd = UC_SETVERBOSE; + else if ((arg_len = is_keyword(ptr, len, "setwide")) != 0) + uc->cmd = UC_SETWIDE; + else if ((arg_len = is_keyword(ptr, len, "setdebug")) != 0) + uc->cmd = UC_SETDEBUG; + else if ((arg_len = is_keyword(ptr, len, "setflag")) != 0) + uc->cmd = UC_SETFLAG; + else + arg_len = 0; + +#ifdef DEBUG_PROC_INFO +printk("ncr_user_command: arg_len=%d, cmd=%ld\n", arg_len, uc->cmd); +#endif + + if (!arg_len) + return -EINVAL; + ptr += arg_len; len -= arg_len; + + switch(uc->cmd) { + case UC_SETSYNC: + case UC_SETTAGS: + case UC_SETWIDE: + case UC_SETFLAG: + SKIP_SPACES(1); + if ((arg_len = is_keyword(ptr, len, "all")) != 0) { + ptr += arg_len; len -= arg_len; + uc->target = ~0; + } else { + GET_INT_ARG(target); + uc->target = (1<cmd) { + case UC_SETVERBOSE: + case UC_SETSYNC: + case UC_SETTAGS: + case UC_SETWIDE: + SKIP_SPACES(1); + GET_INT_ARG(uc->data); +#ifdef DEBUG_PROC_INFO +printk("ncr_user_command: data=%ld\n", uc->data); +#endif + break; + case UC_SETORDER: + SKIP_SPACES(1); + if ((arg_len = is_keyword(ptr, len, "simple"))) + uc->data = M_SIMPLE_TAG; + else if ((arg_len = is_keyword(ptr, len, "ordered"))) + uc->data = M_ORDERED_TAG; + else if ((arg_len = is_keyword(ptr, len, "default"))) + uc->data = 0; + else + return -EINVAL; + break; + case UC_SETDEBUG: + while (len > 0) { + SKIP_SPACES(1); + if ((arg_len = is_keyword(ptr, len, "alloc"))) + uc->data |= DEBUG_ALLOC; + else if ((arg_len = is_keyword(ptr, len, "phase"))) + uc->data |= DEBUG_PHASE; + else if ((arg_len = is_keyword(ptr, len, "queue"))) + uc->data |= DEBUG_QUEUE; + else if ((arg_len = is_keyword(ptr, len, "result"))) + uc->data |= DEBUG_RESULT; + else if ((arg_len = is_keyword(ptr, len, "scatter"))) + uc->data |= DEBUG_SCATTER; + else if ((arg_len = is_keyword(ptr, len, "script"))) + uc->data |= DEBUG_SCRIPT; + else if ((arg_len = is_keyword(ptr, len, "tiny"))) + uc->data |= DEBUG_TINY; + else if ((arg_len = is_keyword(ptr, len, "timing"))) + uc->data |= DEBUG_TIMING; + else if ((arg_len = is_keyword(ptr, len, "nego"))) + uc->data |= DEBUG_NEGO; + else if ((arg_len = is_keyword(ptr, len, "tags"))) + uc->data |= DEBUG_TAGS; + else + return -EINVAL; + ptr += arg_len; len -= arg_len; + } +#ifdef DEBUG_PROC_INFO +printk("ncr_user_command: data=%ld\n", uc->data); +#endif + break; + case UC_SETFLAG: + while (len > 0) { + SKIP_SPACES(1); + if ((arg_len = is_keyword(ptr, len, "trace"))) + uc->data |= UF_TRACE; + else if ((arg_len = is_keyword(ptr, len, "no_disc"))) + uc->data |= UF_NODISC; + else + return -EINVAL; + ptr += arg_len; len -= arg_len; + } + break; + default: + break; + } + + if (len) + return -EINVAL; + else { + unsigned long flags; + + NCR_LOCK_NCB(np, flags); + ncr_usercmd (np); + NCR_UNLOCK_NCB(np, flags); + } + return length; +} + +#endif /* SCSI_NCR_USER_COMMAND_SUPPORT */ + + +#ifdef SCSI_NCR_USER_INFO_SUPPORT +/* +** Copy formatted information into the input buffer. +*/ + +static int ncr_host_info(struct ncb *np, char *ptr, off_t offset, int len) +{ + struct info_str info; + + info.buffer = ptr; + info.length = len; + info.offset = offset; + info.pos = 0; + + copy_info(&info, " Chip NCR53C720, revision id 0x%x, IRQ %d\n", + np->revision_id, (int) np->irq); + copy_info(&info, " Synchronous period factor %d, " + "max commands per lun %d\n", + (int) np->minsync, MAX_TAGS); + + if (driver_setup.debug || driver_setup.verbose > 1) { + copy_info(&info, " Debug flags 0x%x, verbosity level %d\n", + driver_setup.debug, driver_setup.verbose); + } + + return info.pos > info.offset? info.pos - info.offset : 0; +} + +#endif /* SCSI_NCR_USER_INFO_SUPPORT */ + +/* +** Entry point of the scsi proc fs of the driver. +** - func = 0 means read (returns profile data) +** - func = 1 means write (parse user control command) +*/ + +static int ncr53c8xx_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, + int length, int func) +{ + struct host_data *host_data; + struct ncb *ncb = NULL; + int retv; + +#ifdef DEBUG_PROC_INFO +printk("ncr53c8xx_proc_info: hostno=%d, func=%d\n", host->host_no, func); +#endif + + host_data = (struct host_data *) host->hostdata; + ncb = host_data->ncb; + + if (func) { +#ifdef SCSI_NCR_USER_COMMAND_SUPPORT + retv = ncr_user_command(ncb, buffer, length); +#else + retv = -EINVAL; +#endif + } + else { + if (start) + *start = buffer; +#ifdef SCSI_NCR_USER_INFO_SUPPORT + retv = ncr_host_info(ncb, buffer, offset, length); +#else + retv = -EINVAL; +#endif + } + + return retv; +} + +/*========================================================================= +** End of proc file system stuff +**========================================================================= +*/ +#endif + - struct Scsi_Host *host = class_to_shost(dev); - struct host_data *host_data = (struct host_data *)host->hostdata; - - return snprintf(buf, 20, "0x%x\n", host_data->ncb->revision_id); -} - -static struct class_device_attribute ncr53c8xx_revision_attr = { - .attr = { .name = "revision", .mode = S_IRUGO, }, - .show = show_ncr53c8xx_revision, -}; - -static struct class_device_attribute *ncr53c8xx_host_attrs[] = { - &ncr53c8xx_revision_attr, - NULL -}; /*========================================================== ** @@ -8161,7 +8583,7 @@ MODULE_PARM(ncr53c8xx, "s"); #endif +int __init ncr53c8xx_setup(char *str) -static int __init ncr53c8xx_setup(char *str) { return sym53c8xx__setup(str); } @@ -8170,6 +8592,17 @@ __setup("ncr53c8xx=", ncr53c8xx_setup); #endif +/*========================================================== +** +** Entry point for info() function +** +**========================================================== +*/ +const char *ncr53c8xx_info (struct Scsi_Host *host) +{ + return SCSI_NCR_DRIVER_NAME; +} + /* * Host attach and initialisations. @@ -8189,14 +8622,13 @@ u_long flags = 0; int i; +#ifdef SCSI_NCR_PROC_INFO_SUPPORT + tpnt->proc_info = ncr53c8xx_proc_info, +#endif + tpnt->info = ncr53c8xx_info; - if (!tpnt->name) - tpnt->name = SCSI_NCR_DRIVER_NAME; - if (!tpnt->shost_attrs) - tpnt->shost_attrs = ncr53c8xx_host_attrs; - tpnt->queuecommand = ncr53c8xx_queue_command; tpnt->slave_configure = ncr53c8xx_slave_configure; + tpnt->eh_bus_reset_handler = ncr53c8xx_bus_reset; - tpnt->eh_bus_reset_handler = ncr53c8xx_bus_reset; tpnt->can_queue = SCSI_NCR_CAN_QUEUE; tpnt->this_id = 7; tpnt->sg_tablesize = SCSI_NCR_SG_TABLESIZE; @@ -8217,7 +8649,7 @@ np = __m_calloc_dma(device->dev, sizeof(struct ncb), "NCB"); if (!np) goto attach_error; + NCR_INIT_LOCK_NCB(np); - spin_lock_init(&np->smp_lock); np->dev = device->dev; np->p_ncb = vtobus(np); host_data->ncb = np; @@ -8284,6 +8716,7 @@ ncr_name(np)); } + /* Fill Linux host instance structure */ instance->max_channel = 0; instance->this_id = np->myaddr; instance->max_id = np->maxwide ? 16 : 8; @@ -8364,11 +8797,11 @@ * Process the reset exception if interrupts are not enabled yet. * Then enable disconnects. */ + NCR_LOCK_NCB(np, flags); - spin_lock_irqsave(&np->smp_lock, flags); if (ncr_reset_scsi_bus(np, 0, driver_setup.settle_delay) != 0) { printk(KERN_ERR "%s: FATAL ERROR: CHECK SCSI BUS - CABLES, TERMINATION, DEVICE POWER etc.!\n", ncr_name(np)); + NCR_UNLOCK_NCB(np, flags); - spin_unlock_irqrestore(&np->smp_lock, flags); goto attach_error; } ncr_exception(np); @@ -8382,7 +8815,7 @@ if (driver_setup.settle_delay > 2) { printk(KERN_INFO "%s: waiting %d seconds for scsi devices to settle...\n", ncr_name(np), driver_setup.settle_delay); + MDELAY (1000 * driver_setup.settle_delay); - mdelay(1000 * driver_setup.settle_delay); } /* start the timeout daemon */ @@ -8394,7 +8827,7 @@ np->order = M_SIMPLE_TAG; #endif + NCR_UNLOCK_NCB(np, flags); - spin_unlock_irqrestore(&np->smp_lock, flags); return instance; reverted: --- b/drivers/scsi/ncr53c8xx.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/ncr53c8xx.h 2004-10-01 19:21:44 -07:00 @@ -44,6 +44,8 @@ #include +typedef u_long vm_offset_t; + #include "sym53c8xx_defs.h" /* reverted: --- b/drivers/scsi/ql1040_fw.h 2004-10-01 19:21:44 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,2101 +0,0 @@ -/************************************************************************** - * QLOGIC LINUX SOFTWARE - * - * Copyright (C) 2004 QLogic Corporation - * (www.qlogic.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. - * - *************************************************************************/ - -/************************************************************************ - * * - * --- ISP1040 Initiator/Target Firmware --- * - * 32 LUN Support * - * * - ************************************************************************ - */ - -/* - * Firmware Version 7.65.00 (14:17 Jul 20, 1999) - */ - -unsigned short risc_code_version = 7*1024+65; - -unsigned char firmware_version[] = {7,65,0}; - -#define FW_VERSION_STRING "7.65.0" - -unsigned short risc_code_addr01 = 0x1000 ; - -unsigned short risc_code01[] = { - 0x0078, 0x103a, 0x0000, 0x4057, 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, 0x3635, - 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, 0x77ff, 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, 0x5100, 0x8424, - 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7800, 0x2009, - 0x0000, 0x2001, 0x0031, 0x1078, 0x1cba, 0x2218, 0x2079, 0x5100, - 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, 0x5140, 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, 0x5380, 0x2011, 0x0020, - 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00, - 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, - 0x8109, 0x00c0, 0x1122, 0x2069, 0x5400, 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, 0x220a, 0x1078, - 0x482c, 0x1078, 0x1963, 0x1078, 0x4d22, 0x3200, 0xa085, 0x000d, - 0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002, - 0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005, - 0x00c0, 0x117a, 0x1078, 0x1ce3, 0x0010, 0x1180, 0x0068, 0x1180, - 0x1078, 0x20e9, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1a48, - 0x00e0, 0x116c, 0x1078, 0x4ba9, 0x0078, 0x116c, 0x118e, 0x1190, - 0x240b, 0x240b, 0x48ad, 0x48ad, 0x240b, 0x240b, 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, - 0x515b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5164, 0x200b, - 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009, - 0x5162, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca, - 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce, - 0x1078, 0x1948, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0, - 0x11d3, 0x1078, 0x165a, 0x7817, 0x0000, 0x2009, 0x5162, 0x2104, - 0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x19b3, - 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, 0x6007, - 0x0103, 0x1078, 0x1924, 0x00c0, 0x11fb, 0x1078, 0x1948, 0x2009, - 0x5162, 0x200b, 0x0000, 0x2009, 0x515c, 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, - 0x18df, 0x18fc, 0x1298, 0x1298, 0x1298, 0x1900, 0x1908, 0x1298, - 0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x1356, 0x1668, - 0x1764, 0x1778, 0x1298, 0x1829, 0x190e, 0x18bb, 0x18c5, 0x18c9, - 0x18d7, 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, 0x1b53, 0x00c0, 0x129c, 0x75d8, - 0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520, - 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1a8d, 0x0040, 0x1284, - 0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1b53, 0x00c0, 0x129c, - 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000, - 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1aed, 0x0040, - 0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114, - 0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7, - 0x0007, 0x70cb, 0x0041, 0x70cf, 0x0000, 0x0078, 0x1284, 0x1078, - 0x1b53, 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, 0x1b53, - 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, 0x5161, 0x210c, - 0x7aec, 0x0078, 0x1282, 0x2009, 0x5141, 0x210c, 0x0078, 0x1283, - 0x2009, 0x5142, 0x210c, 0x0078, 0x1283, 0x2061, 0x5140, 0x610c, - 0x6210, 0x0078, 0x1282, 0x2009, 0x5145, 0x210c, 0x0078, 0x1283, - 0x2009, 0x5146, 0x210c, 0x0078, 0x1283, 0x2009, 0x5148, 0x210c, - 0x0078, 0x1283, 0x2009, 0x5149, 0x210c, 0x0078, 0x1283, 0x7908, - 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, - 0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a00, 0x6804, 0xa084, 0x0008, - 0x0040, 0x13cd, 0x6b08, 0x0078, 0x13ce, 0x6b0c, 0x0078, 0x1281, - 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, - 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078, 0x1283, 0x77c4, - 0x1078, 0x1973, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091, - 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x127c, - 0x1078, 0x22e2, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010, 0x00c8, - 0x127c, 0x2011, 0x5141, 0x2204, 0x007e, 0x2112, 0x1078, 0x229b, - 0x017f, 0x0078, 0x1283, 0x71c4, 0x2011, 0x1421, 0x20a9, 0x0008, - 0x2204, 0xa106, 0x0040, 0x1413, 0x8210, 0x0070, 0x1411, 0x0078, - 0x1408, 0x0078, 0x127c, 0xa292, 0x1421, 0x027e, 0x2011, 0x5142, - 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x22a7, 0x017f, 0x0078, - 0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, - 0x004b, 0x2061, 0x5140, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8, - 0x6012, 0x0078, 0x1282, 0x2061, 0x5140, 0x6114, 0x70c4, 0x6016, - 0x0078, 0x1283, 0x2061, 0x5140, 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, 0x22b8, 0x1078, 0x4d22, 0x017f, 0x0078, 0x1283, - 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5148, 0x2204, - 0x2112, 0x007e, 0x1078, 0x22da, 0x017f, 0x0078, 0x1283, 0x71c4, - 0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5149, 0x2204, 0x007e, - 0x2112, 0x1078, 0x22c9, 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, - 0x5380, 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, 0x22fc, 0x0078, 0x14f3, 0x1078, - 0x22ee, 0x0078, 0x14f3, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1522, - 0xa2a4, 0x00ff, 0x2061, 0x5140, 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, 0x1973, 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, 0x230a, - 0x0078, 0x1281, 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08, - 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, - 0x77c4, 0x1078, 0x1973, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, - 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1567, 0x1078, 0x21d2, 0x2091, - 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078, 0x1973, 0x2091, - 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, - 0x157b, 0x1078, 0x21d2, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, - 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, - 0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, - 0x1282, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, - 0x19e1, 0x00c0, 0x15a9, 0x6818, 0xa005, 0x0040, 0x15a9, 0x2708, - 0x1078, 0x231a, 0x00c0, 0x15a9, 0x7817, 0x0015, 0x2091, 0x8001, - 0x007c, 0x2091, 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041, - 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, - 0x1980, 0x2061, 0x5140, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, - 0x6073, 0x0000, 0x7817, 0x0016, 0x1078, 0x21d2, 0x2091, 0x8001, - 0x007c, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, - 0x8000, 0x2061, 0x5140, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, - 0x6093, 0x000f, 0x7817, 0x0017, 0x1078, 0x21d2, 0x2091, 0x8001, - 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, - 0x1078, 0x1980, 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, - 0x15e8, 0x2091, 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, - 0x1618, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, - 0x0008, 0x1078, 0x1973, 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, 0x5100, 0x7817, 0x0018, 0x2061, 0x5140, 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, 0x1a2b, 0x71c4, 0x71c6, 0x794a, 0x007c, - 0x1078, 0x1b53, 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de, - 0x0078, 0x1675, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, - 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x5100, 0x2091, 0x8000, 0x1078, - 0x192e, 0x2091, 0x8001, 0x0040, 0x172c, 0x20a9, 0x0005, 0x20a1, - 0x5118, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020, - 0x1078, 0x1929, 0x0040, 0x1698, 0x1078, 0x1948, 0x0078, 0x172c, - 0x6004, 0xa084, 0xff00, 0x8007, 0x8009, 0x0040, 0x16fb, 0x0c7e, - 0x2c68, 0x2091, 0x8000, 0x1078, 0x192e, 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, 0x1929, 0x00c0, - 0x16e3, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16cc, - 0x2d00, 0x6002, 0x0078, 0x16b2, 0x0c7f, 0x0c7e, 0x609c, 0x2060, - 0x1078, 0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, - 0x000c, 0x6008, 0xa085, 0x0200, 0x600a, 0x1078, 0x1924, 0x1078, - 0x1948, 0x0078, 0x172c, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, - 0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1730, 0x2009, 0x000c, - 0x6007, 0x0103, 0x601b, 0x0003, 0x1078, 0x1924, 0x1078, 0x1948, - 0x0078, 0x172c, 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, - 0x8000, 0x7817, 0x0012, 0x0e7e, 0x2071, 0x5140, 0x706f, 0x0005, - 0x7073, 0x0000, 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000, - 0x2c00, 0x708a, 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2, - 0xa184, 0x0060, 0x0040, 0x171e, 0x1078, 0x47c2, 0x0e7f, 0x6596, - 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078, - 0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, - 0x20a9, 0x0005, 0x2099, 0x5118, 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, 0x5167, 0x220c, 0x70c4, - 0x8003, 0x0048, 0x1771, 0x1078, 0x3b7f, 0xa184, 0x7fff, 0x0078, - 0x1775, 0x1078, 0x3b72, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283, - 0x71c4, 0x1078, 0x3b69, 0x6100, 0x2001, 0x5167, 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, 0x5100, 0x2091, 0x8000, 0x1078, - 0x192e, 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, 0x5140, 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, 0x21d2, 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, - 0x1287, 0x0c7e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, - 0x5140, 0x2079, 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, - 0x18b1, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1844, - 0xa286, 0x000f, 0x00c0, 0x18b1, 0x691c, 0xa184, 0x0080, 0x00c0, - 0x18b1, 0x6824, 0xa18c, 0xff00, 0xa085, 0x0019, 0x6826, 0x71b0, - 0x81ff, 0x0040, 0x1867, 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0010, - 0x6908, 0x6808, 0xa106, 0x00c0, 0x1858, 0x690c, 0x680c, 0xa106, - 0x00c0, 0x185d, 0xa184, 0x00ff, 0x00c0, 0x185d, 0x0d7f, 0x78b8, - 0xa084, 0x801f, 0x00c0, 0x1867, 0x7848, 0xa085, 0x000c, 0x784a, - 0x71b0, 0x81ff, 0x0040, 0x188a, 0x70b3, 0x0000, 0x0d7e, 0x2069, - 0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x187b, - 0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x1882, 0x6807, - 0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6, 0x62ca, 0x63ce, - 0x0e7e, 0x2071, 0x5100, 0x7266, 0x736a, 0xae80, 0x0019, 0x0e7f, - 0x7848, 0xa084, 0x000c, 0x00c0, 0x1898, 0x1078, 0x46db, 0x78a3, - 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4, 0xa080, 0x00df, - 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, 0x18ee, 0x0038, 0x18f0, 0x0078, 0x18fa, 0x00a8, 0x18fa, - 0xa18c, 0x0001, 0x00c0, 0x18f8, 0x20b9, 0x2222, 0x0078, 0x18fa, - 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6, 0x0078, 0x1284, - 0x2009, 0x5174, 0x2104, 0x70c6, 0x70c4, 0x200a, 0x0078, 0x1284, - 0x2009, 0x5174, 0x2104, 0x70c6, 0x0078, 0x1284, 0x71c4, 0x8107, - 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5380, 0x6a14, - 0xd2b4, 0x0040, 0x191f, 0x2011, 0x0001, 0x0078, 0x1921, 0x2011, - 0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001, 0x1078, 0x1b0f, - 0x007c, 0xac80, 0x0001, 0x1078, 0x1aaf, 0x007c, 0x7850, 0xa065, - 0x0040, 0x1936, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c, 0x0f7e, - 0x2079, 0x5100, 0x7850, 0xa06d, 0x0040, 0x1946, 0x2d04, 0x7852, - 0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000, 0x0f7f, 0x007c, - 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x2062, 0x2c00, - 0xa005, 0x00c0, 0x1955, 0x1078, 0x23eb, 0x7852, 0x0f7f, 0x2091, - 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5100, 0x7850, 0x206a, 0x2d00, - 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7800, 0x7a52, 0x7bec, 0x8319, - 0x0040, 0x1970, 0xa280, 0x0031, 0x2012, 0x2010, 0x0078, 0x1967, - 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, - 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x5400, 0x007c, - 0x1078, 0x1973, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, - 0xffef, 0xa80d, 0x690a, 0x2009, 0x5152, 0x210c, 0x6804, 0xa005, - 0x0040, 0x19b2, 0xa116, 0x00c0, 0x199d, 0x2060, 0x6000, 0x6806, - 0x017e, 0x200b, 0x0000, 0x0078, 0x19a0, 0x2009, 0x0000, 0x017e, - 0x6804, 0xa065, 0x0040, 0x19af, 0x6000, 0x6806, 0x1078, 0x19c0, - 0x1078, 0x1c5f, 0x6810, 0x8001, 0x6812, 0x00c0, 0x19a0, 0x017f, - 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x19bf, 0x609c, 0x609f, - 0x0000, 0x2008, 0x1078, 0x1948, 0x2100, 0x0078, 0x19b3, 0x007c, - 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, - 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, - 0x007c, 0x0e7e, 0x2071, 0x5140, 0x704c, 0xa08c, 0x0200, 0x00c0, - 0x19df, 0xa088, 0x5180, 0x2d0a, 0x8000, 0x704e, 0xa006, 0x0e7f, - 0x007c, 0x1078, 0x1973, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065, - 0x0040, 0x1a2a, 0x0078, 0x19f2, 0x2c00, 0x781e, 0x6000, 0xa065, - 0x0040, 0x1a2a, 0x600c, 0xa306, 0x00c0, 0x19ec, 0x6010, 0xa206, - 0x00c0, 0x19ec, 0x2c28, 0x2001, 0x5152, 0x2004, 0xac06, 0x00c0, - 0x1a03, 0x0078, 0x1a28, 0x6804, 0xac06, 0x00c0, 0x1a10, 0x6000, - 0xa065, 0x6806, 0x00c0, 0x1a1a, 0x6803, 0x0000, 0x0078, 0x1a1a, - 0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1a1a, - 0x2c00, 0x6802, 0x2560, 0x1078, 0x19c0, 0x601b, 0x0005, 0x6023, - 0x0020, 0x1078, 0x1c5f, 0x6810, 0x8001, 0x1050, 0x23eb, 0x6812, - 0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, - 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1980, 0x8738, - 0xa784, 0x001f, 0x00c0, 0x1a35, 0xa7bc, 0xff00, 0x873f, 0x8738, - 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1a35, 0x2091, 0x8001, 0x007c, - 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1a59, 0x2091, - 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, - 0x1a5a, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1a60, 0x1078, 0x23eb, - 0x0079, 0x1a62, 0x1a72, 0x1a75, 0x1a7b, 0x1a7f, 0x1a73, 0x1a83, - 0x1a89, 0x1a73, 0x1a73, 0x1c29, 0x1c4d, 0x1c51, 0x1a73, 0x1a73, - 0x1a73, 0x1a73, 0x007c, 0x1078, 0x23eb, 0x1078, 0x1a2b, 0x2001, - 0x8001, 0x0078, 0x1c57, 0x2001, 0x8003, 0x0078, 0x1c57, 0x2001, - 0x8004, 0x0078, 0x1c57, 0x1078, 0x1a2b, 0x2001, 0x8006, 0x0078, - 0x1c57, 0x2001, 0x8007, 0x0078, 0x1c57, 0x2030, 0x2138, 0xa782, - 0x0021, 0x0048, 0x1a95, 0x2009, 0x0020, 0x2600, 0x1078, 0x1aaf, - 0x00c0, 0x1aae, 0xa7ba, 0x0020, 0x0048, 0x1aad, 0x0040, 0x1aad, - 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, - 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1a8f, 0xa006, 0x007c, 0x81ff, - 0x0040, 0x1aea, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x00ff, - 0x0040, 0x1ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, - 0x1abc, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e, - 0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007, 0x0001, - 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1ade, 0x2009, - 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ad0, 0x7008, 0x800b, - 0x00c8, 0x1ad0, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1aea, - 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138, 0xa782, - 0x0021, 0x0048, 0x1af5, 0x2009, 0x0020, 0x2600, 0x1078, 0x1b0f, - 0x00c0, 0x1b0e, 0xa7ba, 0x0020, 0x0048, 0x1b0d, 0x0040, 0x1b0d, - 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, - 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1aef, 0xa006, 0x007c, 0x81ff, - 0x0040, 0x1b50, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084, 0x00ff, - 0x0040, 0x1b21, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, - 0x1b1c, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a, 0x731e, - 0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6, 0x7007, - 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b3f, - 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b31, 0x7010, - 0xa084, 0xf000, 0x0040, 0x1b48, 0x7007, 0x0008, 0x0078, 0x1b4c, - 0x7108, 0x8103, 0x00c8, 0x1b31, 0x7007, 0x0002, 0xa184, 0x01e0, - 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0004, - 0x00c8, 0x1b5c, 0x0078, 0x1b5f, 0xa006, 0x0078, 0x1b61, 0xa085, - 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x2d08, 0x7058, 0x6802, - 0xa005, 0x00c0, 0x1b6c, 0x715e, 0x715a, 0x0e7f, 0x007c, 0x2c08, - 0x7858, 0x6002, 0xa005, 0x00c0, 0x1b76, 0x795e, 0x795a, 0x007c, - 0x2091, 0x8000, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065, 0x00c0, - 0x1b84, 0x795a, 0x0078, 0x1b85, 0x6102, 0x795e, 0x2091, 0x8001, - 0x1078, 0x21ef, 0x007c, 0x0e7e, 0x2071, 0x5100, 0x7058, 0xa06d, - 0x0040, 0x1b99, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1b98, 0x705e, - 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5100, - 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1bc9, 0x2068, - 0x6814, 0xa306, 0x00c0, 0x1bb2, 0x6828, 0xa084, 0x00ff, 0xa406, - 0x0040, 0x1bb5, 0x2d60, 0x0078, 0x1ba3, 0x6800, 0xa005, 0x6002, - 0x00c0, 0x1bc1, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bc0, 0x2c00, - 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bc8, 0x1078, 0x19b3, - 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, - 0x0f7e, 0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, - 0x0040, 0x1bf8, 0x2068, 0x6814, 0xa084, 0x00ff, 0xa306, 0x0040, - 0x1be4, 0x2d60, 0x0078, 0x1bd6, 0x6800, 0xa005, 0x6002, 0x00c0, - 0x1bf0, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1bef, 0x2c00, 0x785e, - 0x0d7e, 0x689c, 0xa005, 0x0040, 0x1bf7, 0x1078, 0x19b3, 0x007f, - 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, - 0x2079, 0x5100, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa06d, 0x0040, - 0x1c24, 0x6814, 0xa306, 0x0040, 0x1c10, 0x2d60, 0x0078, 0x1c05, - 0x6800, 0xa005, 0x6002, 0x00c0, 0x1c1c, 0xaf80, 0x0016, 0xac06, - 0x0040, 0x1c1b, 0x2c00, 0x785e, 0x0d7e, 0x689c, 0xa005, 0x0040, - 0x1c23, 0x1078, 0x19b3, 0x007f, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, - 0x007c, 0x2091, 0x8000, 0x2069, 0x5140, 0x6800, 0xa086, 0x0000, - 0x0040, 0x1c37, 0x2091, 0x8001, 0x78e3, 0x0009, 0x007c, 0x6880, - 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, - 0x1078, 0x1980, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1c40, 0x2091, - 0x8001, 0x2001, 0x800a, 0x0078, 0x1c57, 0x2001, 0x800c, 0x0078, - 0x1c57, 0x1078, 0x1a2b, 0x2001, 0x800d, 0x0078, 0x1c57, 0x70c2, - 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0x6004, - 0x2c08, 0x2063, 0x0000, 0x7884, 0x8000, 0x7886, 0x7888, 0xa005, - 0x798a, 0x0040, 0x1c6e, 0x2c02, 0x0078, 0x1c6f, 0x798e, 0x007c, - 0x6807, 0x0103, 0x0c7e, 0x2061, 0x5100, 0x2d08, 0x206b, 0x0000, - 0x6084, 0x8000, 0x6086, 0x6088, 0xa005, 0x618a, 0x0040, 0x1c83, - 0x2d02, 0x0078, 0x1c84, 0x618e, 0x0c7f, 0x007c, 0x1078, 0x1c97, - 0x0040, 0x1c96, 0x0c7e, 0x609c, 0xa065, 0x0040, 0x1c91, 0x1078, - 0x19b3, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1948, 0x007c, 0x788c, - 0xa065, 0x0040, 0x1ca9, 0x2091, 0x8000, 0x7884, 0x8001, 0x7886, - 0x2c04, 0x788e, 0xa005, 0x00c0, 0x1ca7, 0x788a, 0x8000, 0x2091, - 0x8001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, - 0x00c8, 0x1cb3, 0xa200, 0x0070, 0x1cb7, 0x0078, 0x1cae, 0x8086, - 0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x1cdd, - 0xa11a, 0x00c8, 0x1cdd, 0x8213, 0x818d, 0x0048, 0x1cce, 0xa11a, - 0x00c8, 0x1ccf, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0xa11a, 0x2308, - 0x8210, 0x0070, 0x1cd5, 0x0078, 0x1cc3, 0x007e, 0x3200, 0xa084, - 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, - 0x0800, 0x0078, 0x1cd9, 0x7994, 0x70d0, 0xa106, 0x0040, 0x1d51, - 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x1d51, - 0x7008, 0x7208, 0xa206, 0x00c0, 0x1d51, 0xa286, 0x0008, 0x00c0, - 0x1d51, 0x2071, 0x0010, 0x1078, 0x192e, 0x0040, 0x1d51, 0x7a9c, - 0x7b98, 0x7ca4, 0x7da0, 0xa184, 0xff00, 0x0040, 0x1d1f, 0x2031, - 0x0000, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, - 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x2100, 0xa210, 0x2600, - 0xa319, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1d29, 0x8107, - 0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, - 0x0000, 0x2009, 0x0020, 0x1078, 0x1929, 0x2091, 0x8001, 0x0040, - 0x1d48, 0x1078, 0x1948, 0x78a8, 0x8000, 0x78aa, 0xa086, 0x0002, - 0x00c0, 0x1d51, 0x2091, 0x8000, 0x78e3, 0x0002, 0x78ab, 0x0000, - 0x78cc, 0xa085, 0x0003, 0x78ce, 0x2091, 0x8001, 0x0078, 0x1d51, - 0x78ab, 0x0000, 0x1078, 0x20ac, 0x6004, 0xa084, 0x000f, 0x0079, - 0x1d56, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x1d66, 0x1d88, - 0x1dae, 0x1d66, 0x1dcb, 0x1d75, 0x1f2c, 0x1f47, 0x1d66, 0x1d82, - 0x1da8, 0x1e13, 0x1e82, 0x1ed2, 0x1ee4, 0x1f43, 0x2039, 0x0400, - 0x78dc, 0xa705, 0x78de, 0x6008, 0xa705, 0x600a, 0x1078, 0x1fc7, - 0x609c, 0x78da, 0x1078, 0x2094, 0x007c, 0x78dc, 0xa084, 0x0100, - 0x0040, 0x1d7c, 0x0078, 0x1d66, 0x601c, 0xa085, 0x0080, 0x601e, - 0x0078, 0x1d8f, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c6, - 0x78dc, 0xa084, 0x0100, 0x0040, 0x1d8f, 0x0078, 0x1d66, 0x78df, - 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, - 0x0000, 0x0040, 0x1da5, 0x1078, 0x1fc7, 0x0040, 0x1da5, 0x78dc, - 0xa085, 0x0100, 0x78de, 0x0078, 0x1da7, 0x1078, 0x1feb, 0x007c, - 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x1078, 0x20c2, 0x78dc, 0xa08c, - 0x0e00, 0x00c0, 0x1db7, 0xa084, 0x0100, 0x00c0, 0x1db9, 0x0078, - 0x1d66, 0x1078, 0x1fc7, 0x00c0, 0x1dca, 0x6104, 0xa18c, 0x00ff, - 0xa186, 0x0007, 0x0040, 0x1f84, 0xa186, 0x000f, 0x0040, 0x1f84, - 0x1078, 0x1feb, 0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1dd2, - 0x0078, 0x1d66, 0x78df, 0x0000, 0x6714, 0x2011, 0x0001, 0x20a9, - 0x0001, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x1df5, 0x2011, - 0x0001, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, - 0x1df5, 0x2039, 0x0000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, - 0x0002, 0x0040, 0x1df5, 0x0078, 0x1e10, 0x1078, 0x1973, 0x2091, - 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, - 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x0070, 0x1e09, 0x0078, - 0x1df7, 0x8211, 0x0040, 0x1e10, 0x20a9, 0x0100, 0x0078, 0x1df7, - 0x1078, 0x1948, 0x007c, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000, - 0x0040, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6900, 0xa184, 0x0001, - 0x0040, 0x1e34, 0x6028, 0xa084, 0x00ff, 0x00c0, 0x1fa4, 0x6800, - 0xa084, 0x0001, 0x0040, 0x1fac, 0x6803, 0x0000, 0x680b, 0x0000, - 0x6807, 0x0000, 0x0078, 0x1fb4, 0x2011, 0x0001, 0x6020, 0xd0f4, - 0x0040, 0x1e3c, 0xa295, 0x0002, 0xd0c4, 0x0040, 0x1e41, 0xa295, - 0x0008, 0xd0cc, 0x0040, 0x1e46, 0xa295, 0x0400, 0x601c, 0xa084, - 0x0002, 0x0040, 0x1e4d, 0xa295, 0x0004, 0x602c, 0xa08c, 0x00ff, - 0xa182, 0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0, - 0x0040, 0x1fb0, 0x690e, 0x602c, 0x8007, 0xa08c, 0x00ff, 0xa182, - 0x0002, 0x0048, 0x1fb0, 0xa182, 0x001b, 0x00c8, 0x1fb0, 0x0040, - 0x1fb0, 0x6912, 0x6030, 0xa005, 0x00c0, 0x1e70, 0x2001, 0x001e, - 0x8000, 0x6816, 0x6028, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x6806, - 0x6028, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1fac, 0x680a, 0x6a02, - 0x0078, 0x1fb4, 0x2001, 0x5167, 0x2004, 0xa084, 0x8000, 0x0040, - 0x1fac, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6a04, 0x6b08, - 0x6418, 0xa484, 0x0003, 0x0040, 0x1ea8, 0x6128, 0xa18c, 0x00ff, - 0x8001, 0x00c0, 0x1ea1, 0x2100, 0xa210, 0x0048, 0x1ece, 0x0078, - 0x1ea8, 0x8001, 0x00c0, 0x1ece, 0x2100, 0xa212, 0x0048, 0x1ece, - 0xa484, 0x000c, 0x0040, 0x1ec2, 0x6128, 0x810f, 0xa18c, 0x00ff, - 0xa082, 0x0004, 0x00c0, 0x1eba, 0x2100, 0xa318, 0x0048, 0x1ece, - 0x0078, 0x1ec2, 0xa082, 0x0004, 0x00c0, 0x1ece, 0x2100, 0xa31a, - 0x0048, 0x1ece, 0x6030, 0xa005, 0x0040, 0x1ec8, 0x8000, 0x6816, - 0x6a06, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fb4, 0x2091, 0x8001, - 0x0078, 0x1fb0, 0x6114, 0x1078, 0x20e3, 0x2091, 0x8000, 0x6b08, - 0x8318, 0x0048, 0x1ee0, 0x6b0a, 0x2091, 0x8001, 0x0078, 0x1fc3, - 0x2091, 0x8001, 0x0078, 0x1fb0, 0x6024, 0x8007, 0xa084, 0x00ff, - 0x0040, 0x1f02, 0xa086, 0x0080, 0x00c0, 0x1f2a, 0x20a9, 0x0008, - 0x2069, 0x7510, 0x2091, 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802, - 0xade8, 0x0008, 0x0070, 0x1efe, 0x0078, 0x1ef4, 0x2091, 0x8001, - 0x0078, 0x1fb4, 0x6028, 0xa015, 0x0040, 0x1f2a, 0x6114, 0x1078, - 0x20e3, 0x0d7e, 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d, - 0x0040, 0x1f27, 0xa206, 0x0040, 0x1f18, 0x2168, 0x0078, 0x1f0e, - 0x0c7e, 0x2160, 0x6000, 0x6802, 0x1078, 0x1948, 0x0c7f, 0x0d7f, - 0x6808, 0x8000, 0x680a, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091, - 0x8001, 0x0d7f, 0x0078, 0x1fac, 0x6114, 0x1078, 0x20e3, 0x6800, - 0xa084, 0x0001, 0x0040, 0x1f9c, 0x2091, 0x8000, 0x6a04, 0x8210, - 0x0048, 0x1f3f, 0x6a06, 0x2091, 0x8001, 0x0078, 0x1fc3, 0x2091, - 0x8001, 0x0078, 0x1fb0, 0x1078, 0x1b53, 0x00c0, 0x1d66, 0x6114, - 0x1078, 0x20e3, 0x60be, 0x60bb, 0x0000, 0x6900, 0xa184, 0x0008, - 0x0040, 0x1f56, 0x6020, 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, - 0x0040, 0x1fac, 0xa184, 0x0100, 0x00c0, 0x1f98, 0xa184, 0x0200, - 0x00c0, 0x1f94, 0x681c, 0xa005, 0x00c0, 0x1fa0, 0x6004, 0xa084, - 0x00ff, 0xa086, 0x000f, 0x00c0, 0x1f6f, 0x1078, 0x20c6, 0x78df, - 0x0000, 0x6004, 0x8007, 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, - 0x0000, 0x0040, 0x1f84, 0x1078, 0x1fc7, 0x0040, 0x1f84, 0x78dc, - 0xa085, 0x0100, 0x78de, 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, - 0x6024, 0xa084, 0xff00, 0x6026, 0x1078, 0x39de, 0x0040, 0x1ce3, - 0x1078, 0x1b78, 0x0078, 0x1ce3, 0x2009, 0x0017, 0x0078, 0x1fb6, - 0x2009, 0x000e, 0x0078, 0x1fb6, 0x2009, 0x0007, 0x0078, 0x1fb6, - 0x2009, 0x0035, 0x0078, 0x1fb6, 0x2009, 0x003e, 0x0078, 0x1fb6, - 0x2009, 0x0004, 0x0078, 0x1fb6, 0x2009, 0x0006, 0x0078, 0x1fb6, - 0x2009, 0x0016, 0x0078, 0x1fb6, 0x2009, 0x0001, 0x6024, 0xa084, - 0xff00, 0xa105, 0x6026, 0x2091, 0x8000, 0x1078, 0x1c5f, 0x2091, - 0x8001, 0x0078, 0x1ce3, 0x1078, 0x1948, 0x0078, 0x1ce3, 0x78d4, - 0xa06d, 0x00c0, 0x1fd2, 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, - 0x0078, 0x1fde, 0x2c00, 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, - 0x6002, 0x78d8, 0xad06, 0x00c0, 0x1fde, 0x6002, 0x78d0, 0x8001, - 0x78d2, 0x00c0, 0x1fea, 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, - 0x2060, 0xa006, 0x007c, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, - 0xe1ff, 0x601e, 0xa184, 0x0060, 0x0040, 0x1ffa, 0x0e7e, 0x1078, - 0x47c2, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, - 0x60b3, 0x0000, 0x6714, 0x1078, 0x1973, 0x2091, 0x8000, 0x60a0, - 0xa084, 0x8000, 0x00c0, 0x2021, 0x6808, 0xa084, 0x0001, 0x0040, - 0x2021, 0x2091, 0x8001, 0x1078, 0x19c0, 0x2091, 0x8000, 0x1078, - 0x1c5f, 0x2091, 0x8001, 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, - 0x2093, 0x6024, 0xa096, 0x0001, 0x00c0, 0x2028, 0x8000, 0x6026, - 0x6a10, 0x6814, 0x2091, 0x8001, 0xa202, 0x0048, 0x2037, 0x0040, - 0x2037, 0x2039, 0x0200, 0x1078, 0x2094, 0x0078, 0x2093, 0x2c08, - 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x0040, 0x2064, 0x6800, - 0xa065, 0x0040, 0x2069, 0x6a04, 0x0e7e, 0x2071, 0x5140, 0x7000, - 0xa084, 0x0001, 0x0040, 0x205e, 0x7048, 0xa206, 0x00c0, 0x205e, - 0x6b04, 0x231c, 0x2160, 0x6302, 0x2300, 0xa005, 0x00c0, 0x2059, - 0x6902, 0x2260, 0x6102, 0x0e7f, 0x0078, 0x2070, 0x2160, 0x6202, - 0x6906, 0x0e7f, 0x0078, 0x2070, 0x6800, 0xa065, 0x0040, 0x2069, - 0x6102, 0x6902, 0x00c0, 0x206d, 0x6906, 0x2160, 0x6003, 0x0000, - 0x2160, 0x60a0, 0xa084, 0x8000, 0x0040, 0x207a, 0x6808, 0xa084, - 0xfffc, 0x680a, 0x6810, 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, - 0xa08c, 0x0040, 0x0040, 0x2089, 0xa086, 0x0040, 0x680a, 0x1078, - 0x19d1, 0x2091, 0x8000, 0x1078, 0x21d2, 0x2091, 0x8001, 0x78db, - 0x0000, 0x78d7, 0x0000, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, - 0x8000, 0x1078, 0x1c5f, 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, - 0x20a7, 0x609c, 0x78da, 0x609f, 0x0000, 0x0078, 0x2097, 0x78d7, - 0x0000, 0x78db, 0x0000, 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, - 0x00c8, 0x20b3, 0xa006, 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, - 0x20c1, 0x8001, 0x7806, 0x00c0, 0x20c1, 0x0068, 0x20c1, 0x2091, - 0x4080, 0x007c, 0x2039, 0x20da, 0x0078, 0x20c8, 0x2039, 0x20e0, - 0x2704, 0xa005, 0x0040, 0x20d9, 0xac00, 0x2068, 0x6b08, 0x6c0c, - 0x6910, 0x6a14, 0x690a, 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, - 0x20c8, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, - 0x0015, 0x001b, 0x0000, 0x0c7e, 0x1078, 0x3b69, 0x2c68, 0x0c7f, - 0x007c, 0x0010, 0x215a, 0x0068, 0x215a, 0x2029, 0x0000, 0x78cb, - 0x0000, 0x788c, 0xa065, 0x0040, 0x2153, 0x2009, 0x5174, 0x2104, - 0xa084, 0x0001, 0x0040, 0x2121, 0x6004, 0xa086, 0x0103, 0x00c0, - 0x2121, 0x6018, 0xa005, 0x00c0, 0x2121, 0x6014, 0xa005, 0x00c0, - 0x2121, 0x0d7e, 0x2069, 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, - 0x2120, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, - 0x0001, 0x2091, 0x4080, 0x0d7f, 0x1078, 0x1c86, 0x0078, 0x2158, - 0x0d7f, 0x1078, 0x215b, 0x0040, 0x2153, 0x6204, 0xa294, 0x00ff, - 0xa296, 0x0003, 0x0040, 0x2133, 0x6204, 0xa296, 0x0110, 0x00c0, - 0x2141, 0x78cb, 0x0001, 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, - 0x0040, 0x2141, 0x85ff, 0x00c0, 0x2153, 0x8210, 0xa202, 0x00c8, - 0x2153, 0x057e, 0x1078, 0x216a, 0x057f, 0x0040, 0x214e, 0x78e0, - 0xa086, 0x0003, 0x0040, 0x2153, 0x0078, 0x2141, 0x8528, 0x78c8, - 0xa005, 0x0040, 0x20f1, 0x85ff, 0x0040, 0x215a, 0x2091, 0x4080, - 0x78b0, 0x70d6, 0x007c, 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, - 0x2164, 0x2300, 0xa005, 0x007c, 0x0048, 0x2168, 0xa302, 0x007c, - 0x8002, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, - 0x2184, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, - 0x21b9, 0x7008, 0x7208, 0xa206, 0x00c0, 0x21b9, 0xa286, 0x0008, - 0x00c0, 0x21b9, 0x2071, 0x0010, 0x1078, 0x21be, 0x2009, 0x0020, - 0x6004, 0xa086, 0x0103, 0x00c0, 0x2193, 0x6028, 0xa005, 0x00c0, - 0x2193, 0x2009, 0x000c, 0x1078, 0x1924, 0x0040, 0x21ac, 0x78c4, - 0x8000, 0x78c6, 0xa086, 0x0002, 0x00c0, 0x21b9, 0x2091, 0x8000, - 0x78e3, 0x0003, 0x78c7, 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, - 0x2091, 0x8001, 0x0078, 0x21b9, 0x78c7, 0x0000, 0x1078, 0x1c86, - 0x79ac, 0x78b0, 0x8000, 0xa10a, 0x00c8, 0x21b7, 0xa006, 0x78b2, - 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, - 0x8004, 0x7ab8, 0x7bb4, 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, - 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x2009, 0x515b, 0x2091, - 0x8000, 0x200a, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x7000, 0xa086, - 0x0000, 0x00c0, 0x21ec, 0x2009, 0x5112, 0x2104, 0xa005, 0x00c0, - 0x21ec, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x21ec, - 0x0018, 0x21ec, 0x781b, 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, - 0x0e7e, 0x2071, 0x5140, 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, - 0x00c0, 0x2205, 0x2079, 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, - 0x2205, 0x0018, 0x2205, 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, - 0x0f7f, 0x007c, 0x127e, 0x2091, 0x2300, 0x2071, 0x5140, 0x2079, - 0x0100, 0x784b, 0x000f, 0x0098, 0x2218, 0x7838, 0x0078, 0x2211, - 0x20a9, 0x0040, 0x7800, 0xa082, 0x0004, 0x0048, 0x2221, 0x20a9, - 0x0060, 0x789b, 0x0000, 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, - 0x222b, 0x0078, 0x2223, 0x7800, 0xa082, 0x0004, 0x0048, 0x223a, - 0x70b7, 0x0096, 0x2019, 0x4ee7, 0x1078, 0x2276, 0x702f, 0x8001, - 0x0078, 0x2246, 0x70b7, 0x0000, 0x2019, 0x4d5f, 0x1078, 0x2276, - 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7003, 0x0000, - 0x1078, 0x237f, 0x7004, 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, - 0x210c, 0xa18a, 0x0005, 0x0048, 0x225b, 0x0038, 0x2261, 0xa085, - 0x6280, 0x0078, 0x2263, 0x0028, 0x2261, 0xa085, 0x6280, 0x0078, - 0x2263, 0xa085, 0x62c0, 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, - 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, - 0x517f, 0x704f, 0x0000, 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, - 0x157e, 0x047e, 0x20a1, 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, - 0x2296, 0x8318, 0x2324, 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, - 0x0040, 0x228e, 0xa482, 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, - 0xa005, 0x00c0, 0x2285, 0x3318, 0x0078, 0x227c, 0x047f, 0x157f, - 0x147f, 0x137f, 0x007c, 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, - 0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x237f, 0x007c, 0x2011, - 0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x22b0, 0x0078, 0x22ab, - 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, - 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070, 0x22c1, 0x0078, - 0x22bc, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, - 0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b, 0x0070, 0x22d2, - 0x0078, 0x22cd, 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, 0x235d, 0x2061, 0x7500, 0x1078, 0x2365, 0x0040, 0x2349, - 0x20a9, 0x0000, 0x2061, 0x7400, 0x0c7e, 0x1078, 0x2365, 0x0040, - 0x2339, 0x0c7f, 0x8c60, 0x0070, 0x2337, 0x0078, 0x232c, 0x0078, - 0x235d, 0x007f, 0xa082, 0x7400, 0x2071, 0x5140, 0x7086, 0x7182, - 0x2001, 0x0004, 0x706e, 0x7093, 0x000f, 0x1078, 0x21cd, 0x0078, - 0x2359, 0x60c0, 0xa005, 0x00c0, 0x235d, 0x2071, 0x5140, 0x7182, - 0x2c00, 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x1078, - 0x21cd, 0x2001, 0x0000, 0x0078, 0x235f, 0x2001, 0x0001, 0x2091, - 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, - 0x237c, 0x2060, 0x600c, 0xa306, 0x00c0, 0x2379, 0x6010, 0xa206, - 0x00c0, 0x2379, 0x6014, 0xa106, 0x00c0, 0x2379, 0xa006, 0x0078, - 0x237e, 0x6000, 0x0078, 0x2366, 0xa085, 0x0001, 0x007c, 0x2011, - 0x5141, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204, 0xa084, - 0x0100, 0x0040, 0x2395, 0x2021, 0xff04, 0x2122, 0x810b, 0x810b, - 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e, 0x68e4, - 0xa08c, 0x0020, 0x0040, 0x23e9, 0xa084, 0x0006, 0x00c0, 0x23e9, - 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, - 0x5380, 0x7004, 0xa084, 0x000a, 0x00c0, 0x23e9, 0x7108, 0xa194, - 0xff00, 0x0040, 0x23e9, 0xa18c, 0x00ff, 0x2001, 0x000c, 0xa106, - 0x0040, 0x23d0, 0x2001, 0x0012, 0xa106, 0x0040, 0x23d4, 0x2001, - 0x0014, 0xa106, 0x0040, 0x23d8, 0x2001, 0x0019, 0xa106, 0x0040, - 0x23dc, 0x2001, 0x0032, 0xa106, 0x0040, 0x23e0, 0x0078, 0x23e4, - 0x2009, 0x0012, 0x0078, 0x23e6, 0x2009, 0x0014, 0x0078, 0x23e6, - 0x2009, 0x0019, 0x0078, 0x23e6, 0x2009, 0x0020, 0x0078, 0x23e6, - 0x2009, 0x003f, 0x0078, 0x23e6, 0x2011, 0x0000, 0x2100, 0xa205, - 0x700a, 0x0e7f, 0x007c, 0x0068, 0x23eb, 0x2091, 0x8000, 0x2071, - 0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x23f2, 0x007f, - 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, - 0x0741, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, - 0x4080, 0x0078, 0x2409, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300, - 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca, 0x75ce, - 0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079, 0x2420, - 0x2432, 0x2432, 0x2432, 0x276c, 0x393b, 0x2430, 0x2461, 0x246b, - 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, 0x2430, - 0x1078, 0x23eb, 0x8507, 0xa084, 0x001f, 0x0079, 0x2437, 0x2475, - 0x276c, 0x2926, 0x2a23, 0x2a4b, 0x2ced, 0x2f98, 0x2fdb, 0x3026, - 0x30ab, 0x3163, 0x320c, 0x2461, 0x2848, 0x2f6d, 0x2457, 0x3cc8, - 0x3ce8, 0x3eae, 0x3eba, 0x3f8f, 0x2457, 0x2457, 0x4062, 0x4066, - 0x3cc6, 0x2457, 0x3e19, 0x2457, 0x3b8c, 0x246b, 0x2457, 0x1078, - 0x23eb, 0x0018, 0x2410, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, - 0x007c, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x781b, - 0x004f, 0x0078, 0x2459, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, - 0x8000, 0x781b, 0x00d0, 0x0078, 0x2459, 0x7242, 0x2009, 0x510f, - 0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3ba0, 0x0040, 0x2492, - 0x1078, 0x23eb, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043, 0x0000, - 0x7037, 0x0000, 0x1078, 0x3912, 0x0018, 0x2410, 0x2009, 0x510f, - 0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x255d, 0x706c, 0xa084, - 0x0007, 0x0079, 0x249b, 0x2594, 0x24a3, 0x24af, 0x24cc, 0x24ee, - 0x253b, 0x2514, 0x24a3, 0x1078, 0x38fa, 0x2009, 0x0048, 0x1078, - 0x2e39, 0x00c0, 0x24ad, 0x7003, 0x0004, 0x0078, 0x2459, 0x1078, - 0x38fa, 0x00c0, 0x24ca, 0x7080, 0x8007, 0x7882, 0x789b, 0x0010, - 0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, - 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ca, 0x7003, 0x0004, - 0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x24ec, - 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, - 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, - 0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x24ec, - 0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, - 0x00c0, 0x2512, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, - 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184, 0x79aa, - 0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, - 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2512, 0x7003, 0x0004, - 0x7093, 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2539, - 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f, 0xa18d, - 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab, 0x0002, - 0x785b, 0x0004, 0x2009, 0x00e0, 0x1078, 0x2e2d, 0x00c0, 0x2539, - 0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002, 0x7093, - 0x000f, 0x0078, 0x2459, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x7088, - 0x2068, 0x6f14, 0x1078, 0x37ef, 0x2c50, 0x1078, 0x39ac, 0x789b, - 0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x6e1c, - 0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004, 0x0040, - 0x255b, 0x2001, 0x0006, 0x0078, 0x267c, 0x1078, 0x38fa, 0x00c0, - 0x2459, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078, 0x37ef, - 0x2c50, 0x1078, 0x39ac, 0x6008, 0xa085, 0x0010, 0x600a, 0x6824, - 0xa005, 0x0040, 0x257b, 0xa082, 0x0006, 0x0048, 0x2579, 0x0078, - 0x257b, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, - 0x7058, 0xa084, 0x8000, 0x0040, 0x2589, 0xa684, 0x0001, 0x0040, - 0x258b, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041, 0x0001, - 0x2001, 0x0003, 0x0078, 0x267c, 0x0018, 0x2410, 0x744c, 0xa485, - 0x0000, 0x0040, 0x25ae, 0xa080, 0x5180, 0x2030, 0x7150, 0x8108, - 0xa12a, 0x0048, 0x25a5, 0x2009, 0x5180, 0x2164, 0x6504, 0x85ff, - 0x00c0, 0x25bf, 0x8421, 0x00c0, 0x259f, 0x7152, 0x7003, 0x0000, - 0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3ba0, 0x0078, 0x2459, - 0x764c, 0xa6b0, 0x5180, 0x7150, 0x2600, 0x0078, 0x25aa, 0x7152, - 0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, - 0x25bc, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x25f5, 0xa784, - 0x0021, 0x00c0, 0x25bc, 0xa784, 0x0002, 0x0040, 0x25de, 0xa784, - 0x0004, 0x0040, 0x25bc, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, - 0x00c0, 0x25bc, 0xa784, 0x0010, 0x00c0, 0x25bc, 0xa784, 0x0200, - 0x00c0, 0x25bc, 0xa784, 0x0100, 0x0040, 0x25f5, 0x6018, 0xa005, - 0x00c0, 0x25bc, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000, 0x6e1c, - 0xa684, 0x000e, 0x6118, 0x0040, 0x2605, 0x601c, 0xa102, 0x0048, - 0x2608, 0x0040, 0x2608, 0x0078, 0x25b8, 0x81ff, 0x00c0, 0x25b8, - 0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x2610, 0x700c, 0x6022, - 0xa7bc, 0xff7f, 0x670a, 0x1078, 0x39ac, 0x0018, 0x2410, 0x789b, - 0x0010, 0xa046, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x6b14, 0xa39c, - 0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262c, - 0xa684, 0x0001, 0x0040, 0x262e, 0xa39c, 0xffbf, 0xa684, 0x0010, - 0x0040, 0x2634, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, - 0x00c0, 0x263f, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x267a, 0x7158, - 0xa18c, 0x0800, 0x0040, 0x3401, 0x2011, 0x0020, 0xa684, 0x0008, - 0x00c0, 0x2650, 0x8210, 0xa684, 0x0002, 0x00c0, 0x2650, 0x8210, - 0x7aaa, 0x8840, 0x1078, 0x3912, 0x6a14, 0x610c, 0x8108, 0xa18c, - 0x00ff, 0xa1e0, 0x7400, 0x2c64, 0x8cff, 0x0040, 0x2671, 0x6014, - 0xa206, 0x00c0, 0x265b, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2656, - 0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, - 0x2594, 0x1078, 0x38fa, 0x00c0, 0x2459, 0x2a60, 0x610e, 0x79aa, - 0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184, 0x0018, - 0x0040, 0x2697, 0xa184, 0x0010, 0x0040, 0x268a, 0x1078, 0x3604, - 0x00c0, 0x26ba, 0xa184, 0x0008, 0x0040, 0x2697, 0x69a0, 0xa184, - 0x0600, 0x00c0, 0x2697, 0x1078, 0x34f1, 0x0078, 0x26ba, 0x69a0, - 0xa184, 0x0800, 0x0040, 0x26ae, 0x0c7e, 0x027e, 0x2960, 0x6000, - 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x027f, - 0x0c7f, 0x1078, 0x3604, 0x00c0, 0x26ba, 0x69a0, 0xa184, 0x0200, - 0x0040, 0x26b6, 0x1078, 0x3540, 0x0078, 0x26ba, 0xa184, 0x0400, - 0x00c0, 0x2693, 0x69a0, 0xa184, 0x1000, 0x0040, 0x26c5, 0x6914, - 0xa18c, 0xff00, 0x810f, 0x1078, 0x22ee, 0x007f, 0x7002, 0xa68c, - 0x00e0, 0xa684, 0x0060, 0x0040, 0x26d3, 0xa086, 0x0060, 0x00c0, - 0x26d3, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x26d8, 0xa18d, 0x0004, - 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, - 0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c, 0x0080, - 0x0040, 0x26f7, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050, 0x26f5, - 0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x78aa, - 0x8008, 0x810c, 0x0040, 0x3407, 0xa18c, 0x00f8, 0x00c0, 0x3407, - 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, 0x38fa, 0x00c0, 0x272e, 0x702c, 0x8003, 0x0048, - 0x2727, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x7830, - 0xa084, 0x00c0, 0x00c0, 0x272e, 0x0098, 0x2736, 0x6008, 0xa084, - 0xffef, 0x600a, 0x1078, 0x3912, 0x0078, 0x2482, 0x7200, 0xa284, - 0x0007, 0xa086, 0x0001, 0x00c0, 0x2743, 0x781b, 0x004f, 0x1078, - 0x3912, 0x0078, 0x2754, 0x6ab4, 0xa295, 0x2000, 0x7a5a, 0x781b, - 0x004f, 0x1078, 0x3912, 0x7200, 0x2500, 0xa605, 0x0040, 0x2754, - 0xa284, 0x0007, 0x1079, 0x2762, 0xad80, 0x0009, 0x7036, 0xa284, - 0x0007, 0xa086, 0x0001, 0x00c0, 0x2459, 0x6018, 0x8000, 0x601a, - 0x0078, 0x2459, 0x276a, 0x4a3a, 0x4a3a, 0x4a29, 0x4a3a, 0x276a, - 0x4a29, 0x276a, 0x1078, 0x23eb, 0x1078, 0x38fa, 0x0f7e, 0x2079, - 0x5100, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2790, 0x706c, - 0xa086, 0x0001, 0x00c0, 0x277f, 0x706e, 0x0078, 0x2823, 0x706c, - 0xa086, 0x0005, 0x00c0, 0x278e, 0x7088, 0x2068, 0x681b, 0x0004, - 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f, 0x0000, - 0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x27b1, 0xa186, - 0x0007, 0x00c0, 0x27a1, 0x2009, 0x5138, 0x200b, 0x0005, 0x0078, - 0x27b1, 0x2009, 0x5113, 0x2104, 0x2009, 0x5112, 0x200a, 0x2009, - 0x5138, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001, 0x0078, - 0x27b3, 0x706f, 0x0000, 0x1078, 0x4776, 0x157e, 0x20a9, 0x0010, - 0x2039, 0x0000, 0x1078, 0x36e2, 0xa7b8, 0x0100, 0x0070, 0x27c2, - 0x0078, 0x27ba, 0x157f, 0x7000, 0x0079, 0x27c6, 0x27f4, 0x27db, - 0x27db, 0x27ce, 0x27f4, 0x27f4, 0x27f4, 0x27f4, 0x2021, 0x515a, - 0x2404, 0xa005, 0x0040, 0x27f4, 0xad06, 0x00c0, 0x27db, 0x6800, - 0x2022, 0x0078, 0x27eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x27e7, - 0x6f14, 0x1078, 0x37ef, 0x1078, 0x33d8, 0x0078, 0x27eb, 0x7060, - 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, - 0x0008, 0x6822, 0x1078, 0x1c70, 0x2021, 0x7500, 0x1078, 0x2830, - 0x2021, 0x515a, 0x1078, 0x2830, 0x157e, 0x20a9, 0x0000, 0x2021, - 0x7400, 0x1078, 0x2830, 0x8420, 0x0070, 0x2808, 0x0078, 0x2801, - 0x2061, 0x5400, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018, 0x6110, - 0x81ff, 0x0040, 0x2817, 0xa102, 0x0050, 0x2817, 0x6012, 0x601b, - 0x0000, 0xace0, 0x0010, 0x0070, 0x281f, 0x0078, 0x280e, 0x8421, - 0x00c0, 0x280c, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040, 0x282a, - 0x1078, 0x3a00, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078, 0x2459, - 0x047e, 0x2404, 0xa005, 0x0040, 0x2844, 0x2068, 0x6800, 0x007e, - 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x1078, - 0x1c70, 0x007f, 0x0078, 0x2832, 0x047f, 0x2023, 0x0000, 0x007c, - 0xa282, 0x0003, 0x0050, 0x284e, 0x1078, 0x23eb, 0x2300, 0x0079, - 0x2851, 0x2854, 0x28c7, 0x28e4, 0xa282, 0x0002, 0x0040, 0x285a, - 0x1078, 0x23eb, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, - 0x2861, 0x2869, 0x2869, 0x286b, 0x289f, 0x340d, 0x2869, 0x289f, - 0x2869, 0x1078, 0x23eb, 0x7780, 0x1078, 0x36e2, 0x7780, 0xa7bc, - 0x0f00, 0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x2896, 0x2021, - 0x7500, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x0040, - 0x2896, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009, - 0x0004, 0x2011, 0x0010, 0x1078, 0x28ff, 0x047f, 0x0040, 0x2895, - 0x8420, 0x0070, 0x2895, 0x0078, 0x2886, 0x157f, 0x8738, 0xa784, - 0x001f, 0x00c0, 0x2871, 0x0078, 0x2482, 0x0078, 0x2482, 0x7780, - 0x1078, 0x37ef, 0x6018, 0xa005, 0x0040, 0x28c5, 0x2021, 0x7500, - 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x28ff, 0x0040, 0x28c5, - 0x157e, 0x20a9, 0x0000, 0x2021, 0x7400, 0x047e, 0x2009, 0x0005, - 0x2011, 0x0020, 0x1078, 0x28ff, 0x047f, 0x0040, 0x28c4, 0x8420, - 0x0070, 0x28c4, 0x0078, 0x28b5, 0x157f, 0x0078, 0x2482, 0x2200, - 0x0079, 0x28ca, 0x28cd, 0x28cf, 0x28cf, 0x1078, 0x23eb, 0x2009, - 0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x28d8, 0x2009, 0x000e, - 0x6818, 0xa084, 0x8000, 0x0040, 0x28de, 0x691a, 0x706f, 0x0000, - 0x7073, 0x0001, 0x0078, 0x3888, 0x2200, 0x0079, 0x28e7, 0x28ec, - 0x28cf, 0x28ea, 0x1078, 0x23eb, 0x1078, 0x4776, 0x7000, 0xa086, - 0x0001, 0x00c0, 0x339d, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, - 0x600a, 0x1078, 0x3390, 0x0040, 0x339d, 0x0078, 0x2594, 0x2404, - 0xa005, 0x0040, 0x2922, 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, - 0x0040, 0x290e, 0x2d20, 0x007f, 0x0078, 0x2900, 0x007f, 0x2022, - 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078, 0x1c70, - 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, - 0x33ee, 0x007c, 0xa085, 0x0001, 0x0078, 0x2921, 0x2300, 0x0079, - 0x2929, 0x292e, 0x292c, 0x29c7, 0x1078, 0x23eb, 0x78ec, 0xa084, - 0x0001, 0x00c0, 0x2942, 0x7000, 0xa086, 0x0004, 0x00c0, 0x293a, - 0x0078, 0x2965, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, - 0x0078, 0x339d, 0x78e4, 0xa005, 0x00d0, 0x2965, 0x0018, 0x2459, - 0x2008, 0xa084, 0x0030, 0x00c0, 0x2951, 0x781b, 0x004f, 0x0078, - 0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x294d, 0x2100, 0xa084, - 0x0007, 0x0079, 0x295b, 0x299e, 0x29a9, 0x298f, 0x2963, 0x38ed, - 0x38ed, 0x2963, 0x29b8, 0x1078, 0x23eb, 0x7000, 0xa086, 0x0004, - 0x00c0, 0x297f, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2975, 0x2011, - 0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006, - 0x0040, 0x296f, 0x706c, 0xa086, 0x0004, 0x0040, 0x296f, 0x79e4, - 0xa184, 0x0030, 0x0040, 0x2989, 0x78ec, 0xa084, 0x0003, 0x00c0, - 0x298b, 0x0078, 0x2f6d, 0x2001, 0x0003, 0x0078, 0x2d01, 0x6818, - 0xa084, 0x8000, 0x0040, 0x2996, 0x681b, 0x001d, 0x1078, 0x36c1, - 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x6818, 0xa084, - 0x8000, 0x0040, 0x29a5, 0x681b, 0x001d, 0x1078, 0x36c1, 0x0078, - 0x38b8, 0x6818, 0xa084, 0x8000, 0x0040, 0x29b0, 0x681b, 0x001d, - 0x1078, 0x36c1, 0x782b, 0x3008, 0x781b, 0x00cd, 0x0078, 0x2459, - 0x6818, 0xa084, 0x8000, 0x0040, 0x29bf, 0x681b, 0x001d, 0x1078, - 0x36c1, 0x782b, 0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0xa584, - 0x000f, 0x00c0, 0x29e4, 0x7000, 0x0079, 0x29ce, 0x2482, 0x29d8, - 0x29d6, 0x339d, 0x339d, 0x339d, 0x339d, 0x29d6, 0x1078, 0x23eb, - 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078, 0x3390, - 0x0040, 0x339d, 0x0078, 0x2594, 0x78e4, 0xa005, 0x00d0, 0x2965, - 0x0018, 0x2965, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f3, 0x781b, - 0x004f, 0x0078, 0x2459, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ef, - 0x2100, 0xa184, 0x0007, 0x0079, 0x29fd, 0x2a0f, 0x2a13, 0x2a07, - 0x2a05, 0x38ed, 0x38ed, 0x2a05, 0x38e3, 0x1078, 0x23eb, 0x1078, - 0x36c9, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x1078, - 0x36c9, 0x0078, 0x38b8, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b, - 0x00cd, 0x0078, 0x2459, 0x1078, 0x36c9, 0x782b, 0x3008, 0x781b, - 0x008e, 0x0078, 0x2459, 0x2300, 0x0079, 0x2a26, 0x2a2b, 0x2a29, - 0x2a2d, 0x1078, 0x23eb, 0x0078, 0x30ab, 0x681b, 0x0008, 0x78a3, - 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30ab, 0x78ec, 0xa084, - 0x0003, 0x0040, 0x30ab, 0xa184, 0x0007, 0x0079, 0x2a3f, 0x2a47, - 0x2a13, 0x298f, 0x3888, 0x38ed, 0x38ed, 0x2a47, 0x38e3, 0x1078, - 0x389c, 0x0078, 0x2459, 0xa282, 0x0005, 0x0050, 0x2a51, 0x1078, - 0x23eb, 0x2300, 0x0079, 0x2a54, 0x2a57, 0x2cae, 0x2cbc, 0x2200, - 0x0079, 0x2a5a, 0x2a74, 0x2a61, 0x2a74, 0x2a5f, 0x2c93, 0x1078, - 0x23eb, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, - 0x0048, 0x369d, 0xa08a, 0x0004, 0x00c8, 0x369d, 0x0079, 0x2a70, - 0x369d, 0x369d, 0x369d, 0x364b, 0x789b, 0x0018, 0x79a8, 0xa184, - 0x0080, 0x0040, 0x2a85, 0x0078, 0x369d, 0x7000, 0xa005, 0x00c0, - 0x2a7b, 0x2011, 0x0004, 0x0078, 0x321f, 0xa184, 0x00ff, 0xa08a, - 0x0010, 0x00c8, 0x369d, 0x0079, 0x2a8d, 0x2a9f, 0x2a9d, 0x2ab7, - 0x2abb, 0x2b78, 0x369d, 0x369d, 0x2b7a, 0x369d, 0x369d, 0x2c8f, - 0x2c8f, 0x369d, 0x369d, 0x369d, 0x2c91, 0x1078, 0x23eb, 0xa684, - 0x1000, 0x0040, 0x2aac, 0x2001, 0x0500, 0x8000, 0x8000, 0x783a, - 0x781b, 0x008c, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000, 0x0040, - 0x2ab5, 0x681b, 0x001d, 0x0078, 0x2aa3, 0x0078, 0x3888, 0x681b, - 0x001d, 0x0078, 0x36ad, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, - 0x2afc, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2b04, 0x6818, 0xa086, - 0x0008, 0x00c0, 0x2acd, 0x681b, 0x0000, 0xa684, 0x0400, 0x0040, - 0x2b74, 0xa684, 0x0080, 0x0040, 0x2af8, 0x7097, 0x0000, 0x6818, - 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2af8, 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, 0x2459, 0xa684, 0x1000, 0x0040, 0x2b04, - 0x781b, 0x0065, 0x0078, 0x2459, 0xa684, 0x0060, 0x0040, 0x2b70, - 0xa684, 0x0800, 0x0040, 0x2b70, 0xa684, 0x8000, 0x00c0, 0x2b12, - 0x0078, 0x2b2c, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x789b, 0x0076, - 0x7aac, 0x79ac, 0x78ac, 0x801b, 0x00c8, 0x2b1f, 0x8000, 0xa084, - 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, - 0x6b94, 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2b34, - 0xa6b4, 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, - 0x2b41, 0x1078, 0x482c, 0x1078, 0x4a29, 0x781b, 0x0064, 0x0078, - 0x2459, 0xa006, 0x1078, 0x4b30, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, - 0x2200, 0xa105, 0x0040, 0x2b50, 0x2200, 0xa422, 0x2100, 0xa31b, - 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, - 0x00c0, 0x2b62, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, - 0x0078, 0x2459, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2b6c, - 0x1078, 0x4a3a, 0x0078, 0x2459, 0x1078, 0x4a85, 0x0078, 0x2459, - 0x781b, 0x0065, 0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459, - 0x1078, 0x23eb, 0x0078, 0x2bdb, 0x6920, 0xa184, 0x0100, 0x0040, - 0x2b92, 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, - 0xa084, 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, - 0x0078, 0x2bca, 0xa184, 0x0200, 0x0040, 0x2bca, 0xa18c, 0xfdff, - 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, - 0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, - 0x0008, 0x0040, 0x2bca, 0x1078, 0x37eb, 0x1078, 0x34f1, 0x88ff, - 0x0040, 0x2bca, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, - 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2bc4, 0x782b, 0x3008, - 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065, - 0x0078, 0x2459, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2bd3, 0x781b, - 0x0058, 0x0078, 0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x0078, - 0x36a5, 0x0078, 0x36a5, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, - 0x00c0, 0x2be9, 0x6820, 0xa084, 0x0100, 0x0040, 0x2bd9, 0x2009, - 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, - 0x00c0, 0x2c20, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, - 0x2c18, 0x0048, 0x2bfd, 0x0078, 0x2c1a, 0xa380, 0x0002, 0xa102, - 0x00c8, 0x2c18, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, - 0x2060, 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, - 0x6006, 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2bcb, - 0x0078, 0x2b7c, 0x24a8, 0x7aa8, 0x00f0, 0x2c1a, 0x0078, 0x2beb, - 0xa284, 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2c80, 0x8318, 0x8318, - 0x2300, 0xa102, 0x0040, 0x2c30, 0x0048, 0x2c30, 0x0078, 0x2c7d, - 0xa286, 0x0023, 0x0040, 0x2bd9, 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, 0x2c54, 0x1078, 0x37eb, - 0x1078, 0x3604, 0x0078, 0x2c63, 0x0c7e, 0x7054, 0x2060, 0x6004, - 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2bca, 0x1078, - 0x37eb, 0x1078, 0x34f1, 0x88ff, 0x0040, 0x2bca, 0x789b, 0x0060, - 0x2800, 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, - 0x2c77, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7aa8, 0x0078, 0x2beb, - 0x8318, 0x2300, 0xa102, 0x0040, 0x2c89, 0x0048, 0x2c89, 0x0078, - 0x2beb, 0xa284, 0x0080, 0x00c0, 0x36ad, 0x0078, 0x36a5, 0x0078, - 0x36ad, 0x0078, 0x369d, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, - 0xa08e, 0x0001, 0x0040, 0x2c9e, 0x1078, 0x23eb, 0x7aa8, 0xa294, - 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x369d, - 0x0079, 0x2caa, 0x369d, 0x343e, 0x369d, 0x3599, 0xa282, 0x0000, - 0x00c0, 0x2cb4, 0x1078, 0x23eb, 0x1078, 0x36c1, 0x782b, 0x3008, - 0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0003, 0x00c0, 0x2cc2, - 0x1078, 0x23eb, 0xa484, 0x8000, 0x00c0, 0x2ce5, 0x706c, 0xa005, - 0x0040, 0x2ccc, 0x1078, 0x23eb, 0x6f14, 0x7782, 0xa7bc, 0x0f00, - 0x1078, 0x37ef, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, - 0x001f, 0x00c0, 0x2cd0, 0x1078, 0x36c5, 0x706f, 0x0002, 0x2009, - 0x5138, 0x200b, 0x0009, 0x0078, 0x2ce7, 0x1078, 0x36d1, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0xa282, 0x0004, 0x0050, - 0x2cf3, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2cf6, 0x2cf9, 0x2de2, - 0x2e15, 0xa286, 0x0003, 0x0040, 0x2cff, 0x1078, 0x23eb, 0x2001, - 0x0000, 0x007e, 0x68c0, 0xa005, 0x0040, 0x2d08, 0x7003, 0x0003, - 0x68a0, 0xa084, 0x2000, 0x0040, 0x2d11, 0x6008, 0xa085, 0x0002, - 0x600a, 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2d18, - 0x2482, 0x2d22, 0x2d22, 0x2f17, 0x2f53, 0x2482, 0x2f53, 0x2d20, - 0x1078, 0x23eb, 0xa684, 0x1000, 0x00c0, 0x2d2a, 0x1078, 0x4776, - 0x0040, 0x2dbc, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2d72, 0xa186, - 0x0008, 0x00c0, 0x2d41, 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, - 0x600a, 0x1078, 0x3390, 0x0040, 0x2d72, 0x1078, 0x4776, 0x0078, - 0x2d59, 0xa186, 0x0028, 0x00c0, 0x2d72, 0x1078, 0x4776, 0x6008, - 0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2d59, 0x8001, - 0x601a, 0xa005, 0x0040, 0x2d59, 0x8001, 0xa005, 0x0040, 0x2d59, - 0x601e, 0x6820, 0xa084, 0x0001, 0x0040, 0x2482, 0x6820, 0xa084, - 0xfffe, 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, - 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2d6f, 0x6002, 0x6006, - 0x0078, 0x2482, 0x017e, 0x1078, 0x2e46, 0x017f, 0xa684, 0xdf00, - 0x681e, 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2dbc, 0xa186, - 0x0002, 0x00c0, 0x2dbc, 0xa684, 0x0800, 0x00c0, 0x2d8f, 0xa684, - 0x0060, 0x0040, 0x2d8f, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, - 0xa084, 0x0800, 0x00c0, 0x2dbc, 0x8717, 0xa294, 0x000f, 0x8213, - 0x8213, 0x8213, 0xa290, 0x5380, 0xa290, 0x0000, 0x221c, 0xa384, - 0x0100, 0x00c0, 0x2da5, 0x0078, 0x2dab, 0x8210, 0x2204, 0xa085, - 0x0018, 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2db8, 0x68a0, - 0xa084, 0x0100, 0x00c0, 0x2db8, 0x1078, 0x2eca, 0x0078, 0x2482, - 0x6008, 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, - 0x0040, 0x2dc4, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, - 0x33df, 0x1078, 0x33ee, 0x00c0, 0x2dd1, 0x6008, 0xa084, 0xffef, - 0x600a, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2dda, 0x1078, 0x33d8, - 0x0078, 0x2dde, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1c70, - 0x0078, 0x2482, 0xa282, 0x0004, 0x0048, 0x2de8, 0x1078, 0x23eb, - 0x2200, 0x0079, 0x2deb, 0x2de6, 0x2def, 0x2dfc, 0x2def, 0x7000, - 0xa086, 0x0005, 0x0040, 0x2df8, 0x1078, 0x36c1, 0x782b, 0x3008, - 0x781b, 0x0065, 0x0078, 0x2459, 0x7890, 0x8007, 0x8001, 0xa084, - 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, - 0x0003, 0x0040, 0x2e11, 0xa186, 0x0000, 0x0040, 0x2e11, 0x0078, - 0x369d, 0x781b, 0x0065, 0x0078, 0x2459, 0x6820, 0xa085, 0x0004, - 0x6822, 0x82ff, 0x00c0, 0x2e20, 0x1078, 0x36c1, 0x0078, 0x2e27, - 0x8211, 0x0040, 0x2e25, 0x1078, 0x23eb, 0x1078, 0x36d1, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x702c, 0x8003, 0x0048, - 0x2e37, 0x2019, 0x4d9e, 0x1078, 0x2276, 0x702f, 0x8000, 0x1078, - 0x3912, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2e43, 0x0018, 0x2e43, - 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, - 0x00c0, 0x2e50, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2ec9, - 0xa684, 0x0800, 0x00c0, 0x2e72, 0x68b4, 0xa084, 0x4800, 0xa635, - 0xa684, 0x0800, 0x00c0, 0x2e72, 0x6998, 0x6a94, 0x692e, 0x6a32, - 0x703c, 0xa005, 0x00c0, 0x2e6a, 0x2200, 0xa105, 0x0040, 0x2e71, - 0x703f, 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2e71, 0x1078, - 0x4776, 0x007c, 0xa684, 0x0020, 0x0040, 0x2e94, 0xa684, 0x4000, - 0x0040, 0x2e80, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a, - 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e7a, - 0x703c, 0xa005, 0x00c0, 0x2e8e, 0x703f, 0x0015, 0x79d8, 0x7adc, - 0x692e, 0x6a32, 0x0078, 0x2e6a, 0xa684, 0x4000, 0x0040, 0x2e9e, - 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2e6a, 0x68b4, 0xa084, - 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2e98, 0x703c, 0xa005, - 0x00c0, 0x2eac, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, - 0x00c8, 0x2eb3, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, - 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2ec0, 0x0078, 0x2e6a, - 0x7000, 0xa086, 0x0006, 0x0040, 0x2ec9, 0x1078, 0x4b30, 0x0078, - 0x2e6a, 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, - 0x0040, 0x2ed6, 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, - 0x2ef1, 0x2482, 0x2efb, 0x2f04, 0x2ef9, 0x2ef9, 0x2ef9, 0x2ef9, - 0x2ef9, 0x1078, 0x23eb, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2f04, - 0x1078, 0x33d8, 0x0078, 0x2f0a, 0x7060, 0x2c50, 0x2060, 0x6800, - 0x6002, 0x2a60, 0x2021, 0x515a, 0x2404, 0xa005, 0x0040, 0x2f13, - 0x2020, 0x0078, 0x2f0c, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, - 0x33df, 0x1078, 0x33ee, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, - 0x0000, 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4b78, - 0xa684, 0x0800, 0x0040, 0x2f30, 0x691c, 0xa18d, 0x2000, 0x691e, - 0x6818, 0xa084, 0x8000, 0x0040, 0x2f40, 0x7868, 0xa08c, 0x00ff, - 0x0040, 0x2f3e, 0x681b, 0x001e, 0x0078, 0x2f40, 0x681b, 0x0000, - 0x2021, 0x515a, 0x2404, 0xad06, 0x0040, 0x2f47, 0x7460, 0x6800, - 0x2022, 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, - 0x1c70, 0x0078, 0x2482, 0x1078, 0x2e46, 0x682b, 0x0000, 0x2001, - 0x000e, 0x6f14, 0x1078, 0x3918, 0xa08c, 0x00ff, 0x6916, 0x6818, - 0xa084, 0x8000, 0x0040, 0x2f66, 0x703c, 0x681a, 0xa68c, 0xdf00, - 0x691e, 0x706f, 0x0000, 0x0078, 0x2482, 0x7000, 0xa005, 0x00c0, - 0x2f73, 0x0078, 0x2482, 0xa006, 0x1078, 0x4776, 0x6817, 0x0000, - 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, - 0xa085, 0x00ff, 0x6822, 0x7000, 0x0079, 0x2f86, 0x2482, 0x2f90, - 0x2f90, 0x2f92, 0x2f92, 0x2f92, 0x2f92, 0x2f8e, 0x1078, 0x23eb, - 0x1078, 0x33ee, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x33a8, - 0x2300, 0x0079, 0x2f9b, 0x2f9e, 0x2fa0, 0x2fd9, 0x1078, 0x23eb, - 0x7000, 0x0079, 0x2fa3, 0x2482, 0x2fad, 0x2fad, 0x2fc8, 0x2fad, - 0x2fd5, 0x2fc8, 0x2fab, 0x1078, 0x23eb, 0xa684, 0x0060, 0xa086, - 0x0060, 0x00c0, 0x2fc4, 0xa6b4, 0xffdf, 0xa6b4, 0xbfff, 0xa6b5, - 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffdf, 0x681e, 0x1078, 0x4776, - 0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684, 0x2000, 0x0040, 0x2fb7, - 0x6818, 0xa084, 0x8000, 0x0040, 0x2fd5, 0x681b, 0x0015, 0xa684, - 0x4000, 0x0040, 0x2fd5, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078, - 0x2459, 0x1078, 0x23eb, 0x2300, 0x0079, 0x2fde, 0x2fe1, 0x2fe3, - 0x3016, 0x1078, 0x23eb, 0x7000, 0x0079, 0x2fe6, 0x2482, 0x2ff0, - 0x2ff0, 0x300b, 0x2ff0, 0x3012, 0x300b, 0x2fee, 0x1078, 0x23eb, - 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3007, 0xa6b4, 0xffbf, - 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x681c, 0xa084, 0xffbf, - 0x681e, 0x1078, 0x4776, 0x1078, 0x4a3a, 0x0078, 0x3888, 0xa684, - 0x2000, 0x0040, 0x2ffa, 0x6818, 0xa084, 0x8000, 0x0040, 0x3012, - 0x681b, 0x0007, 0x781b, 0x00cd, 0x0078, 0x2459, 0x6820, 0xa085, - 0x0004, 0x6822, 0x1078, 0x3853, 0xa6b5, 0x0800, 0x1078, 0x36c1, - 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x2300, 0x0079, - 0x3029, 0x302c, 0x302e, 0x3030, 0x1078, 0x23eb, 0x0078, 0x36ad, - 0xa684, 0x0400, 0x00c0, 0x3059, 0x79e4, 0xa184, 0x0020, 0x0040, - 0x3040, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3040, 0x782b, 0x3009, - 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, - 0xa184, 0x0020, 0x0040, 0x3051, 0x78ec, 0xa084, 0x0003, 0x00c0, - 0x3055, 0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079, - 0x3091, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, - 0x0040, 0x308f, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, - 0x3080, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x3073, 0x2009, - 0xfff7, 0x0078, 0x3079, 0xa386, 0x0003, 0x00c0, 0x3080, 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, - 0x3888, 0x299e, 0x29a9, 0x309b, 0x30a3, 0x3099, 0x3099, 0x3888, - 0x3888, 0x1078, 0x23eb, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, - 0x6922, 0x0078, 0x3892, 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, - 0x6922, 0x0078, 0x3888, 0x79e4, 0xa184, 0x0030, 0x0040, 0x30b5, - 0x78ec, 0xa084, 0x0003, 0x00c0, 0x30dc, 0x7000, 0xa086, 0x0004, - 0x00c0, 0x30cf, 0x706c, 0xa086, 0x0002, 0x00c0, 0x30c5, 0x2011, - 0x0002, 0x2019, 0x0000, 0x0078, 0x2848, 0x706c, 0xa086, 0x0006, - 0x0040, 0x30bf, 0x706c, 0xa086, 0x0004, 0x0040, 0x30bf, 0x7000, - 0xa086, 0x0000, 0x0040, 0x2459, 0x6818, 0xa085, 0x8000, 0x681a, - 0x2001, 0x0014, 0x0078, 0x2d01, 0xa184, 0x0007, 0x0079, 0x30e0, - 0x3888, 0x3888, 0x30e8, 0x3888, 0x38ed, 0x38ed, 0x3888, 0x3888, - 0xa684, 0x0080, 0x0040, 0x3117, 0x7194, 0x81ff, 0x0040, 0x3117, - 0xa182, 0x000d, 0x00d0, 0x30f8, 0x7097, 0x0000, 0x0078, 0x30fd, - 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, 0x3892, 0xa684, - 0x0400, 0x00c0, 0x3158, 0x6820, 0xa084, 0x0001, 0x0040, 0x3892, - 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x312c, 0xa086, 0x0060, - 0x00c0, 0x312c, 0xa18d, 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, - 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, - 0x8000, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3407, 0xa18c, - 0x00f8, 0x00c0, 0x3407, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, - 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, - 0x147f, 0x137f, 0x157f, 0x6814, 0x8007, 0x7882, 0x0078, 0x3892, - 0x6818, 0xa084, 0x8000, 0x0040, 0x315f, 0x681b, 0x0008, 0x781b, - 0x00c3, 0x0078, 0x2459, 0x2300, 0x0079, 0x3166, 0x316b, 0x320a, - 0x3169, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x0079, 0x3170, - 0x2482, 0x317a, 0x31af, 0x3185, 0x3178, 0x2482, 0x3178, 0x3178, - 0x1078, 0x23eb, 0x681c, 0xa084, 0x2000, 0x0040, 0x3193, 0x6008, - 0xa085, 0x0002, 0x600a, 0x0078, 0x3193, 0x68c0, 0xa005, 0x00c0, - 0x31af, 0x6920, 0xa18d, 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, - 0x706a, 0x0078, 0x31a9, 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, - 0x6006, 0xa005, 0x00c0, 0x319d, 0x6002, 0x681c, 0xa084, 0x000e, - 0x0040, 0x31a9, 0x7014, 0x68ba, 0x7130, 0xa188, 0x7400, 0x0078, - 0x31ab, 0x2009, 0x7500, 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, - 0xa684, 0x0060, 0x0040, 0x3208, 0xa684, 0x0800, 0x00c0, 0x31c3, - 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, - 0x4776, 0x0078, 0x3208, 0xa684, 0x0020, 0x0040, 0x31d8, 0x68c0, - 0xa005, 0x0040, 0x31cf, 0x1078, 0x4b78, 0x0078, 0x31d2, 0xa006, - 0x1078, 0x4b30, 0x79d8, 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x31de, - 0x1078, 0x37fc, 0x69aa, 0x6aa6, 0x1078, 0x4b30, 0xa684, 0x8000, - 0x0040, 0x3208, 0xa684, 0x7fff, 0x68b6, 0x2001, 0x0076, 0x1078, - 0x3918, 0x2010, 0x2001, 0x0078, 0x1078, 0x3918, 0x2008, 0xa684, - 0x0020, 0x00c0, 0x3200, 0x2001, 0x007a, 0x1078, 0x3918, 0x801b, - 0x00c8, 0x31fb, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, - 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, - 0x0078, 0x2482, 0x0078, 0x36ad, 0x7037, 0x0000, 0xa282, 0x0006, - 0x0050, 0x3214, 0x1078, 0x23eb, 0x7000, 0xa084, 0x0007, 0x10c0, - 0x39be, 0x2300, 0x0079, 0x321c, 0x321f, 0x3248, 0x325c, 0x2200, - 0x0079, 0x3222, 0x3246, 0x36ad, 0x3228, 0x3246, 0x3278, 0x32ba, - 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e, 0x20a9, - 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3238, 0x0078, 0x3231, - 0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000, 0x68b7, 0x0700, - 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x369d, 0x1078, 0x23eb, - 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0xad80, 0x0009, - 0x7036, 0x2200, 0x0079, 0x3254, 0x36ad, 0x325a, 0x325a, 0x3278, - 0x325a, 0x36ad, 0x1078, 0x23eb, 0x7003, 0x0005, 0x2001, 0x7610, - 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x3268, - 0x3270, 0x326e, 0x326e, 0x3270, 0x326e, 0x3270, 0x1078, 0x23eb, - 0x1078, 0x36d1, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, - 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, - 0xa484, 0x001f, 0xa215, 0x2069, 0x7500, 0x2d04, 0x2d08, 0x7162, - 0x2068, 0xa005, 0x0040, 0x3293, 0x6814, 0xa206, 0x0040, 0x32af, - 0x6800, 0x0078, 0x3286, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, - 0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, - 0x0070, 0x32a4, 0x0078, 0x329d, 0x157f, 0xad80, 0x0009, 0x7036, - 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, - 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3309, 0x1078, 0x36c9, - 0x0078, 0x3309, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b, - 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8, 0x79a8, 0xa18c, - 0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x7162, 0x2068, 0xa005, - 0x0040, 0x32d9, 0x6814, 0xa206, 0x0040, 0x32f4, 0x6800, 0x0078, - 0x32cc, 0x7003, 0x0005, 0x2001, 0x7610, 0x2068, 0x704a, 0x157e, - 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x32e9, 0x0078, - 0x32e2, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, - 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, - 0x0c00, 0x0040, 0x3309, 0xa084, 0x0800, 0x0040, 0x3303, 0x1078, - 0x36cd, 0x0078, 0x3309, 0x1078, 0x36c9, 0x708b, 0x0000, 0x0078, - 0x3309, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, - 0xa080, 0x5380, 0x2060, 0x7056, 0x6000, 0x705a, 0x6004, 0x705e, - 0xa684, 0x0060, 0x0040, 0x3361, 0x6b98, 0x6c94, 0x69ac, 0x68b0, - 0xa105, 0x00c0, 0x3343, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, - 0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060, 0x0040, 0x3361, - 0x68c0, 0xa005, 0x0040, 0x333c, 0x7003, 0x0003, 0x682b, 0x0000, - 0x1078, 0x4a29, 0x0078, 0x333e, 0x1078, 0x4a3a, 0xa6b5, 0x2000, - 0x7e5a, 0x0078, 0x3361, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, - 0xa305, 0x0040, 0x3361, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, - 0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005, 0x007f, 0x0040, - 0x335f, 0x7003, 0x0003, 0x1078, 0x4a29, 0x0078, 0x3361, 0x1078, - 0x4a85, 0x077f, 0x1078, 0x37ef, 0x2009, 0x0065, 0xa684, 0x0004, - 0x0040, 0x3382, 0x78e4, 0xa084, 0x0030, 0x0040, 0x337a, 0x78ec, - 0xa084, 0x0003, 0x0040, 0x337a, 0x782b, 0x3008, 0x2009, 0x0065, - 0x0078, 0x3382, 0x0f7e, 0x2079, 0x5100, 0x1078, 0x4776, 0x0f7f, - 0x0040, 0x2482, 0x791a, 0x2d00, 0x704a, 0x8207, 0xa084, 0x000f, - 0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2048, 0x0078, 0x2459, - 0x6020, 0xa005, 0x0040, 0x339c, 0x8001, 0x6022, 0x6008, 0xa085, - 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006, 0x1078, 0x4776, - 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, - 0x7000, 0xa084, 0x0007, 0x0079, 0x33ad, 0x2482, 0x33b7, 0x33b7, - 0x33d4, 0x33bf, 0x33bd, 0x33bf, 0x33b5, 0x1078, 0x23eb, 0x1078, - 0x33df, 0x1078, 0x33d8, 0x1078, 0x1c70, 0x0078, 0x2482, 0x706c, - 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x33c6, 0x33d0, 0x33d0, - 0x33ce, 0x33ce, 0x33ce, 0x33d0, 0x33ce, 0x33d0, 0x0079, 0x2861, - 0x706f, 0x0000, 0x0078, 0x2482, 0x681b, 0x0000, 0x0078, 0x2f17, - 0x6800, 0xa005, 0x00c0, 0x33dd, 0x6002, 0x6006, 0x007c, 0x6010, - 0xa005, 0x0040, 0x33e8, 0x8001, 0x00d0, 0x33e8, 0x1078, 0x23eb, - 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018, 0xa005, - 0x0040, 0x33f4, 0x8001, 0x601a, 0x007c, 0x1078, 0x3912, 0x681b, - 0x0018, 0x0078, 0x342b, 0x1078, 0x3912, 0x681b, 0x0019, 0x0078, - 0x342b, 0x1078, 0x3912, 0x681b, 0x001a, 0x0078, 0x342b, 0x1078, - 0x3912, 0x681b, 0x0003, 0x0078, 0x342b, 0x7780, 0x1078, 0x37ef, - 0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7400, 0x2d04, 0x2d08, 0x2068, - 0xa005, 0x00c0, 0x341d, 0x0078, 0x2482, 0x6814, 0x7280, 0xa206, - 0x0040, 0x3425, 0x6800, 0x0078, 0x3416, 0x6800, 0x200a, 0x681b, - 0x0005, 0x708b, 0x0000, 0x1078, 0x33df, 0x6820, 0xa084, 0x0001, - 0x00c0, 0x3434, 0x1078, 0x33d8, 0x1078, 0x33ee, 0x681f, 0x0000, - 0x6823, 0x0020, 0x1078, 0x1c70, 0x0078, 0x2482, 0xa282, 0x0003, - 0x00c0, 0x369d, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, - 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100, 0x0040, 0x34a2, - 0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040, 0x348c, 0xa482, - 0x000c, 0x0048, 0x345f, 0x0040, 0x345f, 0x2021, 0x000c, 0x852b, - 0x852b, 0x1078, 0x3760, 0x0040, 0x3469, 0x1078, 0x355b, 0x0078, - 0x3495, 0x1078, 0x371b, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5, - 0x6006, 0x1078, 0x3586, 0x0c7f, 0x6920, 0xa18d, 0x0100, 0x6922, - 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x3486, - 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, 0x3008, - 0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x2960, 0x6004, 0xa084, - 0xfff5, 0x6006, 0x1078, 0x3586, 0x0c7f, 0x7e58, 0xa684, 0x0400, - 0x00c0, 0x349e, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065, - 0x0078, 0x2459, 0x0c7e, 0x7054, 0x2060, 0x6100, 0xa18c, 0x1000, - 0x0040, 0x34e2, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, - 0x0048, 0x34b6, 0x0040, 0x34b6, 0x2011, 0x000c, 0x2400, 0xa202, - 0x00c8, 0x34bb, 0x2220, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, - 0x0028, 0x00c0, 0x34cb, 0xa282, 0x0019, 0x00c8, 0x34d1, 0x2011, - 0x0019, 0x0078, 0x34d1, 0xa282, 0x000c, 0x00c8, 0x34d1, 0x2011, - 0x000c, 0x2200, 0xa502, 0x00c8, 0x34d6, 0x2228, 0x1078, 0x371f, - 0x852b, 0x852b, 0x1078, 0x3760, 0x0040, 0x34e2, 0x1078, 0x355b, - 0x0078, 0x34e6, 0x1078, 0x371b, 0x1078, 0x3586, 0x7858, 0xa085, - 0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, - 0x2459, 0x0c7e, 0x2960, 0x6000, 0xa084, 0x1000, 0x00c0, 0x3509, - 0x6010, 0xa084, 0x000f, 0x00c0, 0x3503, 0x6104, 0xa18c, 0xfff5, - 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, - 0x3530, 0x68a0, 0xa084, 0x0200, 0x00c0, 0x3503, 0x6208, 0xa294, - 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x351e, 0xa282, 0x0019, - 0x00c8, 0x3524, 0x2011, 0x0019, 0x0078, 0x3524, 0xa282, 0x000c, - 0x00c8, 0x3524, 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, - 0xa382, 0x000c, 0x0048, 0x3530, 0x0040, 0x3530, 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, 0x354b, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, - 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085, 0x0100, - 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7154, 0x2160, 0x1078, 0x3562, - 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, 0x78ec, 0xd08c, 0x00c0, - 0x3585, 0x6004, 0xa084, 0xfff5, 0x6006, 0x007c, 0x0c7e, 0x7054, - 0x2060, 0x1078, 0x358d, 0x0c7f, 0x007c, 0x6018, 0x789a, 0x78a4, - 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, - 0x007c, 0xa282, 0x0002, 0x00c0, 0x369d, 0x7aa8, 0x6920, 0xa18d, - 0x0080, 0x6922, 0xa184, 0x0200, 0x0040, 0x35e2, 0xa18c, 0xfdff, - 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8, 0x369d, 0x1078, - 0x362b, 0x1078, 0x3586, 0xa980, 0x0001, 0x200c, 0x1078, 0x37eb, - 0x1078, 0x34f1, 0x88ff, 0x0040, 0x35d5, 0x789b, 0x0060, 0x2800, - 0x78aa, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, - 0x35cf, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x2459, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x7e58, 0xa684, 0x0400, - 0x00c0, 0x35de, 0x781b, 0x0058, 0x0078, 0x2459, 0x781b, 0x0065, - 0x0078, 0x2459, 0xa282, 0x0002, 0x00c8, 0x35ea, 0xa284, 0x0001, - 0x0040, 0x35f4, 0x7154, 0xa188, 0x0000, 0x210c, 0xa18c, 0x2000, - 0x00c0, 0x35f4, 0x2011, 0x0000, 0x1078, 0x370d, 0x1078, 0x362b, - 0x1078, 0x3586, 0x7858, 0xa085, 0x0004, 0x785a, 0x782b, 0x3008, - 0x781b, 0x0065, 0x0078, 0x2459, 0x0c7e, 0x027e, 0x2960, 0x6000, - 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x361b, 0x6014, 0xa084, - 0x0040, 0x00c0, 0x3619, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, - 0x3628, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, - 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, - 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3632, - 0x0c7f, 0x007c, 0x82ff, 0x0040, 0x3637, 0x2011, 0x0040, 0x6018, - 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6, - 0x788a, 0x6016, 0x78ec, 0xd08c, 0x00c0, 0x364a, 0x6004, 0xa084, - 0xffef, 0x6006, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, - 0x3654, 0x007f, 0x0078, 0x3657, 0x007f, 0x0078, 0x3699, 0xa684, - 0x0020, 0x0040, 0x3699, 0x7888, 0xa084, 0x0040, 0x0040, 0x3699, - 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8, 0x3667, 0x8000, 0xa005, - 0x0040, 0x367d, 0x831b, 0x00c8, 0x3670, 0x8001, 0x0040, 0x3695, - 0xa684, 0x4000, 0x0040, 0x367d, 0x78b8, 0x801b, 0x00c8, 0x3679, - 0x8000, 0xa084, 0x003f, 0x00c0, 0x3695, 0xa6b4, 0xbfff, 0x7e5a, - 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3689, 0xa291, - 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4b30, 0x781b, - 0x0064, 0x1078, 0x49b5, 0x0078, 0x2459, 0x781b, 0x0064, 0x0078, - 0x2459, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36d5, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x1078, 0x36c1, 0x782b, - 0x3008, 0x781b, 0x0065, 0x0078, 0x2459, 0x6827, 0x0002, 0x1078, - 0x36c9, 0x78e4, 0xa084, 0x0030, 0x0040, 0x2482, 0x78ec, 0xa084, - 0x0003, 0x0040, 0x2482, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, - 0x2459, 0x2001, 0x0005, 0x0078, 0x36d7, 0x2001, 0x000c, 0x0078, - 0x36d7, 0x2001, 0x0006, 0x0078, 0x36d7, 0x2001, 0x000d, 0x0078, - 0x36d7, 0x2001, 0x0009, 0x0078, 0x36d7, 0x2001, 0x0007, 0x789b, - 0x0010, 0x78aa, 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, - 0x7e5a, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, - 0x8703, 0xa0e0, 0x5380, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, - 0x000f, 0x0040, 0x36fb, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, - 0xa085, 0x0008, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, - 0x0040, 0x0040, 0x370b, 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, 0x5146, 0x2004, 0xa082, 0x0028, 0x0040, - 0x3749, 0x2021, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, - 0x374f, 0x2021, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, - 0x0064, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040, 0x375e, 0x8420, - 0x2300, 0xa210, 0x0070, 0x375e, 0x0078, 0x3751, 0x157f, 0x007c, - 0x157e, 0x2009, 0x5146, 0x210c, 0xa182, 0x0032, 0x0048, 0x3774, - 0x0040, 0x3778, 0x2009, 0x37c4, 0x2019, 0x0011, 0x20a9, 0x000e, - 0x2011, 0x0032, 0x0078, 0x378a, 0xa182, 0x0028, 0x0040, 0x3782, - 0x2009, 0x37d2, 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, - 0x0078, 0x378a, 0x2009, 0x37de, 0x2019, 0x0019, 0x20a9, 0x000d, - 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x379a, 0x0048, 0x379a, - 0x8108, 0x2300, 0xa210, 0x0070, 0x3797, 0x0078, 0x378a, 0x157f, - 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x37a9, 0x7808, - 0xa085, 0x0070, 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, - 0x37a9, 0x78ec, 0xa084, 0x0300, 0x0040, 0x37b1, 0x2104, 0x0078, - 0x37c2, 0x2104, 0xa09e, 0x1102, 0x00c0, 0x37c2, 0x2001, 0x04fd, - 0x2004, 0xa082, 0x0005, 0x0048, 0x37c1, 0x2001, 0x1201, 0x0078, - 0x37c2, 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, 0x5400, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, - 0x00c8, 0x3803, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, - 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x5140, 0x2091, 0x8000, - 0x2104, 0x0079, 0x3813, 0x3849, 0x381d, 0x381d, 0x381d, 0x381d, - 0x381d, 0x381d, 0x384d, 0x1078, 0x23eb, 0x784b, 0x0004, 0x7848, - 0xa084, 0x0004, 0x00c0, 0x381f, 0x784b, 0x0008, 0x7848, 0xa084, - 0x0008, 0x00c0, 0x3826, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, - 0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3849, - 0x0018, 0x3849, 0x681c, 0xa084, 0x0020, 0x00c0, 0x3847, 0x0e7e, - 0x2071, 0x5140, 0x1078, 0x389c, 0x0e7f, 0x0078, 0x3849, 0x781b, - 0x00cd, 0x2091, 0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078, - 0x3a76, 0x0078, 0x3849, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, - 0x8003, 0x8003, 0x8003, 0xa0e0, 0x5380, 0x6004, 0xa084, 0x000a, - 0x00c0, 0x3886, 0x6108, 0xa194, 0xff00, 0x0040, 0x3886, 0xa18c, - 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x3875, 0x2001, 0x0032, - 0xa106, 0x0040, 0x3879, 0x0078, 0x387d, 0x2009, 0x0020, 0x0078, - 0x387f, 0x2009, 0x003f, 0x0078, 0x387f, 0x2011, 0x0000, 0x2100, - 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c, - 0x781b, 0x0065, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x0065, - 0x0078, 0x2459, 0x781b, 0x0058, 0x0078, 0x2459, 0x782b, 0x3008, - 0x781b, 0x0056, 0x0078, 0x2459, 0x2009, 0x5120, 0x210c, 0xa186, - 0x0000, 0x0040, 0x38b0, 0xa186, 0x0001, 0x0040, 0x38b3, 0x2009, - 0x5138, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c, - 0x781b, 0x00c7, 0x007c, 0x2009, 0x5138, 0x200b, 0x000a, 0x007c, - 0x2009, 0x5120, 0x210c, 0xa186, 0x0000, 0x0040, 0x38d3, 0xa186, - 0x0001, 0x0040, 0x38cd, 0x2009, 0x5138, 0x200b, 0x000b, 0x706f, - 0x0001, 0x781b, 0x0048, 0x0078, 0x2459, 0x2009, 0x5138, 0x200b, - 0x000a, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, 0x00c7, 0x0078, - 0x2459, 0x781b, 0x00cd, 0x0078, 0x2459, 0x782b, 0x3008, 0x781b, - 0x00cd, 0x0078, 0x2459, 0x781b, 0x008e, 0x0078, 0x2459, 0x782b, - 0x3008, 0x781b, 0x008e, 0x0078, 0x2459, 0x6818, 0xa084, 0x8000, - 0x0040, 0x38f4, 0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048, - 0x0078, 0x2459, 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3910, - 0x7808, 0xa084, 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, - 0x78ec, 0xa084, 0x0021, 0x0040, 0x3910, 0x7044, 0x780a, 0xa005, - 0x007f, 0x007c, 0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c, - 0x007e, 0x7830, 0xa084, 0x0040, 0x00c0, 0x3919, 0x0098, 0x3924, - 0x007f, 0x789a, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, - 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, - 0x3933, 0x0098, 0x3931, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044, - 0x780a, 0x007f, 0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4760, - 0xa784, 0x007d, 0x00c0, 0x3947, 0x2700, 0x1078, 0x23eb, 0xa784, - 0x0001, 0x00c0, 0x2f6d, 0xa784, 0x0070, 0x0040, 0x3957, 0x0c7e, - 0x2d60, 0x2f68, 0x1078, 0x2396, 0x2d78, 0x2c68, 0x0c7f, 0xa784, - 0x0008, 0x0040, 0x3964, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, - 0x0040, 0x2482, 0x0078, 0x3888, 0xa784, 0x0004, 0x0040, 0x3997, - 0x78b8, 0xa084, 0x4001, 0x0040, 0x3997, 0x784b, 0x0008, 0x78ec, - 0xa084, 0x0003, 0x0040, 0x2482, 0x78e4, 0xa084, 0x0007, 0xa086, - 0x0001, 0x00c0, 0x3997, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a, - 0x781b, 0x00cd, 0x0078, 0x2459, 0x784b, 0x0008, 0x6818, 0xa084, - 0x8000, 0x0040, 0x3993, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, - 0x3993, 0x681b, 0x0007, 0x1078, 0x389c, 0x0078, 0x2459, 0x681b, - 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, - 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2965, - 0x0018, 0x2459, 0x0078, 0x36a5, 0x6b14, 0x8307, 0xa084, 0x000f, - 0x8003, 0x8003, 0x8003, 0xa080, 0x5380, 0x2060, 0x2048, 0x7056, - 0x6000, 0x705a, 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x39c0, - 0x39c8, 0x39c9, 0x39c8, 0x39cb, 0x39c8, 0x39c8, 0x39c8, 0x39d0, - 0x007c, 0x1078, 0x33ee, 0x1078, 0x4776, 0x7038, 0x600a, 0x007c, - 0x70a0, 0xa005, 0x0040, 0x39dd, 0x2068, 0x1078, 0x1b62, 0x1078, - 0x46f8, 0x1078, 0x46ff, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091, - 0x8000, 0x2071, 0x5140, 0x7000, 0xa086, 0x0007, 0x00c0, 0x39f4, - 0x6110, 0x70bc, 0xa106, 0x00c0, 0x39f4, 0x0e7f, 0x1078, 0x1b6f, - 0x1078, 0x39fa, 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085, - 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5140, 0x0078, 0x21fa, - 0x785b, 0x0000, 0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0, - 0xa06d, 0x0040, 0x3a0f, 0x70a3, 0x0000, 0x0078, 0x3a15, 0x70b3, - 0x0000, 0x1078, 0x1b8b, 0x0040, 0x3a1b, 0x70ac, 0x6826, 0x1078, - 0x3af8, 0x0078, 0x3a0f, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9, - 0x0008, 0x2061, 0x7510, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d, - 0x0040, 0x3a33, 0x6800, 0x601e, 0x1078, 0x195a, 0x6008, 0x8000, - 0x600a, 0x0078, 0x3a26, 0x6018, 0xa06d, 0x0040, 0x3a3d, 0x6800, - 0x601a, 0x1078, 0x195a, 0x0078, 0x3a33, 0xace0, 0x0008, 0x0070, - 0x3a43, 0x0078, 0x3a23, 0x709c, 0xa084, 0x8000, 0x0040, 0x3a4a, - 0x1078, 0x3b72, 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091, - 0x2300, 0x6804, 0xa084, 0x000f, 0x0079, 0x3a56, 0x3a66, 0x3a66, - 0x3a66, 0x3a66, 0x3a66, 0x3a66, 0x3a68, 0x3a6e, 0x3a66, 0x3a66, - 0x3a66, 0x3a66, 0x3a66, 0x3a70, 0x3a66, 0x3a68, 0x1078, 0x23eb, - 0x1078, 0x44d0, 0x1078, 0x195a, 0x0078, 0x3a74, 0x6827, 0x000b, - 0x1078, 0x44d0, 0x1078, 0x3af8, 0x127f, 0x007c, 0x127e, 0x2091, - 0x2300, 0x0098, 0x3a92, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3a92, - 0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001, - 0x0000, 0x6827, 0x0084, 0x1078, 0x46c1, 0x1078, 0x3af8, 0x0d7f, - 0x0078, 0x3ac6, 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3a9b, - 0x794a, 0x0078, 0x3a80, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3aa4, - 0xa185, 0x0004, 0x0078, 0x3aab, 0x7828, 0xa086, 0x1814, 0x00c0, - 0x3a98, 0xa185, 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002, - 0x7858, 0xa084, 0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080, - 0x0091, 0x781a, 0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a, - 0x2009, 0x0004, 0x2001, 0x0000, 0x1078, 0x46c1, 0x127f, 0x007c, - 0x0d7e, 0x6b14, 0x1078, 0x1bfd, 0x0040, 0x3ad5, 0x2068, 0x6827, - 0x0002, 0x1078, 0x3af8, 0x0078, 0x3aca, 0x0d7f, 0x007c, 0x0d7e, - 0x6b14, 0x6c28, 0xa4a4, 0x00ff, 0x1078, 0x1b9b, 0x0040, 0x3ae5, - 0x2068, 0x6827, 0x0002, 0x1078, 0x3af8, 0x0d7f, 0x007c, 0x0d7e, - 0x6b14, 0xa39c, 0x00ff, 0x1078, 0x1bce, 0x0040, 0x3af6, 0x2068, - 0x6827, 0x0002, 0x1078, 0x3af8, 0x0078, 0x3aeb, 0x0d7f, 0x007c, - 0x0c7e, 0x6914, 0x1078, 0x3b69, 0x6904, 0xa18c, 0x00ff, 0xa186, - 0x0006, 0x0040, 0x3b13, 0xa186, 0x000d, 0x0040, 0x3b32, 0xa186, - 0x0017, 0x00c0, 0x3b0f, 0x1078, 0x195a, 0x0078, 0x3b11, 0x1078, - 0x1c72, 0x0c7f, 0x007c, 0x6004, 0x8001, 0x0048, 0x3b30, 0x6006, - 0x2009, 0x0000, 0xa684, 0x0001, 0x00c0, 0x3b20, 0xa18d, 0x8000, - 0xa684, 0x0004, 0x0040, 0x3b26, 0xa18d, 0x0002, 0x691e, 0x6823, - 0x0000, 0x7104, 0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3b0f, - 0x1078, 0x23eb, 0x6018, 0xa005, 0x00c0, 0x3b41, 0x6008, 0x8001, - 0x0048, 0x3b41, 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, - 0x3b57, 0xac88, 0x0006, 0x2104, 0xa005, 0x0040, 0x3b4a, 0x2008, - 0x0078, 0x3b43, 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3b11, - 0x600a, 0x6018, 0x2068, 0x6800, 0x601a, 0x0078, 0x3b3b, 0x157e, - 0x137e, 0x147e, 0x0c7e, 0x0d7e, 0x1078, 0x1937, 0x2da0, 0x137f, - 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x0078, - 0x3b0f, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003, 0xa080, 0x7510, - 0x2060, 0x007c, 0x2019, 0x5151, 0x2304, 0xa085, 0x0001, 0x201a, - 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a, 0x007c, 0x2019, - 0x5151, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019, 0x0102, 0x2304, - 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c, 0xfff8, 0x7992, - 0x70b4, 0xa080, 0x00dd, 0x781a, 0x0078, 0x2459, 0x70a3, 0x0000, - 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000, 0x0018, 0x2410, - 0x1078, 0x1b8b, 0x0040, 0x3bc7, 0x2009, 0x510f, 0x200b, 0x0000, - 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040, 0x3bbb, 0x6827, - 0x000e, 0xa084, 0x0200, 0x0040, 0x3bb7, 0x6827, 0x0017, 0x1078, - 0x3af8, 0x0078, 0x3b96, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3c29, - 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078, 0x3bce, 0x7040, - 0xa086, 0x0001, 0x0040, 0x2492, 0x0078, 0x2459, 0x2031, 0x0000, - 0x691c, 0xa184, 0x0002, 0x0040, 0x3bd7, 0xa6b5, 0x0004, 0xa184, - 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635, - 0x6820, 0xa084, 0x0400, 0x0040, 0x3bef, 0x789b, 0x0018, 0x78ab, - 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0x6820, - 0xa084, 0x8000, 0x00c0, 0x3bfd, 0x681c, 0xa084, 0x8000, 0x00c0, - 0x3c04, 0xa6b5, 0x0800, 0x0078, 0x3c04, 0xa6b5, 0x0400, 0x789b, - 0x000e, 0x6824, 0x8007, 0x78aa, 0x6820, 0xa084, 0x0100, 0x0040, - 0x3c0b, 0xa6b5, 0x4000, 0xa684, 0x0200, 0x0040, 0x3c25, 0x682c, - 0x78d2, 0x6830, 0x78d6, 0xa684, 0x0100, 0x0040, 0x3c23, 0x682c, - 0xa084, 0x0001, 0x0040, 0x3c23, 0x7888, 0xa084, 0x0040, 0x0040, - 0x3c23, 0xa6b5, 0x8000, 0x1078, 0x46f0, 0x7e5a, 0x6eb6, 0x0078, - 0x4727, 0x1078, 0x38fa, 0x00c0, 0x3cbc, 0x702c, 0x8004, 0x0048, - 0x3c37, 0x2019, 0x4e3b, 0x1078, 0x2276, 0x702f, 0x0001, 0x2041, - 0x0001, 0x2031, 0x1000, 0x789b, 0x0018, 0x6814, 0xa084, 0x001f, - 0xa085, 0x0080, 0x78aa, 0x691c, 0xa184, 0x0002, 0x0040, 0x3c50, - 0xa6b5, 0x0004, 0x78ab, 0x0020, 0x6828, 0x78aa, 0xa8c0, 0x0002, - 0x681c, 0xd0f4, 0x0040, 0x3c59, 0x2c50, 0x1078, 0x39ac, 0x1078, - 0x45ff, 0x6820, 0xa084, 0x8000, 0x0040, 0x3c67, 0xa6b5, 0x0400, - 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3c6e, 0x681c, - 0xa084, 0x8000, 0x00c0, 0x3c6e, 0xa6b5, 0x0800, 0x6820, 0xa084, - 0x0100, 0x0040, 0x3c75, 0xa6b5, 0x4000, 0x681c, 0xa084, 0x00c0, - 0x8003, 0x8003, 0x8007, 0xa080, 0x3cc2, 0x2004, 0xa635, 0xa684, - 0x0100, 0x0040, 0x3c8f, 0x682c, 0xa084, 0x0001, 0x0040, 0x3c8f, - 0x7888, 0xa084, 0x0040, 0x0040, 0x3c8f, 0xa6b5, 0x8000, 0x789b, - 0x007e, 0x7eae, 0x6eb6, 0x6814, 0x8007, 0x78aa, 0x7882, 0x2810, - 0x7aaa, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3cbc, 0x0018, 0x3cbc, - 0x70b4, 0xa080, 0x00e2, 0x781a, 0x1078, 0x3912, 0xa684, 0x0200, - 0x0040, 0x3cb0, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x1078, 0x46f0, - 0x2d00, 0x70a2, 0x704a, 0x6810, 0x70be, 0x7003, 0x0007, 0xad80, - 0x000f, 0x7036, 0x0078, 0x2459, 0x1078, 0x1b62, 0x1078, 0x3912, - 0x0078, 0x2459, 0x0000, 0x0300, 0x0200, 0x0000, 0x1078, 0x23eb, - 0x2300, 0x0079, 0x3ccb, 0x3cce, 0x3cce, 0x3cd0, 0x1078, 0x23eb, - 0x1078, 0x46ff, 0x6924, 0xa184, 0x00ff, 0xa086, 0x000a, 0x0040, - 0x3ce2, 0xa184, 0xff00, 0xa085, 0x000a, 0x6826, 0x1078, 0x1b62, - 0x0078, 0x3b96, 0x2001, 0x000a, 0x1078, 0x4691, 0x0078, 0x3b96, - 0xa282, 0x0005, 0x0050, 0x3cee, 0x1078, 0x23eb, 0x7000, 0xa084, - 0x0007, 0x10c0, 0x39be, 0x1078, 0x1937, 0x00c0, 0x3d0d, 0xa684, - 0x0004, 0x0040, 0x3cff, 0x2001, 0x2800, 0x0078, 0x3d01, 0x2001, - 0x0800, 0x71b4, 0xa188, 0x0091, 0x789b, 0x000e, 0x78aa, 0x2031, - 0x0400, 0x7e5a, 0x791a, 0x0078, 0x2459, 0x6807, 0x0106, 0x680b, - 0x0000, 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0, - 0x3d2e, 0xa286, 0x0002, 0x00c0, 0x3d2e, 0x78a0, 0xa005, 0x00c0, - 0x3d2e, 0xa484, 0x8000, 0x00c0, 0x3d2e, 0x78e4, 0xa084, 0x0008, - 0x0040, 0x3d2e, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x411e, - 0x2d00, 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824, - 0xa084, 0x0080, 0x0040, 0x3d40, 0x1078, 0x41d0, 0x0078, 0x2459, - 0x2300, 0x0079, 0x3d43, 0x3d46, 0x3dc7, 0x3de6, 0x2200, 0x0079, - 0x3d49, 0x3d4e, 0x3d5e, 0x3d84, 0x3d90, 0x3db3, 0x2029, 0x0001, - 0xa026, 0x2011, 0x0000, 0x1078, 0x42f1, 0x0079, 0x3d57, 0x3d5c, - 0x2459, 0x3b96, 0x3d5c, 0x3d5c, 0x1078, 0x23eb, 0x7990, 0xa18c, - 0x0007, 0x00c0, 0x3d65, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, - 0x0004, 0x0040, 0x3d6d, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, - 0x0001, 0x1078, 0x42f1, 0x0079, 0x3d75, 0x3d7a, 0x2459, 0x3b96, - 0x3d82, 0x3d7c, 0x0078, 0x472d, 0x70ab, 0x3d80, 0x0078, 0x2459, - 0x0078, 0x3d7a, 0x1078, 0x23eb, 0xa684, 0x0010, 0x0040, 0x3d8e, - 0x1078, 0x419f, 0x0040, 0x3d8e, 0x0078, 0x2459, 0x0078, 0x420c, - 0x6000, 0xa084, 0x0002, 0x0040, 0x3dad, 0x70b4, 0xa080, 0x00d2, - 0x781a, 0x0d7e, 0x1078, 0x4708, 0x2d00, 0x682e, 0x6827, 0x0000, - 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x195a, 0x7003, 0x0000, 0x7037, - 0x0000, 0x704b, 0x0000, 0x0078, 0x3b96, 0xa684, 0x0004, 0x00c0, - 0x3db3, 0x0078, 0x472d, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3dc5, - 0x6000, 0xa084, 0x0001, 0x0040, 0x3dc5, 0x70ab, 0x3dc5, 0x2001, - 0x0007, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x2200, - 0x0079, 0x3dca, 0x3dcf, 0x3dcf, 0x3dcf, 0x3dd1, 0x3dcf, 0x1078, - 0x23eb, 0x70a7, 0x3dd5, 0x0078, 0x4739, 0x2011, 0x0018, 0x1078, - 0x42eb, 0x0079, 0x3ddb, 0x3de0, 0x2459, 0x3b96, 0x3de2, 0x3de4, - 0x1078, 0x23eb, 0x1078, 0x23eb, 0x1078, 0x23eb, 0x2200, 0x0079, - 0x3de9, 0x3dee, 0x3df0, 0x3df0, 0x3dee, 0x3dee, 0x1078, 0x23eb, - 0x78e4, 0xa084, 0x0008, 0x0040, 0x3e05, 0x70a7, 0x3df9, 0x0078, - 0x4739, 0x2011, 0x0004, 0x1078, 0x42eb, 0x0079, 0x3dff, 0x3e05, - 0x2459, 0x3b96, 0x3e05, 0x3e0f, 0x3e13, 0x70ab, 0x3e0d, 0x2001, - 0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x0078, 0x472d, 0x70ab, - 0x3e05, 0x0078, 0x2459, 0x70ab, 0x3e17, 0x0078, 0x2459, 0x0078, - 0x3e0d, 0xa282, 0x0003, 0x0050, 0x3e1f, 0x1078, 0x23eb, 0xa386, - 0x0002, 0x00c0, 0x3e38, 0xa286, 0x0002, 0x00c0, 0x3e3e, 0x78a0, - 0xa005, 0x00c0, 0x3e3e, 0xa484, 0x8000, 0x00c0, 0x3e3e, 0x78e4, - 0xa084, 0x0008, 0x0040, 0x3e38, 0xa6b5, 0x0008, 0x2019, 0x0000, - 0xa684, 0x0008, 0x0040, 0x3e3e, 0x1078, 0x417c, 0x6810, 0x70be, - 0x7003, 0x0007, 0x2300, 0x0079, 0x3e45, 0x3e48, 0x3e75, 0x3e7d, - 0x2200, 0x0079, 0x3e4b, 0x3e50, 0x3e4e, 0x3e69, 0x1078, 0x23eb, - 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078, 0x42f1, - 0x0079, 0x3e5a, 0x3e5f, 0x2459, 0x3b96, 0x3e67, 0x3e61, 0x0078, - 0x472d, 0x70ab, 0x3e65, 0x0078, 0x2459, 0x0078, 0x3e5f, 0x1078, - 0x23eb, 0xa684, 0x0010, 0x0040, 0x3e73, 0x1078, 0x419f, 0x0040, - 0x3e73, 0x0078, 0x2459, 0x0078, 0x420c, 0x2200, 0x0079, 0x3e78, - 0x3e7b, 0x3e7b, 0x3e7b, 0x1078, 0x23eb, 0x2200, 0x0079, 0x3e80, - 0x3e83, 0x3e85, 0x3e85, 0x1078, 0x23eb, 0x78e4, 0xa084, 0x0008, - 0x0040, 0x3e9a, 0x70a7, 0x3e8e, 0x0078, 0x4739, 0x2011, 0x0004, - 0x1078, 0x42eb, 0x0079, 0x3e94, 0x3e9a, 0x2459, 0x3b96, 0x3e9a, - 0x3ea4, 0x3ea8, 0x70ab, 0x3ea2, 0x2001, 0x0003, 0x1078, 0x4689, - 0x0078, 0x4733, 0x0078, 0x472d, 0x70ab, 0x3e9a, 0x0078, 0x2459, - 0x70ab, 0x3eac, 0x0078, 0x2459, 0x0078, 0x3ea2, 0x2300, 0x0079, - 0x3eb1, 0x3eb6, 0x3eb8, 0x3eb4, 0x1078, 0x23eb, 0x70a4, 0x007a, - 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3ec0, 0x1078, 0x23eb, - 0xa684, 0x0200, 0x0040, 0x3eca, 0x1078, 0x46f8, 0x1078, 0x42d3, - 0x1078, 0x46ff, 0x2300, 0x0079, 0x3ecd, 0x3ed0, 0x3ef4, 0x3f5a, - 0xa286, 0x0001, 0x0040, 0x3ed6, 0x1078, 0x23eb, 0xa684, 0x0200, - 0x0040, 0x3ede, 0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001, - 0x1078, 0x4691, 0x78b8, 0xa084, 0xc001, 0x0040, 0x3ef0, 0x7848, - 0xa085, 0x0008, 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3eeb, - 0x7003, 0x0000, 0x0078, 0x3b96, 0x2200, 0x0079, 0x3ef7, 0x3ef9, - 0x3f2a, 0x70a7, 0x3efd, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078, - 0x42eb, 0x0079, 0x3f03, 0x3f0a, 0x2459, 0x3b96, 0x3f12, 0x3f1a, - 0x3f20, 0x3f22, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x0078, 0x4727, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x0078, 0x4727, 0x70ab, 0x3f1e, 0x0078, 0x2459, 0x0078, 0x3f0a, - 0x1078, 0x23eb, 0x70ab, 0x3f26, 0x0078, 0x2459, 0x1078, 0x473f, - 0x0078, 0x2459, 0x70a7, 0x3f2e, 0x0078, 0x4739, 0x2011, 0x0012, - 0x1078, 0x42eb, 0x0079, 0x3f34, 0x3f3a, 0x2459, 0x3b96, 0x3f46, - 0x3f4e, 0x3f54, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, - 0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff, - 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab, 0x3f52, - 0x0078, 0x2459, 0x0078, 0x3f3a, 0x70ab, 0x3f58, 0x0078, 0x2459, - 0x0078, 0x3f46, 0xa286, 0x0001, 0x0040, 0x3f60, 0x1078, 0x23eb, - 0x70a7, 0x3f64, 0x0078, 0x4739, 0x2011, 0x0015, 0x1078, 0x42eb, - 0x0079, 0x3f6a, 0x3f6f, 0x2459, 0x3b96, 0x3f7d, 0x3f89, 0xa6b4, - 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4, - 0xa080, 0x00b4, 0x781a, 0x0078, 0x2459, 0xa6b4, 0x00ff, 0xa6b5, - 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00a6, 0x781a, 0x0078, - 0x2459, 0x70ab, 0x3f8d, 0x0078, 0x2459, 0x0078, 0x3f6f, 0xa282, - 0x0003, 0x0050, 0x3f95, 0x1078, 0x23eb, 0x2300, 0x0079, 0x3f98, - 0x3f9b, 0x3fd2, 0x402d, 0xa286, 0x0001, 0x0040, 0x3fa1, 0x1078, - 0x23eb, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3fae, - 0x1078, 0x3af8, 0x7003, 0x0000, 0x0078, 0x3b96, 0x683b, 0x0000, - 0x6837, 0x0000, 0xa684, 0x0200, 0x0040, 0x3fbc, 0x1078, 0x46f8, - 0x1078, 0x42d3, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691, - 0x78b8, 0xa084, 0xc001, 0x0040, 0x3fce, 0x7848, 0xa085, 0x0008, - 0x784a, 0x7848, 0xa084, 0x0008, 0x00c0, 0x3fc9, 0x7003, 0x0000, - 0x0078, 0x3b96, 0x2200, 0x0079, 0x3fd5, 0x3fd7, 0x4008, 0x70a7, - 0x3fdb, 0x0078, 0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079, - 0x3fe1, 0x3fe8, 0x2459, 0x3b96, 0x3ff0, 0x3ff8, 0x3ffe, 0x4000, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, - 0x70ab, 0x3ffc, 0x0078, 0x2459, 0x0078, 0x3fe8, 0x1078, 0x23eb, - 0x70ab, 0x4004, 0x0078, 0x2459, 0x1078, 0x473f, 0x0078, 0x2459, - 0x70a7, 0x400c, 0x0078, 0x4739, 0x2011, 0x0005, 0x1078, 0x42eb, - 0x0079, 0x4012, 0x4017, 0x2459, 0x3b96, 0x401f, 0x4027, 0xa6b4, - 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0xa6b4, - 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, 0x70ab, - 0x402b, 0x0078, 0x2459, 0x0078, 0x4017, 0xa286, 0x0001, 0x0040, - 0x4033, 0x1078, 0x23eb, 0x70a7, 0x4037, 0x0078, 0x4739, 0x2011, - 0x0006, 0x1078, 0x42eb, 0x0079, 0x403d, 0x4042, 0x2459, 0x3b96, - 0x4048, 0x4052, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4727, - 0xa6b4, 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, - 0x0078, 0x4727, 0x70ab, 0x4056, 0x0078, 0x2459, 0x0078, 0x4042, - 0x2300, 0x0079, 0x405b, 0x4060, 0x405e, 0x405e, 0x1078, 0x23eb, - 0x1078, 0x23eb, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be, - 0xa282, 0x0003, 0x0050, 0x406e, 0x1078, 0x23eb, 0x2300, 0x0079, - 0x4071, 0x4074, 0x4082, 0x40a4, 0xa684, 0x0200, 0x0040, 0x407c, - 0x1078, 0x46f8, 0x1078, 0x46ff, 0x2001, 0x0001, 0x1078, 0x4691, - 0x0078, 0x2459, 0xa296, 0x0002, 0x0040, 0x408b, 0x82ff, 0x0040, - 0x408b, 0x1078, 0x23eb, 0x70a7, 0x408f, 0x0078, 0x4739, 0x2011, - 0x0018, 0x1078, 0x42eb, 0x0079, 0x4095, 0x409a, 0x2459, 0x3b96, - 0x409c, 0x409e, 0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40a2, - 0x0078, 0x2459, 0x0078, 0x409a, 0x2200, 0x0079, 0x40a7, 0x40a9, - 0x40c2, 0x70a7, 0x40ad, 0x0078, 0x4739, 0x2011, 0x0017, 0x1078, - 0x42eb, 0x0079, 0x40b3, 0x40b8, 0x2459, 0x3b96, 0x40ba, 0x40bc, - 0x0078, 0x4727, 0x0078, 0x4727, 0x70ab, 0x40c0, 0x0078, 0x2459, - 0x0078, 0x40b8, 0xa484, 0x8000, 0x00c0, 0x410c, 0xa684, 0x0100, - 0x0040, 0x40d6, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x1078, 0x46ff, - 0x7848, 0xa085, 0x000c, 0x784a, 0x0078, 0x40da, 0x78d8, 0x78d2, - 0x78dc, 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x40e1, 0x0078, - 0x4739, 0x2011, 0x000d, 0x1078, 0x42eb, 0x0079, 0x40e7, 0x40ee, - 0x2459, 0x3b96, 0x40ee, 0x40fc, 0x4102, 0x4104, 0xa684, 0x0100, - 0x0040, 0x40fa, 0x1078, 0x46b6, 0x682c, 0x78d2, 0x6830, 0x78d6, - 0x1078, 0x46f0, 0x0078, 0x4727, 0x70ab, 0x4100, 0x0078, 0x2459, - 0x0078, 0x40ee, 0x1078, 0x23eb, 0x70ab, 0x4108, 0x0078, 0x2459, - 0x1078, 0x473f, 0x0078, 0x2459, 0x1078, 0x46ff, 0x70ab, 0x4116, - 0x2001, 0x0003, 0x1078, 0x4689, 0x0078, 0x4733, 0x1078, 0x46f0, - 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4727, 0x70b8, 0x6812, - 0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008, 0x0040, - 0x4141, 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, 0x4150, 0x692c, - 0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078, 0x415f, - 0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x415f, 0x017e, - 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x46c1, 0x017f, 0xa184, - 0x001f, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0xa684, 0x0004, - 0x0040, 0x4170, 0xa18c, 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, - 0x682a, 0xa6b4, 0x00ff, 0x6000, 0xa084, 0x0008, 0x0040, 0x417a, - 0xa6b5, 0x4000, 0x6eb6, 0x007c, 0x157e, 0x137e, 0x147e, 0x6918, - 0x7890, 0x8004, 0x8004, 0x8004, 0x8004, 0xa084, 0x000f, 0x007e, - 0xa100, 0x681a, 0x007f, 0x8000, 0x8004, 0x0040, 0x419b, 0x20a8, - 0x8104, 0xa080, 0x000b, 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, - 0x002b, 0x2098, 0x53a5, 0x147f, 0x137f, 0x157f, 0x007c, 0x682c, - 0xa084, 0x0020, 0x00c0, 0x41a7, 0x620c, 0x0078, 0x41a8, 0x6210, - 0x6b18, 0x2300, 0xa202, 0x0040, 0x41c8, 0x2018, 0xa382, 0x000e, - 0x0048, 0x41b8, 0x0040, 0x41b8, 0x2019, 0x000e, 0x0078, 0x41bc, - 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, 0x41dd, 0xa196, - 0x000f, 0x0040, 0x41dd, 0x6807, 0x0117, 0x6914, 0x1078, 0x3b69, - 0x6100, 0x8104, 0x00c8, 0x41f8, 0x601c, 0xa005, 0x0040, 0x41ec, - 0x2001, 0x0800, 0x0078, 0x41fa, 0x0d7e, 0x6824, 0x007e, 0x1078, - 0x4708, 0x007f, 0x6826, 0x2d00, 0x682e, 0x1078, 0x3af8, 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, 0x4220, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007, - 0x2008, 0xa805, 0x6816, 0x1078, 0x3b69, 0x68be, 0x0078, 0x4223, - 0x6914, 0x1078, 0x3b69, 0x6100, 0x8104, 0x00c8, 0x4280, 0xa184, - 0x0300, 0x0040, 0x422f, 0x6807, 0x0117, 0x0078, 0x424d, 0x6004, - 0xa005, 0x00c0, 0x4256, 0x6807, 0x0117, 0x601c, 0xa005, 0x00c0, - 0x4243, 0x0d7e, 0x1078, 0x4708, 0x6827, 0x0034, 0x2d00, 0x682e, - 0x1078, 0x3af8, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x424d, 0x2031, - 0x0400, 0x2001, 0x2800, 0x0078, 0x4251, 0x2031, 0x0400, 0x2001, - 0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x42ae, 0x6018, 0xa005, - 0x00c0, 0x4243, 0x601c, 0xa005, 0x00c0, 0x4243, 0x689f, 0x0000, - 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x42bc, 0xd694, 0x00c0, - 0x4279, 0x6100, 0xd1d4, 0x0040, 0x4279, 0x692c, 0x81ff, 0x0040, - 0x42bc, 0xa186, 0x0003, 0x0040, 0x42bc, 0xa186, 0x0012, 0x0040, - 0x42bc, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00af, 0x0078, 0x42b7, - 0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c, 0x00ff, 0xa186, - 0x0012, 0x00c0, 0x4291, 0x2001, 0x42c9, 0x2009, 0x0001, 0x0078, - 0x42a2, 0xa186, 0x0003, 0x00c0, 0x429b, 0x2001, 0x42ca, 0x2009, - 0x0012, 0x0078, 0x42a2, 0x2001, 0x0200, 0x71b4, 0xa188, 0x0091, - 0x0078, 0x42ae, 0x1078, 0x46db, 0x78a3, 0x0000, 0x681c, 0xa085, - 0x0040, 0x681e, 0x71b4, 0xa188, 0x00df, 0xa006, 0x6826, 0x8007, - 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x6eb6, - 0x7e5a, 0x791a, 0x0078, 0x2459, 0x6eb6, 0x1078, 0x3af8, 0x6810, - 0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b, 0x0000, 0x0078, - 0x2459, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00, 0x0000, 0x0000, - 0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684, - 0x0200, 0x0040, 0x42ea, 0x78b8, 0xa08c, 0x001f, 0xa084, 0x8000, - 0x0040, 0x42e3, 0x8108, 0x78d8, 0xa100, 0x6836, 0x78dc, 0xa081, - 0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac, 0x0007, 0x2021, - 0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa184, - 0x0080, 0x00c0, 0x4319, 0xa182, 0x0020, 0x00c8, 0x4337, 0xa182, - 0x0012, 0x00c8, 0x467b, 0x2100, 0x1079, 0x4307, 0x007c, 0x467b, - 0x44e8, 0x467b, 0x467b, 0x4344, 0x4347, 0x4381, 0x43b7, 0x43eb, - 0x43ee, 0x467b, 0x467b, 0x43a2, 0x4412, 0x444c, 0x467b, 0x467b, - 0x4473, 0xa184, 0x0020, 0x00c0, 0x44a7, 0xa18c, 0x001f, 0x6814, - 0xa084, 0x001f, 0xa106, 0x0040, 0x4334, 0x70b4, 0xa080, 0x00d2, - 0x781a, 0x2001, 0x0014, 0x1078, 0x4691, 0x1078, 0x46ff, 0x7003, - 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000, 0x007c, 0xa182, - 0x0024, 0x00c8, 0x467b, 0xa184, 0x0003, 0x1079, 0x4307, 0x007c, - 0x467b, 0x467b, 0x467b, 0x467b, 0x1078, 0x467b, 0x007c, 0x2200, - 0x0079, 0x434a, 0x4476, 0x4476, 0x436e, 0x436e, 0x436e, 0x436e, - 0x436e, 0x436e, 0x436e, 0x436e, 0x436c, 0x436e, 0x4363, 0x436e, - 0x436e, 0x436e, 0x436e, 0x436e, 0x4376, 0x4379, 0x4476, 0x4379, - 0x436e, 0x436e, 0x436e, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x36e2, - 0x077f, 0x0c7f, 0x0078, 0x436e, 0x1078, 0x458b, 0x6827, 0x02b3, - 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x44aa, 0x1078, 0x4670, - 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, - 0x4492, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, - 0x438b, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, 0x4708, 0x6827, - 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ac8, 0x1078, - 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8, 0x2001, - 0x0002, 0x007c, 0x1078, 0x44d0, 0x2001, 0x0017, 0x1078, 0x4691, - 0x70a3, 0x0000, 0x2009, 0x5138, 0x200b, 0x0006, 0x70af, 0x0017, - 0x2009, 0x0200, 0x1078, 0x3a06, 0x2001, 0x0001, 0x007c, 0x2200, - 0x0079, 0x43ba, 0x4476, 0x44a7, 0x44a7, 0x44a7, 0x43db, 0x44b7, - 0x43e3, 0x44b7, 0x44b7, 0x44ba, 0x44ba, 0x44bf, 0x44bf, 0x43d3, - 0x43d3, 0x44a7, 0x44a7, 0x44b7, 0x44a7, 0x43e3, 0x4476, 0x43e3, - 0x43e3, 0x43e3, 0x43e3, 0x6827, 0x0084, 0x2009, 0x000b, 0x2001, - 0x4300, 0x0078, 0x44c9, 0x6827, 0x000d, 0x2009, 0x000b, 0x2001, - 0x4300, 0x0078, 0x44aa, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, - 0x4300, 0x0078, 0x4492, 0x2001, 0x0000, 0x007c, 0x2200, 0x0079, - 0x43f1, 0x4476, 0x440a, 0x440a, 0x440a, 0x440a, 0x44b7, 0x44b7, - 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x44b7, 0x440a, 0x440a, - 0x440a, 0x440a, 0x44b7, 0x440a, 0x440a, 0x44b7, 0x44b7, 0x44b7, - 0x44b7, 0x4476, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001, 0x4300, - 0x0078, 0x4492, 0xa684, 0x0004, 0x00c0, 0x4426, 0x6804, 0xa084, - 0x00ff, 0xa086, 0x0006, 0x00c0, 0x467b, 0x1078, 0x44d0, 0x6807, - 0x0117, 0x1078, 0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, - 0x0004, 0x0040, 0x467b, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086, - 0x0006, 0x00c0, 0x4435, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078, - 0x4708, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, - 0x3ad7, 0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, - 0x3af8, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084, 0x0004, 0x0040, - 0x467b, 0x2d58, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006, 0x00c0, - 0x445b, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078, 0x4708, - 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078, 0x3ae7, - 0x1078, 0x44d0, 0x2b68, 0x1078, 0x3af8, 0x0d7f, 0x1078, 0x3af8, - 0x2001, 0x0002, 0x007c, 0x1078, 0x467b, 0x007c, 0x70b4, 0xa080, - 0x00d2, 0x781a, 0x2001, 0x0001, 0x1078, 0x4691, 0x1078, 0x46ff, - 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x46c1, 0x1078, - 0x46f8, 0x1078, 0x42d3, 0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001, - 0x0001, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3, - 0x70b4, 0xa080, 0x00d2, 0x781a, 0x2001, 0x0013, 0x1078, 0x4691, - 0x1078, 0x46ff, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, - 0x467b, 0x007c, 0x1078, 0x46c1, 0x1078, 0x46f8, 0x1078, 0x42d3, - 0x1078, 0x41d0, 0x1078, 0x46ff, 0x2001, 0x0001, 0x007c, 0x2001, - 0x0003, 0x007c, 0x1078, 0x458b, 0x2001, 0x0000, 0x007c, 0x0c7e, - 0x077e, 0x6f14, 0x1078, 0x36e2, 0x077f, 0x0c7f, 0x2001, 0x0000, - 0x007c, 0x1078, 0x46c1, 0x1078, 0x467b, 0x2001, 0x0006, 0x007c, - 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x44db, 0xa186, - 0x000f, 0x00c0, 0x44df, 0x1078, 0x46f8, 0x1078, 0x42d3, 0x70b4, - 0xa080, 0x00d2, 0x781a, 0x1078, 0x46ff, 0x7003, 0x0000, 0x007c, - 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, - 0x00c8, 0x467b, 0x1079, 0x44f5, 0x007c, 0x467b, 0x44f9, 0x467b, - 0x4592, 0xa282, 0x0003, 0x0040, 0x4500, 0x1078, 0x467b, 0x007c, - 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4, 0x00ff, 0x69b8, 0xa184, - 0x0100, 0x0040, 0x453f, 0xa18c, 0xfeff, 0x69ba, 0x78a0, 0xa005, - 0x00c0, 0x453f, 0xa4a4, 0x00ff, 0x0040, 0x4533, 0xa482, 0x000c, - 0x0040, 0x451c, 0x00c8, 0x4526, 0x852b, 0x852b, 0x1078, 0x3760, - 0x0040, 0x4526, 0x1078, 0x355b, 0x0078, 0x4535, 0x1078, 0x465d, - 0x1078, 0x3586, 0x69b8, 0xa18d, 0x0100, 0x69ba, 0xa6b5, 0x1000, - 0x7e5a, 0x0078, 0x4538, 0x1078, 0x3586, 0xa6b4, 0xefff, 0x7e5a, - 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e, - 0x1078, 0x457f, 0x6200, 0xd2e4, 0x0040, 0x4570, 0x6208, 0x8217, - 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x4552, 0x0040, 0x4552, - 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8, 0x4557, 0x2220, 0x6208, - 0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8, 0x455f, 0x721c, 0x2200, - 0xa502, 0x00c8, 0x4564, 0x2228, 0x1078, 0x4661, 0x852b, 0x852b, - 0x1078, 0x3760, 0x0040, 0x4570, 0x1078, 0x3562, 0x0078, 0x4574, - 0x1078, 0x465d, 0x1078, 0x358d, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, - 0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x007e, - 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e0, - 0x5380, 0x007f, 0x007c, 0x0c7e, 0x1078, 0x457f, 0x1078, 0x358d, - 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0, 0x467b, 0x7aa8, 0xa294, - 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040, 0x45c9, 0xa18c, 0xfdff, - 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x45c9, 0xa282, 0x0002, 0x00c8, - 0x369d, 0x1078, 0x4627, 0x1078, 0x362b, 0x1078, 0x3586, 0xa684, - 0x0100, 0x0040, 0x45bf, 0x682c, 0xa084, 0x0001, 0x0040, 0x45bf, - 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x45bf, 0xc6fd, 0xa6b5, - 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001, 0x0001, - 0x007c, 0x0c7e, 0x1078, 0x457f, 0xa284, 0xfffe, 0x0040, 0x45d4, - 0x2011, 0x0001, 0x0078, 0x45d8, 0xa284, 0x0001, 0x0040, 0x45de, - 0x6100, 0xd1ec, 0x00c0, 0x45de, 0x2011, 0x0000, 0x1078, 0x4619, - 0x1078, 0x3632, 0x1078, 0x358d, 0xa684, 0x0100, 0x0040, 0x45f4, - 0x682c, 0xa084, 0x0001, 0x0040, 0x45f4, 0xc6fc, 0x7888, 0xa084, - 0x0040, 0x0040, 0x45f4, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, - 0xa080, 0x00be, 0x781a, 0x2001, 0x0004, 0x0c7f, 0x007c, 0x0c7e, - 0x2960, 0x6000, 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x460a, - 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, - 0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085, 0x0200, 0x68ba, 0x0c7f, - 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, - 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab, 0x0004, 0x007c, 0x0c7e, - 0x7054, 0x2060, 0x6000, 0xa084, 0x1000, 0x00c0, 0x4635, 0x2029, - 0x0032, 0x2021, 0x0000, 0x0078, 0x4655, 0x6508, 0xa5ac, 0x00ff, - 0x7018, 0xa086, 0x0028, 0x00c0, 0x4645, 0xa582, 0x0019, 0x00c8, - 0x464b, 0x2029, 0x0019, 0x0078, 0x464b, 0xa582, 0x000c, 0x00c8, - 0x464b, 0x2029, 0x000c, 0x6408, 0x8427, 0xa4a4, 0x00ff, 0xa482, - 0x000c, 0x0048, 0x4655, 0x2021, 0x000c, 0x1078, 0x4661, 0x68b8, - 0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c, 0x2021, 0x0000, 0x2029, - 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, - 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081, 0x78ab, 0x0005, 0x007c, - 0x2001, 0x0003, 0x1078, 0x4689, 0x70b4, 0xa080, 0x00be, 0x781a, - 0x2001, 0x0005, 0x007c, 0x2001, 0x0007, 0x1078, 0x4689, 0xa6b5, - 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00be, 0x781a, 0x2001, 0x0004, - 0x007c, 0x789b, 0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001, - 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x469f, - 0xa196, 0x000f, 0x0040, 0x469f, 0x1078, 0x195a, 0x007c, 0x6924, - 0xa194, 0x003f, 0x00c0, 0x46a8, 0xa18c, 0xffc0, 0xa105, 0x6826, - 0x1078, 0x3af8, 0x691c, 0xa184, 0x0100, 0x0040, 0x46b5, 0x6914, - 0x1078, 0x3b69, 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, 0x46e6, 0x53a6, 0xa184, 0x0001, - 0x0040, 0x46ec, 0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, - 0x70b0, 0xa005, 0x10c0, 0x23eb, 0x70b3, 0x8000, 0x0078, 0x4a3a, - 0x71b0, 0x81ff, 0x0040, 0x46fe, 0x1078, 0x4b30, 0x007c, 0x71b0, - 0x81ff, 0x0040, 0x4707, 0x70b3, 0x0000, 0x1078, 0x4776, 0x007c, - 0x0c7e, 0x0d7e, 0x1078, 0x1937, 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, 0x2459, 0x70b4, 0xa080, 0x0081, - 0x781a, 0x0078, 0x2459, 0x70b4, 0xa080, 0x00be, 0x781a, 0x0078, - 0x2459, 0x70b4, 0xa080, 0x00c8, 0x781a, 0x0078, 0x2459, 0x6904, - 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x474c, 0xa196, 0x000f, - 0x0040, 0x474c, 0x6807, 0x0117, 0x2001, 0x0200, 0x6826, 0x8007, - 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, - 0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, - 0x1078, 0x46ff, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4, 0xa080, - 0x00d2, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078, 0x46c1, - 0x2001, 0x0013, 0x1078, 0x4691, 0x0078, 0x3b96, 0x127e, 0x2091, - 0x2200, 0x2049, 0x4776, 0x7000, 0x7204, 0xa205, 0x720c, 0xa215, - 0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4788, 0x0078, 0x478d, - 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084, 0x0001, - 0x00c0, 0x47bb, 0x7108, 0x8103, 0x00c8, 0x479a, 0x1078, 0x48bd, - 0x0078, 0x4792, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x47bb, 0x7004, - 0x8004, 0x00c8, 0x47b2, 0x7014, 0xa005, 0x00c0, 0x47ae, 0x7010, - 0xa005, 0x0040, 0x47b2, 0xa102, 0x00c8, 0x4792, 0x7007, 0x0010, - 0x0078, 0x47bb, 0x8aff, 0x0040, 0x47bb, 0x1078, 0x4b07, 0x00c0, - 0x47b5, 0x0040, 0x4792, 0x1078, 0x4846, 0x7003, 0x0000, 0x127f, - 0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, - 0x0040, 0x47ce, 0xa18e, 0x000f, 0x00c0, 0x47d1, 0x6040, 0x0078, - 0x47d2, 0x6428, 0x017f, 0x84ff, 0x0040, 0x47fc, 0x2c70, 0x7004, - 0xa0bc, 0x000f, 0xa7b8, 0x480c, 0x273c, 0x87fb, 0x00c0, 0x47ea, - 0x0048, 0x47e4, 0x1078, 0x23eb, 0x609c, 0xa075, 0x0040, 0x47fc, - 0x0078, 0x47d7, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, - 0x8421, 0x0040, 0x47fc, 0x8738, 0x2704, 0xa005, 0x00c0, 0x47eb, - 0x709c, 0xa075, 0x00c0, 0x47d7, 0x007c, 0x0000, 0x0005, 0x0009, - 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, - 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4801, 0x47fe, 0x0000, - 0x0000, 0x8000, 0x0000, 0x4801, 0x0000, 0x4809, 0x4806, 0x0000, - 0x0000, 0x0000, 0x0000, 0x4809, 0x0000, 0x4804, 0x4804, 0x0000, - 0x0000, 0x8000, 0x0000, 0x4804, 0x0000, 0x480a, 0x480a, 0x0000, - 0x0000, 0x0000, 0x0000, 0x480a, 0x127e, 0x2091, 0x2200, 0x2079, - 0x5100, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, - 0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, - 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x4846, - 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x4899, 0x7007, 0x0012, - 0x7108, 0x7008, 0xa106, 0x00c0, 0x4850, 0xa184, 0x01e0, 0x0040, - 0x485b, 0x1078, 0x23eb, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, - 0x00c8, 0x4866, 0xa184, 0x4000, 0x00c0, 0x4850, 0xa19c, 0x300c, - 0xa386, 0x2004, 0x0040, 0x4874, 0xa386, 0x0008, 0x0040, 0x487f, - 0xa386, 0x200c, 0x00c0, 0x4850, 0x7200, 0x8204, 0x0048, 0x487f, - 0x730c, 0xa384, 0x00ff, 0x0040, 0x487f, 0x1078, 0x23eb, 0x7007, - 0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x4899, 0x7008, 0xa084, - 0x01e0, 0x00c0, 0x4899, 0x7310, 0x7014, 0xa305, 0x0040, 0x4899, - 0x710c, 0xa184, 0x0300, 0x00c0, 0x4899, 0xa184, 0x00ff, 0x00c0, - 0x4846, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084, 0x0008, - 0x00c0, 0x489d, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048, 0x48a2, - 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e, 0x127e, - 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x48bd, 0x157f, 0x127f, - 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500, 0x730c, - 0xa384, 0x0300, 0x00c0, 0x48e4, 0xa184, 0x01e0, 0x00c0, 0x4908, - 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4908, 0x2001, 0x04fd, 0x2004, - 0xa082, 0x0005, 0x00c8, 0x48d8, 0xa184, 0x4000, 0x00c0, 0x48c8, - 0xa184, 0x0007, 0x0079, 0x48dc, 0x48e6, 0x48f8, 0x48e4, 0x48f8, - 0x48e4, 0x4944, 0x48e4, 0x4942, 0x1078, 0x23eb, 0x7004, 0xa084, - 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x48f3, 0x2049, - 0x0000, 0x0078, 0x48f7, 0x1078, 0x4b07, 0x00c0, 0x48f3, 0x007c, - 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, - 0x4903, 0x0078, 0x4907, 0x1078, 0x4b07, 0x00c0, 0x4903, 0x007c, - 0x7007, 0x0012, 0x7108, 0x00e0, 0x490b, 0x2091, 0x6000, 0x00e0, - 0x490f, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, - 0xa084, 0x0008, 0x00c0, 0x4917, 0x7007, 0x0012, 0x7108, 0x8103, - 0x0048, 0x491c, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4930, - 0x7004, 0xa005, 0x00c0, 0x4930, 0x700c, 0xa005, 0x0040, 0x4932, - 0x0078, 0x4913, 0x2049, 0x0000, 0x1078, 0x3809, 0x6818, 0xa084, - 0x8000, 0x0040, 0x493d, 0x681b, 0x0002, 0x007c, 0x1078, 0x23eb, - 0x1078, 0x23eb, 0x1078, 0x49a0, 0x7210, 0x7114, 0x700c, 0xa09c, - 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x49a0, - 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, - 0xa31b, 0x2400, 0xa305, 0x0040, 0x4967, 0x00c8, 0x4967, 0x8412, - 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x494e, 0x2b60, - 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4973, 0xa7ba, - 0x4806, 0x0078, 0x4975, 0xa7ba, 0x47fe, 0x007f, 0xa73d, 0x2c00, - 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4846, - 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4994, 0x609c, 0xa005, - 0x0040, 0x499d, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x480c, - 0x203c, 0x87fb, 0x1040, 0x23eb, 0x8a51, 0x0040, 0x499c, 0x7008, - 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000, 0x007c, - 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x49b4, 0x6000, 0xa064, - 0x00c0, 0x49ab, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x481c, - 0x203c, 0x87fb, 0x1040, 0x23eb, 0x007c, 0x127e, 0x0d7e, 0x2091, - 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, - 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084, 0x0008, - 0x007f, 0x0040, 0x49cf, 0xa0b8, 0x4806, 0x0078, 0x49d1, 0xa0b8, - 0x47fe, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, - 0x0007, 0x0040, 0x49df, 0xa18e, 0x000f, 0x00c0, 0x49e8, 0x681c, - 0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x0078, 0x49ef, - 0x681c, 0xa084, 0x0040, 0x0040, 0x49ef, 0xa6b5, 0x0001, 0x7007, - 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x49f1, 0x2400, 0xa305, - 0x00c0, 0x49fc, 0x0078, 0x4a22, 0x2c58, 0x2704, 0x6104, 0xac60, - 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008, - 0x0040, 0x4a12, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, - 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, - 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x4981, - 0x0078, 0x4a24, 0x1078, 0x4b07, 0x00c0, 0x4a22, 0x127f, 0x2000, - 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, - 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a30, 0x7003, 0x0008, 0x127f, - 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, - 0x4a3a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a43, - 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, - 0x0040, 0x4a56, 0xa18e, 0x000f, 0x00c0, 0x4a61, 0x681c, 0xa084, - 0x0040, 0x0040, 0x4a5d, 0xa6b5, 0x0001, 0x6840, 0x2050, 0x0078, - 0x4a6a, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4a68, 0xa6b5, 0x0001, - 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x480c, - 0x273c, 0x87fb, 0x00c0, 0x4a7e, 0x0048, 0x4a78, 0x1078, 0x23eb, - 0x689c, 0xa065, 0x0040, 0x4a82, 0x0078, 0x4a6b, 0x1078, 0x4b07, - 0x00c0, 0x4a7e, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e, - 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5, - 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4a9c, - 0xa18e, 0x000f, 0x00c0, 0x4aa5, 0x681c, 0xa084, 0x0040, 0x0040, - 0x4aac, 0xa6b5, 0x0001, 0x0078, 0x4aac, 0x681c, 0xa084, 0x0040, - 0x0040, 0x4aac, 0xa6b5, 0x0001, 0x2049, 0x4a85, 0x017e, 0x6904, - 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4aba, 0xa18e, 0x000f, - 0x00c0, 0x4abd, 0x6840, 0x0078, 0x4abe, 0x6828, 0x017f, 0xa055, - 0x0040, 0x4b04, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, - 0x480c, 0x273c, 0x87fb, 0x00c0, 0x4ad8, 0x0048, 0x4ad1, 0x1078, - 0x23eb, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078, 0x4ac4, - 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x4af1, - 0x8a51, 0x00c0, 0x4ae5, 0x1078, 0x23eb, 0x8738, 0x2704, 0xa005, - 0x00c0, 0x4ad9, 0x709c, 0xa075, 0x2060, 0x0040, 0x4b04, 0x0078, - 0x4ac4, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, - 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4b00, 0x1078, 0x23eb, - 0x2071, 0x0020, 0x0078, 0x49ef, 0x127f, 0x2000, 0x007c, 0x7008, - 0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4b2f, 0x2704, 0xac08, - 0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104, 0x7012, - 0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4b26, - 0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602, 0x7004, - 0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4981, 0x007c, - 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4b30, 0x0d7f, - 0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4b5a, 0x017e, 0x6904, - 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4b4a, 0xa18e, 0x000f, - 0x00c0, 0x4b4d, 0x6840, 0x0078, 0x4b4e, 0x6828, 0x017f, 0xa005, - 0x0040, 0x4b68, 0x0078, 0x478d, 0x0020, 0x4b5a, 0x1078, 0x4944, - 0x0078, 0x4b68, 0x00a0, 0x4b61, 0x7108, 0x1078, 0x48bd, 0x0078, - 0x4b39, 0x7007, 0x0010, 0x00a0, 0x4b63, 0x7108, 0x1078, 0x48bd, - 0x7008, 0xa086, 0x0008, 0x00c0, 0x4b39, 0x7000, 0xa005, 0x00c0, - 0x4b39, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, - 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091, 0x2200, - 0x0d7f, 0x2049, 0x4b78, 0xad80, 0x0011, 0x20a0, 0x2099, 0x0031, - 0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, - 0x7003, 0x0001, 0x0040, 0x4b97, 0x8000, 0x80ac, 0x53a5, 0x7007, - 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b99, 0x0c7f, 0x2049, - 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000, - 0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005, 0x0040, - 0x4bc0, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4bc0, 0x7804, 0xa005, - 0x0040, 0x4bc0, 0x7807, 0x0000, 0x0068, 0x4bc0, 0x2091, 0x4080, - 0x7820, 0x8001, 0x7822, 0x00c0, 0x4c1b, 0x7824, 0x7822, 0x2069, - 0x5140, 0x6800, 0xa084, 0x0007, 0x0040, 0x4bde, 0xa086, 0x0002, - 0x0040, 0x4bde, 0x6834, 0xa00d, 0x0040, 0x4bde, 0x2104, 0xa005, - 0x0040, 0x4bde, 0x8001, 0x200a, 0x0040, 0x4cc3, 0x7848, 0xa005, - 0x0040, 0x4bec, 0x8001, 0x784a, 0x00c0, 0x4bec, 0x2009, 0x0102, - 0x6844, 0x200a, 0x1078, 0x21d2, 0x6890, 0xa005, 0x0040, 0x4bf8, - 0x8001, 0x6892, 0x00c0, 0x4bf8, 0x686f, 0x0000, 0x6873, 0x0001, - 0x2061, 0x5400, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034, 0xa005, - 0x0040, 0x4c0e, 0x8001, 0x6036, 0x00c0, 0x4c0e, 0x6010, 0xa005, - 0x0040, 0x4c0e, 0x017e, 0x1078, 0x21d2, 0x017f, 0xace0, 0x0010, - 0x0070, 0x4c14, 0x0078, 0x4bfe, 0x8109, 0x0040, 0x4c1b, 0x20a9, - 0x0100, 0x0078, 0x4bfe, 0x1078, 0x4c28, 0x1078, 0x4c4d, 0x2009, - 0x5151, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001, 0x007c, - 0x7834, 0x8001, 0x7836, 0x00c0, 0x4c4c, 0x7838, 0x7836, 0x2091, - 0x8000, 0x7844, 0xa005, 0x00c0, 0x4c37, 0x2001, 0x0101, 0x8001, - 0x7846, 0xa080, 0x7400, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c, - 0x6024, 0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x0040, 0x4c7c, - 0x6000, 0x2c40, 0x0078, 0x4c3d, 0x007c, 0x7828, 0x8001, 0x782a, - 0x00c0, 0x4c7b, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0, 0x4c5a, - 0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003, 0x8003, - 0xa090, 0x5400, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008, 0x0040, - 0x4c7b, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4c73, 0x8001, - 0x2012, 0x00c0, 0x4c7b, 0x2304, 0xa084, 0xfff7, 0xa085, 0x0080, - 0x201a, 0x1078, 0x21d2, 0x007c, 0x2069, 0x5140, 0x6800, 0xa005, - 0x0040, 0x4c86, 0x6848, 0xac06, 0x0040, 0x4cc3, 0x601b, 0x0006, - 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, - 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078, 0x1973, - 0x6818, 0xa005, 0x0040, 0x4c9e, 0x8001, 0x681a, 0x6808, 0xa084, - 0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4ca8, 0x1078, 0x23eb, - 0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x1c70, - 0x2069, 0x5140, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006, 0x686e, - 0x00c0, 0x4cbe, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078, 0x21cd, - 0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5140, 0x2104, - 0xa084, 0x0007, 0x0040, 0x4d1f, 0xa086, 0x0007, 0x00c0, 0x4cd9, - 0x0d7e, 0x2009, 0x5152, 0x216c, 0x1078, 0x3a4e, 0x0d7f, 0x0078, - 0x4d1f, 0x2009, 0x5152, 0x2164, 0x1078, 0x2396, 0x601b, 0x0006, - 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, - 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830, 0xa084, - 0x0040, 0x0040, 0x4d13, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, - 0xa084, 0x0004, 0x0040, 0x4d00, 0x0070, 0x4d00, 0x0078, 0x4cf7, - 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040, - 0x4d0d, 0x0070, 0x4d0d, 0x0078, 0x4d04, 0x20a9, 0x00fa, 0x0070, - 0x4d13, 0x0078, 0x4d0f, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, - 0x0048, 0x2009, 0x515b, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091, - 0x8001, 0x007c, 0x2079, 0x5100, 0x1078, 0x4d4d, 0x1078, 0x4d31, - 0x1078, 0x4d3f, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b, 0x0000, - 0x007c, 0x2019, 0x0003, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c, - 0x0040, 0x4d3c, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c, 0x2019, - 0x0039, 0x2011, 0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d4a, - 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971, 0x2011, - 0x5146, 0x2204, 0xa086, 0x003c, 0x0040, 0x4d58, 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, 0x98d0, 0x009e, 0x0096, 0xa202, 0x8838, 0x3806, 0x8839, - 0x20c3, 0x0864, 0x9884, 0x28c1, 0x9cb1, 0xa203, 0x300c, 0x2846, - 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2, 0x9c90, - 0x9858, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3, 0x282d, - 0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824, 0x68c1, - 0x7864, 0x883e, 0x9878, 0x8576, 0x8677, 0x206b, 0x28c1, 0x9cb1, - 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209, 0x2901, 0x988c, - 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xc601, - 0xa20a, 0x856e, 0x0704, 0x9c90, 0x0014, 0xa204, 0xa300, 0x3009, - 0x19e2, 0xf868, 0x8176, 0x86eb, 0x85eb, 0x872e, 0x87a9, 0x883f, - 0x08e6, 0x9890, 0xf881, 0x988b, 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, 0x98c3, 0x8000, 0xa000, 0x2802, 0x1011, - 0x98c9, 0x9865, 0x283e, 0x1011, 0x98cd, 0xa20b, 0x0017, 0x300c, - 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0x98da, 0x0014, 0x26e0, - 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, - 0x9cb6, 0x0704, 0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e, - 0x00a5, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd5, 0x8772, - 0x8837, 0x2101, 0x987a, 0x10d2, 0x78e2, 0x9cd8, 0x9859, 0xd984, - 0xf0e2, 0xf0a1, 0x98d2, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f, - 0x9401, 0xb520, 0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2, - 0x78e4, 0x9cd8, 0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101, - 0x98cb, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001, - 0x0014, 0x6845, 0x0214, 0xa21b, 0x9cd5, 0x2001, 0x98ca, 0x8201, - 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8, - 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9cc1, 0x692a, 0x6902, - 0x1834, 0x989d, 0x1a14, 0x8010, 0x8592, 0x8026, 0x84b9, 0x7021, - 0x0014, 0xa300, 0x69e1, 0x9caa, 0x694c, 0xa213, 0x9cba, 0x1462, - 0xa213, 0x8000, 0x16e1, 0x98b4, 0x8023, 0x16e1, 0x8001, 0x10f1, - 0x0016, 0x6968, 0xa214, 0x9cba, 0x8004, 0x16e1, 0x0101, 0x300a, - 0x8827, 0x0014, 0x9cba, 0x0014, 0x61c2, 0x8002, 0x14e1, 0x0016, - 0xa217, 0x9cc1, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8, 0x1ce6, - 0x882c, 0x0016, 0xa212, 0x9cd5, 0x10d2, 0x70e4, 0x0004, 0x8007, - 0x9424, 0xcc1a, 0x9cd8, 0x98ca, 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, 0x98ef, 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, 0x98e5, - 0x98d0, 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, 0xa82e, 0x28c1, 0x9cb1, 0xa203, 0x300c, - 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804, 0x28f2, - 0x9c90, 0xa8f4, 0x300c, 0x28e1, 0x9c90, 0x2802, 0xa206, 0x64c3, - 0x282d, 0xa207, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b, 0x7824, - 0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677, 0x206b, 0x28c1, - 0x9cb1, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e5, 0xa209, 0x2901, - 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c, 0x1fe2, - 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c90, 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, 0xa898, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017, - 0x300c, 0xa300, 0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014, - 0x26e0, 0x873a, 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, - 0x0210, 0x9cb6, 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, - 0x9d6b, 0x8772, 0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d6e, - 0xa8fc, 0xd984, 0xf0e2, 0xf0a1, 0xa871, 0x0014, 0x8831, 0xd166, - 0x8830, 0x800f, 0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301, - 0xa80d, 0x10d2, 0x78e4, 0x9d6e, 0x8821, 0x8820, 0xa8e6, 0xf123, - 0xf142, 0xf101, 0xa854, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, - 0xd99e, 0x6001, 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d6b, 0x2001, - 0xa845, 0x8201, 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801, - 0x3027, 0x84a8, 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d57, - 0x692a, 0x6902, 0x1834, 0xa805, 0x1a14, 0x8010, 0x8592, 0x8026, - 0x84b9, 0x7021, 0x0014, 0xa300, 0x69e1, 0x9d40, 0x694c, 0xa213, - 0x9d50, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa80a, 0x8023, 0x16e1, - 0x8001, 0x10f1, 0x0016, 0x6968, 0xa214, 0x9d50, 0x8004, 0x16e1, - 0x0101, 0x300a, 0x8827, 0x0014, 0x9d50, 0x0014, 0x61c2, 0x8002, - 0x14e1, 0x0016, 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, 0xa8af, 0xa210, 0x3807, - 0x300c, 0x817e, 0x872b, 0x8772, 0xa8a8, 0x0000, 0xdf21 -}; -unsigned short risc_code_length01 = 0x4057; - reverted: --- b/drivers/scsi/qla1280.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/qla1280.c 2004-10-01 19:21:44 -07:00 @@ -17,12 +17,9 @@ * General Public License for more details. * ******************************************************************************/ +#define QLA1280_VERSION "3.24.4" -#define QLA1280_VERSION "3.25" /***************************************************************************** Revision History: - Rev 3.25, September 28, 2004, Christoph Hellwig - - add support for ISP1020/1040 - - don't include "scsi.h" anymore for 2.6.x Rev 3.24.4 June 7, 2004 Christoph Hellwig - restructure firmware loading, cleanup initialization code - prepare support for ISP1020/1040 chips @@ -359,6 +356,7 @@ #include #include #include +#include "scsi.h" #else #include #include "scsi.h" @@ -392,7 +390,6 @@ #include "qla1280.h" #include "ql12160_fw.h" /* ISP RISC codes */ #include "ql1280_fw.h" -#include "ql1040_fw.h" /* @@ -635,22 +632,18 @@ unsigned char *fwver; /* Ptr to F/W version array */ }; +/* NOTE: qla1280_pci_tbl and ql1280_board_tbl must be in the same order */ -/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */ 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}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1080, -#ifdef CONFIG_SCSI_QLOGIC_1280_1040 - {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240, -#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_ISP1280, - {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, + {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160, - {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP1280, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - {PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP10160, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, {0,} }; MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl); @@ -659,8 +652,6 @@ /* Name , Number of ports, FW details */ {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01, &fw12160i_addr01, &fw12160i_version_str[0]}, - {"QLA1040", 1, &risc_code01[0], &risc_code_length01, - &risc_code_addr01, &firmware_version[0]}, {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01, &fw1280ei_addr01, &fw1280ei_version_str[0]}, {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01, @@ -1788,10 +1779,6 @@ } #endif - /* TODO: implement support for the 1040 nvram format */ - if (IS_ISP1040(ha)) - driver_setup.no_nvram = 1; - dprintk(1, "Configure PCI space for adapter...\n"); reg = ha->iobase; @@ -2352,7 +2339,9 @@ #if 1 /* Some SCSI Processors do not seem to like this */ nv->bus[bus].target[target].parameter.f.enable_wide = 1; #endif + if (!IS_ISP1040(ha)) + nv->bus[bus].target[target].parameter.f.parity_checking = 1; + - nv->bus[bus].target[target].parameter.f.parity_checking = 1; nv->bus[bus].target[target].parameter.f.disconnect_allowed = 1; nv->bus[bus].target[target].execution_throttle = nv->bus[bus].max_queue_depth - 1; @@ -4652,7 +4641,6 @@ #if LINUX_VERSION_CODE >= 0x020600 static struct scsi_host_template qla1280_driver_template = { - .module = THIS_MODULE, .proc_name = "qla1280", .name = "Qlogic ISP 1280/12160", .info = qla1280_info, diff -u b/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c --- b/drivers/scsi/qla2xxx/qla_dbg.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/qla2xxx/qla_dbg.c 2004-10-01 19:23:17 -07:00 @@ -712,6 +712,7 @@ /* Reset the ISP. */ WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ } for (cnt = 30000; RD_MAILBOX_REG(ha, reg, 0) != 0 && @@ -745,6 +746,7 @@ /* Release RISC. */ WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); + RD_REG_WORD(®->hccr); /* PCI Posting. */ } } diff -u b/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c --- b/drivers/scsi/qla2xxx/qla_init.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/qla2xxx/qla_init.c 2004-10-01 19:23:17 -07:00 @@ -463,10 +463,13 @@ } WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); + RD_REG_WORD(®->hccr); /* PCI Posting. */ WRT_REG_WORD(®->hccr, HCCR_CLR_HOST_INT); + RD_REG_WORD(®->hccr); /* PCI Posting. */ /* Reset ISP chip. */ WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ /* Wait for RISC to recover from reset. */ if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) { @@ -487,6 +490,7 @@ /* Reset RISC processor. */ WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); + RD_REG_WORD(®->hccr); /* PCI Posting. */ WRT_REG_WORD(®->semaphore, 0); @@ -555,6 +559,7 @@ /* Reset ISP chip. */ WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); + RD_REG_WORD(®->ctrl_status); /* PCI Posting. */ /* * We need to have a delay here since the card will not respond while @@ -576,7 +581,9 @@ /* Reset RISC processor. */ WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); + RD_REG_WORD(®->hccr); /* PCI Posting. */ WRT_REG_WORD(®->hccr, HCCR_RELEASE_RISC); + RD_REG_WORD(®->hccr); /* PCI Posting. */ /* Workaround for QLA2312 PCI parity error */ if (IS_QLA2100(ha) || IS_QLA2200(ha) || IS_QLA2300(ha)) { diff -u b/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c --- b/drivers/scsi/qla2xxx/qla_os.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/qla2xxx/qla_os.c 2004-10-01 19:23:17 -07:00 @@ -2892,19 +2892,6 @@ continue; } - /* get consistent memory allocated for init control block */ - ha->init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, - &ha->init_cb_dma); - if (ha->init_cb == NULL) { - qla_printk(KERN_WARNING, ha, - "Memory Allocation failed - init_cb\n"); - - qla2x00_mem_free(ha); - msleep(100); - - continue; - } - memset(ha->init_cb, 0, sizeof(init_cb_t)); /* Get consistent memory allocated for Get Port Database cmd */ ha->iodesc_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, @@ -2996,6 +2983,21 @@ memset(ha->ct_sns, 0, sizeof(struct ct_sns_pkt)); } + /* Get consistent memory allocated for Get Port Database cmd */ + ha->iodesc_pd = pci_alloc_consistent(ha->pdev, + PORT_DATABASE_SIZE, &ha->iodesc_pd_dma); + if (ha->iodesc_pd == NULL) { + /* error */ + qla_printk(KERN_WARNING, ha, + "Memory Allocation failed - iodesc_pd\n"); + + qla2x00_mem_free(ha); + msleep(100); + + continue; + } + memset(ha->iodesc_pd, 0, PORT_DATABASE_SIZE); + /* Done all allocations without any error. */ status = 0; reverted: --- b/drivers/scsi/qlogicfc.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/qlogicfc.c 2004-10-01 19:21:44 -07:00 @@ -815,11 +815,9 @@ some time before recognizing it is attached to a fabric */ #if ISP2x00_FABRIC + for (wait_time = jiffies + 5 * HZ; time_before(jiffies, wait_time);) { + barrier(); + cpu_relax(); - if (hosts) { - for (wait_time = jiffies + 5 * HZ; time_before(jiffies, wait_time);) { - barrier(); - cpu_relax(); - } } #endif reverted: --- b/drivers/scsi/scsi.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/scsi.c 2004-10-01 19:21:44 -07:00 @@ -244,13 +244,7 @@ */ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask) { + struct scsi_cmnd *cmd = __scsi_get_command(dev->host, gfp_mask); - struct scsi_cmnd *cmd; - - /* Bail if we can't get a reference to the device */ - if (!get_device(&dev->sdev_gendev)) - return NULL; - - cmd = __scsi_get_command(dev->host, gfp_mask); if (likely(cmd != NULL)) { unsigned long flags; @@ -264,8 +258,7 @@ spin_lock_irqsave(&dev->list_lock, flags); list_add_tail(&cmd->list, &dev->cmd_list); spin_unlock_irqrestore(&dev->list_lock, flags); + } - } else - put_device(&dev->sdev_gendev); return cmd; } @@ -283,8 +276,7 @@ */ void scsi_put_command(struct scsi_cmnd *cmd) { + struct Scsi_Host *shost = cmd->device->host; - struct scsi_device *sdev = cmd->device; - struct Scsi_Host *shost = sdev->host; unsigned long flags; /* serious error if the command hasn't come from a device list */ @@ -302,8 +294,6 @@ if (likely(cmd != NULL)) kmem_cache_free(shost->cmd_pool->slab, cmd); - - put_device(&sdev->sdev_gendev); } /* diff -u b/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c --- b/drivers/scsi/scsi_devinfo.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/scsi_devinfo.c 2004-10-01 19:23:16 -07:00 @@ -185,7 +185,6 @@ {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, - {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH}, {"SMSC", "USB 2 HS-CF", NULL, BLIST_SPARSELUN | BLIST_INQUIRY_36}, {"SONY", "CD-ROM CDU-8001", NULL, BLIST_BORKEN}, {"SONY", "TSL", NULL, BLIST_FORCELUN}, /* DDS3 & DDS4 autoloaders */ reverted: --- b/drivers/scsi/scsi_ioctl.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/scsi_ioctl.c 2004-10-01 19:21:44 -07:00 @@ -20,7 +20,6 @@ #include #include #include -#include #include "scsi_logging.h" @@ -457,51 +456,3 @@ } return -EINVAL; } - -/* - * the scsi_nonblock_ioctl() function is designed for ioctls which may - * be executed even if the device is in recovery. - */ -int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, - void __user *arg, struct file *filp) -{ - int val, result; - - /* The first set of iocts may be executed even if we're doing - * error processing, as long as the device was opened - * non-blocking */ - if (filp && filp->f_flags & O_NONBLOCK) { - if (test_bit(SHOST_RECOVERY, - &sdev->host->shost_state)) - return -ENODEV; - } else if (!scsi_block_when_processing_errors(sdev)) - return -ENODEV; - - switch (cmd) { - case SG_SCSI_RESET: - result = get_user(val, (int __user *)arg); - if (result) - return result; - if (val == SG_SCSI_RESET_NOTHING) - return 0; - switch (val) { - case SG_SCSI_RESET_DEVICE: - val = SCSI_TRY_RESET_DEVICE; - break; - case SG_SCSI_RESET_BUS: - val = SCSI_TRY_RESET_BUS; - break; - case SG_SCSI_RESET_HOST: - val = SCSI_TRY_RESET_HOST; - break; - default: - return -EINVAL; - } - if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) - return -EACCES; - return (scsi_reset_provider(sdev, val) == - SUCCESS) ? 0 : -EIO; - } - return -ENODEV; -} -EXPORT_SYMBOL(scsi_nonblockable_ioctl); diff -u b/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- b/drivers/scsi/scsi_lib.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/scsi_lib.c 2004-10-01 19:23:16 -07:00 @@ -365,7 +365,7 @@ unsigned long flags; spin_lock_irqsave(shost->host_lock, flags); - current_sdev->sdev_target->starget_sdev_user = NULL; + scsi_target(current_sdev)->starget_sdev_user = NULL; spin_unlock_irqrestore(shost->host_lock, flags); /* @@ -377,7 +377,7 @@ blk_run_queue(current_sdev->request_queue); spin_lock_irqsave(shost->host_lock, flags); - if (current_sdev->sdev_target->starget_sdev_user) + if (scsi_target(current_sdev)->starget_sdev_user) goto out; list_for_each_entry_safe(sdev, tmp, ¤t_sdev->same_target_siblings, same_target_siblings) { @@ -1253,10 +1253,10 @@ if (!scsi_host_queue_ready(q, shost, sdev)) goto not_ready; if (sdev->single_lun) { - if (sdev->sdev_target->starget_sdev_user && - sdev->sdev_target->starget_sdev_user != sdev) + if (scsi_target(sdev)->starget_sdev_user && + scsi_target(sdev)->starget_sdev_user != sdev) goto not_ready; - sdev->sdev_target->starget_sdev_user = sdev; + scsi_target(sdev)->starget_sdev_user = sdev; } shost->host_busy++; @@ -1753,0 +1754,28 @@ + +static int +device_quiesce_fn(struct device *dev, void *data) +{ + scsi_device_quiesce(to_scsi_device(dev)); + return 0; +} + +void +scsi_target_quiesce(struct scsi_target *starget) +{ + device_for_each_child(&starget->dev, NULL, device_quiesce_fn); +} +EXPORT_SYMBOL(scsi_target_quiesce); + +static int +device_resume_fn(struct device *dev, void *data) +{ + scsi_device_resume(to_scsi_device(dev)); + return 0; +} + +void +scsi_target_resume(struct scsi_target *starget) +{ + device_for_each_child(&starget->dev, NULL, device_resume_fn); +} +EXPORT_SYMBOL(scsi_target_resume); diff -u b/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- b/drivers/scsi/scsi_scan.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/scsi_scan.c 2004-10-01 19:23:17 -07:00 @@ -202,11 +202,11 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, uint channel, uint id, uint lun, void *hostdata) { - struct scsi_device *sdev, *device; + struct scsi_device *sdev; unsigned long flags; - int display_failure_msg = 1, ret; - sdev = kmalloc(sizeof(*sdev) + shost->transportt->size, GFP_ATOMIC); + sdev = kmalloc(sizeof(*sdev) + shost->transportt->device_size, + GFP_ATOMIC); if (!sdev) goto out; @@ -253,79 +253,32 @@ scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); if (shost->hostt->slave_alloc) { - ret = shost->hostt->slave_alloc(sdev); - if (ret) { - /* - * if LLDD reports slave not present, don't clutter - * console with alloc failure messages - */ - if (ret == -ENXIO) - display_failure_msg = 0; + if (shost->hostt->slave_alloc(sdev)) goto out_free_queue; - } } - if (shost->transportt->setup) { - if (shost->transportt->setup(sdev)) + if (shost->transportt->device_setup) { + if (shost->transportt->device_setup(sdev)) goto out_cleanup_slave; } - if (get_device(&sdev->host->shost_gendev)) { + if (get_device(&sdev->host->shost_gendev) == NULL || + scsi_sysfs_device_initialize(sdev) != 0) + goto out_cleanup_slave; - device_initialize(&sdev->sdev_gendev); - sdev->sdev_gendev.parent = &sdev->host->shost_gendev; - sdev->sdev_gendev.bus = &scsi_bus_type; - sdev->sdev_gendev.release = scsi_device_dev_release; - sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", - sdev->host->host_no, sdev->channel, sdev->id, - sdev->lun); - class_device_initialize(&sdev->sdev_classdev); - sdev->sdev_classdev.dev = &sdev->sdev_gendev; - sdev->sdev_classdev.class = &sdev_class; - snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, - "%d:%d:%d:%d", sdev->host->host_no, - sdev->channel, sdev->id, sdev->lun); + /* NOTE: this target initialisation code depends critically on + * lun scanning being sequential. */ + if (scsi_sysfs_target_initialize(sdev)) + goto out_remove_siblings; - class_device_initialize(&sdev->transport_classdev); - sdev->transport_classdev.dev = &sdev->sdev_gendev; - sdev->transport_classdev.class = sdev->host->transportt->class; - snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE, - "%d:%d:%d:%d", sdev->host->host_no, - sdev->channel, sdev->id, sdev->lun); - } else - goto out_cleanup_transport; + return sdev; - /* - * If there are any same target siblings, add this to the - * sibling list - */ +out_remove_siblings: spin_lock_irqsave(shost->host_lock, flags); - list_for_each_entry(device, &shost->__devices, siblings) { - if (device->id == sdev->id && - device->channel == sdev->channel) { - list_add_tail(&sdev->same_target_siblings, - &device->same_target_siblings); - sdev->scsi_level = device->scsi_level; - break; - } - } - - /* - * If there wasn't another lun already configured at this - * target, then default this device to SCSI_2 until we - * know better - */ - if (!sdev->scsi_level) - sdev->scsi_level = SCSI_2; - - list_add_tail(&sdev->siblings, &shost->__devices); + list_del(&sdev->siblings); + list_del(&sdev->same_target_siblings); spin_unlock_irqrestore(shost->host_lock, flags); - return sdev; - -out_cleanup_transport: - if (shost->transportt->cleanup) - shost->transportt->cleanup(sdev); out_cleanup_slave: if (shost->hostt->slave_destroy) shost->hostt->slave_destroy(sdev); @@ -334,8 +287,7 @@ out_free_dev: kfree(sdev); out: - if (display_failure_msg) - printk(ALLOC_FAILURE_MSG, __FUNCTION__); + printk(ALLOC_FAILURE_MSG, __FUNCTION__); return NULL; } @@ -510,10 +462,6 @@ **/ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) { - struct scsi_device *sdev_sibling; - struct scsi_target *starget; - unsigned long flags; - /* * XXX do not save the inquiry, since it can change underneath us, * save just vendor/model/rev. @@ -543,8 +491,7 @@ */ inq_result[0] = TYPE_ROM; inq_result[1] |= 0x80; /* removable */ - } else if (*bflags & BLIST_NO_ULD_ATTACH) - sdev->no_uld_attach = 1; + } switch (sdev->type = (inq_result[0] & 0x1f)) { case TYPE_TAPE: @@ -623,40 +570,9 @@ if (*bflags & BLIST_NOSTARTONADD) sdev->no_start_on_add = 1; - /* - * If we need to allow I/O to only one of the luns attached to - * this target id at a time set single_lun, and allocate or modify - * sdev_target. - */ - if (*bflags & BLIST_SINGLELUN) { + if (*bflags & BLIST_SINGLELUN) sdev->single_lun = 1; - spin_lock_irqsave(sdev->host->host_lock, flags); - starget = NULL; - /* - * Search for an existing target for this sdev. - */ - list_for_each_entry(sdev_sibling, &sdev->same_target_siblings, - same_target_siblings) { - if (sdev_sibling->sdev_target != NULL) { - starget = sdev_sibling->sdev_target; - break; - } - } - if (!starget) { - starget = kmalloc(sizeof(*starget), GFP_ATOMIC); - if (!starget) { - printk(ALLOC_FAILURE_MSG, __FUNCTION__); - spin_unlock_irqrestore(sdev->host->host_lock, - flags); - return SCSI_SCAN_NO_RESPONSE; - } - starget->starget_refcnt = 0; - starget->starget_sdev_user = NULL; - } - starget->starget_refcnt++; - sdev->sdev_target = starget; - spin_unlock_irqrestore(sdev->host->host_lock, flags); - } + sdev->use_10_for_rw = 1; @@ -796,8 +712,6 @@ } else { if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } out: @@ -1357,6 +1271,4 @@ if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); } diff -u b/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c --- b/drivers/scsi/scsi_sysfs.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/scsi_sysfs.c 2004-10-01 19:23:16 -07:00 @@ -153,25 +153,36 @@ struct scsi_device *sdev; struct device *parent; unsigned long flags; + int delete; parent = dev->parent; sdev = to_scsi_device(dev); spin_lock_irqsave(sdev->host->host_lock, flags); + /* If we're the last LUN on the target, destroy the target */ + delete = list_empty(&sdev->same_target_siblings); list_del(&sdev->siblings); list_del(&sdev->same_target_siblings); list_del(&sdev->starved_entry); - if (sdev->single_lun && --sdev->sdev_target->starget_refcnt == 0) - kfree(sdev->sdev_target); spin_unlock_irqrestore(sdev->host->host_lock, flags); + if (delete) { + struct scsi_target *starget = to_scsi_target(parent); + if (!starget->create) { + device_del(parent); + if (starget->transport_classdev.class) + class_device_unregister(&starget->transport_classdev); + } + put_device(parent); + } if (sdev->request_queue) scsi_free_queue(sdev->request_queue); kfree(sdev->inquiry); kfree(sdev); - put_device(parent); + if (parent) + put_device(parent); } struct class sdev_class = { @@ -183,8 +194,6 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) { struct scsi_device *sdp = to_scsi_device(dev); - if (sdp->no_uld_attach) - return 0; return (sdp->inq_periph_qual == SCSI_INQ_PQ_CON)? 1: 0; } @@ -432,6 +441,14 @@ return device_create_file(dev, attr); } +static void scsi_target_dev_release(struct device *dev) +{ + struct scsi_target *starget = to_scsi_target(dev); + struct device *parent = dev->parent; + kfree(starget); + put_device(parent); +} + /** * scsi_sysfs_add_sdev - add scsi device to sysfs * @sdev: scsi_device to add @@ -442,13 +459,55 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) { struct class_device_attribute **attrs; - int error, i; + struct scsi_target *starget = sdev->sdev_target; + struct Scsi_Host *shost = sdev->host; + int error, i, create; + unsigned long flags; + + spin_lock_irqsave(shost->host_lock, flags); + create = starget->create; + starget->create = 0; + spin_unlock_irqrestore(shost->host_lock, flags); + + if (create) { + error = device_add(&starget->dev); + if (error) { + printk(KERN_ERR "Target device_add failed\n"); + return error; + } + if (starget->transport_classdev.class) { + int i; + struct class_device_attribute **attrs = + sdev->host->transportt->target_attrs; + + error = class_device_add(&starget->transport_classdev); + if (error) { + dev_printk(KERN_ERR, &starget->dev, + "Target transport add failed\n"); + return error; + } + + /* take a reference for the transport_classdev; this + * is released by the transport_class .release */ + get_device(&starget->dev); + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(&starget->transport_classdev, + attrs[i]); + if (error) { + dev_printk(KERN_ERR, &starget->dev, + "Target transport attr add failed\n"); + return error; + } + } + } + } if ((error = scsi_device_set_state(sdev, SDEV_RUNNING)) != 0) return error; error = device_add(&sdev->sdev_gendev); if (error) { + put_device(sdev->sdev_gendev.parent); printk(KERN_INFO "error 1\n"); return error; } @@ -461,7 +520,6 @@ /* take a reference for the sdev_classdev; this is * released by the sdev_class .release */ get_device(&sdev->sdev_gendev); - if (sdev->transport_classdev.class) { error = class_device_add(&sdev->transport_classdev); if (error) @@ -496,7 +554,7 @@ } if (sdev->transport_classdev.class) { - attrs = sdev->host->transportt->attrs; + attrs = sdev->host->transportt->device_attrs; for (i = 0; attrs[i]; i++) { error = class_device_create_file(&sdev->transport_classdev, attrs[i]); @@ -540,8 +598,6 @@ scsi_device_set_state(sdev, SDEV_DEL); if (sdev->host->hostt->slave_destroy) sdev->host->hostt->slave_destroy(sdev); - if (sdev->host->transportt->cleanup) - sdev->host->transportt->cleanup(sdev); put_device(&sdev->sdev_gendev); out: @@ -628,6 +684,121 @@ } } + class_device_initialize(&shost->transport_classdev); + shost->transport_classdev.class = shost->transportt->host_class; + shost->transport_classdev.dev = &shost->shost_gendev; + snprintf(shost->transport_classdev.class_id, BUS_ID_SIZE, + "host%d", shost->host_no); + + if (shost->transport_classdev.class) { + struct class_device_attribute **attrs = + shost->transportt->host_attrs; + error = class_device_add(&shost->transport_classdev); + if (error) + return error; + /* take a reference for the transport_classdev; this + * is released by the transport_class .release */ + get_device(&shost->shost_gendev); + for (i = 0; attrs[i]; i++) { + error = class_device_create_file(&shost->transport_classdev, + attrs[i]); + if (error) + return error; + } + } + + return 0; +} + +int scsi_sysfs_device_initialize(struct scsi_device *sdev) +{ + device_initialize(&sdev->sdev_gendev); + sdev->sdev_gendev.bus = &scsi_bus_type; + sdev->sdev_gendev.release = scsi_device_dev_release; + sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", + sdev->host->host_no, sdev->channel, sdev->id, + sdev->lun); + + class_device_initialize(&sdev->sdev_classdev); + sdev->sdev_classdev.dev = &sdev->sdev_gendev; + sdev->sdev_classdev.class = &sdev_class; + snprintf(sdev->sdev_classdev.class_id, BUS_ID_SIZE, + "%d:%d:%d:%d", sdev->host->host_no, + sdev->channel, sdev->id, sdev->lun); + + class_device_initialize(&sdev->transport_classdev); + sdev->transport_classdev.dev = &sdev->sdev_gendev; + sdev->transport_classdev.class = sdev->host->transportt->device_class; + snprintf(sdev->transport_classdev.class_id, BUS_ID_SIZE, + "%d:%d:%d:%d", sdev->host->host_no, + sdev->channel, sdev->id, sdev->lun); + return 0; +} + +int scsi_sysfs_target_initialize(struct scsi_device *sdev) +{ + struct scsi_target *starget = NULL; + struct Scsi_Host *shost = sdev->host; + struct scsi_device *device; + struct device *dev = NULL; + unsigned long flags; + int create = 0; + + spin_lock_irqsave(shost->host_lock, flags); + /* + * Search for an existing target for this sdev. + */ + list_for_each_entry(device, &shost->__devices, siblings) { + if (device->id == sdev->id && + device->channel == sdev->channel) { + list_add_tail(&sdev->same_target_siblings, + &device->same_target_siblings); + sdev->scsi_level = device->scsi_level; + starget = device->sdev_target; + break; + } + } + + if (!starget) { + const int size = sizeof(*starget) + + shost->transportt->target_size; + starget = kmalloc(size, GFP_ATOMIC); + if (!starget) { + printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); + spin_unlock_irqrestore(shost->host_lock, + flags); + return -ENOMEM; + } + memset(starget, 0, size); + dev = &starget->dev; + device_initialize(dev); + dev->parent = &shost->shost_gendev; + dev->release = scsi_target_dev_release; + sprintf(dev->bus_id, "target%d:%d:%d", + shost->host_no, sdev->channel, sdev->id); + class_device_initialize(&starget->transport_classdev); + starget->transport_classdev.dev = &starget->dev; + starget->transport_classdev.class = shost->transportt->target_class; + snprintf(starget->transport_classdev.class_id, BUS_ID_SIZE, + "target%d:%d:%d", + shost->host_no, sdev->channel, sdev->id); + starget->id = sdev->id; + starget->channel = sdev->channel; + create = starget->create = 1; + /* + * If there wasn't another lun already configured at + * this target, then default this device to SCSI_2 + * until we know better + */ + sdev->scsi_level = SCSI_2; + } + get_device(&starget->dev); + sdev->sdev_gendev.parent = &starget->dev; + sdev->sdev_target = starget; + list_add_tail(&sdev->siblings, &shost->__devices); + spin_unlock_irqrestore(shost->host_lock, flags); + if (create && shost->transportt->target_setup) + shost->transportt->target_setup(starget); return 0; } diff -u b/drivers/scsi/sd.c b/drivers/scsi/sd.c --- b/drivers/scsi/sd.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/sd.c 2004-10-01 19:23:16 -07:00 @@ -574,9 +574,8 @@ * may try and take the device offline, in which case all further * access to the device is prohibited. */ - error = scsi_nonblockable_ioctl(sdp, cmd, p, filp); - if (!scsi_block_when_processing_errors(sdp) || !error) - return error; + if (!scsi_block_when_processing_errors(sdp)) + return -ENODEV; if (cmd == HDIO_GETGEO) { if (!arg) reverted: --- b/drivers/scsi/sr_ioctl.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sr_ioctl.c 2004-10-01 19:21:44 -07:00 @@ -549,17 +549,5 @@ unsigned int cmd, unsigned long arg) { Scsi_CD *cd = cdi->handle; - int ret; - - ret = scsi_nonblockable_ioctl(cd->device, cmd, - (void __user *)arg, NULL); - /* - * ENODEV means that we didn't recognise the ioctl, or that we - * cannot execute it in the current device state. In either - * case fall through to scsi_ioctl, which will return ENDOEV again - * if it doesn't recognise the ioctl - */ - if (ret != -ENODEV) - return ret; return scsi_ioctl(cd->device, cmd, (void __user *)arg); } reverted: --- b/drivers/scsi/st.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/st.c 2004-10-01 19:21:44 -07:00 @@ -40,16 +40,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include - - /* The driver prints some debugging information on the console if DEBUG is defined and non-zero. */ #define DEBUG 0 @@ -66,6 +56,13 @@ #define DEBC(a) #endif + +#include "scsi.h" +#include + +#include +#include + #define ST_KILOBYTE 1024 #include "st_options.h" @@ -74,8 +71,8 @@ static int buffer_kbs; static int max_sg_segs; static int try_direct_io = TRY_DIRECT_IO; +static int try_rdio = TRUE; +static int try_wdio = TRUE; -static int try_rdio = 1; -static int try_wdio = 1; static int st_dev_max; static int st_nr_dev; @@ -240,7 +237,7 @@ /* If the device signature is on the list of incompatible drives, the function returns a pointer to the name of the correct driver (if known) */ +static char * st_incompatible(Scsi_Device* SDp) -static char * st_incompatible(struct scsi_device* SDp) { struct st_reject_data *rp; @@ -263,7 +260,7 @@ } /* Convert the result to success code */ +static int st_chk_result(Scsi_Tape *STp, Scsi_Request * SRpnt) -static int st_chk_result(Scsi_Tape *STp, struct scsi_request * SRpnt) { int result = SRpnt->sr_result; unsigned char *sense = SRpnt->sr_sense_buffer, scode; @@ -290,7 +287,7 @@ SRpnt->sr_cmnd[3], SRpnt->sr_cmnd[4], SRpnt->sr_cmnd[5], SRpnt->sr_bufflen); if (driver_byte(result) & DRIVER_SENSE) + print_req_sense("st", SRpnt); - scsi_print_req_sense("st", SRpnt); } else ) /* end DEB */ if (!(driver_byte(result) & DRIVER_SENSE) || ((sense[0] & 0x70) == 0x70 && @@ -303,7 +300,7 @@ SRpnt->sr_cmnd[0] != TEST_UNIT_READY)) { /* Abnormal conditions for tape */ if (driver_byte(result) & DRIVER_SENSE) { printk(KERN_WARNING "%s: Error with sense data: ", name); + print_req_sense("st", SRpnt); - scsi_print_req_sense("st", SRpnt); } else printk(KERN_WARNING "%s: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n", @@ -354,7 +351,7 @@ /* Wakeup from interrupt */ +static void st_sleep_done(Scsi_Cmnd * SCpnt) -static void st_sleep_done(struct scsi_cmnd * SCpnt) { int remainder; Scsi_Tape *STp = container_of(SCpnt->request->rq_disk->private_data, @@ -388,9 +385,9 @@ /* Do the scsi command. Waits until command performed if do_wait is true. Otherwise write_behind_check() is used to check that the command has finished. */ +static Scsi_Request * + st_do_scsi(Scsi_Request * SRpnt, Scsi_Tape * STp, unsigned char *cmd, int bytes, + int direction, int timeout, int retries, int do_wait) -static struct scsi_request * -st_do_scsi(struct scsi_request * SRpnt, Scsi_Tape * STp, unsigned char *cmd, - int bytes, int direction, int timeout, int retries, int do_wait) { unsigned char *bp; @@ -473,7 +470,7 @@ it messes up the block number). */ static int cross_eof(Scsi_Tape * STp, int forward) { + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; unsigned char cmd[MAX_COMMAND_SIZE]; cmd[0] = SPACE; @@ -488,8 +485,8 @@ DEBC(printk(ST_DEB_MSG "%s: Stepping over filemark %s.\n", tape_name(STp), forward ? "forward" : "backward")); + SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, + STp->device->timeout, MAX_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -510,7 +507,7 @@ int offset, transfer, blks; int result; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; ST_partstat *STps; if ((STp->buffer)->writing) { @@ -546,8 +543,8 @@ cmd[3] = blks >> 8; cmd[4] = blks; + SRpnt = st_do_scsi(NULL, STp, cmd, transfer, SCSI_DATA_WRITE, + STp->device->timeout, MAX_WRITE_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, cmd, transfer, DMA_TO_DEVICE, - STp->device->timeout, MAX_WRITE_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -613,7 +610,7 @@ result = 0; if (!seek_next) { if (STps->eof == ST_FM_HIT) { + result = cross_eof(STp, FALSE); /* Back over the EOF hit */ - result = cross_eof(STp, 0); /* Back over the EOF hit */ if (!result) STps->eof = ST_NOEOF; else { @@ -637,7 +634,7 @@ /* Set the mode parameters */ static int set_mode_densblk(Scsi_Tape * STp, ST_mode * STm) { + int set_it = FALSE; - int set_it = 0; unsigned long arg; char *name = tape_name(STp); @@ -645,7 +642,7 @@ STm->default_density >= 0 && STm->default_density != STp->density) { arg = STm->default_density; + set_it = TRUE; - set_it = 1; } else arg = STp->density; arg <<= MT_ST_DENSITY_SHIFT; @@ -653,7 +650,7 @@ STm->default_blksize >= 0 && STm->default_blksize != STp->block_size) { arg |= STm->default_blksize; + set_it = TRUE; - set_it = 1; } else arg |= STp->block_size; if (set_it && @@ -668,7 +665,7 @@ } +/* Lock or unlock the drive door. Don't use when Scsi_Request allocated. */ -/* Lock or unlock the drive door. Don't use when scsi_request allocated. */ static int do_door_lock(Scsi_Tape * STp, int do_lock) { int retval, cmd; @@ -701,7 +698,7 @@ STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; + STps->last_block_valid = FALSE; - STps->last_block_valid = 0; STps->drv_block = -1; STps->drv_file = -1; } @@ -725,17 +722,17 @@ static int test_ready(Scsi_Tape *STp, int do_wait) { int attentions, waits, max_wait, scode; + int retval = CHKRES_READY, new_session = FALSE; - int retval = CHKRES_READY, new_session = 0; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; max_wait = do_wait ? ST_BLOCK_SECONDS : 0; for (attentions=waits=0; ; ) { memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE); cmd[0] = TEST_UNIT_READY; + SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, SCSI_DATA_NONE, + STp->long_timeout, MAX_READY_RETRIES, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, 0, DMA_NONE, - STp->long_timeout, MAX_READY_RETRIES, 1); if (!SRpnt) { retval = (STp->buffer)->syscall_result; @@ -747,7 +744,7 @@ scode = (SRpnt->sr_sense_buffer[2] & 0x0f); if (scode == UNIT_ATTENTION) { /* New media? */ + new_session = TRUE; - new_session = 1; if (attentions < MAX_ATTENTIONS) { attentions++; continue; @@ -799,10 +796,10 @@ */ static int check_tape(Scsi_Tape *STp, struct file *filp) { + int i, retval, new_session = FALSE, do_wait; - int i, retval, new_session = 0, do_wait; unsigned char cmd[MAX_COMMAND_SIZE], saved_cleaning; unsigned short st_flags = filp->f_flags; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; ST_mode *STm; ST_partstat *STps; char *name = tape_name(STp); @@ -814,7 +811,7 @@ if (mode != STp->current_mode) { DEBC(printk(ST_DEB_MSG "%s: Mode change from %d to %d.\n", name, STp->current_mode, mode)); + new_session = TRUE; - new_session = 1; STp->current_mode = mode; } STm = &(STp->modes[STp->current_mode]); @@ -839,11 +836,11 @@ STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; + STps->last_block_valid = FALSE; - STps->last_block_valid = 0; STps->drv_block = 0; STps->drv_file = 0; } + new_session = TRUE; - new_session = 1; } else { STp->cleaning_req |= saved_cleaning; @@ -870,8 +867,8 @@ memset((void *) &cmd[0], 0, MAX_COMMAND_SIZE); cmd[0] = READ_BLOCK_LIMITS; + SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, SCSI_DATA_READ, STp->device->timeout, + MAX_READY_RETRIES, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, 6, DMA_FROM_DEVICE, - STp->device->timeout, MAX_READY_RETRIES, 1); if (!SRpnt) { retval = (STp->buffer)->syscall_result; goto err_out; @@ -897,8 +894,8 @@ cmd[0] = MODE_SENSE; cmd[4] = 12; + SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, SCSI_DATA_READ, STp->device->timeout, + MAX_READY_RETRIES, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, 12, DMA_FROM_DEVICE, - STp->device->timeout, MAX_READY_RETRIES, 1); if (!SRpnt) { retval = (STp->buffer)->syscall_result; goto err_out; @@ -931,7 +928,7 @@ } scsi_release_request(SRpnt); SRpnt = NULL; + STp->inited = TRUE; - STp->inited = 1; if (STp->block_size > 0) (STp->buffer)->buffer_blocks = @@ -973,8 +970,8 @@ } if (new_session) { /* Change the drive parameters for the new mode */ + STp->density_changed = STp->blksize_changed = FALSE; + STp->compression_changed = FALSE; - STp->density_changed = STp->blksize_changed = 0; - STp->compression_changed = 0; if (!(STm->defaults_for_writes) && (retval = set_mode_densblk(STp, STm)) < 0) goto err_out; @@ -1079,7 +1076,7 @@ { int result = 0, result2; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; Scsi_Tape *STp = filp->private_data; ST_mode *STm = &(STp->modes[STp->current_mode]); ST_partstat *STps = &(STp->ps[STp->partition]); @@ -1119,8 +1116,8 @@ cmd[0] = WRITE_FILEMARKS; cmd[4] = 1 + STp->two_fm; + SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, + STp->device->timeout, MAX_WRITE_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, - STp->device->timeout, MAX_WRITE_RETRIES, 1); if (!SRpnt) { result = (STp->buffer)->syscall_result; goto out; @@ -1146,7 +1143,7 @@ STps->drv_file++; STps->drv_block = 0; if (STp->two_fm) + cross_eof(STp, FALSE); - cross_eof(STp, 0); STps->eof = ST_FM; } @@ -1158,7 +1155,7 @@ if (STp->can_bsr) result = flush_buffer(STp, 0); else if (STps->eof == ST_FM_HIT) { + result = cross_eof(STp, FALSE); - result = cross_eof(STp, 0); if (result) { if (STps->drv_file >= 0) STps->drv_file++; @@ -1168,7 +1165,7 @@ STps->eof = ST_NOEOF; } } else if ((STps->eof == ST_NOEOF && + !(result = cross_eof(STp, TRUE))) || - !(result = cross_eof(STp, 1))) || STps->eof == ST_FM_HIT) { if (STps->drv_file >= 0) STps->drv_file++; @@ -1293,7 +1290,7 @@ STbp->buffer_bytes = 0; /* can be used as transfer counter */ } else + STbp->do_dio = FALSE; /* fall back to buffering with any error */ - STbp->do_dio = 0; /* fall back to buffering with any error */ STbp->sg_segs = STbp->do_dio; STbp->frp_sg_current = 0; DEB( @@ -1306,7 +1303,7 @@ } ) } else + STbp->do_dio = FALSE; - STbp->do_dio = 0; DEB( STp->nbr_requests++; ) if (!STbp->do_dio) { @@ -1338,7 +1335,7 @@ STbp = STp->buffer; if (STbp->do_dio) { + sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, FALSE); - sgl_unmap_user_pages(&(STbp->sg[0]), STbp->do_dio, 0); STbp->do_dio = 0; } } @@ -1355,7 +1352,7 @@ int async_write; unsigned char cmd[MAX_COMMAND_SIZE]; const char __user *b_point; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; Scsi_Tape *STp = filp->private_data; ST_mode *STm; ST_partstat *STps; @@ -1441,7 +1438,7 @@ goto out; } + retval = setup_buffering(STp, buf, count, FALSE); - retval = setup_buffering(STp, buf, count, 0); if (retval) goto out; @@ -1485,7 +1482,7 @@ if (STp->block_size != 0 && STm->do_buffer_writes && !(STp->try_dio && try_wdio) && STps->eof < ST_EOM_OK && STbp->buffer_bytes < STbp->buffer_size) { + STp->dirty = TRUE; - STp->dirty = 1; /* Don't write a buffer that is not full enough. */ if (!async_write && count == 0) break; @@ -1506,7 +1503,7 @@ cmd[3] = blks >> 8; cmd[4] = blks; + SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, SCSI_DATA_WRITE, - SRpnt = st_do_scsi(SRpnt, STp, cmd, transfer, DMA_TO_DEVICE, STp->device->timeout, MAX_WRITE_RETRIES, !async_write); if (!SRpnt) { retval = STbp->syscall_result; @@ -1562,7 +1559,7 @@ if (!retry_eot && (SRpnt->sr_sense_buffer[0] & 1) == 0 && (scode == NO_SENSE || scode == RECOVERED_ERROR)) { move_buffer_data(STp->buffer, transfer - undone); + retry_eot = TRUE; - retry_eot = 1; if (STps->drv_block >= 0) { STps->drv_block += (transfer - undone) / STp->block_size; @@ -1633,11 +1630,11 @@ Does release user buffer mapping if it is set. */ +static long read_tape(Scsi_Tape *STp, long count, Scsi_Request ** aSRpnt) -static long read_tape(Scsi_Tape *STp, long count, struct scsi_request ** aSRpnt) { int transfer, blks, bytes; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; ST_mode *STm; ST_partstat *STps; ST_buffer *STbp; @@ -1676,8 +1673,8 @@ cmd[4] = blks; SRpnt = *aSRpnt; + SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, SCSI_DATA_READ, + STp->device->timeout, MAX_RETRIES, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, bytes, DMA_FROM_DEVICE, - STp->device->timeout, MAX_RETRIES, 1); release_buffering(STp); *aSRpnt = SRpnt; if (!SRpnt) @@ -1821,7 +1818,7 @@ ssize_t retval = 0; ssize_t i, transfer; int special, do_dio = 0; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; Scsi_Tape *STp = filp->private_data; ST_mode *STm; ST_partstat *STps; @@ -1855,7 +1852,7 @@ STps->eof, STbp->buffer_bytes); ) /* end DEB */ + retval = setup_buffering(STp, buf, count, TRUE); - retval = setup_buffering(STp, buf, count, 1); if (retval) goto out; do_dio = STbp->do_dio; @@ -1999,7 +1996,7 @@ cd0 = STm->cdevs[0]; cd1 = STm->cdevs[1]; memcpy(STm, &(STp->modes[0]), sizeof(ST_mode)); STm->cdevs[0] = cd0; STm->cdevs[1] = cd1; + modes_defined = TRUE; - modes_defined = 1; DEBC(printk(ST_DEB_MSG "%s: Initialized mode %d definition from mode 0\n", name, STp->current_mode)); @@ -2068,7 +2065,7 @@ DEBC( printk(KERN_INFO "%s: Default block size set to %d bytes.\n", name, STm->default_blksize)); if (STp->ready == ST_READY) { + STp->blksize_changed = FALSE; - STp->blksize_changed = 0; set_mode_densblk(STp, STm); } } @@ -2107,7 +2104,7 @@ DEBC( printk(KERN_INFO "%s: Density default set to %x\n", name, STm->default_density)); if (STp->ready == ST_READY) { + STp->density_changed = FALSE; - STp->density_changed = 0; set_mode_densblk(STp, STm); } } @@ -2140,7 +2137,7 @@ DEBC( printk(KERN_INFO "%s: Compression default set to %x\n", name, (value & 1))); if (STp->ready == ST_READY) { + STp->compression_changed = FALSE; - STp->compression_changed = 0; st_compression(STp, (STm->default_compression == ST_YES)); } } @@ -2177,7 +2174,7 @@ static int read_mode_page(Scsi_Tape *STp, int page, int omit_block_descs) { unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SENSE; @@ -2186,8 +2183,8 @@ cmd[2] = page; cmd[4] = 255; + SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_READ, + STp->device->timeout, 0, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_FROM_DEVICE, - STp->device->timeout, 0, 1); if (SRpnt == NULL) return (STp->buffer)->syscall_result; @@ -2203,7 +2200,7 @@ { int pgo; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt = NULL; - struct scsi_request *SRpnt = NULL; memset(cmd, 0, MAX_COMMAND_SIZE); cmd[0] = MODE_SELECT; @@ -2217,8 +2214,8 @@ (STp->buffer)->b_data[MH_OFF_DEV_SPECIFIC] &= ~MH_BIT_WP; (STp->buffer)->b_data[pgo + MP_OFF_PAGE_NBR] &= MP_MSK_PAGE_NBR; + SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], SCSI_DATA_WRITE, + (slow ? STp->long_timeout : STp->device->timeout), 0, TRUE); - SRpnt = st_do_scsi(SRpnt, STp, cmd, cmd[4], DMA_TO_DEVICE, - (slow ? STp->long_timeout : STp->device->timeout), 0, 1); if (SRpnt == NULL) return (STp->buffer)->syscall_result; @@ -2256,7 +2253,7 @@ return (-EIO); /* Read the current page contents */ + retval = read_mode_page(STp, COMPRESSION_PAGE, FALSE); - retval = read_mode_page(STp, COMPRESSION_PAGE, 0); if (retval) { DEBC(printk(ST_DEB_MSG "%s: Compression mode page not supported.\n", name)); @@ -2285,7 +2282,7 @@ b_data[mpoffs + CP_OFF_C_ALGO] = 0; /* no compression */ } + retval = write_mode_page(STp, COMPRESSION_PAGE, FALSE); - retval = write_mode_page(STp, COMPRESSION_PAGE, 0); if (retval) { DEBC(printk(ST_DEB_MSG "%s: Compression change failed.\n", name)); return (-EIO); @@ -2293,7 +2290,7 @@ DEBC(printk(ST_DEB_MSG "%s: Compression state changed to %d.\n", name, state)); + STp->compression_changed = TRUE; - STp->compression_changed = 1; return 0; } @@ -2305,7 +2302,7 @@ DEB( char *name = tape_name(STp); ) unsigned char cmd[MAX_COMMAND_SIZE]; ST_partstat *STps; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; if (STp->ready != ST_READY && !load_code) { if (STp->ready == ST_NO_TAPE) @@ -2342,8 +2339,8 @@ printk(ST_DEB_MSG "%s: Loading tape.\n", name); ); + SRpnt = st_do_scsi(NULL, STp, cmd, 0, SCSI_DATA_NONE, + timeout, MAX_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, cmd, 0, DMA_NONE, - timeout, MAX_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -2378,12 +2375,12 @@ int timeout; long ltmp; int ioctl_result; + int chg_eof = TRUE; - int chg_eof = 1; unsigned char cmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; ST_partstat *STps; int fileno, blkno, at_sm, undone; + int datalen = 0, direction = SCSI_DATA_NONE; - int datalen = 0, direction = DMA_NONE; char *name = tape_name(STp); WARN_ON(STp->buffer->do_dio != 0); @@ -2402,7 +2399,7 @@ memset(cmd, 0, MAX_COMMAND_SIZE); switch (cmd_in) { case MTFSFM: + chg_eof = FALSE; /* Changed from the FSF after this */ - chg_eof = 0; /* Changed from the FSF after this */ case MTFSF: cmd[0] = SPACE; cmd[1] = 0x01; /* Space FileMarks */ @@ -2417,7 +2414,7 @@ at_sm &= (arg == 0); break; case MTBSFM: + chg_eof = FALSE; /* Changed from the FSF after this */ - chg_eof = 0; /* Changed from the FSF after this */ case MTBSF: cmd[0] = SPACE; cmd[1] = 0x01; /* Space FileMarks */ @@ -2586,7 +2583,7 @@ case MTSETDENSITY: /* Set tape density */ case MTSETDRVBUFFER: /* Set drive buffering */ case SET_DENS_AND_BLK: /* Set density and block size */ + chg_eof = FALSE; - chg_eof = 0; if (STp->dirty || (STp->buffer)->buffer_bytes != 0) return (-EIO); /* Not allowed if data in buffer */ if ((cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) && @@ -2601,7 +2598,7 @@ if ((STp->use_pf & USE_PF)) cmd[1] = MODE_SELECT_PAGE_FORMAT; cmd[4] = datalen = 12; + direction = SCSI_DATA_WRITE; - direction = DMA_TO_DEVICE; memset((STp->buffer)->b_data, 0, 12); if (cmd_in == MTSETDRVBUFFER) @@ -2612,7 +2609,7 @@ (STp->buffer)->b_data[3] = 8; /* block descriptor length */ if (cmd_in == MTSETDENSITY) { (STp->buffer)->b_data[4] = arg; + STp->density_changed = TRUE; /* At least we tried ;-) */ - STp->density_changed = 1; /* At least we tried ;-) */ } else if (cmd_in == SET_DENS_AND_BLK) (STp->buffer)->b_data[4] = arg >> 24; else @@ -2620,7 +2617,7 @@ if (cmd_in == MTSETBLK || cmd_in == SET_DENS_AND_BLK) { ltmp = arg & MT_ST_BLKSIZE_MASK; if (cmd_in == MTSETBLK) + STp->blksize_changed = TRUE; /* At least we tried ;-) */ - STp->blksize_changed = 1; /* At least we tried ;-) */ } else ltmp = STp->block_size; (STp->buffer)->b_data[9] = (ltmp >> 16); @@ -2649,7 +2646,7 @@ } SRpnt = st_do_scsi(NULL, STp, cmd, datalen, direction, + timeout, MAX_RETRIES, TRUE); - timeout, MAX_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -2792,7 +2789,7 @@ { int result; unsigned char scmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; DEB( char *name = tape_name(STp); ) if (STp->ready != ST_READY) @@ -2807,8 +2804,8 @@ if (!logical && !STp->scsi2_logical) scmd[1] = 1; } + SRpnt = st_do_scsi(NULL, STp, scmd, 20, SCSI_DATA_READ, STp->device->timeout, + MAX_READY_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, scmd, 20, DMA_FROM_DEVICE, - STp->device->timeout, MAX_READY_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -2855,7 +2852,7 @@ unsigned int blk; int timeout; unsigned char scmd[MAX_COMMAND_SIZE]; + Scsi_Request *SRpnt; - struct scsi_request *SRpnt; DEB( char *name = tape_name(STp); ) if (STp->ready != ST_READY) @@ -2874,9 +2871,9 @@ return (-EINVAL); if (partition != STp->partition) { if (get_location(STp, &blk, &p, 1)) + STps->last_block_valid = FALSE; - STps->last_block_valid = 0; else { + STps->last_block_valid = TRUE; - STps->last_block_valid = 1; STps->last_block_visited = blk; DEBC(printk(ST_DEB_MSG "%s: Visited block %d for partition %d saved.\n", @@ -2912,8 +2909,8 @@ timeout = STp->device->timeout; } + SRpnt = st_do_scsi(NULL, STp, scmd, 0, SCSI_DATA_NONE, + timeout, MAX_READY_RETRIES, TRUE); - SRpnt = st_do_scsi(NULL, STp, scmd, 0, DMA_NONE, - timeout, MAX_READY_RETRIES, 1); if (!SRpnt) return (STp->buffer)->syscall_result; @@ -3000,7 +2997,7 @@ if (STp->ready != ST_READY) return (-EIO); + result = read_mode_page(STp, PART_PAGE, TRUE); - result = read_mode_page(STp, PART_PAGE, 1); if (result) { DEBC(printk(ST_DEB_MSG "%s: Can't read medium partition page.\n", @@ -3042,7 +3039,7 @@ int pgo, psd_cnt, psdo; unsigned char *bp; + result = read_mode_page(STp, PART_PAGE, FALSE); - result = read_mode_page(STp, PART_PAGE, 0); if (result) { DEBC(printk(ST_DEB_MSG "%s: Can't read partition mode page.\n", name)); return result; @@ -3085,7 +3082,7 @@ bp[pgo + PP_OFF_RESERVED] = 0; bp[pgo + PP_OFF_FLAGS] = PP_BIT_IDP | PP_MSK_PSUM_MB; + result = write_mode_page(STp, PART_PAGE, TRUE); - result = write_mode_page(STp, PART_PAGE, 1); if (result) { printk(KERN_INFO "%s: Partitioning of tape failed.\n", name); result = (-EIO); @@ -3128,10 +3125,10 @@ * may try and take the device offline, in which case all further * access to the device is prohibited. */ + if (!scsi_block_when_processing_errors(STp->device)) { + retval = (-ENXIO); - retval = scsi_nonblockable_ioctl(STp->device, cmd_in, p, file); - if (!scsi_block_when_processing_errors(STp->device) || !retval) goto out; + } - cmd_type = _IOC_TYPE(cmd_in); cmd_nr = _IOC_NR(cmd_in); @@ -3262,7 +3259,7 @@ for (i = 0; i < ST_NBR_PARTITIONS; i++) { STp->ps[i].rw = ST_IDLE; STp->ps[i].at_sm = 0; + STp->ps[i].last_block_valid = FALSE; - STp->ps[i].last_block_valid = 0; } STp->partition = STp->new_partition = 0; STp->nbr_partitions = 1; /* Bad guess ?-) */ @@ -3311,7 +3308,7 @@ goto out; } + if ((i = flush_buffer(STp, FALSE)) < 0) { - if ((i = flush_buffer(STp, 0)) < 0) { retval = i; goto out; } @@ -3451,7 +3448,7 @@ tb->b_data = page_address(tb->sg[0].page); tb->frp = (struct st_buf_fragment *)(&(tb->sg[0]) + max_sg); + tb->in_use = TRUE; - tb->in_use = 1; tb->dma = need_dma; tb->buffer_size = got; @@ -3465,7 +3462,7 @@ int segs, nbr, max_segs, b_size, priority, order, got; if (new_size <= STbuffer->buffer_size) + return TRUE; - return 1; if (STbuffer->buffer_size <= PAGE_SIZE) normalize_buffer(STbuffer); /* Avoid extra segment */ @@ -3473,7 +3470,7 @@ max_segs = STbuffer->use_sg; nbr = max_segs - STbuffer->frp_segs; if (nbr <= 0) + return FALSE; - return 0; priority = GFP_KERNEL | __GFP_NOWARN; if (need_dma) @@ -3494,7 +3491,7 @@ } DEB(STbuffer->buffer_size = got); normalize_buffer(STbuffer); + return FALSE; - return 0; } STbuffer->frp[segs].length = b_size; STbuffer->frp_segs += 1; @@ -3504,7 +3501,7 @@ } STbuffer->b_data = page_address(STbuffer->frp[0].page); + return TRUE; - return 1; } @@ -3744,7 +3741,7 @@ i = SDp->host->sg_tablesize; if (st_max_sg_segs < i) i = st_max_sg_segs; + buffer = new_tape_buffer(TRUE, (SDp->host)->unchecked_isa_dma, i); - buffer = new_tape_buffer(1, (SDp->host)->unchecked_isa_dma, i); if (buffer == NULL) { printk(KERN_ERR "st: Can't allocate new tape buffer. Device not attached.\n"); goto out; @@ -3847,7 +3844,7 @@ for (i = 0; i < ST_NBR_MODES; i++) { STm = &(tpnt->modes[i]); + STm->defined = FALSE; - STm->defined = 0; STm->sysv = ST_SYSV; STm->defaults_for_writes = 0; STm->do_async_writes = ST_ASYNC_WRITES; @@ -3863,16 +3860,16 @@ STps->rw = ST_IDLE; STps->eof = ST_NOEOF; STps->at_sm = 0; + STps->last_block_valid = FALSE; - STps->last_block_valid = 0; STps->drv_block = (-1); STps->drv_file = (-1); } tpnt->current_mode = 0; + tpnt->modes[0].defined = TRUE; - tpnt->modes[0].defined = 1; tpnt->density_changed = tpnt->compression_changed = + tpnt->blksize_changed = FALSE; - tpnt->blksize_changed = 0; init_MUTEX(&tpnt->lock); st_nr_dev++; @@ -3964,7 +3961,7 @@ static int st_remove(struct device *dev) { + Scsi_Device *SDp = to_scsi_device(dev); - struct scsi_device *SDp = to_scsi_device(dev); Scsi_Tape *tpnt; int i, j, mode; @@ -4256,7 +4253,7 @@ return nr_pages; out_unmap: + sgl_unmap_user_pages(sgl, nr_pages, FALSE); - sgl_unmap_user_pages(sgl, nr_pages, 0); return 0; } reverted: --- b/drivers/scsi/st.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/st.h 2004-10-01 19:21:44 -07:00 @@ -2,9 +2,11 @@ #ifndef _ST_H #define _ST_H +#ifndef _SCSI_H +#include "scsi.h" +#endif #include - /* The tape buffer descriptor. */ typedef struct { unsigned char in_use; @@ -17,7 +19,7 @@ int writing; int midlevel_result; int syscall_result; + Scsi_Request *last_SRpnt; - struct scsi_request *last_SRpnt; unsigned char *b_data; unsigned short use_sg; /* zero or max number of s/g segments for this adapter */ unsigned short sg_segs; /* number of segments in s/g list */ @@ -74,7 +76,7 @@ /* The tape drive descriptor */ typedef struct { struct scsi_driver *driver; + Scsi_Device *device; - struct scsi_device *device; struct semaphore lock; /* For serialization */ struct completion wait; /* For SCSI commands */ ST_buffer *buffer; reverted: --- b/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym53c8xx.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM53C8XX_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_conf.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_conf.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_CONF_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_defs.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_defs.h 2004-10-01 19:21:44 -07:00 @@ -22,25 +22,38 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_DEFS_H #define SYM_DEFS_H +#define SYM_VERSION "2.1.18j" -#define SYM_VERSION "2.1.18k" #define SYM_DRIVER_NAME "sym-" SYM_VERSION /* reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw.c 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ @@ -398,6 +411,7 @@ if (opcode == 0) { printf ("%s: ERROR0 IN SCRIPT at %d.\n", sym_name(np), (int) (cur-start)); + MDELAY (10000); ++cur; continue; }; @@ -441,6 +455,7 @@ if ((tmp1 ^ tmp2) & 3) { printf ("%s: ERROR1 IN SCRIPT at %d.\n", sym_name(np), (int) (cur-start)); + MDELAY (10000); } /* * If PREFETCH feature not enabled, remove reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_FW_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw1.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw1.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* reverted: --- b/drivers/scsi/sym53c8xx_2/sym_fw2.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_fw2.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* diff -u b/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- b/drivers/scsi/sym53c8xx_2/sym_glue.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c 2004-10-01 19:23:17 -07:00 @@ -3,7 +3,6 @@ * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier - * Copyright (c) 2003-2004 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -23,19 +22,32 @@ * *----------------------------------------------------------------------------- * - * 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 of the License, or - * (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * 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. + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #define SYM_GLUE_C @@ -561,6 +573,7 @@ switch (cp->cdb_buf[0]) { case 0x0A: case 0x2A: case 0xAA: panic("XXXXXXXXXXXXX WRITE NOT YET ALLOWED XXXXXXXXXXXXXX\n"); + MDELAY(10000); break; default: break; @@ -1083,7 +1096,8 @@ lp->s.scdev_depth = depth_to_use; sym_tune_dev_queuing(np, device->id, device->lun, reqtags); - spi_dv_device(device); + if (!spi_initial_dv(device->sdev_target)) + spi_dv_device(device); return 0; } @@ -1966,14 +1980,39 @@ __setup("sym53c8xx=", sym53c8xx_setup); #endif -static int __devinit sym_check_supported(struct sym_device *device) +/* + * Read and check the PCI configuration for any detected NCR + * boards and save data for attaching after all boards have + * been detected. + */ +static int __devinit +sym53c8xx_pci_init(struct pci_dev *pdev, struct sym_device *device) { struct sym_pci_chip *chip; - struct pci_dev *pdev = device->pdev; - u_char revision; - unsigned long io_port = device->s.io_port; - unsigned long base = device->s.base; + u_long base, base_2; + u_long base_c, base_2_c, io_port; int i; + u_short device_id, status_reg; + u_char revision; + + /* Choose some short name for this device */ + sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); + + device_id = pdev->device; + + io_port = pdev->resource[0].start; + + base_c = pdev->resource[1].start; + i = pci_get_base_address(pdev, 1, &base); + + base_2_c = pdev->resource[i].start; + pci_get_base_address(pdev, i, &base_2); + + base &= PCI_BASE_ADDRESS_MEM_MASK; + base_2 &= PCI_BASE_ADDRESS_MEM_MASK; + + pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); /* * If user excluded this chip, do not initialize it. @@ -1981,11 +2020,20 @@ if (io_port) { for (i = 0 ; i < 8 ; i++) { if (sym_driver_setup.excludes[i] == io_port) - return -ENODEV; + return -1; } } /* + * Check if the chip is supported. + */ + chip = sym_lookup_pci_chip_table(device_id, revision); + if (!chip) { + printf_info("%s: device not supported\n", sym_name(device)); + return -1; + } + + /* * Check if the chip has been assigned resources we need. * XXX: can this still happen with Linux 2.6's PCI layer? */ @@ -1993,84 +2041,66 @@ if (!io_port) { printf_info("%s: IO base address disabled.\n", sym_name(device)); - return -ENODEV; + return -1; } #else if (!base) { printf_info("%s: MMIO base address disabled.\n", sym_name(device)); - return -ENODEV; + return -1; } #endif /* - * Check if the chip is supported. Then copy the chip description - * to our device structure so we can make it match the actual device - * and options. + * Ignore Symbios chips controlled by various RAID controllers. + * These controllers set value 0x52414944 at RAM end - 16. */ - pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); - chip = sym_lookup_pci_chip_table(pdev->device, revision); - if (!chip) { - printf_info("%s: device not supported\n", sym_name(device)); - return -ENODEV; +#if defined(__i386__) + if (base_2_c) { + unsigned int ram_size, ram_val; + void *ram_ptr; + + if (chip->features & FE_RAM8K) + ram_size = 8192; + else + ram_size = 4096; + + ram_ptr = ioremap(base_2_c, ram_size); + if (ram_ptr) { + ram_val = readl_raw(ram_ptr + ram_size - 16); + iounmap(ram_ptr); + if (ram_val == 0x52414944) { + printf_info("%s: not initializing, " + "driven by RAID controller.\n", + sym_name(device)); + return -1; + } + } } +#endif /* i386 and PCI MEMORY accessible */ + + /* + * Copy the chip description to our device structure, + * so we can make it match the actual device and options. + */ memcpy(&device->chip, chip, sizeof(device->chip)); device->chip.revision_id = revision; - return 0; -} - -/* - * Ignore Symbios chips controlled by various RAID controllers. - * These controllers set value 0x52414944 at RAM end - 16. - */ -static int __devinit sym_check_raid(struct sym_device *device) -{ - unsigned long base_2_c = device->s.base_2_c; - unsigned int ram_size, ram_val; - void *ram_ptr; - - if (!base_2_c) - return 0; - - if (device->chip.features & FE_RAM8K) - ram_size = 8192; - else - ram_size = 4096; - - ram_ptr = ioremap(base_2_c, ram_size); - if (!ram_ptr) - return 0; - - ram_val = readl(ram_ptr + ram_size - 16); - iounmap(ram_ptr); - if (ram_val != 0x52414944) - return 0; - - printf_info("%s: not initializing, driven by RAID controller.\n", - sym_name(device)); - return -ENODEV; -} - -static int __devinit sym_set_workarounds(struct sym_device *device) -{ - struct sym_pci_chip *chip = &device->chip; - struct pci_dev *pdev = device->pdev; - u_short status_reg; - /* + * Some features are required to be enabled in order to + * work around some chip problems. :) ;) * (ITEM 12 of a DEL about the 896 I haven't yet). * We must ensure the chip will use WRITE AND INVALIDATE. * The revision number limit is for now arbitrary. */ - if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && chip->revision_id < 0x4) { + if (device_id == PCI_DEVICE_ID_NCR_53C896 && revision < 0x4) { chip->features |= (FE_WRIE | FE_CLSE); } /* If the chip can do Memory Write Invalidate, enable it */ if (chip->features & FE_WRIE) { if (pci_set_mwi(pdev)) - return -ENODEV; + return -1; } /* @@ -2096,36 +2126,18 @@ } } - return 0; -} - -/* - * Read and check the PCI configuration for any detected NCR - * boards and save data for attaching after all boards have - * been detected. - */ -static void __devinit -sym_init_device(struct pci_dev *pdev, struct sym_device *device) -{ - unsigned long base, base_2; - int i; - - device->pdev = pdev; - device->s.irq = pdev->irq; - - /* Choose some short name for this device */ - sprintf(device->s.inst_name, "sym.%d.%d.%d", pdev->bus->number, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - device->s.io_port = pdev->resource[0].start; - - device->s.base_c = pdev->resource[1].start; - i = pci_get_base_address(pdev, 1, &base); - device->s.base = base & PCI_BASE_ADDRESS_MEM_MASK; + /* + * Initialise device structure with items required by sym_attach. + */ + device->pdev = pdev; + device->s.base = base; + device->s.base_2 = base_2; + device->s.base_c = base_c; + device->s.base_2_c = base_2_c; + device->s.io_port = io_port; + device->s.irq = pdev->irq; - device->s.base_2_c = pdev->resource[i].start; - pci_get_base_address(pdev, i, &base_2); - device->s.base_2 = base_2 & PCI_BASE_ADDRESS_MEM_MASK; + return 0; } /* @@ -2204,7 +2216,7 @@ return 1; } -MODULE_LICENSE("GPL"); +MODULE_LICENSE("Dual BSD/GPL"); MODULE_VERSION(SYM_VERSION); /* @@ -2241,7 +2253,7 @@ memset(&nvram, 0, sizeof(nvram)); if (pci_enable_device(pdev)) - goto leave; + return -ENODEV; pci_set_master(pdev); @@ -2249,15 +2261,7 @@ goto disable; sym_dev.host_id = SYM_SETUP_HOST_ID; - - sym_init_device(pdev, &sym_dev); - if (sym_check_supported(&sym_dev)) - goto free; - - if (sym_check_raid(&sym_dev)) - goto leave; /* Don't disable the device */ - - if (sym_set_workarounds(&sym_dev)) + if (sym53c8xx_pci_init(pdev, &sym_dev)) goto free; sym_config_pqs(pdev, &sym_dev); @@ -2282,7 +2286,6 @@ pci_release_regions(pdev); disable: pci_disable_device(pdev); - leave: return -ENODEV; } @@ -2302,35 +2305,61 @@ attach_count--; } -static void sym2_get_offset(struct scsi_device *sdev) +static void sym2_get_signalling(struct Scsi_Host *shost) +{ + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + enum spi_signal_type type; + + switch (np->scsi_mode) { + case SMODE_SE: + type = SPI_SIGNAL_SE; + break; + case SMODE_LVD: + type = SPI_SIGNAL_LVD; + break; + case SMODE_HVD: + type = SPI_SIGNAL_HVD; + break; + default: + type = SPI_SIGNAL_UNKNOWN; + break; + } + spi_signalling(shost) = type; +} + +static void sym2_get_offset(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_offset(sdev) = tp->tinfo.curr.offset; + spi_offset(starget) = tp->tinfo.curr.offset; } -static void sym2_set_offset(struct scsi_device *sdev, int offset) +static void sym2_set_offset(struct scsi_target *starget, int offset) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; tp->tinfo.goal.offset = offset; } -static void sym2_get_period(struct scsi_device *sdev) +static void sym2_get_period(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_period(sdev) = tp->tinfo.curr.period; + spi_period(starget) = tp->tinfo.curr.period; } -static void sym2_set_period(struct scsi_device *sdev, int period) +static void sym2_set_period(struct scsi_target *starget, int period) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; /* have to have DT for these transfers */ if (period <= np->minsync) @@ -2339,18 +2368,20 @@ tp->tinfo.goal.period = period; } -static void sym2_get_width(struct scsi_device *sdev) +static void sym2_get_width(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_width(sdev) = tp->tinfo.curr.width ? 1 : 0; + spi_width(starget) = tp->tinfo.curr.width ? 1 : 0; } -static void sym2_set_width(struct scsi_device *sdev, int width) +static void sym2_set_width(struct scsi_target *starget, int width) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; /* It is illegal to have DT set on narrow transfers */ if (width == 0) @@ -2359,18 +2390,20 @@ tp->tinfo.goal.width = width; } -static void sym2_get_dt(struct scsi_device *sdev) +static void sym2_get_dt(struct scsi_target *starget) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; - spi_dt(sdev) = (tp->tinfo.curr.options & PPR_OPT_DT) ? 1 : 0; + spi_dt(starget) = (tp->tinfo.curr.options & PPR_OPT_DT) ? 1 : 0; } -static void sym2_set_dt(struct scsi_device *sdev, int dt) +static void sym2_set_dt(struct scsi_target *starget, int dt) { - struct sym_hcb *np = ((struct host_data *)sdev->host->hostdata)->ncb; - struct sym_tcb *tp = &np->target[sdev->id]; + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct sym_hcb *np = ((struct host_data *)shost->hostdata)->ncb; + struct sym_tcb *tp = &np->target[starget->id]; if (dt) tp->tinfo.goal.options |= PPR_OPT_DT; @@ -2392,6 +2425,7 @@ .get_dt = sym2_get_dt, .set_dt = sym2_set_dt, .show_dt = 1, + .get_signalling = sym2_get_signalling, }; static struct pci_device_id sym2_id_table[] __devinitdata = { reverted: --- b/drivers/scsi/sym53c8xx_2/sym_glue.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_glue.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_GLUE_H @@ -76,6 +89,7 @@ #define SYM_OPT_HANDLE_DIR_UNKNOWN #define SYM_OPT_HANDLE_DEVICE_QUEUEING +#define SYM_OPT_NVRAM_PRE_READ #define SYM_OPT_LIMIT_COMMAND_REORDERING #define SYM_OPT_ANNOUNCE_TRANSFER_RATE @@ -93,9 +107,10 @@ #define printf(args...) printk(args) /* + * Insert a delay in micro-seconds and milli-seconds. - * Insert a delay in micro-seconds */ #define sym_udelay(us) udelay(us) +#define sym_mdelay(ms) mdelay(ms) /* * A 'read barrier' flushes any data that have been prefetched reverted: --- b/drivers/scsi/sym53c8xx_2/sym_hipd.c 2004-10-01 19:21:43 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_hipd.c 2004-10-01 19:21:43 -07:00 @@ -3,7 +3,6 @@ * of PCI-SCSI IO processors. * * Copyright (C) 1999-2001 Gerard Roudier - * Copyright (c) 2003-2004 Matthew Wilcox * * This driver is derived from the Linux sym53c8xx driver. * Copyright (C) 1998-2000 Gerard Roudier @@ -23,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * 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 of the License, 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sym_glue.h" #include "sym_nvram.h" @@ -287,6 +299,7 @@ } out: OUTB (nc_scntl1, 0); + /* MDELAY(100); */ return retv; } @@ -1942,7 +1955,7 @@ if (np->features & (FE_ULTRA2|FE_ULTRA3)) { OUTONW (nc_sien, SBMC); if (reason == 0) { + MDELAY(100); - mdelay(100); INW (nc_sist); } np->scsi_mode = INB (nc_stest4) & SMODE; @@ -5505,6 +5518,7 @@ printf ("CCB=%lx STAT=%x/%x/%x DEV=%d/%d\n", (unsigned long)cp, cp->host_status, cp->ssss_status, cp->host_flags, cp->target, cp->lun); + MDELAY(100); } /* @@ -5732,8 +5746,15 @@ /* * Soft-attach the controller. */ +#ifdef SYM_OPT_NVRAM_PRE_READ int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram) +#else +int sym_hcb_attach(hcb_p np, struct sym_fw *fw) +#endif { +#ifndef SYM_OPT_NVRAM_PRE_READ + struct sym_nvram nvram_buf, *nvram = &nvram_buf; +#endif int i; /* @@ -5758,6 +5779,13 @@ * if the chip is currently active. */ sym_chip_reset (np); + + /* + * Try to read the user set-up. + */ +#ifndef SYM_OPT_NVRAM_PRE_READ + (void) sym_read_nvram(np, nvram); +#endif /* * Prepare controller and devices settings, according reverted: --- b/drivers/scsi/sym53c8xx_2/sym_hipd.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_hipd.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_HIPD_H @@ -1108,7 +1121,12 @@ int sym_abort_ccb(hcb_p np, ccb_p cp, int timed_out); int sym_reset_scsi_target(hcb_p np, int target); void sym_hcb_free(hcb_p np); + +#ifdef SYM_OPT_NVRAM_PRE_READ int sym_hcb_attach(hcb_p np, struct sym_fw *fw, struct sym_nvram *nvram); +#else +int sym_hcb_attach(hcb_p np, struct sym_fw *fw); +#endif /* * Optionnaly, the driver may handle IO timeouts. @@ -1332,6 +1350,7 @@ #define PRINT_ADDR sym_print_addr #define PRINT_TARGET sym_print_target #define PRINT_LUN sym_print_lun +#define MDELAY sym_mdelay #define UDELAY sym_udelay #endif /* SYM_HIPD_H */ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_malloc.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_malloc.c 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_misc.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_misc.c 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef __FreeBSD__ reverted: --- b/drivers/scsi/sym53c8xx_2/sym_misc.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_misc.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_MISC_H reverted: --- b/drivers/scsi/sym53c8xx_2/sym_nvram.c 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_nvram.c 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sym_glue.h" reverted: --- b/drivers/scsi/sym53c8xx_2/sym_nvram.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_2/sym_nvram.h 2004-10-01 19:21:44 -07:00 @@ -22,19 +22,32 @@ * *----------------------------------------------------------------------------- * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. - * 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 of the License, or - * (at your option) any later version. * + * Where this Software is combined with software released under the terms of + * the GNU Public License ("GPL") and the terms of the GPL would require the + * combined work to also be released under the terms of the GPL, the terms + * and conditions of this License will apply in addition to those of the + * GPL with the exception of any terms or conditions of this License that + * conflict with, or are expressly prohibited by, the GPL. - * 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. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SYM_NVRAM_H reverted: --- b/drivers/scsi/sym53c8xx_comm.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_comm.h 2004-10-01 19:21:44 -07:00 @@ -54,6 +54,57 @@ ******************************************************************************* */ +/* +** This file contains definitions and code that the +** sym53c8xx and ncr53c8xx drivers should share. +** The sharing will be achieved in a further version +** of the driver bundle. For now, only the ncr53c8xx +** driver includes this file. +*/ + +/*========================================================== +** +** Hmmm... What complex some PCI-HOST bridges actually +** are, despite the fact that the PCI specifications +** are looking so smart and simple! ;-) +** +**========================================================== +*/ + +/*========================================================== +** +** Miscallaneous defines. +** +**========================================================== +*/ + +#define u_char unsigned char +#define u_long unsigned long + +#ifndef bzero +#define bzero(d, n) memset((d), 0, (n)) +#endif + +/*========================================================== +** +** assert () +** +**========================================================== +** +** modified copy from 386bsd:/usr/include/sys/assert.h +** +**---------------------------------------------------------- +*/ + +#define assert(expression) { \ + if (!(expression)) { \ + (void)panic( \ + "assertion \"%s\" failed: file \"%s\", line %d\n", \ + #expression, \ + __FILE__, __LINE__); \ + } \ +} + /*========================================================== ** ** Debugging tags @@ -86,22 +137,170 @@ #define DEBUG_FLAGS SCSI_NCR_DEBUG_FLAGS #endif +/*========================================================== +** +** A la VMS/CAM-3 queue management. +** Implemented from linux list management. +** +**========================================================== +*/ + +typedef struct xpt_quehead { + struct xpt_quehead *flink; /* Forward pointer */ + struct xpt_quehead *blink; /* Backward pointer */ +} XPT_QUEHEAD; + +#define xpt_que_init(ptr) do { \ + (ptr)->flink = (ptr); (ptr)->blink = (ptr); \ +} while (0) + +static inline void __xpt_que_add(struct xpt_quehead * new, + struct xpt_quehead * blink, + struct xpt_quehead * flink) +{ + flink->blink = new; + new->flink = flink; + new->blink = blink; + blink->flink = new; +} + +static inline void __xpt_que_del(struct xpt_quehead * blink, + struct xpt_quehead * flink) +{ + flink->blink = blink; + blink->flink = flink; +} + +static inline int xpt_que_empty(struct xpt_quehead *head) +{ + return head->flink == head; +} + +static inline void xpt_que_splice(struct xpt_quehead *list, + struct xpt_quehead *head) -static inline struct list_head *ncr_list_pop(struct list_head *head) { + struct xpt_quehead *first = list->flink; + + if (first != list) { + struct xpt_quehead *last = list->blink; + struct xpt_quehead *at = head->flink; - if (!list_empty(head)) { - struct list_head *elem = head->next; + first->blink = head; + head->flink = first; + + last->flink = at; + at->blink = last; - list_del(elem); - return elem; } +} + +#define xpt_que_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + + +#define xpt_insque(new, pos) __xpt_que_add(new, pos, (pos)->flink) + +#define xpt_remque(el) __xpt_que_del((el)->blink, (el)->flink) + +#define xpt_insque_head(new, head) __xpt_que_add(new, head, (head)->flink) + +static inline struct xpt_quehead *xpt_remque_head(struct xpt_quehead *head) +{ + struct xpt_quehead *elem = head->flink; + + if (elem != head) + __xpt_que_del(head, elem->flink); + else + elem = NULL; + return elem; +} + +#define xpt_insque_tail(new, head) __xpt_que_add(new, (head)->blink, head) +static inline struct xpt_quehead *xpt_remque_tail(struct xpt_quehead *head) +{ + struct xpt_quehead *elem = head->blink; + + if (elem != head) + __xpt_que_del(elem->blink, head); + else + elem = 0; + return elem; - return NULL; } + +/*========================================================== +** +** SMP threading. +** +** Assuming that SMP systems are generally high end +** systems and may use several SCSI adapters, we are +** using one lock per controller instead of some global +** one. For the moment (linux-2.1.95), driver's entry +** points are called with the 'io_request_lock' lock +** held, so: +** - We are uselessly loosing a couple of micro-seconds +** to lock the controller data structure. +** - But the driver is not broken by design for SMP and +** so can be more resistant to bugs or bad changes in +** the IO sub-system code. +** - A small advantage could be that the interrupt code +** is grained as wished (e.g.: by controller). +** +**========================================================== +*/ + +spinlock_t DRIVER_SMP_LOCK = SPIN_LOCK_UNLOCKED; +#define NCR_LOCK_DRIVER(flags) spin_lock_irqsave(&DRIVER_SMP_LOCK, flags) +#define NCR_UNLOCK_DRIVER(flags) \ + spin_unlock_irqrestore(&DRIVER_SMP_LOCK, flags) + +#define NCR_INIT_LOCK_NCB(np) spin_lock_init(&np->smp_lock) +#define NCR_LOCK_NCB(np, flags) spin_lock_irqsave(&np->smp_lock, flags) +#define NCR_UNLOCK_NCB(np, flags) spin_unlock_irqrestore(&np->smp_lock, flags) + +#define NCR_LOCK_SCSI_DONE(host, flags) \ + spin_lock_irqsave((host)->host_lock, flags) +#define NCR_UNLOCK_SCSI_DONE(host, flags) \ + spin_unlock_irqrestore(((host)->host_lock), flags) + +/*========================================================== +** +** Memory mapped IO +** +** Since linux-2.1, we must use ioremap() to map the io +** memory space and iounmap() to unmap it. This allows +** portability. Linux 1.3.X and 2.0.X allow to remap +** physical pages addresses greater than the highest +** physical memory address to kernel virtual pages with +** vremap() / vfree(). That was not portable but worked +** with i386 architecture. +** +**========================================================== +*/ + #ifdef __sparc__ #include #endif +#define memcpy_to_pci(a, b, c) memcpy_toio((a), (b), (c)) + +/*========================================================== +** +** Insert a delay in micro-seconds and milli-seconds. +** +** Under Linux, udelay() is restricted to delay < +** 1 milli-second. In fact, it generally works for up +** to 1 second delay. Since 2.1.105, the mdelay() function +** is provided for delays in milli-seconds. +** Under 2.0 kernels, udelay() is an inline function +** that is very inaccurate on Pentium processors. +** +**========================================================== +*/ + +#define UDELAY udelay +#define MDELAY mdelay + /*========================================================== ** ** Simple power of two buddy-like allocator. @@ -120,6 +319,8 @@ **========================================================== */ +#define __GetFreePages(flags, order) __get_free_pages(flags, order) + #define MEMO_SHIFT 4 /* 16 bytes minimum memory chunk */ #if PAGE_SIZE >= 8192 #define MEMO_PAGE_ORDER 0 /* 1 PAGE maximum */ @@ -155,6 +356,10 @@ m_bush_t bush; m_addr_t (*getp)(struct m_pool *); void (*freep)(struct m_pool *, m_addr_t); +#define M_GETP() mp->getp(mp) +#define M_FREEP(p) mp->freep(mp, p) +#define GetPages() __GetFreePages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER) +#define FreePages(p) free_pages(p, MEMO_PAGE_ORDER) int nump; m_vtob_s *(vtob[VTOB_HASH_SIZE]); struct m_pool *next; @@ -180,7 +385,7 @@ j = i; while (!h[j].next) { if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { + h[j].next = (m_link_s *) M_GETP(); - h[j].next = (m_link_s *)mp->getp(mp); if (h[j].next) h[j].next->next = NULL; break; @@ -229,7 +434,7 @@ while (1) { #ifdef MEMO_FREE_UNUSED if (s == (PAGE_SIZE << MEMO_PAGE_ORDER)) { + M_FREEP(a); - mp->freep(mp, a); break; } #endif @@ -250,8 +455,6 @@ } } -static spinlock_t ncr53c8xx_lock = SPIN_LOCK_UNLOCKED; - static void *__m_calloc2(m_pool_s *mp, int size, char *name, int uflags) { void *p; @@ -262,7 +465,7 @@ printk ("new %-10s[%4d] @%p.\n", name, size, p); if (p) + bzero(p, size); - memset(p, 0, size); else if (uflags & MEMO_WARN) printk (NAME53C8XX ": failed to allocate %s[%d]\n", name, size); @@ -288,7 +491,7 @@ static m_addr_t ___mp0_getp(m_pool_s *mp) { + m_addr_t m = GetPages(); - m_addr_t m = __get_free_pages(MEMO_GFP_FLAGS, MEMO_PAGE_ORDER); if (m) ++mp->nump; return m; @@ -296,7 +499,7 @@ static void ___mp0_freep(m_pool_s *mp, m_addr_t m) { + FreePages(m); - free_pages(m, MEMO_PAGE_ORDER); --mp->nump; } @@ -366,7 +569,7 @@ m_pool_s *mp; mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL"); if (mp) { + bzero(mp, sizeof(*mp)); - memset(mp, 0, sizeof(*mp)); mp->bush = bush; mp->getp = ___dma_getp; mp->freep = ___dma_freep; @@ -394,7 +597,7 @@ struct m_pool *mp; void *m = NULL; + NCR_LOCK_DRIVER(flags); - spin_lock_irqsave(&ncr53c8xx_lock, flags); mp = ___get_dma_pool(bush); if (!mp) mp = ___cre_dma_pool(bush); @@ -402,7 +605,7 @@ m = __m_calloc(mp, size, name); if (mp && !mp->nump) ___del_dma_pool(mp); + NCR_UNLOCK_DRIVER(flags); - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); return m; } @@ -412,13 +615,13 @@ u_long flags; struct m_pool *mp; + NCR_LOCK_DRIVER(flags); - spin_lock_irqsave(&ncr53c8xx_lock, flags); mp = ___get_dma_pool(bush); if (mp) __m_free(mp, m, size, name); if (mp && !mp->nump) ___del_dma_pool(mp); + NCR_UNLOCK_DRIVER(flags); - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); } static m_addr_t __vtobus(m_bush_t bush, void *m) @@ -429,14 +632,14 @@ m_vtob_s *vp = NULL; m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; + NCR_LOCK_DRIVER(flags); - spin_lock_irqsave(&ncr53c8xx_lock, flags); mp = ___get_dma_pool(bush); if (mp) { vp = mp->vtob[hc]; while (vp && (m_addr_t) vp->vaddr != a) vp = vp->next; } + NCR_UNLOCK_DRIVER(flags); - spin_unlock_irqrestore(&ncr53c8xx_lock, flags); return vp ? vp->baddr + (((m_addr_t) m) - a) : 0; } @@ -455,89 +658,100 @@ #define __data_mapped SCp.phase #define __data_mapping SCp.have_data_in +static void __unmap_scsi_data(struct device *dev, Scsi_Cmnd *cmd) -static void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd) { + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); + switch(cmd->__data_mapped) { case 2: + dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, dma_dir); - dma_unmap_sg(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); break; case 1: dma_unmap_single(dev, cmd->__data_mapping, + cmd->request_bufflen, dma_dir); - cmd->request_bufflen, - cmd->sc_data_direction); break; } cmd->__data_mapped = 0; } +static u_long __map_scsi_single_data(struct device *dev, Scsi_Cmnd *cmd) -static u_long __map_scsi_single_data(struct device *dev, struct scsi_cmnd *cmd) { dma_addr_t mapping; + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); + if (cmd->request_bufflen == 0) return 0; mapping = dma_map_single(dev, cmd->request_buffer, + cmd->request_bufflen, dma_dir); - cmd->request_bufflen, - cmd->sc_data_direction); cmd->__data_mapped = 1; cmd->__data_mapping = mapping; return mapping; } +static int __map_scsi_sg_data(struct device *dev, Scsi_Cmnd *cmd) -static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd) { int use_sg; + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); if (cmd->use_sg == 0) return 0; + use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, dma_dir); - use_sg = dma_map_sg(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); cmd->__data_mapped = 2; cmd->__data_mapping = use_sg; return use_sg; } +static void __sync_scsi_data_for_cpu(struct device *dev, Scsi_Cmnd *cmd) -static void __sync_scsi_data_for_cpu(struct device *dev, struct scsi_cmnd *cmd) { + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); + switch(cmd->__data_mapped) { case 2: + dma_sync_sg_for_cpu(dev, cmd->buffer, cmd->use_sg, dma_dir); - dma_sync_sg_for_cpu(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); break; case 1: dma_sync_single_for_cpu(dev, cmd->__data_mapping, + cmd->request_bufflen, dma_dir); - cmd->request_bufflen, - cmd->sc_data_direction); break; } } +static void __sync_scsi_data_for_device(struct device *dev, Scsi_Cmnd *cmd) -static void __sync_scsi_data_for_device(struct device *dev, struct scsi_cmnd *cmd) { + enum dma_data_direction dma_dir = + (enum dma_data_direction)scsi_to_pci_dma_dir(cmd->sc_data_direction); + switch(cmd->__data_mapped) { case 2: + dma_sync_sg_for_device(dev, cmd->buffer, cmd->use_sg, dma_dir); - dma_sync_sg_for_device(dev, cmd->buffer, cmd->use_sg, - cmd->sc_data_direction); break; case 1: dma_sync_single_for_device(dev, cmd->__data_mapping, + cmd->request_bufflen, dma_dir); - cmd->request_bufflen, - cmd->sc_data_direction); break; } } +#define scsi_sg_dma_address(sc) sg_dma_address(sc) +#define scsi_sg_dma_len(sc) sg_dma_len(sc) + #define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd) #define map_scsi_single_data(np, cmd) __map_scsi_single_data(np->dev, cmd) #define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd) #define sync_scsi_data_for_cpu(np, cmd) __sync_scsi_data_for_cpu(np->dev, cmd) #define sync_scsi_data_for_device(np, cmd) __sync_scsi_data_for_device(np->dev, cmd) +#define scsi_data_direction(cmd) (cmd->sc_data_direction) + /*========================================================== ** ** Driver setup. @@ -559,6 +773,58 @@ #define initverbose (driver_setup.verbose) #define bootverbose (np->verbose) + +/*=================================================================== +** +** Utility routines that protperly return data through /proc FS. +** +**=================================================================== +*/ +#ifdef SCSI_NCR_USER_INFO_SUPPORT + +struct info_str +{ + char *buffer; + int length; + int offset; + int pos; +}; + +static void copy_mem_info(struct info_str *info, char *data, int len) +{ + if (info->pos + len > info->length) + len = info->length - info->pos; + + if (info->pos + len < info->offset) { + info->pos += len; + return; + } + if (info->pos < info->offset) { + data += (info->offset - info->pos); + len -= (info->offset - info->pos); + } + + if (len > 0) { + memcpy(info->buffer + info->pos, data, len); + info->pos += len; + } +} + +static int copy_info(struct info_str *info, char *fmt, ...) +{ + va_list args; + char buf[81]; + int len; + + va_start(args, fmt); + len = vsprintf(buf, fmt, args); + va_end(args); + + copy_mem_info(info, buf, len); + return len; +} + +#endif /*=================================================================== ** reverted: --- b/drivers/scsi/sym53c8xx_defs.h 2004-10-01 19:21:44 -07:00 +++ a/drivers/scsi/sym53c8xx_defs.h 2004-10-01 19:21:44 -07:00 @@ -66,12 +66,19 @@ #include +/* These options are not tunable from 'make config' */ +#define SCSI_NCR_PROC_INFO_SUPPORT + /* ** If you want a driver as small as possible, donnot define the ** following options. */ #define SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT #define SCSI_NCR_DEBUG_INFO_SUPPORT +#ifdef SCSI_NCR_PROC_INFO_SUPPORT +# define SCSI_NCR_USER_COMMAND_SUPPORT +# define SCSI_NCR_USER_INFO_SUPPORT +#endif /* ** To disable integrity checking, do not define the diff -u b/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- b/drivers/scsi/tmscsim.c 2004-10-01 19:21:44 -07:00 +++ b/drivers/scsi/tmscsim.c 2004-10-01 19:23:17 -07:00 @@ -388,6 +388,22 @@ * Lists are managed using two pointers and eventually a counter */ +/* Return next free SRB */ +static __inline__ struct dc390_srb* dc390_Free_get ( struct dc390_acb* pACB ) +{ + struct dc390_srb* pSRB; + + pSRB = pACB->pFreeSRB; + DEBUG0(printk ("DC390: Get Free SRB %p\n", pSRB)); + if( pSRB ) + { + pACB->pFreeSRB = pSRB->pNextSRB; + pSRB->pNextSRB = NULL; + } + + return( pSRB ); +} + /* Insert SRB oin top of free list */ static __inline__ void dc390_Free_insert (struct dc390_acb* pACB, struct dc390_srb* pSRB) { @@ -409,6 +425,21 @@ } +/* Queue SRB to waiting list */ +static __inline__ void dc390_Waiting_append ( struct dc390_dcb* pDCB, struct dc390_srb* pSRB) +{ + DEBUG0(printk ("DC390: Append pSRB %p cmd %li to Waiting\n", pSRB, pSRB->pcmd->pid)); + if( pDCB->pWaitingSRB ) + pDCB->pWaitLast->pNextSRB = pSRB; + else + pDCB->pWaitingSRB = pSRB; + + pDCB->pWaitLast = pSRB; + pSRB->pNextSRB = NULL; + pDCB->WaitSRBCnt++; + pDCB->pDCBACB->CmdInQ++; +} + static __inline__ void dc390_Going_append (struct dc390_dcb* pDCB, struct dc390_srb* pSRB) { pDCB->GoingSRBCnt++; @@ -528,6 +559,47 @@ spin_unlock_irqrestore(pACB->pScsiHost->host_lock, iflags); } +/*********************************************************************** + * Function: static void dc390_SendSRB (struct dc390_acb* pACB, struct dc390_srb* pSRB) + * + * Purpose: Send SCSI Request Block (pSRB) to adapter (pACB) + * + ***********************************************************************/ + +static void dc390_SendSRB( struct dc390_acb* pACB, struct dc390_srb* pSRB ) +{ + struct dc390_dcb* pDCB; + + pDCB = pSRB->pSRBDCB; + if( (pDCB->MaxCommand <= pDCB->GoingSRBCnt) || (pACB->pActiveDCB) || + (pACB->ACBFlag & (RESET_DETECT+RESET_DONE+RESET_DEV)) ) + { + dc390_Waiting_append (pDCB, pSRB); + dc390_Waiting_process (pACB); + return; + } + +#if 0 + if( pDCB->pWaitingSRB ) + { + dc390_Waiting_append (pDCB, pSRB); +/* pSRB = GetWaitingSRB(pDCB); */ /* non-existent */ + pSRB = pDCB->pWaitingSRB; + /* Remove from waiting list */ + pDCB->pWaitingSRB = pSRB->pNextSRB; + pSRB->pNextSRB = NULL; + if (!pDCB->pWaitingSRB) pDCB->pWaitLast = NULL; + } +#endif + + if (!dc390_StartSCSI(pACB, pDCB, pSRB)) + dc390_Going_append (pDCB, pSRB); + else { + dc390_Waiting_insert (pDCB, pSRB); + dc390_waiting_timer (pACB, HZ/5); + } +} + static struct scatterlist* dc390_sg_build_single(struct scatterlist *sg, void *addr, unsigned int length) { memset(sg, 0, sizeof(struct scatterlist)); @@ -603,72 +675,86 @@ } } -static int DC390_queuecommand(struct scsi_cmnd *cmd, - void (*done)(struct scsi_cmnd *)) -{ - struct scsi_device *sdev = cmd->device; - struct dc390_acb *acb = (struct dc390_acb *)sdev->host->hostdata; - struct dc390_dcb *dcb = sdev->hostdata; - struct dc390_srb *srb; - - if (dcb->pWaitingSRB) - goto device_busy; - if (dcb->MaxCommand <= dcb->GoingSRBCnt) - goto device_busy; - if (acb->pActiveDCB) - goto host_busy; - if (acb->ACBFlag & (RESET_DETECT|RESET_DONE|RESET_DEV)) - goto host_busy; - - srb = acb->pFreeSRB; - if (unlikely(srb == NULL)) - goto host_busy; - - cmd->scsi_done = done; - cmd->result = 0; - acb->Cmds++; - acb->pFreeSRB = srb->pNextSRB; - srb->pNextSRB = NULL; +/*********************************************************************** + * Function: static void dc390_BuildSRB (Scsi_Cmd *pcmd, struct dc390_dcb* pDCB, + * struct dc390_srb* pSRB) + * + * Purpose: Prepare SRB for being sent to Device DCB w/ command *pcmd + * + ***********************************************************************/ - srb->pSRBDCB = dcb; - srb->pcmd = cmd; +static void dc390_BuildSRB (struct scsi_cmnd *pcmd, struct dc390_dcb* pDCB, struct dc390_srb* pSRB) +{ + pSRB->pSRBDCB = pDCB; + pSRB->pcmd = pcmd; - srb->SGIndex = 0; - srb->AdaptStatus = 0; - srb->TargetStatus = 0; - srb->MsgCnt = 0; - if (dcb->DevType == TYPE_TAPE) - srb->RetryCnt = 0; - else - srb->RetryCnt = 1; - srb->SRBStatus = 0; - srb->SRBFlag = 0; - srb->SRBState = 0; - srb->TotalXferredLen = 0; - srb->SGBusAddr = 0; - srb->SGToBeXferLen = 0; - srb->ScsiPhase = 0; - srb->EndMessage = 0; - srb->TagNumber = 255; - - if (dc390_StartSCSI(acb, dcb, srb)) { - dc390_Waiting_insert(dcb, srb); - dc390_waiting_timer(acb, HZ/5); - goto done; - } + pSRB->SGIndex = 0; + pSRB->AdaptStatus = 0; + pSRB->TargetStatus = 0; + pSRB->MsgCnt = 0; + if( pDCB->DevType != TYPE_TAPE ) + pSRB->RetryCnt = 1; + else + pSRB->RetryCnt = 0; + pSRB->SRBStatus = 0; + pSRB->SRBFlag = 0; + pSRB->SRBState = 0; + pSRB->TotalXferredLen = 0; + pSRB->SGBusAddr = 0; + pSRB->SGToBeXferLen = 0; + pSRB->ScsiPhase = 0; + pSRB->EndMessage = 0; + pSRB->TagNumber = 255; + /* KG: deferred PCI mapping to dc390_StartSCSI */ +} - dc390_Going_append(dcb, srb); - done: - return 0; +/*********************************************************************** + * Function : static int DC390_queue_command (struct scsi_cmnd *cmd, + * void (*done)(struct scsi_cmnd *)) + * + * Purpose : enqueues a SCSI command + * + * Inputs : cmd - SCSI command, done - callback function called on + * completion, with a pointer to the command descriptor. + * + * Returns : (depending on kernel version) + * 2.0.x: always return 0 + * 2.1.x: old model: (use_new_eh_code == 0): like 2.0.x + * TO BE DONE: + * new model: return 0 if successful, or must not be re-queued + * return 1 if command cannot be queued (queue full) + * command will be inserted in midlevel queue then ... + * + ***********************************************************************/ - host_busy: - dc390_Waiting_process(acb); - return SCSI_MLQUEUE_HOST_BUSY; - - device_busy: - dc390_Waiting_process(acb); - return SCSI_MLQUEUE_DEVICE_BUSY; +static int DC390_queue_command(struct scsi_cmnd *cmd, + void (* done)(struct scsi_cmnd *)) +{ + struct dc390_dcb* pDCB = (struct dc390_dcb*) cmd->device->hostdata; + struct dc390_srb* pSRB; + struct dc390_acb* pACB = (struct dc390_acb*) cmd->device->host->hostdata; + + pACB->Cmds++; + cmd->scsi_done = done; + cmd->result = 0; + + pSRB = dc390_Free_get(pACB); + if (!pSRB) + goto requeue; + + dc390_BuildSRB(cmd, pDCB, pSRB); + if (pDCB->pWaitingSRB) { + dc390_Waiting_append(pDCB, pSRB); + dc390_Waiting_process(pACB); + } else + dc390_SendSRB(pACB, pSRB); + + DEBUG1(printk (KERN_DEBUG " ... command (pid %li) queued successfully.\n", cmd->pid)); + return(0); + + requeue: + return 1; } static void dc390_dumpinfo (struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* pSRB) @@ -979,7 +1065,7 @@ .slave_alloc = dc390_slave_alloc, .slave_configure = dc390_slave_configure, .slave_destroy = dc390_slave_destroy, - .queuecommand = DC390_queuecommand, + .queuecommand = DC390_queue_command, .eh_abort_handler = DC390_abort, .eh_bus_reset_handler = DC390_bus_reset, .can_queue = 42, @@ -989,204 +1075,164 @@ .use_clustering = DISABLE_CLUSTERING, }; -/*********************************************************************** - * Functions for access to DC390 EEPROM - * and some to emulate it - * - **********************************************************************/ - - -static void __devinit dc390_EnDisableCE(u8 mode, struct pci_dev *pdev, u8 *regval) +static void __devinit dc390_eeprom_prepare_read(struct pci_dev *pdev, u8 cd) { - u8 bval; - - bval = 0; - if(mode == ENABLE_CE) - *regval = 0xc0; - else - *regval = 0x80; - pci_write_config_byte(pdev, *regval, bval); - if(mode == DISABLE_CE) - pci_write_config_byte(pdev, *regval, bval); - udelay(160); -} + u8 carryFlag = 1, j = 0x80, i, bval, regval; + for (i = 0; i < 9; i++) { + if (carryFlag) { + bval = 0x40; + regval = 0x80; + + pci_write_config_byte(pdev, regval, bval); + } else { + bval = 0; + regval = 0xc0; + } + + udelay(160); + pci_write_config_byte(pdev, regval, bval | 0x80); + udelay(160); + pci_write_config_byte(pdev, regval, 0); + udelay(160); -/* Override EEprom values with explicitly set values */ -static void __devinit dc390_EEprom_Override (u8 index) -{ - u8 *ptr = (u8 *) dc390_eepromBuf[index]; - u8 id; - - /* Adapter Settings */ - if (tmscsim[0] != -2) - ptr[EE_ADAPT_SCSI_ID] = (u8)tmscsim[0]; /* Adapter ID */ - if (tmscsim[3] != -2) - ptr[EE_MODE2] = (u8)tmscsim[3]; - if (tmscsim[5] != -2) - ptr[EE_DELAY] = tmscsim[5]; /* Reset delay */ - if (tmscsim[4] != -2) - ptr[EE_TAG_CMD_NUM] = (u8)tmscsim[4]; /* Tagged Cmds */ - - /* Device Settings */ - for (id = 0; id < MAX_SCSI_ID; id++) - { - if (tmscsim[2] != -2) - ptr[id<<2] = (u8)tmscsim[2]; /* EE_MODE1 */ - if (tmscsim[1] != -2) - ptr[(id<<2) + 1] = (u8)tmscsim[1]; /* EE_Speed */ - } + carryFlag = (cmd & j) ? 1 : 0; + j >>= 1; + } } -/* Handle "-1" case */ -static void __devinit dc390_check_for_safe_settings (void) +static u16 __devinit dc390_eeprom_get_data(struct pci_dev *pdev) { - if (tmscsim[0] == -1 || tmscsim[0] > 15) /* modules-2.0.0 passes -1 as string */ - { - tmscsim[0] = 7; tmscsim[1] = 4; - tmscsim[2] = 0x09; tmscsim[3] = 0x0f; - tmscsim[4] = 2; tmscsim[5] = 10; - printk (KERN_INFO "DC390: Using safe settings.\n"); - } -} + u8 wval = 0, bval, i; + for (i = 0; i < 16; i++) { + wval <<= 1; -static int __initdata tmscsim_def[] = {7, 0 /* 10MHz */, - PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_ - | SYNC_NEGO_ | TAG_QUEUEING_, - MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION - /* | NO_SEEK */ -# ifdef CONFIG_SCSI_MULTI_LUN - | LUN_CHECK -# endif - , 3 /* 16 Tags per LUN */, 1 /* s delay after Reset */ }; + pci_write_config_byte(pdev, 0x80, 0x80); + udelay(160); + pci_write_config_byte(pdev, 0x80, 0x40); + udelay(160); + pci_read_config_byte(pdev, 0x00, &bval); -/* Copy defaults over set values where missing */ -static void __devinit dc390_fill_with_defaults (void) -{ - int i; - PARSEDEBUG(printk(KERN_INFO "DC390: setup %08x %08x %08x %08x %08x %08x\n", tmscsim[0],\ - tmscsim[1], tmscsim[2], tmscsim[3], tmscsim[4], tmscsim[5])); - for (i = 0; i < 6; i++) - { - if (tmscsim[i] < 0 || tmscsim[i] > 255) - tmscsim[i] = tmscsim_def[i]; + wval |= ((bval == 0x22) ? 1 : 0); } - /* Sanity checks */ - if (tmscsim[0] > 7) tmscsim[0] = 7; - if (tmscsim[1] > 7) tmscsim[1] = 4; - if (tmscsim[4] > 5) tmscsim[4] = 4; - if (tmscsim[5] > 180) tmscsim[5] = 180; + + return wval; } -static void __devinit dc390_EEpromOutDI(struct pci_dev *pdev, u8 *regval, u8 Carry) +static void __devinit dc390_read_eeprom(struct pci_dev *pdev, u16 *ptr) { - u8 bval; + u8 cmd = EEPROM_READ, i; - bval = 0; - if(Carry) - { - bval = 0x40; - *regval = 0x80; - pci_write_config_byte(pdev, *regval, bval); - } - udelay(160); - bval |= 0x80; - pci_write_config_byte(pdev, *regval, bval); - udelay(160); - bval = 0; - pci_write_config_byte(pdev, *regval, bval); - udelay(160); + for (i = 0; i < 0x40; i++) { + pci_write_config_byte(pdev, 0xc0, 0); + udelay(160); + + dc390_eeprom_prepare_read(pdev, cmd++); + *ptr++ = dc390_eeprom_get_data(pdev); + + pci_write_config_byte(pdev, 0x80, 0); + pci_write_config_byte(pdev, 0x80, 0); + udelay(160); + } } - -static u8 __devinit dc390_EEpromInDO(struct pci_dev *pdev) +/* Override EEprom values with explicitly set values */ +static void __devinit dc390_eeprom_override(u8 index) { - u8 bval; - - pci_write_config_byte(pdev, 0x80, 0x80); - udelay(160); - pci_write_config_byte(pdev, 0x80, 0x40); - udelay(160); - pci_read_config_byte(pdev, 0x00, &bval); - if(bval == 0x22) - return(1); - else - return(0); + u8 *ptr = (u8 *) dc390_eepromBuf[index], id; + + /* Adapter Settings */ + if (tmscsim[0] != -2) + ptr[EE_ADAPT_SCSI_ID] = (u8)tmscsim[0]; /* Adapter ID */ + if (tmscsim[3] != -2) + ptr[EE_MODE2] = (u8)tmscsim[3]; + if (tmscsim[5] != -2) + ptr[EE_DELAY] = tmscsim[5]; /* Reset delay */ + if (tmscsim[4] != -2) + ptr[EE_TAG_CMD_NUM] = (u8)tmscsim[4]; /* Tagged Cmds */ + + /* Device Settings */ + for (id = 0; id < MAX_SCSI_ID; id++) { + if (tmscsim[2] != -2) + ptr[id<<2] = (u8)tmscsim[2]; /* EE_MODE1 */ + if (tmscsim[1] != -2) + ptr[(id<<2) + 1] = (u8)tmscsim[1];/* EE_Speed */ + } } +static int __devinitdata tmscsim_def[] = { + 7, + 0 /* 10MHz */, + PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_ | SYNC_NEGO_ | TAG_QUEUEING_, + MORE2_DRV | GREATER_1G | RST_SCSI_BUS | ACTIVE_NEGATION | LUN_CHECK, + 3 /* 16 Tags per LUN */, + 1 /* s delay after Reset */, +}; -static u16 __devinit dc390_EEpromGetData1(struct pci_dev *pdev) +/* Copy defaults over set values where missing */ +static void __devinit dc390_fill_with_defaults (void) { - u8 i; - u8 carryFlag; - u16 wval; - - wval = 0; - for(i=0; i<16; i++) - { - wval <<= 1; - carryFlag = dc390_EEpromInDO(pdev); - wval |= carryFlag; - } - return(wval); -} + int i; -static void __devinit dc390_Prepare(struct pci_dev *pdev, u8 *regval, u8 EEpromCmd) -{ - u8 i,j; - u8 carryFlag; + for (i = 0; i < 6; i++) { + if (tmscsim[i] < 0 || tmscsim[i] > 255) + tmscsim[i] = tmscsim_def[i]; + } - carryFlag = 1; - j = 0x80; - for(i=0; i<9; i++) - { - dc390_EEpromOutDI(pdev, regval, carryFlag); - carryFlag = (EEpromCmd & j) ? 1 : 0; - j >>= 1; - } + /* Sanity checks */ + if (tmscsim[0] > 7) + tmscsim[0] = 7; + if (tmscsim[1] > 7) + tmscsim[1] = 4; + if (tmscsim[4] > 5) + tmscsim[4] = 4; + if (tmscsim[5] > 180) + tmscsim[5] = 180; } - -static void __devinit dc390_ReadEEprom(struct pci_dev *pdev, u16 *ptr) +static void __devinit dc390_check_eeprom(struct pci_dev *pdev, u8 index) { - u8 regval,cmd; - u8 i; + char interpd[] = { 1, 3, 5, 10, 16, 30, 60, 120 }; + char EEbuf[128]; + u16 *ptr = (u16 *)EEbuf, wval = 0; + u8 i; + + dc390_read_eeprom(pdev, ptr); + memcpy(dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID); + memcpy(&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], + &EEbuf[REAL_EE_ADAPT_SCSI_ID], + EE_LEN - EE_ADAPT_SCSI_ID); + + dc390_eepromBuf[index][EE_DELAY] = + interpd[dc390_eepromBuf[index][EE_DELAY]]; + + for (i = 0; i < 0x40; i++, ptr++) + wval += *ptr; - cmd = EEPROM_READ; - for(i=0; i<0x40; i++) - { - dc390_EnDisableCE(ENABLE_CE, pdev, ®val); - dc390_Prepare(pdev, ®val, cmd++); - *ptr++ = dc390_EEpromGetData1(pdev); - dc390_EnDisableCE(DISABLE_CE, pdev, ®val); - } -} + /* no Tekram EEprom found */ + if (wval != 0x1234) { + int speed; + printk(KERN_INFO "DC390_init: No EEPROM found! " + "Trying default settings ...\n"); -static void __devinit dc390_interpret_delay (u8 index) -{ - char interpd [] = {1,3,5,10,16,30,60,120}; - dc390_eepromBuf[index][EE_DELAY] = interpd [dc390_eepromBuf[index][EE_DELAY]]; -} + /* + * XXX(hch): bogus, because we might have tekram and + * non-tekram hbas in a single machine. + */ + dc390_fill_with_defaults(); -static u8 __devinit dc390_CheckEEpromCheckSum(struct pci_dev *pdev, u8 index) -{ - u8 i; - char EEbuf[128]; - u16 wval, *ptr = (u16 *)EEbuf; - - dc390_ReadEEprom(pdev, ptr); - memcpy (dc390_eepromBuf[index], EEbuf, EE_ADAPT_SCSI_ID); - memcpy (&dc390_eepromBuf[index][EE_ADAPT_SCSI_ID], - &EEbuf[REAL_EE_ADAPT_SCSI_ID], EE_LEN - EE_ADAPT_SCSI_ID); - dc390_interpret_delay (index); - - wval = 0; - for(i=0; i<0x40; i++, ptr++) - wval += *ptr; - return (wval == 0x1234 ? 0 : 1); + speed = dc390_clock_speed[tmscsim[1]]; + printk(KERN_INFO "DC390: Used defaults: AdaptID=%i, " + "SpeedIdx=%i (%i.%i MHz)," + " DevMode=0x%02x, AdaptMode=0x%02x, " + "TaggedCmnds=%i (%i), DelayReset=%is\n", + tmscsim[0], tmscsim[1], speed/10, speed%10, + (u8)tmscsim[2], (u8)tmscsim[3], tmscsim[4], + 2 << (tmscsim[4]), tmscsim[5]); + } } static void __devinit dc390_init_hw(struct dc390_acb *pACB, u8 index) @@ -1260,21 +1306,8 @@ pACB = (struct dc390_acb *)shost->hostdata; memset(pACB, 0, sizeof(struct dc390_acb)); - if (dc390_CheckEEpromCheckSum(pdev, dc390_adapterCnt)) { - int speed; - printk(KERN_INFO "DC390_init: No EEPROM found! Trying default settings ...\n"); - dc390_check_for_safe_settings(); - dc390_fill_with_defaults(); - dc390_EEprom_Override(dc390_adapterCnt); - speed = dc390_clock_speed[tmscsim[1]]; - printk(KERN_INFO "DC390: Used defaults: AdaptID=%i, SpeedIdx=%i (%i.%i MHz)," - " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n", - tmscsim[0], tmscsim[1], speed/10, speed%10, - (u8)tmscsim[2], (u8)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]); - } else { - dc390_check_for_safe_settings(); - dc390_EEprom_Override(dc390_adapterCnt); - } + dc390_check_eeprom(pdev, dc390_adapterCnt); + dc390_eeprom_override(dc390_adapterCnt); io_port = pci_resource_start(pdev, 0); @@ -1418,6 +1451,16 @@ static int __init dc390_module_init(void) { + if (tmscsim[0] == -1 || tmscsim[0] > 15) { + tmscsim[0] = 7; + tmscsim[1] = 4; + tmscsim[2] = 0x09; + tmscsim[3] = 0x0f; + tmscsim[4] = 2; + tmscsim[5] = 10; + printk(KERN_INFO "DC390: Using safe settings.\n"); + } + return pci_module_init(&dc390_driver); } reverted: --- b/include/scsi/scsi.h 2004-10-01 19:21:44 -07:00 +++ a/include/scsi/scsi.h 2004-10-01 19:21:44 -07:00 @@ -246,35 +246,24 @@ #define EXTENDED_SDTR 0x01 #define EXTENDED_EXTENDED_IDENTIFY 0x02 /* SCSI-I only */ #define EXTENDED_WDTR 0x03 -#define EXTENDED_PPR 0x04 -#define EXTENDED_MODIFY_BIDI_DATA_PTR 0x05 #define SAVE_POINTERS 0x02 #define RESTORE_POINTERS 0x03 #define DISCONNECT 0x04 #define INITIATOR_ERROR 0x05 +#define ABORT 0x06 -#define ABORT_TASK_SET 0x06 #define MESSAGE_REJECT 0x07 #define NOP 0x08 #define MSG_PARITY_ERROR 0x09 #define LINKED_CMD_COMPLETE 0x0a #define LINKED_FLG_CMD_COMPLETE 0x0b +#define BUS_DEVICE_RESET 0x0c + -#define TARGET_RESET 0x0c -#define ABORT_TASK 0x0d -#define CLEAR_TASK_SET 0x0e #define INITIATE_RECOVERY 0x0f /* SCSI-II only */ #define RELEASE_RECOVERY 0x10 /* SCSI-II only */ + -#define CLEAR_ACA 0x16 -#define LOGICAL_UNIT_RESET 0x17 #define SIMPLE_QUEUE_TAG 0x20 #define HEAD_OF_QUEUE_TAG 0x21 #define ORDERED_QUEUE_TAG 0x22 -#define IGNORE_WIDE_RESIDUE 0x23 -#define ACA 0x24 -#define QAS_REQUEST 0x55 - -/* Old SCSI2 names, don't use in new code */ -#define BUS_DEVICE_RESET TARGET_RESET -#define ABORT ABORT_TASK_SET /* * Host byte codes diff -u b/include/scsi/scsi_device.h b/include/scsi/scsi_device.h --- b/include/scsi/scsi_device.h 2004-10-01 19:21:43 -07:00 +++ b/include/scsi/scsi_device.h 2004-10-01 19:23:16 -07:00 @@ -106,7 +106,6 @@ unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ - unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned int device_blocked; /* Device returned QUEUE_FULL. */ @@ -121,7 +120,7 @@ struct class_device transport_classdev; enum scsi_device_state sdev_state; - unsigned long transport_data[0]; + unsigned long sdev_data[0]; } __attribute__((aligned(sizeof(unsigned long)))); #define to_scsi_device(d) \ container_of(d, struct scsi_device, sdev_gendev) @@ -130,6 +129,30 @@ #define transport_class_to_sdev(class_dev) \ container_of(class_dev, struct scsi_device, transport_classdev) +/* + * scsi_target: representation of a scsi target, for now, this is only + * used for single_lun devices. If no one has active IO to the target, + * starget_sdev_user is NULL, else it points to the active sdev. + */ +struct scsi_target { + struct scsi_device *starget_sdev_user; + struct device dev; + unsigned int channel; + unsigned int id; /* target id ... replace + * scsi_device.id eventually */ + struct class_device transport_classdev; + unsigned long create:1; /* signal that it needs to be added */ + unsigned long starget_data[0]; +} __attribute__((aligned(sizeof(unsigned long)))); + +#define to_scsi_target(d) container_of(d, struct scsi_target, dev) +static inline struct scsi_target *scsi_target(struct scsi_device *sdev) +{ + return to_scsi_target(sdev->sdev_gendev.parent); +} +#define transport_class_to_starget(class_dev) \ + container_of(class_dev, struct scsi_target, transport_classdev) + extern struct scsi_device *__scsi_add_device(struct Scsi_Host *, uint, uint, uint, void *hostdata); #define scsi_add_device(host, channel, target, lun) \ @@ -192,6 +215,8 @@ enum scsi_device_state state); extern int scsi_device_quiesce(struct scsi_device *sdev); extern void scsi_device_resume(struct scsi_device *sdev); +extern void scsi_target_quiesce(struct scsi_target *); +extern void scsi_target_resume(struct scsi_target *); extern const char *scsi_device_state_name(enum scsi_device_state); static inline int scsi_device_online(struct scsi_device *sdev) { reverted: --- b/include/scsi/scsi_devinfo.h 2004-10-01 19:21:43 -07:00 +++ a/include/scsi/scsi_devinfo.h 2004-10-01 19:21:43 -07:00 @@ -25,5 +25,4 @@ (if HBA supports more than 8 LUNs) */ #define BLIST_NOREPORTLUN 0x40000 /* don't try REPORT_LUNS scan (SCSI-3 devs) */ #define BLIST_NOT_LOCKABLE 0x80000 /* don't use PREVENT-ALLOW commands */ -#define BLIST_NO_ULD_ATTACH 0x100000 /* device is actually for RAID config */ #endif diff -u b/include/scsi/scsi_host.h b/include/scsi/scsi_host.h --- b/include/scsi/scsi_host.h 2004-10-01 19:21:43 -07:00 +++ b/include/scsi/scsi_host.h 2004-10-01 19:23:16 -07:00 @@ -146,6 +146,15 @@ enum scsi_eh_timer_return (* eh_timed_out)(struct scsi_cmnd *); /* + * Old EH handlers, no longer used. Make them warn the user of old + * drivers by using a wrong type + * + * Status: MORE THAN OBSOLETE + */ + int (* abort)(int); + int (* reset)(int, int); + + /* * Before the mid layer attempts to scan for a new device where none * currently exists, it will call this entry in your driver. Should * your driver need to allocate any structs or perform any other init @@ -502,6 +511,13 @@ struct list_head sht_legacy_list; /* + * Points to the transport data (if any) which is allocated + * separately + */ + void *shost_data; + struct class_device transport_classdev; + + /* * We should ensure that this is aligned, both for better performance * and also because some compilers (m68k) don't automatically force * alignment to a long boundary. @@ -513,9 +529,12 @@ container_of(d, struct Scsi_Host, shost_gendev) #define class_to_shost(d) \ container_of(d, struct Scsi_Host, shost_classdev) +#define transport_class_to_shost(class_dev) \ + container_of(class_dev, struct Scsi_Host, transport_classdev) + extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int); -extern int __must_check scsi_add_host(struct Scsi_Host *, struct device *); +extern int scsi_add_host(struct Scsi_Host *, struct device *); extern void scsi_scan_host(struct Scsi_Host *); extern void scsi_remove_host(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); reverted: --- b/include/scsi/scsi_ioctl.h 2004-10-01 19:21:43 -07:00 +++ a/include/scsi/scsi_ioctl.h 2004-10-01 19:21:43 -07:00 @@ -43,8 +43,6 @@ extern int scsi_ioctl(struct scsi_device *, int, void __user *); extern int scsi_ioctl_send_command(struct scsi_device *, struct scsi_ioctl_command __user *); -extern int scsi_nonblockable_ioctl(struct scsi_device *sdev, int cmd, - void __user *arg, struct file *filp); #endif /* __KERNEL__ */ #endif /* _SCSI_IOCTL_H */ only in patch2: unchanged: --- a/drivers/scsi/53c700.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/53c700.c 2004-10-01 19:23:16 -07:00 @@ -287,8 +287,9 @@ struct NCR_700_Host_Parameters *hostdata = (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; - return NCR_700_offset_period_to_sxfer(hostdata, spi_offset(SDp), - spi_period(SDp)); + return NCR_700_offset_period_to_sxfer(hostdata, + spi_offset(SDp->sdev_target), + spi_period(SDp->sdev_target)); } struct Scsi_Host * @@ -403,6 +404,8 @@ (hostdata->fast ? "53c700-66" : "53c700"), hostdata->rev, hostdata->differential ? "(Differential)" : ""); + spi_signalling(host) = hostdata->differential ? SPI_SIGNAL_HVD : + SPI_SIGNAL_SE; /* reset the chip */ NCR_700_chip_reset(host); @@ -803,7 +806,7 @@ } if(NCR_700_is_flag_set(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION)) { - if(spi_offset(SCp->device) != 0) + if(spi_offset(SCp->device->sdev_target) != 0) printk(KERN_INFO "scsi%d: (%d:%d) Synchronous at offset %d, period %dns\n", host->host_no, pun, lun, offset, period*4); @@ -813,8 +816,8 @@ NCR_700_clear_flag(SCp->device, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); } - spi_offset(SCp->device) = offset; - spi_period(SCp->device) = period; + spi_offset(SCp->device->sdev_target) = offset; + spi_period(SCp->device->sdev_target) = period; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); @@ -894,7 +897,8 @@ case A_REJECT_MSG: if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION)) { /* Rejected our sync negotiation attempt */ - spi_period(SCp->device) = spi_offset(SCp->device) = 0; + spi_period(SCp->device->sdev_target) = + spi_offset(SCp->device->sdev_target) = 0; NCR_700_set_flag(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC); NCR_700_clear_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } else if(SCp != NULL && NCR_700_is_flag_set(SCp->device, NCR_700_DEV_BEGIN_TAG_QUEUEING)) { @@ -1420,8 +1424,8 @@ NCR_700_is_flag_clear(SCp->device, NCR_700_DEV_NEGOTIATED_SYNC)) { memcpy(&hostdata->msgout[count], NCR_700_SDTR_msg, sizeof(NCR_700_SDTR_msg)); - hostdata->msgout[count+3] = spi_period(SCp->device); - hostdata->msgout[count+4] = spi_offset(SCp->device); + hostdata->msgout[count+3] = spi_period(SCp->device->sdev_target); + hostdata->msgout[count+4] = spi_offset(SCp->device->sdev_target); count += sizeof(NCR_700_SDTR_msg); NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } @@ -1999,10 +2003,11 @@ } STATIC void -NCR_700_set_period(struct scsi_device *SDp, int period) +NCR_700_set_period(struct scsi_target *STp, int period) { + struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent); struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SHp->hostdata[0]; if(!hostdata->fast) return; @@ -2010,17 +2015,18 @@ if(period < hostdata->min_period) period = hostdata->min_period; - spi_period(SDp) = period; - NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); - NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); - NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); + spi_period(STp) = period; + spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC | + NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; } STATIC void -NCR_700_set_offset(struct scsi_device *SDp, int offset) +NCR_700_set_offset(struct scsi_target *STp, int offset) { + struct Scsi_Host *SHp = dev_to_shost(STp->dev.parent); struct NCR_700_Host_Parameters *hostdata = - (struct NCR_700_Host_Parameters *)SDp->host->hostdata[0]; + (struct NCR_700_Host_Parameters *)SHp->hostdata[0]; int max_offset = hostdata->chip710 ? NCR_710_MAX_OFFSET : NCR_700_MAX_OFFSET; @@ -2031,14 +2037,14 @@ offset = max_offset; /* if we're currently async, make sure the period is reasonable */ - if(spi_offset(SDp) == 0 && (spi_period(SDp) < hostdata->min_period || - spi_period(SDp) > 0xff)) - spi_period(SDp) = hostdata->min_period; - - spi_offset(SDp) = offset; - NCR_700_clear_flag(SDp, NCR_700_DEV_NEGOTIATED_SYNC); - NCR_700_clear_flag(SDp, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); - NCR_700_set_flag(SDp, NCR_700_DEV_PRINT_SYNC_NEGOTIATION); + if(spi_offset(STp) == 0 && (spi_period(STp) < hostdata->min_period || + spi_period(STp) > 0xff)) + spi_period(STp) = hostdata->min_period; + + spi_offset(STp) = offset; + spi_flags(STp) &= ~(NCR_700_DEV_NEGOTIATED_SYNC | + NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); + spi_flags(STp) |= NCR_700_DEV_PRINT_SYNC_NEGOTIATION; } @@ -2058,10 +2064,11 @@ } if(hostdata->fast) { /* Find the correct offset and period via domain validation */ - spi_dv_device(SDp); + if (!spi_initial_dv(SDp->sdev_target)) + spi_dv_device(SDp); } else { - spi_offset(SDp) = 0; - spi_period(SDp) = 0; + spi_offset(SDp->sdev_target) = 0; + spi_period(SDp->sdev_target) = 0; } return 0; } only in patch2: unchanged: --- a/drivers/scsi/53c700.h 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/53c700.h 2004-10-01 19:23:16 -07:00 @@ -121,22 +121,22 @@ static inline int NCR_700_is_flag_set(struct scsi_device *SDp, __u32 flag) { - return (((unsigned long)SDp->hostdata) & flag) == flag; + return (spi_flags(SDp->sdev_target) & flag) == flag; } static inline int NCR_700_is_flag_clear(struct scsi_device *SDp, __u32 flag) { - return (((unsigned long)SDp->hostdata) & flag) == 0; + return (spi_flags(SDp->sdev_target) & flag) == 0; } static inline void NCR_700_set_flag(struct scsi_device *SDp, __u32 flag) { - SDp->hostdata = (void *)((long)SDp->hostdata | (flag & 0xffff0000)); + spi_flags(SDp->sdev_target) |= flag; } static inline void NCR_700_clear_flag(struct scsi_device *SDp, __u32 flag) { - SDp->hostdata = (void *)((long)SDp->hostdata & ~(flag & 0xffff0000)); + spi_flags(SDp->sdev_target) &= ~flag; } struct NCR_700_command_slot { only in patch2: unchanged: --- a/drivers/scsi/NCR_D700.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/NCR_D700.c 2004-10-01 19:23:16 -07:00 @@ -99,6 +99,9 @@ #include #include #include +#include +#include +#include #include "53c700.h" #include "NCR_D700.h" only in patch2: unchanged: --- a/drivers/scsi/hosts.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/hosts.c 2004-10-01 19:23:16 -07:00 @@ -82,6 +82,8 @@ set_bit(SHOST_DEL, &shost->shost_state); class_device_unregister(&shost->shost_classdev); + if (shost->transport_classdev.class) + class_device_unregister(&shost->transport_classdev); device_del(&shost->shost_gendev); } @@ -154,6 +156,7 @@ scsi_proc_hostdir_rm(shost->hostt); scsi_destroy_command_freelist(shost); + kfree(shost->shost_data); /* * Some drivers (eg aha1542) do scsi_register()/scsi_unregister() @@ -278,15 +281,26 @@ snprintf(shost->shost_classdev.class_id, BUS_ID_SIZE, "host%d", shost->host_no); + if (shost->transportt->host_size && + (shost->shost_data = kmalloc(shost->transportt->host_size, + GFP_KERNEL)) == NULL) + goto fail_destroy_freelist; + + if (shost->transportt->host_setup) + shost->transportt->host_setup(shost); + shost->eh_notify = &complete; rval = kernel_thread(scsi_error_handler, shost, 0); if (rval < 0) - goto fail_destroy_freelist; + goto fail_free_shost_data; wait_for_completion(&complete); shost->eh_notify = NULL; + scsi_proc_hostdir_add(shost->hostt); return shost; + fail_free_shost_data: + kfree(shost->shost_data); fail_destroy_freelist: scsi_destroy_command_freelist(shost); fail_kfree: only in patch2: unchanged: --- a/drivers/scsi/lasi700.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/lasi700.c 2004-10-01 19:23:16 -07:00 @@ -50,6 +50,9 @@ #include #include +#include +#include +#include #include "lasi700.h" #include "53c700.h" only in patch2: unchanged: --- a/drivers/scsi/scsi_priv.h 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/scsi_priv.h 2004-10-01 19:23:16 -07:00 @@ -58,16 +58,6 @@ */ #define SCAN_WILD_CARD ~0 -/* - * scsi_target: representation of a scsi target, for now, this is only - * used for single_lun devices. If no one has active IO to the target, - * starget_sdev_user is NULL, else it points to the active sdev. - */ -struct scsi_target { - struct scsi_device *starget_sdev_user; - unsigned int starget_refcnt; -}; - /* hosts.c */ extern int scsi_init_hosts(void); extern void scsi_exit_hosts(void); @@ -156,6 +146,8 @@ extern int scsi_sysfs_add_host(struct Scsi_Host *); extern int scsi_sysfs_register(void); extern void scsi_sysfs_unregister(void); +extern int scsi_sysfs_device_initialize(struct scsi_device *); +extern int scsi_sysfs_target_initialize(struct scsi_device *); extern struct scsi_transport_template blank_transport_template; extern struct class sdev_class; only in patch2: unchanged: --- a/drivers/scsi/scsi_transport_fc.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/scsi_transport_fc.c 2004-10-01 19:23:16 -07:00 @@ -84,7 +84,7 @@ struct scsi_device *sdev = transport_class_to_sdev(cdev); \ struct fc_transport_attrs *tp; \ struct fc_internal *i = to_fc_internal(sdev->host->transportt); \ - tp = (struct fc_transport_attrs *)&sdev->transport_data; \ + tp = (struct fc_transport_attrs *)&sdev->sdev_data; \ if (i->f->get_##field) \ i->f->get_##field(sdev); \ return snprintf(buf, 20, format_string, cast tp->field); \ @@ -156,10 +156,10 @@ memset(i, 0, sizeof(struct fc_internal)); - i->t.attrs = &i->attrs[0]; - i->t.class = &fc_transport_class; - i->t.setup = &fc_setup_transport_attrs; - i->t.size = sizeof(struct fc_transport_attrs); + i->t.device_attrs = &i->attrs[0]; + i->t.device_class = &fc_transport_class; + i->t.device_setup = &fc_setup_transport_attrs; + i->t.device_size = sizeof(struct fc_transport_attrs); i->f = ft; SETUP_ATTRIBUTE_RD(port_id); only in patch2: unchanged: --- a/drivers/scsi/scsi_transport_spi.c 2004-10-01 19:23:16 -07:00 +++ b/drivers/scsi/scsi_transport_spi.c 2004-10-01 19:23:16 -07:00 @@ -27,25 +27,28 @@ #include #include #include +#include "scsi_priv.h" #include #include #include #include #include -#define SPI_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a) +#define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) static void transport_class_release(struct class_device *class_dev); +static void host_class_release(struct class_device *class_dev); #define SPI_NUM_ATTRS 10 /* increase this if you add attributes */ #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always * on" attributes */ +#define SPI_HOST_ATTRS 1 #define SPI_MAX_ECHO_BUFFER_SIZE 4096 /* Private data accessors (keep these out of the header file) */ -#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_pending) -#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dv_sem) +#define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) +#define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem) struct spi_internal { struct scsi_transport_template t; @@ -55,6 +58,8 @@ /* The array of null terminated pointers to attributes * needed by scsi_sysfs.c */ struct class_device_attribute *attrs[SPI_NUM_ATTRS + SPI_OTHER_ATTRS + 1]; + struct class_device_attribute private_host_attrs[SPI_HOST_ATTRS]; + struct class_device_attribute *host_attrs[SPI_HOST_ATTRS + 1]; }; #define to_spi_internal(tmpl) container_of(tmpl, struct spi_internal, t) @@ -80,43 +85,100 @@ * by 4 */ #define SPI_STATIC_PPR 0x0c +static struct { + enum spi_signal_type value; + char *name; +} signal_types[] = { + { SPI_SIGNAL_UNKNOWN, "unknown" }, + { SPI_SIGNAL_SE, "SE" }, + { SPI_SIGNAL_LVD, "LVD" }, + { SPI_SIGNAL_HVD, "HVD" }, +}; + +static inline const char *spi_signal_to_string(enum spi_signal_type type) +{ + int i; + + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { + if (type == signal_types[i].value) + return signal_types[i].name; + } + return NULL; +} +static inline enum spi_signal_type spi_signal_to_value(const char *name) +{ + int i, len; + + for (i = 0; i < sizeof(signal_types)/sizeof(signal_types[0]); i++) { + len = strlen(signal_types[i].name); + if (strncmp(name, signal_types[i].name, len) == 0 && + (name[len] == '\n' || name[len] == '\0')) + return signal_types[i].value; + } + return SPI_SIGNAL_UNKNOWN; +} + + struct class spi_transport_class = { .name = "spi_transport", .release = transport_class_release, }; +struct class spi_host_class = { + .name = "spi_host", + .release = host_class_release, +}; + static __init int spi_transport_init(void) { + int error = class_register(&spi_host_class); + if (error) + return error; return class_register(&spi_transport_class); } static void __exit spi_transport_exit(void) { class_unregister(&spi_transport_class); + class_unregister(&spi_host_class); +} + +static int spi_setup_host_attrs(struct Scsi_Host *shost) +{ + spi_signalling(shost) = SPI_SIGNAL_UNKNOWN; + + return 0; } -static int spi_setup_transport_attrs(struct scsi_device *sdev) +static int spi_setup_transport_attrs(struct scsi_target *starget) { - spi_period(sdev) = -1; /* illegal value */ - spi_offset(sdev) = 0; /* async */ - spi_width(sdev) = 0; /* narrow */ - spi_iu(sdev) = 0; /* no IU */ - spi_dt(sdev) = 0; /* ST */ - spi_qas(sdev) = 0; - spi_wr_flow(sdev) = 0; - spi_rd_strm(sdev) = 0; - spi_rti(sdev) = 0; - spi_pcomp_en(sdev) = 0; - spi_dv_pending(sdev) = 0; - init_MUTEX(&spi_dv_sem(sdev)); + spi_period(starget) = -1; /* illegal value */ + spi_offset(starget) = 0; /* async */ + spi_width(starget) = 0; /* narrow */ + spi_iu(starget) = 0; /* no IU */ + spi_dt(starget) = 0; /* ST */ + spi_qas(starget) = 0; + spi_wr_flow(starget) = 0; + spi_rd_strm(starget) = 0; + spi_rti(starget) = 0; + spi_pcomp_en(starget) = 0; + spi_dv_pending(starget) = 0; + spi_initial_dv(starget) = 0; + init_MUTEX(&spi_dv_sem(starget)); return 0; } static void transport_class_release(struct class_device *class_dev) { - struct scsi_device *sdev = transport_class_to_sdev(class_dev); - put_device(&sdev->sdev_gendev); + struct scsi_target *starget = transport_class_to_starget(class_dev); + put_device(&starget->dev); +} + +static void host_class_release(struct class_device *class_dev) +{ + struct Scsi_Host *shost = transport_class_to_shost(class_dev); + put_device(&shost->shost_gendev); } #define spi_transport_show_function(field, format_string) \ @@ -124,12 +186,13 @@ static ssize_t \ show_spi_transport_##field(struct class_device *cdev, char *buf) \ { \ - struct scsi_device *sdev = transport_class_to_sdev(cdev); \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ struct spi_transport_attrs *tp; \ - struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ - tp = (struct spi_transport_attrs *)&sdev->transport_data; \ + struct spi_internal *i = to_spi_internal(shost->transportt); \ + tp = (struct spi_transport_attrs *)&starget->starget_data; \ if (i->f->get_##field) \ - i->f->get_##field(sdev); \ + i->f->get_##field(starget); \ return snprintf(buf, 20, format_string, tp->field); \ } @@ -139,11 +202,12 @@ size_t count) \ { \ int val; \ - struct scsi_device *sdev = transport_class_to_sdev(cdev); \ - struct spi_internal *i = to_spi_internal(sdev->host->transportt); \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ + struct spi_internal *i = to_spi_internal(shost->transportt); \ \ val = simple_strtoul(buf, NULL, 0); \ - i->f->set_##field(sdev, val); \ + i->f->set_##field(starget, val); \ return count; \ } @@ -168,8 +232,13 @@ static ssize_t store_spi_revalidate(struct class_device *cdev, const char *buf, size_t count) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct scsi_target *starget = transport_class_to_starget(cdev); + /* FIXME: we're relying on an awful lot of device internals + * here. We really need a function to get the first available + * child */ + struct device *dev = container_of(starget->dev.children.next, struct device, node); + struct scsi_device *sdev = to_scsi_device(dev); spi_dv_device(sdev); return count; } @@ -180,15 +249,16 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); struct spi_transport_attrs *tp; const char *str; - struct spi_internal *i = to_spi_internal(sdev->host->transportt); + struct spi_internal *i = to_spi_internal(shost->transportt); - tp = (struct spi_transport_attrs *)&sdev->transport_data; + tp = (struct spi_transport_attrs *)&starget->starget_data; if (i->f->get_period) - i->f->get_period(sdev); + i->f->get_period(starget); switch(tp->period) { @@ -212,8 +282,9 @@ store_spi_transport_period(struct class_device *cdev, const char *buf, size_t count) { - struct scsi_device *sdev = transport_class_to_sdev(cdev); - struct spi_internal *i = to_spi_internal(sdev->host->transportt); + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct spi_internal *i = to_spi_internal(shost->transportt); int j, period = -1; for (j = 0; j < SPI_STATIC_PPR; j++) { @@ -246,7 +317,7 @@ if (period > 0xff) period = 0xff; - i->f->set_period(sdev, period); + i->f->set_period(starget, period); return count; } @@ -255,9 +326,36 @@ show_spi_transport_period, store_spi_transport_period); +static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf) +{ + struct Scsi_Host *shost = transport_class_to_shost(cdev); + struct spi_internal *i = to_spi_internal(shost->transportt); + + if (i->f->get_signalling) + i->f->get_signalling(shost); + + return sprintf(buf, "%s\n", spi_signal_to_string(spi_signalling(shost))); +} +static ssize_t store_spi_host_signalling(struct class_device *cdev, + const char *buf, size_t count) +{ + struct Scsi_Host *shost = transport_class_to_shost(cdev); + struct spi_internal *i = to_spi_internal(shost->transportt); + enum spi_signal_type type = spi_signal_to_value(buf); + + if (type != SPI_SIGNAL_UNKNOWN) + return count; + + i->f->set_signalling(shost, type); + return count; +} +static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR, + show_spi_host_signalling, + store_spi_host_signalling); + #define DV_SET(x, y) \ if(i->f->set_##x) \ - i->f->set_##x(sdev, y) + i->f->set_##x(sdev->sdev_target, y) #define DV_LOOPS 3 #define DV_TIMEOUT (10*HZ) @@ -325,7 +423,7 @@ DV_TIMEOUT, DV_RETRIES); if(sreq->sr_result || !scsi_device_online(sdev)) { scsi_device_set_state(sdev, SDEV_QUIESCE); - SPI_PRINTK(sdev, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Write Buffer failure %x\n", sreq->sr_result); return 0; } @@ -401,8 +499,8 @@ /* OK, retrain, fallback */ if (i->f->get_period) - i->f->get_period(sdev); - newperiod = spi_period(sdev); + i->f->get_period(sdev->sdev_target); + newperiod = spi_period(sdev->sdev_target); period = newperiod > period ? newperiod : period; if (period < 0x0d) period++; @@ -411,11 +509,11 @@ if (unlikely(period > 0xff || period == prevperiod)) { /* Total failure; set to async and return */ - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Failure, dropping back to Asynchronous\n"); DV_SET(offset, 0); return 0; } - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation detected failure, dropping back\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation detected failure, dropping back\n"); DV_SET(period, period); prevperiod = period; } @@ -486,20 +584,20 @@ DV_SET(width, 0); if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer, DV_LOOPS)) { - SPI_PRINTK(sdev, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Domain Validation Initial Inquiry Failed\n"); /* FIXME: should probably offline the device here? */ return; } /* test width */ if (i->f->set_width && sdev->wdtr) { - i->f->set_width(sdev, 1); + i->f->set_width(sdev->sdev_target, 1); if (!spi_dv_device_compare_inquiry(sreq, buffer, buffer + len, DV_LOOPS)) { - SPI_PRINTK(sdev, KERN_ERR, "Wide Transfers Fail\n"); - i->f->set_width(sdev, 0); + SPI_PRINTK(sdev->sdev_target, KERN_ERR, "Wide Transfers Fail\n"); + i->f->set_width(sdev->sdev_target, 0); } } @@ -521,11 +619,11 @@ * test, now try an echo buffer test (if the device allows it) */ if ((len = spi_dv_device_get_echo_buffer(sreq, buffer)) == 0) { - SPI_PRINTK(sdev, KERN_INFO, "Domain Validation skipping write tests\n"); + SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); return; } if (len > SPI_MAX_ECHO_BUFFER_SIZE) { - SPI_PRINTK(sdev, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); + SPI_PRINTK(sdev->sdev_target, KERN_WARNING, "Echo buffer size %d is too big, trimming to %d\n", len, SPI_MAX_ECHO_BUFFER_SIZE); len = SPI_MAX_ECHO_BUFFER_SIZE; } @@ -547,6 +645,7 @@ spi_dv_device(struct scsi_device *sdev) { struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL); + struct scsi_target *starget = sdev->sdev_target; u8 *buffer; const int len = SPI_MAX_ECHO_BUFFER_SIZE*2; @@ -563,22 +662,28 @@ memset(buffer, 0, len); + /* We need to verify that the actual device will quiesce; the + * later target quiesce is just a nice to have */ if (unlikely(scsi_device_quiesce(sdev))) goto out_free; - spi_dv_pending(sdev) = 1; - down(&spi_dv_sem(sdev)); + scsi_target_quiesce(starget); + + spi_dv_pending(starget) = 1; + down(&spi_dv_sem(starget)); - SPI_PRINTK(sdev, KERN_INFO, "Beginning Domain Validation\n"); + SPI_PRINTK(starget, KERN_INFO, "Beginning Domain Validation\n"); spi_dv_device_internal(sreq, buffer); - SPI_PRINTK(sdev, KERN_INFO, "Ending Domain Validation\n"); + SPI_PRINTK(starget, KERN_INFO, "Ending Domain Validation\n"); - up(&spi_dv_sem(sdev)); - spi_dv_pending(sdev) = 0; + up(&spi_dv_sem(starget)); + spi_dv_pending(starget) = 0; - scsi_device_resume(sdev); + scsi_target_resume(starget); + + spi_initial_dv(starget) = 1; out_free: kfree(buffer); @@ -602,7 +707,7 @@ kfree(wqw); spi_dv_device(sdev); - spi_dv_pending(sdev) = 0; + spi_dv_pending(sdev->sdev_target) = 0; scsi_device_put(sdev); } @@ -625,15 +730,15 @@ if (unlikely(!wqw)) return; - if (unlikely(spi_dv_pending(sdev))) { + if (unlikely(spi_dv_pending(sdev->sdev_target))) { kfree(wqw); return; } /* Set pending early (dv_device doesn't check it, only sets it) */ - spi_dv_pending(sdev) = 1; + spi_dv_pending(sdev->sdev_target) = 1; if (unlikely(scsi_device_get(sdev))) { kfree(wqw); - spi_dv_pending(sdev) = 0; + spi_dv_pending(sdev->sdev_target) = 0; return; } @@ -654,6 +759,15 @@ if (i->f->show_##field) \ count++ +#define SETUP_HOST_ATTRIBUTE(field) \ + i->private_host_attrs[count] = class_device_attr_##field; \ + if (!i->f->set_##field) { \ + i->private_host_attrs[count].attr.mode = S_IRUGO; \ + i->private_host_attrs[count].store = NULL; \ + } \ + i->host_attrs[count] = &i->private_host_attrs[count]; \ + count++ + struct scsi_transport_template * spi_attach_transport(struct spi_function_template *ft) { @@ -666,10 +780,14 @@ memset(i, 0, sizeof(struct spi_internal)); - i->t.attrs = &i->attrs[0]; - i->t.class = &spi_transport_class; - i->t.setup = &spi_setup_transport_attrs; - i->t.size = sizeof(struct spi_transport_attrs); + i->t.target_attrs = &i->attrs[0]; + i->t.target_class = &spi_transport_class; + i->t.target_setup = &spi_setup_transport_attrs; + i->t.target_size = sizeof(struct spi_transport_attrs); + i->t.host_attrs = &i->host_attrs[0]; + i->t.host_class = &spi_host_class; + i->t.host_setup = &spi_setup_host_attrs; + i->t.host_size = sizeof(struct spi_host_attrs); i->f = ft; SETUP_ATTRIBUTE(period); @@ -690,6 +808,13 @@ i->attrs[count++] = &class_device_attr_revalidate; i->attrs[count] = NULL; + + count = 0; + SETUP_HOST_ATTRIBUTE(signalling); + + BUG_ON(count > SPI_HOST_ATTRS); + + i->host_attrs[count] = NULL; return &i->t; } only in patch2: unchanged: --- a/drivers/scsi/sim710.c 2004-10-01 19:23:17 -07:00 +++ b/drivers/scsi/sim710.c 2004-10-01 19:23:17 -07:00 @@ -36,6 +36,9 @@ #include #include #include +#include +#include +#include #include "53c700.h" only in patch2: unchanged: --- a/include/scsi/scsi_transport.h 2004-10-01 19:23:16 -07:00 +++ b/include/scsi/scsi_transport.h 2004-10-01 19:23:16 -07:00 @@ -24,18 +24,27 @@ /* The NULL terminated list of transport attributes * that should be exported. */ - struct class_device_attribute **attrs; + struct class_device_attribute **device_attrs; + struct class_device_attribute **target_attrs; + struct class_device_attribute **host_attrs; + /* The transport class that the device is in */ - struct class *class; + struct class *device_class; + struct class *target_class; + struct class *host_class; + + /* Constructor functions */ + int (*device_setup)(struct scsi_device *); + int (*target_setup)(struct scsi_target *); + int (*host_setup)(struct Scsi_Host *); - /* Constructor/Destructor functions */ - int (* setup)(struct scsi_device *); - void (* cleanup)(struct scsi_device *); /* The size of the specific transport attribute structure (a * space of this size will be left at the end of the - * scsi_device structure */ - int size; + * scsi_* structure */ + int device_size; + int target_size; + int host_size; }; #endif /* SCSI_TRANSPORT_H */ only in patch2: unchanged: --- a/include/scsi/scsi_transport_fc.h 2004-10-01 19:23:16 -07:00 +++ b/include/scsi/scsi_transport_fc.h 2004-10-01 19:23:16 -07:00 @@ -31,9 +31,9 @@ }; /* accessor functions */ -#define fc_port_id(x) (((struct fc_transport_attrs *)&(x)->transport_data)->port_id) -#define fc_node_name(x) (((struct fc_transport_attrs *)&(x)->transport_data)->node_name) -#define fc_port_name(x) (((struct fc_transport_attrs *)&(x)->transport_data)->port_name) +#define fc_port_id(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->port_id) +#define fc_node_name(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->node_name) +#define fc_port_name(x) (((struct fc_transport_attrs *)&(x)->sdev_data)->port_name) /* The functions by which the transport class and the driver communicate */ struct fc_function_template { only in patch2: unchanged: --- a/include/scsi/scsi_transport_spi.h 2004-10-01 19:23:16 -07:00 +++ b/include/scsi/scsi_transport_spi.h 2004-10-01 19:23:16 -07:00 @@ -35,45 +35,63 @@ unsigned int rd_strm:1; /* Read streaming enabled */ unsigned int rti:1; /* Retain Training Information */ unsigned int pcomp_en:1;/* Precompensation enabled */ + unsigned int initial_dv:1; /* DV done to this target yet */ + unsigned long flags; /* flags field for drivers to use */ /* Private Fields */ unsigned int dv_pending:1; /* Internal flag */ struct semaphore dv_sem; /* semaphore to serialise dv */ }; +enum spi_signal_type { + SPI_SIGNAL_UNKNOWN = 1, + SPI_SIGNAL_SE, + SPI_SIGNAL_LVD, + SPI_SIGNAL_HVD, +}; + +struct spi_host_attrs { + enum spi_signal_type signalling; +}; + /* accessor functions */ -#define spi_period(x) (((struct spi_transport_attrs *)&(x)->transport_data)->period) -#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->transport_data)->offset) -#define spi_width(x) (((struct spi_transport_attrs *)&(x)->transport_data)->width) -#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->transport_data)->iu) -#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->transport_data)->dt) -#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->transport_data)->qas) -#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->transport_data)->wr_flow) -#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->transport_data)->rd_strm) -#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->transport_data)->rti) -#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->transport_data)->pcomp_en) +#define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) +#define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) +#define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) +#define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) +#define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) +#define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) +#define spi_wr_flow(x) (((struct spi_transport_attrs *)&(x)->starget_data)->wr_flow) +#define spi_rd_strm(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rd_strm) +#define spi_rti(x) (((struct spi_transport_attrs *)&(x)->starget_data)->rti) +#define spi_pcomp_en(x) (((struct spi_transport_attrs *)&(x)->starget_data)->pcomp_en) +#define spi_initial_dv(x) (((struct spi_transport_attrs *)&(x)->starget_data)->initial_dv) +#define spi_flags(x) (((struct spi_transport_attrs *)&(x)->starget_data)->flags) +#define spi_signalling(h) (((struct spi_host_attrs *)&(h)->shost_data)->signalling) /* The functions by which the transport class and the driver communicate */ struct spi_function_template { - void (*get_period)(struct scsi_device *); - void (*set_period)(struct scsi_device *, int); - void (*get_offset)(struct scsi_device *); - void (*set_offset)(struct scsi_device *, int); - void (*get_width)(struct scsi_device *); - void (*set_width)(struct scsi_device *, int); - void (*get_iu)(struct scsi_device *); - void (*set_iu)(struct scsi_device *, int); - void (*get_dt)(struct scsi_device *); - void (*set_dt)(struct scsi_device *, int); - void (*get_qas)(struct scsi_device *); - void (*set_qas)(struct scsi_device *, int); - void (*get_wr_flow)(struct scsi_device *); - void (*set_wr_flow)(struct scsi_device *, int); - void (*get_rd_strm)(struct scsi_device *); - void (*set_rd_strm)(struct scsi_device *, int); - void (*get_rti)(struct scsi_device *); - void (*set_rti)(struct scsi_device *, int); - void (*get_pcomp_en)(struct scsi_device *); - void (*set_pcomp_en)(struct scsi_device *, int); + void (*get_period)(struct scsi_target *); + void (*set_period)(struct scsi_target *, int); + void (*get_offset)(struct scsi_target *); + void (*set_offset)(struct scsi_target *, int); + void (*get_width)(struct scsi_target *); + void (*set_width)(struct scsi_target *, int); + void (*get_iu)(struct scsi_target *); + void (*set_iu)(struct scsi_target *, int); + void (*get_dt)(struct scsi_target *); + void (*set_dt)(struct scsi_target *, int); + void (*get_qas)(struct scsi_target *); + void (*set_qas)(struct scsi_target *, int); + void (*get_wr_flow)(struct scsi_target *); + void (*set_wr_flow)(struct scsi_target *, int); + void (*get_rd_strm)(struct scsi_target *); + void (*set_rd_strm)(struct scsi_target *, int); + void (*get_rti)(struct scsi_target *); + void (*set_rti)(struct scsi_target *, int); + void (*get_pcomp_en)(struct scsi_target *); + void (*set_pcomp_en)(struct scsi_target *, int); + void (*get_signalling)(struct Scsi_Host *); + void (*set_signalling)(struct Scsi_Host *, enum spi_signal_type); /* The driver sets these to tell the transport class it * wants the attributes displayed in sysfs. If the show_ flag * is not set, the attribute will be private to the transport