summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2005-10-06 18:47:58 +0000
committerXin LI <delphij@FreeBSD.org>2005-10-06 18:47:58 +0000
commit53f5bec08c5419fa69543f30087b47479847f996 (patch)
tree16017765b5c2101ee258be5bfd087240d884f56e /sys/dev
parentb2529c3c2b78b761b01d6411deb40e88433a679c (diff)
Notes
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/hptmv/access601.h2
-rw-r--r--sys/dev/hptmv/array.h14
-rw-r--r--sys/dev/hptmv/atapi.h31
-rw-r--r--sys/dev/hptmv/command.h2
-rw-r--r--sys/dev/hptmv/entry.c2856
-rw-r--r--sys/dev/hptmv/global.h107
-rw-r--r--sys/dev/hptmv/gui_lib.c80
-rw-r--r--sys/dev/hptmv/hptintf.h68
-rw-r--r--sys/dev/hptmv/hptproc.c104
-rw-r--r--sys/dev/hptmv/i386-elf.raid.o.uu2669
-rw-r--r--sys/dev/hptmv/ioctl.c81
-rw-r--r--sys/dev/hptmv/mv.c74
-rw-r--r--sys/dev/hptmv/mvOs.h108
-rw-r--r--sys/dev/hptmv/mvSata.h2
-rw-r--r--sys/dev/hptmv/mvStorageDev.h2
-rw-r--r--sys/dev/hptmv/osbsd.h290
-rw-r--r--sys/dev/hptmv/raid5n.h7
-rw-r--r--sys/dev/hptmv/readme.txt145
-rw-r--r--sys/dev/hptmv/vdevice.h6
19 files changed, 3350 insertions, 3298 deletions
diff --git a/sys/dev/hptmv/access601.h b/sys/dev/hptmv/access601.h
index 57acf8f5e4d8..26eaab283b95 100644
--- a/sys/dev/hptmv/access601.h
+++ b/sys/dev/hptmv/access601.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/hptmv/array.h b/sys/dev/hptmv/array.h
index 104eb9b94275..14d627af5832 100644
--- a/sys/dev/hptmv/array.h
+++ b/sys/dev/hptmv/array.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -62,6 +62,7 @@ typedef struct _RaidArray
UCHAR reserve1;
ULONG dArStamp; /* array ID. all disks in a array has same ID */
+ ULONG failedStamp; /* stamp for failed member */
USHORT bStripeWitch; /* = (1 << BlockSizeShift) */
USHORT rf_broken: 1;
@@ -83,7 +84,7 @@ typedef struct _RaidArray
USHORT CriticalMembers; /* tell which member is critial */
UCHAR last_read; /* for RAID 1 load banlancing */
- UCHAR pad1;
+ UCHAR PrivateFlag1;
LBA_T RebuildSectors; /* how many sectors is OK (LBA on member disk) */
@@ -151,7 +152,9 @@ typedef struct _ArrayDescript
#define ArrayDescript_3_1_size 512
UCHAR bCheckSum31; /* new check sum */
- UCHAR reserve2[2];
+ UCHAR PrivateFlag1; /* private */
+ UCHAR reserve1;
+
#ifdef __BIG_ENDIAN_BITFIELD
UCHAR df_read_ahead: 1; /* enable read ahead */
UCHAR df_read_ahead_set: 1;
@@ -178,8 +181,13 @@ typedef struct _ArrayDescript
}
levelex[2];
+ ULONG failedStamp; /* array stamp for failed memebr */
+
} ArrayDescript;
+/* report an error if ArrayDescript size exceed 512 */
+typedef char ArrayDescript_size_should_not_exceed_512[512-sizeof(ArrayDescript)];
+
#pragma pack()
/* Signature */
diff --git a/sys/dev/hptmv/atapi.h b/sys/dev/hptmv/atapi.h
index f6dda77a5cb3..b00100a900e9 100644
--- a/sys/dev/hptmv/atapi.h
+++ b/sys/dev/hptmv/atapi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -267,39 +267,66 @@ typedef struct _ATAPI_REGISTERS_1 {
#define ATAPI_FORMAT_UNIT 0x24
#define ATAPI_INQUIRY 0x12
#define ATAPI_MODE_SELECT 0x15
+#define ATAPI_RELEASE6 0x17
#define ATAPI_MODE_SENSE 0x1A
#define ATAPI_START_STOP_UNIT 0x1B
#define ATAPI_LOAD_UNLOAD 0x1B
+#define ATAPI_RECEIVE_DIAGNOSTIC 0x1C
+#define ATAPI_SEND_DIAGNOSTIC 0x1D
#define ATAPI_MEDIUM_REMOVAL 0x1E
+#define ATAPI_READ_FORMAT_CAPACITY 0x23
#define ATAPI_READ_CAPACITY 0x25
#define ATAPI_READ 0x28
#define ATAPI_WRITE 0x2A
#define ATAPI_SEEK 0x2B
+#define ATAPI_ERASE 0x2C
#define ATAPI_VERIFY 0x2F
+#define ATAPI_WRITE_VERIFY 0x2E
+#define ATAPI_SYNCHRONIZE_CACHE 0x35
+#define ATAPI_LOCK_CACHE 0x36
+#define ATAPI_COMPARE 0x39
+#define ATAPI_WRITE_BUFFER 0x3B
#define ATAPI_READ_DATA_BUFF 0x3C
#define ATAPI_READ_SUB_CHANNEL 0x42
#define ATAPI_READ_TOC 0x43
#define ATAPI_READ_HEADER 0x44
+#define ATAPI_PLAY_AUDIO10 0x45
#define ATAPI_GET_CONFIGURATION 0x46
#define ATAPI_PLAY_AUDIO_MSF 0x47
#define ATAPI_GET_EVENT_STATUS_NOTIFICATION 0x4A
#define ATAPI_PAUSE_RESUME 0x4B
+#define ATAPI_LOG_SELECT 0x4C
+#define ATAPI_LOG_SENSE 0x4D
#define ATAPI_STOP_PLAY_SCAN 0x4E
#define ATAPI_READ_DISK_INFORMATION 0x51
#define ATAPI_READ_TRACK_INFORMATION 0x52
+#define ATAPI_RESERVE_TRACK_RZONE 0x53
+#define ATAPI_SEND_OPC_INFORMATION 0x54
#define ATAPI_MODE_SELECT10 0x55
+#define ATAPI_RELEASE10 0x57
+#define ATAPI_REPAIR_ZONE 0x58
#define ATAPI_MODE_SENSE10 0x5A
#define ATAPI_CLOSE_TRACK_SESSION 0x5B
#define ATAPI_READ_BUFFER_CAPACITY 0x5C
+#define ATAPI_SEND_CUE_SHEET 0x5D
#define ATAPI_BLANK_COMMAND 0xA1 /*Provide the ability to erase any part of a CD-RW disc.*/
+#define ATAPI_SEND_EVENT 0xA2 /* add for DVD */
+#define ATAPI_SEND_KEY 0xA3 /* add for DVD */
#define ATAPI_REPORT_KEY 0xA4
#define ATAPI_PLAY_AUDIO 0xA5
+#define ATAPI_LOAD_UNLOAD_MEDIUM 0xA6
+#define ATAPI_SET_READ_AHEAD 0xA7
#define ATAPI_READ12 0xA8
#define ATAPI_READ_DVD_STRUCTURE 0xAD
+#define ATAPI_WRITE12 0xAA
+#define ATAPI_GET_PERFORM_NOTIFICATION 0xAC /* add for DVD-RW */
+#define ATAPI_SET_STREAM 0xB6 /* add for DVD-RW */
#define ATAPI_READ_CD_MSF 0xB9
-#define ATAPI_SET_CD_SPEED 0xBB
+#define ATAPI_SCAN 0xBA
+#define ATAPI_SET_SPEED 0xBB /* no payload */
#define ATAPI_MECHANISM_STATUS 0xBD
#define ATAPI_READ_CD 0xBE
+#define ATAPI_SEND_DVD_STRUCTURE 0xBF
#define ATAPI_SET_CDRW_SPEED 0xDA /*WindowsXP need*/
#define MODE_DSP_WRITE_PROTECT 0x80
diff --git a/sys/dev/hptmv/command.h b/sys/dev/hptmv/command.h
index dbc0bd67ce7d..12eb694af81d 100644
--- a/sys/dev/hptmv/command.h
+++ b/sys/dev/hptmv/command.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/hptmv/entry.c b/sys/dev/hptmv/entry.c
index fa2d41d698b4..6b7631e2db37 100644
--- a/sys/dev/hptmv/entry.c
+++ b/sys/dev/hptmv/entry.c
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,6 +25,7 @@
*
* $FreeBSD$
*/
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -38,41 +39,85 @@
#include <sys/proc.h>
#include <sys/kthread.h>
+#if (__FreeBSD_version >= 500000)
+#include <sys/mutex.h>
+#include <sys/module.h>
+#endif
+
+#if (__FreeBSD_version >= 500000)
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#else
+#include <pci/pcireg.h>
+#include <pci/pcivar.h>
+#include <machine/clock.h>
+#include <sys/wait.h>
+#include <sys/sysproto.h>
+#endif
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
#include <dev/hptmv/global.h>
#include <dev/hptmv/hptintf.h>
#include <dev/hptmv/osbsd.h>
#include <dev/hptmv/access601.h>
+
#ifdef DEBUG
#ifdef DEBUG_LEVEL
int hpt_dbg_level = DEBUG_LEVEL;
-#else
+#else
int hpt_dbg_level = 0;
#endif
#endif
#define MV_ERROR printf
+
/*
* CAM SIM entry points
*/
-static int hpt_probe(device_t dev);
-static int hpt_attach(device_t dev);
-static int hpt_detach(device_t dev);
-static int hpt_shutdown(device_t dev);
-static void hpt_poll(struct cam_sim *sim);
-static void hpt_intr(void *arg);
-static void hpt_action(struct cam_sim *sim, union ccb *ccb);
-static void SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev);
-static void HPTLIBAPI OsSendCommand (_VBUS_ARG union ccb * ccb);
-static void HPTLIBAPI fOsCommandDone(_VBUS_ARG PCommand pCmd);
-static void ccb_done(union ccb *ccb);
-static void hpt_queue_ccb(union ccb **ccb_Q, union ccb *ccb);
-static void hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb);
-static void launch_worker_thread(void);
-static MV_SATA_CHANNEL gMvSataChannels[MAX_VBUS][MV_SATA_CHANNELS_NUM];
+static int hpt_probe (device_t dev);
+static void launch_worker_thread(void);
+static int hpt_attach(device_t dev);
+static int hpt_detach(device_t dev);
+static int hpt_shutdown(device_t dev);
+static void hpt_poll(struct cam_sim *sim);
+static void hpt_intr(void *arg);
+static void hpt_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg);
+static void hpt_action(struct cam_sim *sim, union ccb *ccb);
+
+static device_method_t driver_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, hpt_probe),
+ DEVMETHOD(device_attach, hpt_attach),
+ DEVMETHOD(device_detach, hpt_detach),
+
+/* DEVMETHOD(device_shutdown, hpt_shutdown), */
+ { 0, 0 }
+};
+
+static driver_t hpt_pci_driver = {
+ __str(PROC_DIR_NAME),
+ driver_methods,
+ sizeof(IAL_ADAPTER_T)
+};
+
+static devclass_t hpt_devclass;
+
+#define __DRIVER_MODULE(p1, p2, p3, p4, p5, p6) DRIVER_MODULE(p1, p2, p3, p4, p5, p6)
+__DRIVER_MODULE(PROC_DIR_NAME, pci, hpt_pci_driver, hpt_devclass, 0, 0);
+
+#define ccb_ccb_ptr spriv_ptr0
+#define ccb_adapter ccb_h.spriv_ptr1
+
+static void SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev);
+static void HPTLIBAPI OsSendCommand (_VBUS_ARG union ccb * ccb);
+static void HPTLIBAPI fOsCommandDone(_VBUS_ARG PCommand pCmd);
+static void ccb_done(union ccb *ccb);
+static void hpt_queue_ccb(union ccb **ccb_Q, union ccb *ccb);
+static void hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb);
static void hptmv_free_edma_queues(IAL_ADAPTER_T *pAdapter);
static void hptmv_free_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
static void handleEdmaError(_VBUS_ARG PCommand pCmd);
@@ -85,8 +130,6 @@ static void hptmv_handle_event_connect(void *data);
static int start_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
static void init_vdev_params(IAL_ADAPTER_T *pAdapter, MV_U8 channel);
static int hptmv_parse_identify_results(MV_SATA_CHANNEL *pMvSataChannel);
-static void hpt_async(void *callback_arg, u_int32_t code,
- struct cam_path *path, void *arg);
static int HPTLIBAPI fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg,
int logical);
static MV_BOOLEAN CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter,
@@ -101,6 +144,7 @@ static MV_BOOLEAN hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter,
IAL_ADAPTER_T *gIal_Adapter = 0;
IAL_ADAPTER_T *pCurAdapter = 0;
+static MV_SATA_CHANNEL gMvSataChannels[MAX_VBUS][MV_SATA_CHANNELS_NUM];
typedef struct st_HPT_DPC {
IAL_ADAPTER_T *pAdapter;
@@ -115,37 +159,46 @@ static ST_HPT_DPC DpcQueue[MAX_DPC];
static int DpcQueue_First=0;
static int DpcQueue_Last = 0;
-static device_method_t driver_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, hpt_probe),
- DEVMETHOD(device_attach, hpt_attach),
- DEVMETHOD(device_detach, hpt_detach),
- { 0, 0 }
-};
-
-static driver_t hpt_pci_driver = {
- __str(PROC_DIR_NAME),
- driver_methods,
- sizeof(IAL_ADAPTER_T)
-};
-
-static devclass_t hpt_devclass;
+char DRIVER_VERSION[] = "v1.12 (" __DATE__ " " __TIME__ ")";
-DRIVER_MODULE(PROC_DIR_NAME, pci, hpt_pci_driver, hpt_devclass, 0, 0);
-MODULE_DEPEND(PROC_DIR_NAME, cam, 1, 1, 1);
+#if (__FreeBSD_version >= 500000)
+static struct mtx driver_lock;
+intrmask_t lock_driver()
+{
-intrmask_t
-lock_driver()
+ intrmask_t spl = 0;
+ mtx_lock_spin(&driver_lock);
+ return spl;
+}
+void unlock_driver(intrmask_t spl)
+{
+ mtx_unlock_spin(&driver_lock);
+}
+#else
+static int driver_locked = 0;
+intrmask_t lock_driver()
{
intrmask_t spl = splcam();
+loop:
+ while (driver_locked)
+ tsleep(&driver_locked, PRIBIO, "hptlck", hz);
+ atomic_add_int(&driver_locked, 1);
+ if (driver_locked>1) {
+ atomic_subtract_int(&driver_locked, 1);
+ goto loop;
+ }
return spl;
}
-void
-unlock_driver(intrmask_t spl)
+void unlock_driver(intrmask_t spl)
{
+ atomic_subtract_int(&driver_locked, 1);
+ if (driver_locked==0) {
+ wakeup(&driver_locked);
+ }
splx(spl);
}
+#endif
/*******************************************************************************
* Name: hptmv_free_channel
@@ -160,25 +213,33 @@ unlock_driver(intrmask_t spl)
static void
hptmv_free_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
{
- PVDevice pVDev = &(pAdapter->VDevices[channelNum]);
- _VBUS_INST(&pAdapter->VBus);
-
HPT_ASSERT(channelNum < MV_SATA_CHANNELS_NUM);
-
pAdapter->mvSataAdapter.sataChannel[channelNum] = NULL;
+}
- if(pVDev->vf_online)
- {
- pVDev->u.disk.df_on_line = 0;
- pVDev->vf_online = 0;
- if (pVDev->pfnDeviceFailed) {
- CallWhenIdle(_VBUS_P (DPC_PROC)pVDev->pfnDeviceFailed,
- pVDev);
- }
+static void failDevice(PVDevice pVDev)
+{
+ PVBus _vbus_p = pVDev->pVBus;
+ IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
+
+ pVDev->u.disk.df_on_line = 0;
+ pVDev->vf_online = 0;
+ if (pVDev->pfnDeviceFailed)
+ CallWhenIdle(_VBUS_P (DPC_PROC)pVDev->pfnDeviceFailed, pVDev);
+
+ fNotifyGUI(ET_DEVICE_REMOVED, pVDev);
+
+#ifndef FOR_DEMO
+ if (pAdapter->ver_601==2 && !pAdapter->beeping) {
+ pAdapter->beeping = 1;
+ BeepOn(pAdapter->mvSataAdapter.adapterIoBaseAddress);
+ set_fail_led(&pAdapter->mvSataAdapter, pVDev->u.disk.mv->channelNumber, 1);
}
+#endif
}
int MvSataResetChannel(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channel);
+/*void fDeviceSendCommand(_VBUS_ARG PCommand pCmd); */
static void
handleEdmaError(_VBUS_ARG PCommand pCmd)
@@ -186,10 +247,6 @@ handleEdmaError(_VBUS_ARG PCommand pCmd)
PDevice pDevice = &pCmd->pVDevice->u.disk;
MV_SATA_ADAPTER * pSataAdapter = pDevice->mv->mvSataAdapter;
- MV_ERROR("Reset channel\n");
-
- MvSataResetChannel(pSataAdapter, pDevice->mv->channelNumber);
- /*now no other cmds on this channel*/
if (!pDevice->df_on_line) {
KdPrint(("Device is offline"));
pCmd->Result = RETURN_BAD_DEVICE;
@@ -198,26 +255,30 @@ handleEdmaError(_VBUS_ARG PCommand pCmd)
}
if (pCmd->RetryCount++>5) {
- pDevice->df_on_line = 0;
- pCmd->pVDevice->vf_online = 0;
- if (pCmd->pVDevice->pfnDeviceFailed)
- CallWhenIdle(_VBUS_P
- (DPC_PROC)pCmd->pVDevice->pfnDeviceFailed,
- pCmd->pVDevice);
- fNotifyGUI(ET_DEVICE_REMOVED, Map2pVDevice(pDevice));
+ hpt_printk(("too many retries on channel(%d)\n", pDevice->mv->channelNumber));
+failed:
+ failDevice(pCmd->pVDevice);
pCmd->Result = RETURN_IDE_ERROR;
CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
return;
}
- /* retry the command */
+
+ /* reset the channel and retry the command */
+ if (MvSataResetChannel(pSataAdapter, pDevice->mv->channelNumber))
+ goto failed;
+
+ fNotifyGUI(ET_DEVICE_ERROR, Map2pVDevice(pDevice));
+
+ hpt_printk(("Retry on channel(%d)\n", pDevice->mv->channelNumber));
fDeviceSendCommand(_VBUS_P pCmd);
}
/****************************************************************
* Name: hptmv_init_channel
*
- * Description: allocate request and response queues for the EDMA of
- * the given channel and sets other fields.
+ * Description: allocate request and response queues for the EDMA of the
+ * given channel and sets other fields.
+ *
* Parameters:
* pAdapter - pointer to the emulated adapter data structure
* channelNum - channel number.
@@ -237,58 +298,49 @@ hptmv_init_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
return -1;
}
- pMvSataChannel =
- &gMvSataChannels[pAdapter->mvSataAdapter.adapterId][channelNum];
+ pMvSataChannel = &gMvSataChannels[pAdapter->mvSataAdapter.adapterId][channelNum];
pAdapter->mvSataAdapter.sataChannel[channelNum] = pMvSataChannel;
pMvSataChannel->channelNumber = channelNum;
pMvSataChannel->lba48Address = MV_FALSE;
pMvSataChannel->maxReadTransfer = MV_FALSE;
- pMvSataChannel->requestQueue =
- (struct mvDmaRequestQueueEntry *)
- (pAdapter->requestsArrayBaseAlignedAddr +
- (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE));
- req_dma_addr = pAdapter->requestsArrayBaseDmaAlignedAddr +
- (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE);
+ pMvSataChannel->requestQueue = (struct mvDmaRequestQueueEntry *)
+ (pAdapter->requestsArrayBaseAlignedAddr + (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE));
+ req_dma_addr = pAdapter->requestsArrayBaseDmaAlignedAddr + (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE);
- KdPrint(("requestQueue addr is 0x%lX", (u_long)req_dma_addr));
+ KdPrint(("requestQueue addr is 0x%llX", (HPT_U64)(ULONG_PTR)req_dma_addr));
/* check the 1K alignment of the request queue*/
if (req_dma_addr & 0x3ff)
{
- MV_ERROR("RR182x[%d]: request queue allocated not 1 K aligned,"
- " dma_addr=%lx channel=%d\n",
- pAdapter->mvSataAdapter.adapterId,(u_long)req_dma_addr,
- channelNum);
+ MV_ERROR("RR182x[%d]: request queue allocated isn't 1 K aligned,"
+ " dma_addr=%llx channel=%d\n", pAdapter->mvSataAdapter.adapterId,
+ (HPT_U64)(ULONG_PTR)req_dma_addr, channelNum);
return -1;
}
pMvSataChannel->requestQueuePciLowAddress = req_dma_addr;
pMvSataChannel->requestQueuePciHiAddress = 0;
KdPrint(("RR182x[%d,%d]: request queue allocated: 0x%p",
- pAdapter->mvSataAdapter.adapterId, channelNum,
- pMvSataChannel->requestQueue));
- pMvSataChannel->responseQueue =
- (struct mvDmaResponseQueueEntry *)
- (pAdapter->responsesArrayBaseAlignedAddr +
- (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE));
- rsp_dma_addr = pAdapter->responsesArrayBaseDmaAlignedAddr +
- (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE);
+ pAdapter->mvSataAdapter.adapterId, channelNum,
+ pMvSataChannel->requestQueue));
+ pMvSataChannel->responseQueue = (struct mvDmaResponseQueueEntry *)
+ (pAdapter->responsesArrayBaseAlignedAddr + (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE));
+ rsp_dma_addr = pAdapter->responsesArrayBaseDmaAlignedAddr + (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE);
/* check the 256 alignment of the response queue*/
if (rsp_dma_addr & 0xff)
{
- MV_ERROR("RR182x[%d,%d]: response queue allocated not 256 byte"
- " aligned, dma_addr=%lx\n",
- pAdapter->mvSataAdapter.adapterId, channelNum,
- (u_long)rsp_dma_addr);
+ MV_ERROR("RR182x[%d,%d]: response queue allocated isn't 256 byte "
+ "aligned, dma_addr=%llx\n",
+ pAdapter->mvSataAdapter.adapterId, channelNum, (HPT_U64)(ULONG_PTR)rsp_dma_addr);
return -1;
}
pMvSataChannel->responseQueuePciLowAddress = rsp_dma_addr;
pMvSataChannel->responseQueuePciHiAddress = 0;
KdPrint(("RR182x[%d,%d]: response queue allocated: 0x%p",
- pAdapter->mvSataAdapter.adapterId, channelNum,
- pMvSataChannel->responseQueue));
+ pAdapter->mvSataAdapter.adapterId, channelNum,
+ pMvSataChannel->responseQueue));
pAdapter->mvChannel[channelNum].online = MV_TRUE;
return 0;
@@ -297,10 +349,10 @@ hptmv_init_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
/******************************************************************************
* Name: hptmv_parse_identify_results
*
- * Description: this functions parses the identify command results,
- * checks that the connected deives can be accesed by
- * RR182x EDMA, and updates the channel stucture
- * accordingly.
+ * Description: this functions parses the identify command results, checks
+ * that the connected deives can be accesed by RR182x EDMA,
+ * and updates the channel stucture accordingly.
+ *
* Parameters: pMvSataChannel, pointer to the channel data structure.
*
* Returns: =0 ->success, < 0 ->failure.
@@ -312,40 +364,49 @@ hptmv_parse_identify_results(MV_SATA_CHANNEL *pMvSataChannel)
MV_U16 *iden = pMvSataChannel->identifyDevice;
/*LBA addressing*/
- if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x200)) {
+ if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x200))
+ {
KdPrint(("IAL Error in IDENTIFY info: LBA not supported\n"));
return -1;
- } else {
+ }
+ else
+ {
KdPrint(("%25s - %s\n", "Capabilities", "LBA supported"));
}
/*DMA support*/
- if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x100)) {
+ if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x100))
+ {
KdPrint(("IAL Error in IDENTIFY info: DMA not supported\n"));
return -1;
- } else {
+ }
+ else
+ {
KdPrint(("%25s - %s\n", "Capabilities", "DMA supported"));
}
/* PIO */
- if ((iden[IDEN_VALID] & 2) == 0) {
- KdPrint(("IAL Error in IDENTIFY info: not able to find PIO "
- "mode\n"));
+ if ((iden[IDEN_VALID] & 2) == 0)
+ {
+ KdPrint(("IAL Error in IDENTIFY info: not able to find PIO mode\n"));
return -1;
}
KdPrint(("%25s - 0x%02x\n", "PIO modes supported",
iden[IDEN_PIO_MODE_SPPORTED] & 0xff));
/*UDMA*/
- if ((iden[IDEN_VALID] & 4) == 0) {
- KdPrint(("IAL Error in IDENTIFY info: not able to find UDMA "
- "mode\n"));
+ if ((iden[IDEN_VALID] & 4) == 0)
+ {
+ KdPrint(("IAL Error in IDENTIFY info: not able to find UDMA mode\n"));
return -1;
}
/* 48 bit address */
- if ((iden[IDEN_SUPPORTED_COMMANDS2] & 0x400)) {
+ if ((iden[IDEN_SUPPORTED_COMMANDS2] & 0x400))
+ {
KdPrint(("%25s - %s\n", "LBA48 addressing", "supported"));
pMvSataChannel->lba48Address = MV_TRUE;
- } else {
+ }
+ else
+ {
KdPrint(("%25s - %s\n", "LBA48 addressing", "Not supported"));
pMvSataChannel->lba48Address = MV_FALSE;
}
@@ -355,14 +416,11 @@ hptmv_parse_identify_results(MV_SATA_CHANNEL *pMvSataChannel)
static void
init_vdev_params(IAL_ADAPTER_T *pAdapter, MV_U8 channel)
{
- PVDevice pVDev;
- MV_SATA_CHANNEL *pMvSataChannel;
- MV_U16_PTR IdentifyData;
+ PVDevice pVDev = &pAdapter->VDevices[channel];
+ MV_SATA_CHANNEL *pMvSataChannel = pAdapter->mvSataAdapter.sataChannel[channel];
+ MV_U16_PTR IdentifyData = pMvSataChannel->identifyDevice;
- pVDev = &pAdapter->VDevices[channel];
- pMvSataChannel = pAdapter->mvSataAdapter.sataChannel[channel];
pMvSataChannel->outstandingCommands = 0;
- IdentifyData = pMvSataChannel->identifyDevice;
pVDev->u.disk.mv = pMvSataChannel;
pVDev->u.disk.df_on_line = 1;
@@ -371,67 +429,54 @@ init_vdev_params(IAL_ADAPTER_T *pAdapter, MV_U8 channel)
#ifdef SUPPORT_48BIT_LBA
if (pMvSataChannel->lba48Address == MV_TRUE)
- pVDev->u.disk.dDeRealCapacity =
- ((IdentifyData[101]<<16) | IdentifyData[100]) - 1;
+ pVDev->u.disk.dDeRealCapacity = ((IdentifyData[101]<<16) | IdentifyData[100]) - 1;
else
#endif
if(IdentifyData[53] & 1) {
- pVDev->u.disk.dDeRealCapacity =
- (((IdentifyData[58]<<16 | IdentifyData[57]) <
- (IdentifyData[61]<<16 | IdentifyData[60])) ?
- (IdentifyData[61]<<16 | IdentifyData[60]) :
- (IdentifyData[58]<<16 | IdentifyData[57])) - 1;
+ pVDev->u.disk.dDeRealCapacity =
+ (((IdentifyData[58]<<16 | IdentifyData[57]) < (IdentifyData[61]<<16 | IdentifyData[60])) ?
+ (IdentifyData[61]<<16 | IdentifyData[60]) :
+ (IdentifyData[58]<<16 | IdentifyData[57])) - 1;
} else
pVDev->u.disk.dDeRealCapacity =
- (IdentifyData[61]<<16 | IdentifyData[60]) - 1;
+ (IdentifyData[61]<<16 | IdentifyData[60]) - 1;
pVDev->u.disk.bDeUsable_Mode = pVDev->u.disk.bDeModeSetting =
- pAdapter->mvChannel[channel].maxPioModeSupported -
- MV_ATA_TRANSFER_PIO_0;
+ pAdapter->mvChannel[channel].maxPioModeSupported - MV_ATA_TRANSFER_PIO_0;
if (pAdapter->mvChannel[channel].maxUltraDmaModeSupported!=0xFF) {
pVDev->u.disk.bDeUsable_Mode = pVDev->u.disk.bDeModeSetting =
- pAdapter->mvChannel[channel].maxUltraDmaModeSupported -
- MV_ATA_TRANSFER_UDMA_0 + 8;
+ pAdapter->mvChannel[channel].maxUltraDmaModeSupported - MV_ATA_TRANSFER_UDMA_0 + 8;
}
}
-static void
-device_change(IAL_ADAPTER_T *pAdapter , MV_U8 channelIndex, int plugged)
+static void device_change(IAL_ADAPTER_T *pAdapter , MV_U8 channelIndex, int plugged)
{
PVDevice pVDev;
- MV_SATA_ADAPTER *pMvSataAdapter;
- MV_SATA_CHANNEL *pMvSataChannel;
- PVBus _vbus_p;
-
- pMvSataAdapter = &pAdapter->mvSataAdapter;
- pMvSataChannel = pMvSataAdapter->sataChannel[channelIndex];
- _vbus_p = &pAdapter->VBus;
-
- if (!pMvSataChannel)
- return;
+ MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
+ MV_SATA_CHANNEL *pMvSataChannel = pMvSataAdapter->sataChannel[channelIndex];
+
+ if (!pMvSataChannel) return;
- if (plugged) {
+ if (plugged)
+ {
pVDev = &(pAdapter->VDevices[channelIndex]);
init_vdev_params(pAdapter, channelIndex);
- pVDev->VDeviceType = pVDev->u.disk.df_atapi ? VD_ATAPI :
- pVDev->u.disk.df_removable_drive ? VD_REMOVABLE :
- VD_SINGLE_DISK;
+ pVDev->VDeviceType = pVDev->u.disk.df_atapi? VD_ATAPI :
+ pVDev->u.disk.df_removable_drive? VD_REMOVABLE : VD_SINGLE_DISK;
- pVDev->VDeviceCapacity = pVDev->u.disk.dDeRealCapacity;
+ pVDev->VDeviceCapacity = pVDev->u.disk.dDeRealCapacity-SAVE_FOR_RAID_INFO;
pVDev->pfnSendCommand = pfnSendCommand[pVDev->VDeviceType];
pVDev->pfnDeviceFailed = pfnDeviceFailed[pVDev->VDeviceType];
pVDev->vf_online = 1;
#ifdef SUPPORT_ARRAY
- if(pVDev->pParent) {
+ if(pVDev->pParent)
+ {
int iMember;
-
- for (iMember = 0;
- iMember < pVDev->pParent->u.array.bArnMember;
- iMember++)
- if ((PVDevice)pVDev->pParent->u.array.pMember[iMember] == pVDev)
+ for(iMember = 0; iMember < pVDev->pParent->u.array.bArnMember; iMember++)
+ if((PVDevice)pVDev->pParent->u.array.pMember[iMember] == pVDev)
pVDev->pParent->u.array.pMember[iMember] = NULL;
pVDev->pParent = NULL;
}
@@ -447,315 +492,291 @@ device_change(IAL_ADAPTER_T *pAdapter , MV_U8 channelIndex, int plugged)
}
#endif
- } else {
+ }
+ else
+ {
pVDev = &(pAdapter->VDevices[channelIndex]);
- pVDev->u.disk.df_on_line = 0;
- pVDev->vf_online = 0;
- if (pVDev->pfnDeviceFailed) {
- _VBUS_INST(&pAdapter->VBus)
- CallWhenIdle(_VBUS_P (DPC_PROC)pVDev->pfnDeviceFailed,
- pVDev);
- }
- fNotifyGUI(ET_DEVICE_REMOVED,pVDev);
-
-#ifndef FOR_DEMO
- if (pAdapter->ver_601==2 && !pAdapter->beeping) {
- pAdapter->beeping = 1;
- BeepOn(pAdapter->mvSataAdapter.adapterIoBaseAddress);
- set_fail_led(&pAdapter->mvSataAdapter, channelIndex, 1);
- }
-#endif
-
+ failDevice(pVDev);
}
}
static int
start_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
{
- MV_SATA_ADAPTER *pMvSataAdapter;
- MV_SATA_CHANNEL *pMvSataChannel;
- MV_CHANNEL *pChannelInfo;
- MV_U32 udmaMode,pioMode;
-
- pMvSataAdapter = &pAdapter->mvSataAdapter;
- pMvSataChannel = pMvSataAdapter->sataChannel[channelNum];
- pChannelInfo = &(pAdapter->mvChannel[channelNum]);
+ MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
+ MV_SATA_CHANNEL *pMvSataChannel = pMvSataAdapter->sataChannel[channelNum];
+ MV_CHANNEL *pChannelInfo = &(pAdapter->mvChannel[channelNum]);
+ MV_U32 udmaMode,pioMode;
KdPrint(("RR182x [%d]: start channel (%d)", pMvSataAdapter->adapterId,
- channelNum));
+ channelNum));
/* Software reset channel */
- if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) ==
- MV_FALSE) {
+ if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
MV_ERROR("RR182x [%d,%d]: failed to perform Software reset\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
/* Hardware reset channel */
- if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE) {
- /*
- * If failed, try again - this is when trying to hardreset a
- * channel when drive is just spinning up
- */
+ if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
+ /* If failed, try again - this is when trying to hardreset a channel */
+ /* when drive is just spinning up */
StallExec(5000000); /* wait 5 sec before trying again */
- if (mvSataChannelHardReset(pMvSataAdapter, channelNum) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d,%d]: failed to perform Hard "
- "reset\n", pMvSataAdapter->adapterId,
- channelNum);
+ if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d,%d]: failed to perform Hard reset\n",
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
}
/* identify device*/
- if (mvStorageDevATAIdentifyDevice(pMvSataAdapter, channelNum) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d,%d]: failed to perform ATA Identify "
- "command\n", pMvSataAdapter->adapterId, channelNum);
+ if (mvStorageDevATAIdentifyDevice(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d,%d]: failed to perform ATA Identify command\n"
+ , pMvSataAdapter->adapterId, channelNum);
return -1;
}
- if (hptmv_parse_identify_results(pMvSataChannel)) {
- MV_ERROR("RR182x [%d,%d]: Error in parsing ATA Identify "
- "message\n", pMvSataAdapter->adapterId, channelNum);
+ if (hptmv_parse_identify_results(pMvSataChannel))
+ {
+ MV_ERROR("RR182x [%d,%d]: Error in parsing ATA Identify message\n"
+ , pMvSataAdapter->adapterId, channelNum);
return -1;
}
/* mvStorageDevATASetFeatures */
/* Disable 8 bit PIO in case CFA enabled */
- if (pMvSataChannel->identifyDevice[86] & 4) {
+ if (pMvSataChannel->identifyDevice[86] & 4)
+ {
KdPrint(("RR182x [%d]: Disable 8 bit PIO (CFA enabled) \n",
- pMvSataAdapter->adapterId));
+ pMvSataAdapter->adapterId));
if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_DISABLE_8_BIT_PIO, 0, 0, 0, 0) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d]: channel %d: "
- "mvStorageDevATASetFeatures failed\n",
- pMvSataAdapter->adapterId, channelNum);
+ MV_ATA_SET_FEATURES_DISABLE_8_BIT_PIO, 0,
+ 0, 0, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d]: channel %d: mvStorageDevATASetFeatures"
+ " failed\n", pMvSataAdapter->adapterId, channelNum);
return -1;
}
}
-
-#ifdef ENABLE_WRITE_CACHE
/* Write cache */
- if (pMvSataChannel->identifyDevice[82] & 0x20) {
- if (!(pMvSataChannel->identifyDevice[85] & 0x20)) {
- /* if not enabled by default */
- if (mvStorageDevATASetFeatures(pMvSataAdapter,
- channelNum, MV_ATA_SET_FEATURES_ENABLE_WCACHE, 0,
- 0, 0, 0) == MV_FALSE) {
- MV_ERROR("RR182x [%d]: channel %d: "
- "mvStorageDevATASetFeatures failed\n",
- pMvSataAdapter->adapterId, channelNum);
+#ifdef ENABLE_WRITE_CACHE
+ if (pMvSataChannel->identifyDevice[82] & 0x20)
+ {
+ if (!(pMvSataChannel->identifyDevice[85] & 0x20)) /* if not enabled by default */
+ {
+ if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_ENABLE_WCACHE, 0,
+ 0, 0, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d]: channel %d: mvStorageDevATASetFeatures failed\n",
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
}
KdPrint(("RR182x [%d]: channel %d, write cache enabled\n",
- pMvSataAdapter->adapterId, channelNum));
- } else {
+ pMvSataAdapter->adapterId, channelNum));
+ }
+ else
+ {
KdPrint(("RR182x [%d]: channel %d, write cache not supported\n",
- pMvSataAdapter->adapterId, channelNum));
+ pMvSataAdapter->adapterId, channelNum));
}
-#else
- /* disable write cache */
- if (pMvSataChannel->identifyDevice[85] & 0x20) {
- KdPrint(("RR182x [%d]: channel =%d, disable write cache\n",
- pMvSataAdapter->adapterId, channelNum));
- if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_DISABLE_WCACHE, 0, 0, 0, 0) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d]: channel %d: "
- "mvStorageDevATASetFeatures failed\n",
- pMvSataAdapter->adapterId, channelNum);
- return -1;
+#else /* disable write cache */
+ {
+ if (pMvSataChannel->identifyDevice[85] & 0x20)
+ {
+ KdPrint(("RR182x [%d]: channel =%d, disable write cache\n",
+ pMvSataAdapter->adapterId, channelNum));
+ if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_DISABLE_WCACHE, 0,
+ 0, 0, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d]: channel %d: mvStorageDevATASetFeatures failed\n",
+ pMvSataAdapter->adapterId, channelNum);
+ return -1;
+ }
}
+ KdPrint(("RR182x [%d]: channel=%d, write cache disabled\n",
+ pMvSataAdapter->adapterId, channelNum));
}
- KdPrint(("RR182x [%d]: channel=%d, write cache disabled\n",
- pMvSataAdapter->adapterId, channelNum));
#endif
/* Set transfer mode */
KdPrint(("RR182x [%d] Set transfer mode XFER_PIO_SLOW\n",
- pMvSataAdapter->adapterId));
+ pMvSataAdapter->adapterId));
if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_TRANSFER, MV_ATA_TRANSFER_PIO_SLOW, 0, 0, 0) ==
- MV_FALSE) {
+ MV_ATA_SET_FEATURES_TRANSFER,
+ MV_ATA_TRANSFER_PIO_SLOW, 0, 0, 0) ==
+ MV_FALSE)
+ {
MV_ERROR("RR182x [%d] channel %d: Set Features failed\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
- if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 1) {
+ if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 1)
+ {
pioMode = MV_ATA_TRANSFER_PIO_4;
- } else if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 2) {
+ }
+ else if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 2)
+ {
pioMode = MV_ATA_TRANSFER_PIO_3;
- } else {
- MV_ERROR("IAL Error in IDENTIFY info: PIO modes 3 and 4 not "
- "supported\n");
+ }
+ else
+ {
+ MV_ERROR("IAL Error in IDENTIFY info: PIO modes 3 and 4 not supported\n");
pioMode = MV_ATA_TRANSFER_PIO_SLOW;
}
KdPrint(("RR182x [%d] Set transfer mode XFER_PIO_4\n",
- pMvSataAdapter->adapterId));
+ pMvSataAdapter->adapterId));
pAdapter->mvChannel[channelNum].maxPioModeSupported = pioMode;
if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_TRANSFER, pioMode, 0, 0, 0) == MV_FALSE) {
+ MV_ATA_SET_FEATURES_TRANSFER,
+ pioMode, 0, 0, 0) == MV_FALSE)
+ {
MV_ERROR("RR182x [%d] channel %d: Set Features failed\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
udmaMode = MV_ATA_TRANSFER_UDMA_0;
- if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x40) {
+ if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x40)
+ {
udmaMode = MV_ATA_TRANSFER_UDMA_6;
- } else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x20) {
+ }
+ else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x20)
+ {
udmaMode = MV_ATA_TRANSFER_UDMA_5;
- } else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x10) {
+ }
+ else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x10)
+ {
udmaMode = MV_ATA_TRANSFER_UDMA_4;
- } else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 8) {
+ }
+ else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 8)
+ {
udmaMode = MV_ATA_TRANSFER_UDMA_3;
- } else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 4) {
+ }
+ else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 4)
+ {
udmaMode = MV_ATA_TRANSFER_UDMA_2;
}
KdPrint(("RR182x [%d] Set transfer mode XFER_UDMA_%d\n",
- pMvSataAdapter->adapterId, udmaMode & 0xf));
+ pMvSataAdapter->adapterId, udmaMode & 0xf));
pChannelInfo->maxUltraDmaModeSupported = udmaMode;
-#if 0
- if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_TRANSFER, udmaMode, 0, 0, 0) == MV_FALSE) {
+ /*if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_TRANSFER, udmaMode,
+ 0, 0, 0) == MV_FALSE)
+ {
MV_ERROR("RR182x [%d] channel %d: Set Features failed\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
return -1;
- }
-#endif
+ }*/
if (pChannelInfo->maxUltraDmaModeSupported == 0xFF)
return TRUE;
-
- do {
- if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_TRANSFER,
- pChannelInfo->maxUltraDmaModeSupported, 0, 0, 0) !=
- MV_FALSE) {
+ else
+ do
+ {
+ if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_TRANSFER,
+ pChannelInfo->maxUltraDmaModeSupported,
+ 0, 0, 0) == MV_FALSE)
+ {
+ if (pChannelInfo->maxUltraDmaModeSupported > MV_ATA_TRANSFER_UDMA_0)
+ {
+ if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
+ MV_REG_WRITE_BYTE(pMvSataAdapter->adapterIoBaseAddress,
+ pMvSataChannel->eDmaRegsOffset +
+ 0x11c, /* command reg */
+ MV_ATA_COMMAND_IDLE_IMMEDIATE);
+ mvMicroSecondsDelay(10000);
+ mvSataChannelHardReset(pMvSataAdapter, channelNum);
+ if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
+ return FALSE;
+ }
+ if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
+ return FALSE;
+ pChannelInfo->maxUltraDmaModeSupported--;
+ continue;
+ }
+ else return FALSE;
+ }
break;
- }
-
- if (pChannelInfo->maxUltraDmaModeSupported <=
- MV_ATA_TRANSFER_UDMA_0) {
- return FALSE;
- }
- if (mvStorageDevATASoftResetDevice(pMvSataAdapter,
- channelNum) == MV_FALSE) {
- mv_reg_write_byte(pMvSataAdapter->adapterIoBaseAddress,
- pMvSataChannel->eDmaRegsOffset + 0x11c,
- /* command reg */ MV_ATA_COMMAND_IDLE_IMMEDIATE);
- mvMicroSecondsDelay(10000);
- mvSataChannelHardReset(pMvSataAdapter, channelNum);
- if (mvStorageDevATASoftResetDevice(pMvSataAdapter,
- channelNum) == MV_FALSE)
- return FALSE;
- }
- if (mvSataChannelHardReset(pMvSataAdapter, channelNum) ==
- MV_FALSE)
- return FALSE;
- pChannelInfo->maxUltraDmaModeSupported--;
- } while (1);
+ }while (1);
-#ifdef ENABLE_READ_AHEAD
/* Read look ahead */
- if (pMvSataChannel->identifyDevice[82] & 0x40) {
- if (!(pMvSataChannel->identifyDevice[85] & 0x40)) {
- /* if not enabled by default */
- if (mvStorageDevATASetFeatures(pMvSataAdapter,
- channelNum, MV_ATA_SET_FEATURES_ENABLE_RLA, 0, 0,
- 0, 0) == MV_FALSE) {
- MV_ERROR("RR182x [%d] channel %d: Set Features "
- "failed\n", pMvSataAdapter->adapterId,
- channelNum);
+#ifdef ENABLE_READ_AHEAD
+ if (pMvSataChannel->identifyDevice[82] & 0x40)
+ {
+ if (!(pMvSataChannel->identifyDevice[85] & 0x40)) /* if not enabled by default */
+ {
+ if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_ENABLE_RLA, 0, 0,
+ 0, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d] channel %d: Set Features failed\n",
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
}
KdPrint(("RR182x [%d]: channel=%d, read look ahead enabled\n",
- pMvSataAdapter->adapterId, channelNum));
- } else {
- KdPrint(("RR182x [%d]: channel %d, Read Look Ahead not "
- "supported\n", pMvSataAdapter->adapterId, channelNum));
+ pMvSataAdapter->adapterId, channelNum));
}
-#else
- if (pMvSataChannel->identifyDevice[86] & 0x20) {
- KdPrint(("RR182x [%d]:channel %d, disable read look ahead\n",
- pMvSataAdapter->adapterId, channelNum));
- if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
- MV_ATA_SET_FEATURES_DISABLE_RLA, 0, 0, 0, 0) == MV_FALSE) {
- MV_ERROR("RR182x [%d]:channel %d: ATA Set Features "
- "failed\n", pMvSataAdapter->adapterId,
- channelNum);
- return -1;
- }
- }
- KdPrint(("RR182x [%d]:channel %d, read look ahead disabled\n",
- pMvSataAdapter->adapterId, channelNum));
-#endif
-
-#if 0
- KdPrint(("RR182x [%d]:channel %d, Set standby timer to 200 seconds\n",
- pMvSataAdapter->adapterId, channelNum));
- if (mvStorageDevATAExecuteNonUDMACommand(pMvSataAdapter, channelNum,
- MV_NON_UDMA_PROTOCOL_NON_DATA,
- MV_FALSE, /* isEXT*/
- NULL, 0, 0, /* features*/
- 40, /*sectorCount*/
- 0, /*lbaLow*/
- 0, /*lbaMid*/
- 0, /*lbaHigh*/
- 0, /*device*/
- MV_ATA_COMMAND_IDLE) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d]:channel %d: ATA Idle command failed\n",
- pMvSataAdapter->adapterId, channelNum);
- return -1;
+ else
+ {
+ KdPrint(("RR182x [%d]: channel %d, Read Look Ahead not supported\n",
+ pMvSataAdapter->adapterId, channelNum));
}
+#else
+ {
+ if (pMvSataChannel->identifyDevice[86] & 0x20)
+ {
+ KdPrint(("RR182x [%d]:channel %d, disable read look ahead\n",
+ pMvSataAdapter->adapterId, channelNum));
+ if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
+ MV_ATA_SET_FEATURES_DISABLE_RLA, 0, 0,
+ 0, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d]:channel %d: ATA Set Features failed\n",
+ pMvSataAdapter->adapterId, channelNum);
+ return -1;
+ }
+ }
+ KdPrint(("RR182x [%d]:channel %d, read look ahead disabled\n",
+ pMvSataAdapter->adapterId, channelNum));
+ }
#endif
-#if 0
- /* 2003-9-16 disable TCQ until we have better solution */
- if ((pMvSataChannel->identifyDevice[IDEN_SUPPORTED_COMMANDS2] & 2)) {
- MV_U8 depth;
- MV_BOOLEAN result;
- depth = (pMvSataChannel->identifyDevice[IDEN_QUEUE_DEPTH] &
- 0x1f) + 1;
- KdPrint(("RR182x [%d]: channel %d config EDMA, Queued Mode, "
- "queue depth %d\n", pMvSataAdapter->adapterId,
- channelNum, depth));
- result = mvSataConfigEdmaMode(pMvSataAdapter, channelNum,
- MV_EDMA_MODE_QUEUED, depth);
- if (result == MV_FALSE) {
- MV_ERROR("RR182x [%d] Error: mvSataConfigEdmaMode "
- "failed\n", pMvSataAdapter->adapterId);
+ {
+ KdPrint(("RR182x [%d]: channel %d config EDMA, Non Queued Mode\n",
+ pMvSataAdapter->adapterId,
+ channelNum));
+ if (mvSataConfigEdmaMode(pMvSataAdapter, channelNum,
+ MV_EDMA_MODE_NOT_QUEUED, 0) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d] channel %d Error: mvSataConfigEdmaMode failed\n",
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
- } else {
-#endif
- KdPrint(("RR182x [%d]: channel %d config EDMA, Non Queued Mode\n",
- pMvSataAdapter->adapterId, channelNum));
- if (mvSataConfigEdmaMode(pMvSataAdapter, channelNum,
- MV_EDMA_MODE_NOT_QUEUED, 0) == MV_FALSE) {
- MV_ERROR("RR182x [%d] channel %d Error: mvSataConfigEdmaMode "
- "failed\n", pMvSataAdapter->adapterId, channelNum);
- return -1;
}
-
/* Enable EDMA */
- if (mvSataEnableChannelDma(pMvSataAdapter, channelNum) == MV_FALSE) {
+ if (mvSataEnableChannelDma(pMvSataAdapter, channelNum) == MV_FALSE)
+ {
MV_ERROR("RR182x [%d] Failed to enable DMA, channel=%d\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
return -1;
}
MV_ERROR("RR182x [%d,%d]: channel started successfully\n",
- pMvSataAdapter->adapterId, channelNum);
+ pMvSataAdapter->adapterId, channelNum);
#ifndef FOR_DEMO
set_fail_led(pMvSataAdapter, channelNum, 0);
@@ -766,91 +787,82 @@ start_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
static void
hptmv_handle_event(void * data, int flag)
{
- IAL_ADAPTER_T *pAdapter;
- MV_SATA_ADAPTER *pMvSataAdapter;
- MV_U8 channelIndex;
-
- pAdapter = (IAL_ADAPTER_T *)data;
- pMvSataAdapter = &pAdapter->mvSataAdapter;
-
- mvOsSemTake(&pMvSataAdapter->semaphore);
- for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM;
- channelIndex++) {
- switch(pAdapter->sataEvents[channelIndex]) {
- case SATA_EVENT_CHANNEL_CONNECTED:
- /* Handle only connects */
- if (flag == 1)
- break;
- KdPrint(("RR182x [%d,%d]: new device connected\n",
- pMvSataAdapter->adapterId, channelIndex));
- hptmv_init_channel(pAdapter, channelIndex);
- if (mvSataConfigureChannel( pMvSataAdapter,
- channelIndex) == MV_FALSE) {
- MV_ERROR("RR182x [%d,%d] Failed to configure\n",
- pMvSataAdapter->adapterId,
- channelIndex);
- hptmv_free_channel(pAdapter, channelIndex);
- } else {
-#if 0
- mvSataChannelHardReset(pMvSataAdapter, channel);
-#endif
- if (start_channel( pAdapter, channelIndex)) {
- MV_ERROR("RR182x [%d,%d]Failed to start"
- " channel\n",
- pMvSataAdapter->adapterId,
- channelIndex);
- hptmv_free_channel(pAdapter,
- channelIndex);
- } else {
- device_change(pAdapter, channelIndex,
- TRUE);
+ IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)data;
+ MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
+ MV_U8 channelIndex;
+
+/* mvOsSemTake(&pMvSataAdapter->semaphore); */
+ for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
+ {
+ switch(pAdapter->sataEvents[channelIndex])
+ {
+ case SATA_EVENT_CHANNEL_CONNECTED:
+ /* Handle only connects */
+ if (flag == 1)
+ break;
+ KdPrint(("RR182x [%d,%d]: new device connected\n",
+ pMvSataAdapter->adapterId, channelIndex));
+ hptmv_init_channel(pAdapter, channelIndex);
+ if (mvSataConfigureChannel( pMvSataAdapter, channelIndex) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d,%d] Failed to configure\n",
+ pMvSataAdapter->adapterId, channelIndex);
+ hptmv_free_channel(pAdapter, channelIndex);
}
- }
- pAdapter->sataEvents[channelIndex] =
- SATA_EVENT_NO_CHANGE;
- break;
+ else
+ {
+ /*mvSataChannelHardReset(pMvSataAdapter, channel);*/
+ if (start_channel( pAdapter, channelIndex))
+ {
+ MV_ERROR("RR182x [%d,%d]Failed to start channel\n",
+ pMvSataAdapter->adapterId, channelIndex);
+ hptmv_free_channel(pAdapter, channelIndex);
+ }
+ else
+ {
+ device_change(pAdapter, channelIndex, TRUE);
+ }
+ }
+ pAdapter->sataEvents[channelIndex] = SATA_EVENT_NO_CHANGE;
+ break;
- case SATA_EVENT_CHANNEL_DISCONNECTED:
- /* Handle only disconnects */
- if (flag == 0)
+ case SATA_EVENT_CHANNEL_DISCONNECTED:
+ /* Handle only disconnects */
+ if (flag == 0)
+ break;
+ KdPrint(("RR182x [%d,%d]: device disconnected\n",
+ pMvSataAdapter->adapterId, channelIndex));
+ /* Flush pending commands */
+ if(pMvSataAdapter->sataChannel[channelIndex])
+ {
+ _VBUS_INST(&pAdapter->VBus)
+ mvSataFlushDmaQueue (pMvSataAdapter, channelIndex,
+ MV_FLUSH_TYPE_CALLBACK);
+ CheckPendingCall(_VBUS_P0);
+ mvSataRemoveChannel(pMvSataAdapter,channelIndex);
+ hptmv_free_channel(pAdapter, channelIndex);
+ pMvSataAdapter->sataChannel[channelIndex] = NULL;
+ KdPrint(("RR182x [%d,%d]: channel removed\n",
+ pMvSataAdapter->adapterId, channelIndex));
+ if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
+ Check_Idle_Call(pAdapter);
+ }
+ else
+ {
+ KdPrint(("RR182x [%d,%d]: channel already removed!!\n",
+ pMvSataAdapter->adapterId, channelIndex));
+ }
+ pAdapter->sataEvents[channelIndex] = SATA_EVENT_NO_CHANGE;
break;
- KdPrint(("RR182x [%d,%d]: device disconnected\n",
- pMvSataAdapter->adapterId, channelIndex));
- /* Flush pending commands */
- if(pMvSataAdapter->sataChannel[channelIndex]) {
- _VBUS_INST(&pAdapter->VBus)
- mvSataFlushDmaQueue (pMvSataAdapter,
- channelIndex, MV_FLUSH_TYPE_CALLBACK);
- CheckPendingCall(_VBUS_P0);
- mvSataRemoveChannel(pMvSataAdapter,
- channelIndex);
- hptmv_free_channel(pAdapter, channelIndex);
- pMvSataAdapter->sataChannel[channelIndex] =
- NULL;
- KdPrint(("RR182x [%d,%d]: channel removed\n",
- pMvSataAdapter->adapterId,
- channelIndex));
- if (pAdapter->outstandingCommands==0 &&
- DPC_Request_Nums==0)
- Check_Idle_Call(pAdapter);
- } else {
- KdPrint(("RR182x [%d,%d]: channel already "
- "removed!!\n",
- pMvSataAdapter->adapterId,
- channelIndex));
- }
- pAdapter->sataEvents[channelIndex] =
- SATA_EVENT_NO_CHANGE;
- break;
- case SATA_EVENT_NO_CHANGE:
- break;
+ case SATA_EVENT_NO_CHANGE:
+ break;
- default:
- break;
+ default:
+ break;
}
}
- mvOsSemRelease(&pMvSataAdapter->semaphore);
+/* mvOsSemRelease(&pMvSataAdapter->semaphore); */
}
#define EVENT_CONNECT 1
@@ -859,161 +871,122 @@ hptmv_handle_event(void * data, int flag)
static void
hptmv_handle_event_connect(void *data)
{
- hptmv_handle_event (data, 0);
+ hptmv_handle_event (data, 0);
}
static void
hptmv_handle_event_disconnect(void *data)
{
- hptmv_handle_event (data, 1);
+ hptmv_handle_event (data, 1);
}
static MV_BOOLEAN
hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter, MV_EVENT_TYPE eventType,
- MV_U32 param1, MV_U32 param2)
+ MV_U32 param1, MV_U32 param2)
{
- IAL_ADAPTER_T *pAdapter = pMvSataAdapter->IALData;
+ IAL_ADAPTER_T *pAdapter = pMvSataAdapter->IALData;
- switch (eventType) {
- case MV_EVENT_TYPE_SATA_CABLE:
+ switch (eventType)
{
- MV_U8 channel = param2;
+ case MV_EVENT_TYPE_SATA_CABLE:
+ {
+ MV_U8 channel = param2;
- if (param1 == EVENT_CONNECT) {
- pAdapter->sataEvents[channel] =
- SATA_EVENT_CHANNEL_CONNECTED;
- KdPrint(("RR182x [%d,%d]: device connected event "
- "received\n", pMvSataAdapter->adapterId,
- channel));
- /*
- * Delete previous timers (if multiple drives connected
- * in the same time
- */
- pAdapter->event_timer_connect =
- timeout(hptmv_handle_event_connect, pAdapter,10*hz);
- } else if (param1 == EVENT_DISCONNECT) {
- pAdapter->sataEvents[channel] =
- SATA_EVENT_CHANNEL_DISCONNECTED;
- KdPrint(("RR182x [%d,%d]: device disconnected event "
- "received \n", pMvSataAdapter->adapterId,
- channel));
- device_change(pAdapter, channel, FALSE);
- /*
- * Delete previous timers (if multiple drives
- * disconnected in the same time
- */
- pAdapter->event_timer_disconnect =
- timeout(hptmv_handle_event_disconnect, pAdapter,
- 10*hz);
- } else {
- MV_ERROR("RR182x: illigal value for param1(%d) at "
- "connect/disconect event, host=%d\n", param1,
- pMvSataAdapter->adapterId );
+ if (param1 == EVENT_CONNECT)
+ {
+ pAdapter->sataEvents[channel] = SATA_EVENT_CHANNEL_CONNECTED;
+ KdPrint(("RR182x [%d,%d]: device connected event received\n",
+ pMvSataAdapter->adapterId, channel));
+ /* Delete previous timers (if multiple drives connected in the same time */
+ pAdapter->event_timer_connect = timeout(hptmv_handle_event_connect, pAdapter, 10*hz);
+ }
+ else if (param1 == EVENT_DISCONNECT)
+ {
+ pAdapter->sataEvents[channel] = SATA_EVENT_CHANNEL_DISCONNECTED;
+ KdPrint(("RR182x [%d,%d]: device disconnected event received \n",
+ pMvSataAdapter->adapterId, channel));
+ device_change(pAdapter, channel, FALSE);
+ /* Delete previous timers (if multiple drives disconnected in the same time */
+ /*pAdapter->event_timer_disconnect = timeout(hptmv_handle_event_disconnect, pAdapter, 10*hz); */
+ /*It is not necessary to wait, handle it directly*/
+ hptmv_handle_event_disconnect(pAdapter);
+ }
+ else
+ {
- }
- break;
- }
- case MV_EVENT_TYPE_ADAPTER_ERROR:
- KdPrint(("RR182x: DEVICE error event received, pci cause "
- "reg=%x, don't how to handle this\n", param1));
- return MV_TRUE;
- default:
- MV_ERROR("RR182x[%d]: unknown event type (%d)\n",
- pMvSataAdapter->adapterId, eventType);
- return MV_FALSE;
+ MV_ERROR("RR182x: illigal value for param1(%d) at "
+ "connect/disconect event, host=%d\n", param1,
+ pMvSataAdapter->adapterId );
+
+ }
+ }
+ break;
+ case MV_EVENT_TYPE_ADAPTER_ERROR:
+ KdPrint(("RR182x: DEVICE error event received, pci cause "
+ "reg=%x, don't how to handle this\n", param1));
+ return MV_TRUE;
+ default:
+ MV_ERROR("RR182x[%d]: unknown event type (%d)\n",
+ pMvSataAdapter->adapterId, eventType);
+ return MV_FALSE;
}
return MV_TRUE;
}
-static void
-hptmv_map_req(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
-{
- dma_addr_t *addr;
-
- addr = (dma_addr_t *)arg;
-
- if (error || nsegs != 1)
- return;
-
- *addr = segs[0].ds_addr;
-
- return;
-}
-
-static int
+static int
hptmv_allocate_edma_queues(IAL_ADAPTER_T *pAdapter)
{
- if (bus_dmamem_alloc(pAdapter->req_dmat,
- (void **)&pAdapter->requestsArrayBaseAddr, BUS_DMA_WAITOK,
- &pAdapter->req_map) != 0) {
- MV_ERROR("RR182x[%d]: Failed to allocate memory for EDMA "
- "request queues\n", pAdapter->mvSataAdapter.adapterId);
+ pAdapter->requestsArrayBaseAddr = (MV_U8 *)contigmalloc(REQUESTS_ARRAY_SIZE,
+ M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
+ if (pAdapter->requestsArrayBaseAddr == NULL)
+ {
+ MV_ERROR("RR182x[%d]: Failed to allocate memory for EDMA request"
+ " queues\n", pAdapter->mvSataAdapter.adapterId);
return -1;
}
-
- (void)bus_dmamap_load(pAdapter->req_dmat, pAdapter->req_map,
- pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, hptmv_map_req,
- &pAdapter->requestsArrayBaseDmaAddr, 0);
-
- pAdapter->requestsArrayBaseAlignedAddr =
- pAdapter->requestsArrayBaseAddr;
+ pAdapter->requestsArrayBaseDmaAddr = fOsPhysicalAddress(pAdapter->requestsArrayBaseAddr);
+ pAdapter->requestsArrayBaseAlignedAddr = pAdapter->requestsArrayBaseAddr;
pAdapter->requestsArrayBaseAlignedAddr += MV_EDMA_REQUEST_QUEUE_SIZE;
- pAdapter->requestsArrayBaseAlignedAddr =
- (MV_U8 *)(((ULONG_PTR)pAdapter->requestsArrayBaseAlignedAddr) &
- ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1));
- pAdapter->requestsArrayBaseDmaAlignedAddr =
- pAdapter->requestsArrayBaseDmaAddr;
+ pAdapter->requestsArrayBaseAlignedAddr = (MV_U8 *)
+ (((ULONG_PTR)pAdapter->requestsArrayBaseAlignedAddr) & ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1));
+ pAdapter->requestsArrayBaseDmaAlignedAddr = pAdapter->requestsArrayBaseDmaAddr;
pAdapter->requestsArrayBaseDmaAlignedAddr += MV_EDMA_REQUEST_QUEUE_SIZE;
- pAdapter->requestsArrayBaseDmaAlignedAddr &=
- ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1);
+ pAdapter->requestsArrayBaseDmaAlignedAddr &= ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1);
- if ((pAdapter->requestsArrayBaseDmaAlignedAddr -
- pAdapter->requestsArrayBaseDmaAddr) !=
- (pAdapter->requestsArrayBaseAlignedAddr -
- pAdapter->requestsArrayBaseAddr)) {
+ if ((pAdapter->requestsArrayBaseDmaAlignedAddr - pAdapter->requestsArrayBaseDmaAddr) !=
+ (pAdapter->requestsArrayBaseAlignedAddr - pAdapter->requestsArrayBaseAddr))
+ {
MV_ERROR("RR182x[%d]: Error in Request Quueues Alignment\n",
- pAdapter->mvSataAdapter.adapterId);
- bus_dmamap_unload(pAdapter->req_dmat, pAdapter->req_map);
- bus_dmamem_free(pAdapter->req_dmat,
- pAdapter->requestsArrayBaseAddr, pAdapter->req_map);
+ pAdapter->mvSataAdapter.adapterId);
+ contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
return -1;
}
/* response queues */
- if (bus_dmamem_alloc(pAdapter->resp_dmat,
- (void **)&pAdapter->responsesArrayBaseAddr, BUS_DMA_WAITOK,
- &pAdapter->resp_map) != 0) {
- MV_ERROR("RR182x[%d]: Failed to allocate memory for EDMA "
- "response queues\n", pAdapter->mvSataAdapter.adapterId);
- bus_dmamap_unload(pAdapter->req_dmat, pAdapter->req_map);
- bus_dmamem_free(pAdapter->req_dmat,
- pAdapter->requestsArrayBaseAddr, pAdapter->req_map);
+ pAdapter->responsesArrayBaseAddr = (MV_U8 *)contigmalloc(RESPONSES_ARRAY_SIZE,
+ M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
+ if (pAdapter->responsesArrayBaseAddr == NULL)
+ {
+ MV_ERROR("RR182x[%d]: Failed to allocate memory for EDMA response"
+ " queues\n", pAdapter->mvSataAdapter.adapterId);
+ contigfree(pAdapter->requestsArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
return -1;
}
-
- (void)bus_dmamap_load(pAdapter->resp_dmat, pAdapter->resp_map,
- pAdapter->responsesArrayBaseAddr, RESPONSES_ARRAY_SIZE,
- hptmv_map_req, &pAdapter->responsesArrayBaseDmaAddr, 0);
-
- pAdapter->responsesArrayBaseAlignedAddr =
- pAdapter->responsesArrayBaseAddr;
+ pAdapter->responsesArrayBaseDmaAddr = fOsPhysicalAddress(pAdapter->responsesArrayBaseAddr);
+ pAdapter->responsesArrayBaseAlignedAddr = pAdapter->responsesArrayBaseAddr;
pAdapter->responsesArrayBaseAlignedAddr += MV_EDMA_RESPONSE_QUEUE_SIZE;
- pAdapter->responsesArrayBaseAlignedAddr =
- (MV_U8 *)(((ULONG_PTR)pAdapter->responsesArrayBaseAlignedAddr) &
- ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1));
- pAdapter->responsesArrayBaseDmaAlignedAddr =
- pAdapter->responsesArrayBaseDmaAddr;
- pAdapter->responsesArrayBaseDmaAlignedAddr +=
- MV_EDMA_RESPONSE_QUEUE_SIZE;
- pAdapter->responsesArrayBaseDmaAlignedAddr &=
- ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1);
+ pAdapter->responsesArrayBaseAlignedAddr = (MV_U8 *)
+ (((ULONG_PTR)pAdapter->responsesArrayBaseAlignedAddr) & ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1));
+ pAdapter->responsesArrayBaseDmaAlignedAddr = pAdapter->responsesArrayBaseDmaAddr;
+ pAdapter->responsesArrayBaseDmaAlignedAddr += MV_EDMA_RESPONSE_QUEUE_SIZE;
+ pAdapter->responsesArrayBaseDmaAlignedAddr &= ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1);
- if ((pAdapter->responsesArrayBaseDmaAlignedAddr -
- pAdapter->responsesArrayBaseDmaAddr) !=
- (pAdapter->responsesArrayBaseAlignedAddr -
- pAdapter->responsesArrayBaseAddr)) {
+ if ((pAdapter->responsesArrayBaseDmaAlignedAddr - pAdapter->responsesArrayBaseDmaAddr) !=
+ (pAdapter->responsesArrayBaseAlignedAddr - pAdapter->responsesArrayBaseAddr))
+ {
MV_ERROR("RR182x[%d]: Error in Response Quueues Alignment\n",
- pAdapter->mvSataAdapter.adapterId);
- hptmv_free_edma_queues(pAdapter);
+ pAdapter->mvSataAdapter.adapterId);
+ contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
+ contigfree(pAdapter->responsesArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
return -1;
}
return 0;
@@ -1022,12 +995,8 @@ hptmv_allocate_edma_queues(IAL_ADAPTER_T *pAdapter)
static void
hptmv_free_edma_queues(IAL_ADAPTER_T *pAdapter)
{
- bus_dmamap_unload(pAdapter->req_dmat, pAdapter->req_map);
- bus_dmamem_free(pAdapter->req_dmat, pAdapter->requestsArrayBaseAddr,
- pAdapter->req_map);
- bus_dmamap_unload(pAdapter->resp_dmat, pAdapter->resp_map);
- bus_dmamem_free(pAdapter->resp_dmat, pAdapter->responsesArrayBaseAddr,
- pAdapter->resp_map);
+ contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
+ contigfree(pAdapter->responsesArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
}
static PVOID
@@ -1035,8 +1004,7 @@ AllocatePRDTable(IAL_ADAPTER_T *pAdapter)
{
PVOID ret;
if (pAdapter->pFreePRDLink) {
- KdPrint(("pAdapter->pFreePRDLink:%p\n",
- pAdapter->pFreePRDLink));
+ KdPrint(("pAdapter->pFreePRDLink:%p\n",pAdapter->pFreePRDLink));
ret = pAdapter->pFreePRDLink;
pAdapter->pFreePRDLink = *(void**)ret;
return ret;
@@ -1060,7 +1028,7 @@ fRegisterVdevice(IAL_ADAPTER_T *pAdapter)
PVBus pVBus;
int i,j;
- for(i = 0; i < MV_SATA_CHANNELS_NUM; i++) {
+ for(i=0;i<MV_SATA_CHANNELS_NUM;i++) {
pPhysical = &(pAdapter->VDevices[i]);
pLogical = pPhysical;
while (pLogical->pParent) pLogical = pLogical->pParent;
@@ -1068,27 +1036,24 @@ fRegisterVdevice(IAL_ADAPTER_T *pAdapter)
pPhysical->vf_bootmark = pLogical->vf_bootmark = 0;
continue;
}
- if (pLogical->VDeviceType == VD_SPARE ||
- pPhysical != fGetFirstChild(pLogical))
+ if (pLogical->VDeviceType==VD_SPARE || pPhysical!=fGetFirstChild(pLogical))
continue;
pVBus = &pAdapter->VBus;
- if(pVBus) {
+ if(pVBus)
+ {
j=0;
- while(j < MAX_VDEVICE_PER_VBUS && pVBus->pVDevice[j])
- j++;
- if (j < MAX_VDEVICE_PER_VBUS) {
+ while(j<MAX_VDEVICE_PER_VBUS && pVBus->pVDevice[j]) j++;
+ if(j<MAX_VDEVICE_PER_VBUS){
pVBus->pVDevice[j] = pLogical;
pLogical->pVBus = pVBus;
if (j>0 && pLogical->vf_bootmark) {
if (pVBus->pVDevice[0]->vf_bootmark) {
fResetBootMark(pLogical);
- } else {
- do {
- pVBus->pVDevice[j] =
- pVBus->pVDevice[j-1];
- } while (--j);
+ }
+ else {
+ do { pVBus->pVDevice[j] = pVBus->pVDevice[j-1]; } while (--j);
pVBus->pVDevice[0] = pLogical;
}
}
@@ -1100,27 +1065,26 @@ fRegisterVdevice(IAL_ADAPTER_T *pAdapter)
PVDevice
GetSpareDisk(_VBUS_ARG PVDevice pArray)
{
- IAL_ADAPTER_T *pAdapter;
- ULONG capacity;
+ IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)pArray->pVBus->OsExt;
+ ULONG capacity = LongDiv(pArray->VDeviceCapacity, pArray->u.array.bArnMember-1);
ULONG thiscap, maxcap = MAX_LBA_T;
PVDevice pVDevice, pFind = NULL;
int i;
- pAdapter = (IAL_ADAPTER_T *)pArray->pVBus->OsExt;
- capacity =
- LongDiv(pArray->VDeviceCapacity, pArray->u.array.bArnMember-1);
- for (i = 0;i < MV_SATA_CHANNELS_NUM; i++) {
+ for(i=0;i<MV_SATA_CHANNELS_NUM;i++)
+ {
pVDevice = &pAdapter->VDevices[i];
if(!pVDevice)
continue;
- thiscap = pArray->vf_format_v2 ?
- pVDevice->u.disk.dDeRealCapacity : pVDevice->VDeviceCapacity;
+ thiscap = pArray->vf_format_v2? pVDevice->u.disk.dDeRealCapacity : pVDevice->VDeviceCapacity;
/* find the smallest usable spare disk */
if (pVDevice->VDeviceType==VD_SPARE &&
- pVDevice->u.disk.df_on_line && thiscap < maxcap &&
- thiscap >= capacity) {
- maxcap = pVDevice->VDeviceCapacity;
- pFind = pVDevice;
+ pVDevice->u.disk.df_on_line &&
+ thiscap < maxcap &&
+ thiscap >= capacity)
+ {
+ maxcap = pVDevice->VDeviceCapacity;
+ pFind = pVDevice;
}
}
return pFind;
@@ -1137,16 +1101,10 @@ fDeReadWrite(PDevice pDev, ULONG Lba, UCHAR Cmd, void *tmpBuffer)
void HPTLIBAPI fDeSelectMode(PDevice pDev, UCHAR NewMode)
{
-#ifndef SIMULATE
- MV_SATA_CHANNEL *pSataChannel;
- MV_SATA_ADAPTER *pSataAdapter;
- MV_U8 channelIndex;
+ MV_SATA_CHANNEL *pSataChannel = pDev->mv;
+ MV_SATA_ADAPTER *pSataAdapter = pSataChannel->mvSataAdapter;
+ MV_U8 channelIndex = pSataChannel->channelNumber;
UCHAR mvMode;
-
- pSataChannel = pDev->mv;
- pSataAdapter = pSataChannel->mvSataAdapter;
- channelIndex = pSataChannel->channelNumber;
-
/* 508x don't use MW-DMA? */
if (NewMode>4 && NewMode<8) NewMode = 4;
pDev->bDeModeSetting = NewMode;
@@ -1164,25 +1122,26 @@ void HPTLIBAPI fDeSelectMode(PDevice pDev, UCHAR NewMode)
mvSataFlushDmaQueue (pSataAdapter, channelIndex, MV_FLUSH_TYPE_NONE);
if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
- MV_ATA_SET_FEATURES_TRANSFER, mvMode, 0, 0, 0) == MV_FALSE) {
+ MV_ATA_SET_FEATURES_TRANSFER,
+ mvMode, 0, 0, 0) == MV_FALSE)
+ {
KdPrint(("channel %d: Set Features failed\n", channelIndex));
}
/* Enable EDMA */
if (mvSataEnableChannelDma(pSataAdapter, channelIndex) == MV_FALSE)
KdPrint(("Failed to enable DMA, channel=%d", channelIndex));
-#endif
}
#ifdef SUPPORT_ARRAY
#define IdeRegisterVDevice fCheckArray
-#else
+#else
void
IdeRegisterVDevice(PDevice pDev)
{
PVDevice pVDev = Map2pVDevice(pDev);
pVDev->VDeviceType = pDev->df_atapi? VD_ATAPI :
- pDev->df_removable_drive ? VD_REMOVABLE : VD_SINGLE_DISK;
+ pDev->df_removable_drive? VD_REMOVABLE : VD_SINGLE_DISK;
pVDev->vf_online = 1;
pVDev->VDeviceCapacity = pDev->dDeRealCapacity;
pVDev->pfnSendCommand = pfnSendCommand[pVDev->VDeviceType];
@@ -1190,16 +1149,38 @@ IdeRegisterVDevice(PDevice pDev)
}
#endif
+static __inline PBUS_DMAMAP
+dmamap_get(struct IALAdapter * pAdapter)
+{
+ PBUS_DMAMAP p = pAdapter->pbus_dmamap_list;
+ if (p)
+ pAdapter->pbus_dmamap_list = p-> next;
+ return p;
+}
+
+static __inline void
+dmamap_put(PBUS_DMAMAP p)
+{
+ p->next = p->pAdapter->pbus_dmamap_list;
+ p->pAdapter->pbus_dmamap_list = p;
+}
+
+/*Since mtx not provide the initialize when declare, so we Final init here to initialize the global mtx*/
+#if __FreeBSD_version >= 500000
+static void hpt_init(void *dummy)
+{
+ mtx_init(&driver_lock, "hptlock", NULL, MTX_SPIN);
+}
+SYSINIT(hptinit, SI_SUB_CONFIGURE, SI_ORDER_FIRST, hpt_init, NULL);
+#endif
+
static int num_adapters = 0;
static int
init_adapter(IAL_ADAPTER_T *pAdapter)
{
- PCommand pCmd;
- pPrivCommand prvCmd;
PVBus _vbus_p = &pAdapter->VBus;
MV_SATA_ADAPTER *pMvSataAdapter;
- PUCHAR PRDTable;
- int i, channel, rid, error;
+ int i, channel, rid;
PVDevice pVDev;
@@ -1207,10 +1188,11 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
pAdapter->next = 0;
- if(gIal_Adapter == 0) {
+ if(gIal_Adapter == 0){
gIal_Adapter = pAdapter;
pCurAdapter = gIal_Adapter;
- } else {
+ }
+ else {
pCurAdapter->next = pAdapter;
pCurAdapter = pAdapter;
}
@@ -1221,72 +1203,55 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
_vbus_p->OsExt = (void *)pAdapter;
pMvSataAdapter->IALData = pAdapter;
- if (bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT,
- BUS_SPACE_MAXADDR, NULL, NULL, BUS_SPACE_MAXSIZE_32BIT,
- MV_MAX_SEGMENTS, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
- &pAdapter->parent_dmat) != 0) {
- MV_ERROR("RR182x: Failed to create busdma resources\n");
- unlock_driver(oldspl);
- return (ENOMEM);
- }
-
- if (bus_dma_tag_create(pAdapter->parent_dmat, PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- REQUESTS_ARRAY_SIZE, 1, REQUESTS_ARRAY_SIZE, 0, NULL, NULL,
- &pAdapter->req_dmat) != 0) {
- MV_ERROR("RR182x: Failed to create busdma resources\n");
- error = ENOMEM;
- goto unregister;
- }
-
- if (bus_dma_tag_create(pAdapter->parent_dmat, PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- RESPONSES_ARRAY_SIZE, 1, RESPONSES_ARRAY_SIZE, 0, NULL, NULL,
- &pAdapter->resp_dmat) != 0) {
- MV_ERROR("RR182x: Failed to create busdma resources\n");
- error = ENOMEM;
- goto unregister;
+ if (bus_dma_tag_create(NULL,/* parent */
+ 4, /* alignment */
+ BUS_SPACE_MAXADDR_32BIT+1, /* boundary */
+ BUS_SPACE_MAXADDR, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ PAGE_SIZE * (MAX_SG_DESCRIPTORS-1), /* maxsize */
+ MAX_SG_DESCRIPTORS, /* nsegments */
+ 0x10000, /* maxsegsize */
+ BUS_DMA_WAITOK, /* flags */
+#if __FreeBSD_version>502000
+ busdma_lock_mutex, /* lockfunc */
+ &driver_lock, /* lockfuncarg */
+#endif
+ &pAdapter->io_dma_parent /* tag */))
+ {
+ return ENXIO;;
}
- if (bus_dma_tag_create(pAdapter->parent_dmat, 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- MAXBSIZE, MV_MAX_SEGMENTS, MAXBSIZE, 0, busdma_lock_mutex, &Giant,
- &pAdapter->buf_dmat) != 0) {
- MV_ERROR("RR182x: Failed to create busdma resources\n");
- error = ENOMEM;
- goto unregister;
- }
- if (hptmv_allocate_edma_queues(pAdapter)) {
+ if (hptmv_allocate_edma_queues(pAdapter))
+ {
MV_ERROR("RR182x: Failed to allocate memory for EDMA queues\n");
- error = ENOMEM;
- goto unregister;
+ unlock_driver(oldspl);
+ return ENOMEM;
}
/* also map EPROM address */
rid = 0x10;
- if ((pAdapter->mem_res = bus_alloc_resource(pAdapter->hpt_dev,
- SYS_RES_MEMORY, &rid, 0, ~0, MV_SATA_PCI_BAR0_SPACE_SIZE+0x40000,
- RF_ACTIVE)) == 0) {
+ if (!(pAdapter->mem_res = bus_alloc_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, &rid,
+ 0, ~0, MV_SATA_PCI_BAR0_SPACE_SIZE+0x40000, RF_ACTIVE))
+ ||
+ !(pMvSataAdapter->adapterIoBaseAddress = rman_get_virtual(pAdapter->mem_res)))
+ {
MV_ERROR("RR182x: Failed to remap memory space\n");
- error = ENXIO;
- goto unregister;
+ hptmv_free_edma_queues(pAdapter);
+ unlock_driver(oldspl);
+ return ENXIO;
+ }
+ else
+ {
+ KdPrint(("RR182x: io base address 0x%p\n", pMvSataAdapter->adapterIoBaseAddress));
}
- /*
- * This field is opaque. Abuse it so that the bus_space functions
- * can get the info that they need when called.
- */
- pMvSataAdapter->adapterIoBaseAddress = pAdapter;
- pAdapter->mem_bsh = rman_get_bushandle(pAdapter->mem_res);
- pAdapter->mem_btag = rman_get_bustag(pAdapter->mem_res);
-
pMvSataAdapter->adapterId = num_adapters++;
/* get the revision ID */
- pMvSataAdapter->pciConfigRevisionId =
- pci_read_config(pAdapter->hpt_dev, PCIR_REVID, 1);
+ pMvSataAdapter->pciConfigRevisionId = pci_read_config(pAdapter->hpt_dev, PCIR_REVID, 1);
pMvSataAdapter->pciConfigDeviceId = pci_get_device(pAdapter->hpt_dev);
-
+
/* init RR182x */
pMvSataAdapter->intCoalThre[0]= 1;
pMvSataAdapter->intCoalThre[1]= 1;
@@ -1297,11 +1262,15 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
pMvSataAdapter->pciInterruptMask = 0xd77fe6ul;
pMvSataAdapter->mvSataEventNotify = hptmv_event_notify;
- if (mvSataInitAdapter(pMvSataAdapter) == MV_FALSE) {
+ if (mvSataInitAdapter(pMvSataAdapter) == MV_FALSE)
+ {
MV_ERROR("RR182x[%d]: core failed to initialize the adapter\n",
- pMvSataAdapter->adapterId);
- error = ENXIO;
- goto unregister;
+ pMvSataAdapter->adapterId);
+unregister:
+ bus_release_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, rid, pAdapter->mem_res);
+ hptmv_free_edma_queues(pAdapter);
+ unlock_driver(oldspl);
+ return ENXIO;
}
pAdapter->ver_601 = pMvSataAdapter->pcbVersion;
@@ -1312,103 +1281,98 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
/* setup command blocks */
KdPrint(("Allocate command blocks\n"));
_vbus_(pFreeCommands) = 0;
- pAdapter->pCommandBlocks = malloc(sizeof(struct _Command) *
- MAX_COMMAND_BLOCKS_FOR_EACH_VBUS, M_DEVBUF, M_ZERO | M_WAITOK);
- KdPrint(("pCommandBlocks:%p\n", pAdapter->pCommandBlocks));
-
- /*
- * Gotta cheat here. The _Command struct only gives us a single
- * pointer for private data, but we need to store more than that.
- * Of course the pCommand retains no type stability, and FreeCommand
- * is hidden in the binary object, so gotta track these on our own
- * list.
- */
- pAdapter->pPrivateBlocks = malloc(sizeof(struct _privCommand) *
- MAX_COMMAND_BLOCKS_FOR_EACH_VBUS, M_DEVBUF, M_ZERO | M_WAITOK);
- TAILQ_INIT(&pAdapter->PrivCmdTQH);
-
- for (i = 0; i < MAX_COMMAND_BLOCKS_FOR_EACH_VBUS; i++) {
- pCmd = &pAdapter->pCommandBlocks[i];
- prvCmd = &pAdapter->pPrivateBlocks[i];
- prvCmd->pAdapter = pAdapter;
- if ((error = bus_dmamap_create(pAdapter->buf_dmat, 0,
- &prvCmd->buf_map)) == 0) {
- FreeCommand(_VBUS_P (pCmd));
- FreePrivCommand(pAdapter, prvCmd);
- } else
- break;
+ pAdapter->pCommandBlocks =
+ malloc(sizeof(struct _Command) * MAX_COMMAND_BLOCKS_FOR_EACH_VBUS, M_DEVBUF, M_NOWAIT);
+ KdPrint(("pCommandBlocks:%p\n",pAdapter->pCommandBlocks));
+ if (!pAdapter->pCommandBlocks) {
+ MV_ERROR("insufficient memory\n");
+ goto unregister;
}
- /* setup PRD Tables */
- KdPrint(("Allocate PRD Tables\n"));
- pAdapter->pFreePRDLink = 0;
-
- if (bus_dma_tag_create(pAdapter->parent_dmat, PAGE_SIZE, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- PRD_ENTRIES_SIZE * PRD_TABLES_FOR_VBUS, 1,
- PRD_ENTRIES_SIZE * PRD_TABLES_FOR_VBUS, 0, NULL, NULL,
- &pAdapter->prd_dmat) != 0) {
- MV_ERROR("RR182x: Failed to create busdma resources\n");
- error = ENOMEM;
- goto unregister;
+ for (i=0; i<MAX_COMMAND_BLOCKS_FOR_EACH_VBUS; i++) {
+ FreeCommand(_VBUS_P &(pAdapter->pCommandBlocks[i]));
}
- if (bus_dmamem_alloc(pAdapter->prd_dmat,
- (void **)&pAdapter->prdTableAddr, BUS_DMA_WAITOK,
- &pAdapter->prd_map) != 0)
+ /*Set up the bus_dmamap*/
+ pAdapter->pbus_dmamap = (PBUS_DMAMAP)malloc (sizeof(struct _BUS_DMAMAP) * MAX_QUEUE_COMM, M_DEVBUF, M_NOWAIT);
+ if(!pAdapter->pbus_dmamap) {
+ MV_ERROR("insufficient memory\n");
+ free(pAdapter->pCommandBlocks, M_DEVBUF);
goto unregister;
+ }
- (void)bus_dmamap_load(pAdapter->prd_dmat, pAdapter->prd_map,
- pAdapter->prdTableAddr, PRD_ENTRIES_SIZE * PRD_TABLES_FOR_VBUS,
- hptmv_map_req, &pAdapter->prdTableDmaAddr, 0);
+ memset((void *)pAdapter->pbus_dmamap, 0, sizeof(struct _BUS_DMAMAP) * MAX_QUEUE_COMM);
+ pAdapter->pbus_dmamap_list = 0;
+ for (i=0; i < MAX_QUEUE_COMM; i++) {
+ PBUS_DMAMAP pmap = &(pAdapter->pbus_dmamap[i]);
+ pmap->pAdapter = pAdapter;
+ dmamap_put(pmap);
+ if(bus_dmamap_create(pAdapter->io_dma_parent, 0, &pmap->dma_map)) {
+ MV_ERROR("Can not allocate dma map\n");
+ free(pAdapter->pCommandBlocks, M_DEVBUF);
+ free(pAdapter->pbus_dmamap, M_DEVBUF);
+ goto unregister;
+ }
+ }
+ /* setup PRD Tables */
+ KdPrint(("Allocate PRD Tables\n"));
+ pAdapter->pFreePRDLink = 0;
+
+ pAdapter->prdTableAddr = (PUCHAR)contigmalloc(
+ (PRD_ENTRIES_SIZE*PRD_TABLES_FOR_VBUS + 32), M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
+
KdPrint(("prdTableAddr:%p\n",pAdapter->prdTableAddr));
if (!pAdapter->prdTableAddr) {
MV_ERROR("insufficient PRD Tables\n");
- error = ENOMEM;
goto unregister;
}
-
- PRDTable = pAdapter->prdTableAddr;
- for (i = 0; i < PRD_TABLES_FOR_VBUS; i++) {
- KdPrint(("i= %d, pAdapter->pFreePRDLink= %p\n", i,
- pAdapter->pFreePRDLink));
- FreePRDTable(pAdapter, PRDTable);
- PRDTable += PRD_ENTRIES_SIZE;
+ pAdapter->prdTableAlignedAddr = (PUCHAR)(((ULONG_PTR)pAdapter->prdTableAddr + 0x1f) & ~(ULONG_PTR)0x1fL);
+ {
+ PUCHAR PRDTable = pAdapter->prdTableAlignedAddr;
+ for (i=0; i<PRD_TABLES_FOR_VBUS; i++)
+ {
+/* KdPrint(("i=%d,pAdapter->pFreePRDLink=%p\n",i,pAdapter->pFreePRDLink)); */
+ FreePRDTable(pAdapter, PRDTable);
+ PRDTable += PRD_ENTRIES_SIZE;
+ }
}
/* enable the adapter interrupts */
/* configure and start the connected channels*/
- for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++) {
+ for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++)
+ {
pAdapter->mvChannel[channel].online = MV_FALSE;
if (mvSataIsStorageDeviceConnected(pMvSataAdapter, channel)
- != MV_TRUE)
- continue;
-
- KdPrint(("RR182x[%d]: channel %d is connected\n",
- pMvSataAdapter->adapterId, channel));
+ == MV_TRUE)
+ {
+ KdPrint(("RR182x[%d]: channel %d is connected\n",
+ pMvSataAdapter->adapterId, channel));
- if (hptmv_init_channel(pAdapter, channel) == 0) {
- if (mvSataConfigureChannel(pMvSataAdapter, channel)
- == MV_FALSE) {
- MV_ERROR("RR182x[%d]: Failed to configure "
- "channel %d\n", pMvSataAdapter->adapterId,
- channel);
- hptmv_free_channel(pAdapter, channel);
- continue;
- }
- if (start_channel(pAdapter, channel)) {
- MV_ERROR("RR182x[%d]: Failed to start channel, "
- "channel=%d\n", pMvSataAdapter->adapterId,
- channel);
- hptmv_free_channel(pAdapter, channel);
+ if (hptmv_init_channel(pAdapter, channel) == 0)
+ {
+ if (mvSataConfigureChannel(pMvSataAdapter, channel) == MV_FALSE)
+ {
+ MV_ERROR("RR182x[%d]: Failed to configure channel"
+ " %d\n",pMvSataAdapter->adapterId, channel);
+ hptmv_free_channel(pAdapter, channel);
+ }
+ else
+ {
+ if (start_channel(pAdapter, channel))
+ {
+ MV_ERROR("RR182x[%d]: Failed to start channel,"
+ " channel=%d\n",pMvSataAdapter->adapterId,
+ channel);
+ hptmv_free_channel(pAdapter, channel);
+ }
+ pAdapter->mvChannel[channel].online = MV_TRUE;
+ /* mvSataChannelSetEdmaLoopBackMode(pMvSataAdapter,
+ channel,
+ MV_TRUE);*/
+ }
}
- pAdapter->mvChannel[channel].online = MV_TRUE;
-#if 0
- mvSataChannelSetEdmaLoopBackMode(
- pMvSataAdapter, channel, MV_TRUE);
-#endif
}
KdPrint(("pAdapter->mvChannel[channel].online:%x, channel:%d\n",
pAdapter->mvChannel[channel].online, channel));
@@ -1423,9 +1387,7 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
KdPrint(("Initialize Devices\n"));
for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++) {
- MV_SATA_CHANNEL *pMvSataChannel;
-
- pMvSataChannel = pMvSataAdapter->sataChannel[channel];
+ MV_SATA_CHANNEL *pMvSataChannel = pMvSataAdapter->sataChannel[channel];
if (pMvSataChannel) {
init_vdev_params(pAdapter, channel);
IdeRegisterVDevice(&pAdapter->VDevices[channel].u.disk);
@@ -1446,84 +1408,85 @@ init_adapter(IAL_ADAPTER_T *pAdapter)
#if defined(SUPPORT_ARRAY) && defined(_RAID5N_)
init_raid5_memory(_VBUS_P0);
_vbus_(r5).enable_write_back = 1;
- printf("RR182x: RAID5 write-back %s\n",
- _vbus_(r5).enable_write_back? "enabled" : "disabled");
+ printf("RR182x: RAID5 write-back %s\n", _vbus_(r5).enable_write_back? "enabled" : "disabled");
#endif
mvSataUnmaskAdapterInterrupt(pMvSataAdapter);
unlock_driver(oldspl);
return 0;
-
-unregister:
- if (pAdapter->mem_res != 0)
- bus_release_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, rid,
- pAdapter->mem_res);
-
- hptmv_free_edma_queues(pAdapter);
-
- if (pAdapter->resp_dmat != NULL)
- bus_dma_tag_destroy(pAdapter->resp_dmat);
- if (pAdapter->req_dmat != NULL)
- bus_dma_tag_destroy(pAdapter->req_dmat);
- if (pAdapter->buf_dmat != NULL)
- bus_dma_tag_destroy(pAdapter->buf_dmat);
- if (pAdapter->parent_dmat != NULL)
- bus_dma_tag_destroy(pAdapter->parent_dmat);
-
- unlock_driver(oldspl);
- return error;
}
int
MvSataResetChannel(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channel)
{
- IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)pMvSataAdapter->IALData;
+ IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)pMvSataAdapter->IALData;
mvSataDisableChannelDma(pMvSataAdapter, channel);
-
/* Flush pending commands */
mvSataFlushDmaQueue (pMvSataAdapter, channel, MV_FLUSH_TYPE_CALLBACK);
/* Software reset channel */
- if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channel) ==
- MV_FALSE) {
+ if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channel) == MV_FALSE)
+ {
MV_ERROR("RR182x [%d,%d]: failed to perform Software reset\n",
- pMvSataAdapter->adapterId, channel);
+ pMvSataAdapter->adapterId, channel);
+ hptmv_free_channel(pAdapter, channel);
return -1;
}
/* Hardware reset channel */
- if (mvSataChannelHardReset(pMvSataAdapter, channel)== MV_FALSE) {
- MV_ERROR("RR182x [%d,%d] Failed to Hard reser the SATA "
- "channel\n", pMvSataAdapter->adapterId, channel);
+ if (mvSataChannelHardReset(pMvSataAdapter, channel)== MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d,%d] Failed to Hard reser the SATA channel\n",
+ pMvSataAdapter->adapterId, channel);
hptmv_free_channel(pAdapter, channel);
return -1;
}
- if (mvSataIsStorageDeviceConnected(pMvSataAdapter, channel) ==
- MV_FALSE) {
- MV_ERROR("RR182x [%d,%d] Failed to Connect Device\n",
- pMvSataAdapter->adapterId, channel);
+ if (mvSataIsStorageDeviceConnected(pMvSataAdapter, channel) == MV_FALSE)
+ {
+ MV_ERROR("RR182x [%d,%d] Failed to Connect Device\n",
+ pMvSataAdapter->adapterId, channel);
hptmv_free_channel(pAdapter, channel);
return -1;
- } else {
+ }else
+ {
+ MV_ERROR("channel %d: perform recalibrate command", channel);
+ if (!mvStorageDevATAExecuteNonUDMACommand(pMvSataAdapter, channel,
+ MV_NON_UDMA_PROTOCOL_NON_DATA,
+ MV_FALSE,
+ NULL, /* pBuffer*/
+ 0, /* count */
+ 0, /*features*/
+ /* sectorCount */
+ 0,
+ 0, /* lbaLow */
+ 0, /* lbaMid */
+ /* lbaHigh */
+ 0,
+ 0, /* device */
+ /* command */
+ 0x10))
+ MV_ERROR("channel %d: recalibrate failed", channel);
+
/* Set transfer mode */
if((mvStorageDevATASetFeatures(pMvSataAdapter, channel,
- MV_ATA_SET_FEATURES_TRANSFER, MV_ATA_TRANSFER_PIO_SLOW, 0,
- 0, 0) == MV_FALSE) ||
- (mvStorageDevATASetFeatures(pMvSataAdapter, channel,
- MV_ATA_SET_FEATURES_TRANSFER,
- pAdapter->mvChannel[channel].maxPioModeSupported, 0, 0, 0)
- == MV_FALSE) || (mvStorageDevATASetFeatures(pMvSataAdapter,
- channel, MV_ATA_SET_FEATURES_TRANSFER,
- pAdapter->mvChannel[channel].maxUltraDmaModeSupported, 0,
- 0, 0) == MV_FALSE)) {
+ MV_ATA_SET_FEATURES_TRANSFER,
+ MV_ATA_TRANSFER_PIO_SLOW, 0, 0, 0) == MV_FALSE) ||
+ (mvStorageDevATASetFeatures(pMvSataAdapter, channel,
+ MV_ATA_SET_FEATURES_TRANSFER,
+ pAdapter->mvChannel[channel].maxPioModeSupported, 0, 0, 0) == MV_FALSE) ||
+ (mvStorageDevATASetFeatures(pMvSataAdapter, channel,
+ MV_ATA_SET_FEATURES_TRANSFER,
+ pAdapter->mvChannel[channel].maxUltraDmaModeSupported, 0, 0, 0) == MV_FALSE) )
+ {
MV_ERROR("channel %d: Set Features failed", channel);
hptmv_free_channel(pAdapter, channel);
return -1;
}
/* Enable EDMA */
- if (mvSataEnableChannelDma(pMvSataAdapter, channel)==MV_FALSE) {
+ if (mvSataEnableChannelDma(pMvSataAdapter, channel) == MV_FALSE)
+ {
MV_ERROR("Failed to enable DMA, channel=%d", channel);
hptmv_free_channel(pAdapter, channel);
return -1;
@@ -1535,31 +1498,23 @@ MvSataResetChannel(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channel)
static int
fResetActiveCommands(PVBus _vbus_p)
{
- MV_SATA_ADAPTER *pMvSataAdapter;
+ MV_SATA_ADAPTER *pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
MV_U8 channel;
- int rtn = 0;
-
- pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
for (channel=0;channel< MV_SATA_CHANNELS_NUM;channel++) {
- if (pMvSataAdapter->sataChannel[channel] &&
- pMvSataAdapter->sataChannel[channel]->outstandingCommands)
- if (MvSataResetChannel(pMvSataAdapter,channel) == -1)
- rtn = -1;
+ if (pMvSataAdapter->sataChannel[channel] && pMvSataAdapter->sataChannel[channel]->outstandingCommands)
+ MvSataResetChannel(pMvSataAdapter,channel);
}
- HPT_ASSERT(rtn==0);
return 0;
}
-void
-fCompleteAllCommandsSynchronously(PVBus _vbus_p)
+void fCompleteAllCommandsSynchronously(PVBus _vbus_p)
{
UINT cont;
ULONG ticks = 0;
MV_U8 channel;
- MV_SATA_ADAPTER *pMvSataAdapter;
+ MV_SATA_ADAPTER *pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
MV_SATA_CHANNEL *pMvSataChannel;
- pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
do {
check_cmds:
cont = 0;
@@ -1568,21 +1523,19 @@ check_cmds:
dataxfer_poll();
xor_poll();
#endif
- for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++) {
+ for (channel=0;channel< MV_SATA_CHANNELS_NUM;channel++) {
pMvSataChannel = pMvSataAdapter->sataChannel[channel];
- if (pMvSataChannel &&
- pMvSataChannel->outstandingCommands) {
+ if (pMvSataChannel && pMvSataChannel->outstandingCommands)
+ {
while (pMvSataChannel->outstandingCommands) {
- if (!mvSataInterruptServiceRoutine(
- pMvSataAdapter)) {
+ if (!mvSataInterruptServiceRoutine(pMvSataAdapter)) {
StallExec(1000);
if (ticks++ > 3000) {
- MvSataResetChannel(
- pMvSataAdapter,
- channel);
+ MvSataResetChannel(pMvSataAdapter,channel);
goto check_cmds;
}
- } else
+ }
+ else
ticks = 0;
}
cont = 1;
@@ -1611,24 +1564,29 @@ fResetVBus(_VBUS_ARG0)
KdPrint(("fMvResetBus() done"));
}
+/*No rescan function*/
void
fRescanAllDevice(_VBUS_ARG0)
{
}
static MV_BOOLEAN
-CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channelNum,
- MV_COMPLETION_TYPE comp_type, MV_VOID_PTR commandId, MV_U16 responseFlags,
- MV_U32 timeStamp, MV_STORAGE_DEVICE_REGISTERS *registerStruct)
+CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter,
+ MV_U8 channelNum,
+ MV_COMPLETION_TYPE comp_type,
+ MV_VOID_PTR commandId,
+ MV_U16 responseFlags,
+ MV_U32 timeStamp,
+ MV_STORAGE_DEVICE_REGISTERS *registerStruct)
{
PCommand pCmd = (PCommand) commandId;
_VBUS_INST(pCmd->pVDevice->pVBus)
if (pCmd->uScratch.sata_param.prdAddr)
- FreePRDTable(pMvSataAdapter->IALData,
- pCmd->uScratch.sata_param.prdAddr);
+ FreePRDTable(pMvSataAdapter->IALData,pCmd->uScratch.sata_param.prdAddr);
- switch (comp_type) {
+ switch (comp_type)
+ {
case MV_COMPLETION_TYPE_NORMAL:
pCmd->Result = RETURN_SUCCESS;
break;
@@ -1636,31 +1594,25 @@ CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channelNum,
pCmd->Result = RETURN_BUS_RESET;
break;
case MV_COMPLETION_TYPE_ERROR:
- MV_ERROR("IAL: COMPLETION ERROR, adapter %d, channel %d, "
- "flags=%x\n", pMvSataAdapter->adapterId, channelNum,
- responseFlags);
+ MV_ERROR("IAL: COMPLETION ERROR, adapter %d, channel %d, flags=%x\n",
+ pMvSataAdapter->adapterId, channelNum, responseFlags);
if (responseFlags & 4) {
- MV_ERROR("ATA regs: error %x, sector count %x, LBA low "
- "%x, LBA mid %x, LBA high %x, device %x, "
- "status %x\n", registerStruct->errorRegister,
- registerStruct->sectorCountRegister,
- registerStruct->lbaLowRegister,
- registerStruct->lbaMidRegister,
- registerStruct->lbaHighRegister,
- registerStruct->deviceRegister,
- registerStruct->statusRegister);
+ MV_ERROR("ATA regs: error %x, sector count %x, LBA low %x, LBA mid %x,"
+ " LBA high %x, device %x, status %x\n",
+ registerStruct->errorRegister,
+ registerStruct->sectorCountRegister,
+ registerStruct->lbaLowRegister,
+ registerStruct->lbaMidRegister,
+ registerStruct->lbaHighRegister,
+ registerStruct->deviceRegister,
+ registerStruct->statusRegister);
}
- /*
- * We can't do handleEdmaError directly here, because
- * CommandCompletionCB is called by mv's ISR, if we retry the
- * command, than the internel data structure may be destroyed
- */
+ /*We can't do handleEdmaError directly here, because CommandCompletionCB is called by
+ * mv's ISR, if we retry the command, than the internel data structure may be destroyed*/
pCmd->uScratch.sata_param.responseFlags = responseFlags;
- pCmd->uScratch.sata_param.bIdeStatus =
- registerStruct->statusRegister;
- pCmd->uScratch.sata_param.errorRegister =
- registerStruct->errorRegister;
+ pCmd->uScratch.sata_param.bIdeStatus = registerStruct->statusRegister;
+ pCmd->uScratch.sata_param.errorRegister = registerStruct->errorRegister;
pCmd->pVDevice->u.disk.QueueLength--;
CallAfterReturn(_VBUS_P (DPC_PROC)handleEdmaError,pCmd);
return TRUE;
@@ -1670,8 +1622,7 @@ CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channelNum,
return MV_FALSE;
}
- if (pCmd->uCmd.Ide.Command == IDE_COMMAND_VERIFY &&
- pCmd->uScratch.sata_param.cmd_priv > 1) {
+ if (pCmd->uCmd.Ide.Command == IDE_COMMAND_VERIFY && pCmd->uScratch.sata_param.cmd_priv > 1) {
pCmd->uScratch.sata_param.cmd_priv --;
return TRUE;
}
@@ -1683,29 +1634,23 @@ CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channelNum,
void
fDeviceSendCommand(_VBUS_ARG PCommand pCmd)
{
- MV_SATA_EDMA_PRD_ENTRY *pPRDTable = 0;
+ MV_SATA_EDMA_PRD_ENTRY *pPRDTable = 0;
MV_SATA_ADAPTER *pMvSataAdapter;
MV_SATA_CHANNEL *pMvSataChannel;
- IAL_ADAPTER_T *pAdapter;
+ PVDevice pVDevice = pCmd->pVDevice;
+ PDevice pDevice = &pVDevice->u.disk;
+ ULONG Lba = pCmd->uCmd.Ide.Lba;
+ USHORT nSector = pCmd->uCmd.Ide.nSectors;
+
MV_QUEUE_COMMAND_RESULT result;
MV_QUEUE_COMMAND_INFO commandInfo;
- MV_UDMA_COMMAND_PARAMS *pUdmaParams;
- MV_NONE_UDMA_COMMAND_PARAMS *pNoUdmaParams;
- MV_BOOLEAN is48bit = MV_FALSE;
- PVDevice pVDevice;
- PDevice pDevice;
- ULONG Lba;
- USHORT nSector;
- MV_U8 channel;
- int i=0;
-
- pVDevice = pCmd->pVDevice;
- pDevice = &pVDevice->u.disk;
- Lba = pCmd->uCmd.Ide.Lba;
- nSector = pCmd->uCmd.Ide.nSectors;
- pUdmaParams = &commandInfo.commandParams.udmaCommand;
- pNoUdmaParams = &commandInfo.commandParams.NoneUdmaCommand;
+ MV_UDMA_COMMAND_PARAMS *pUdmaParams = &commandInfo.commandParams.udmaCommand;
+ MV_NONE_UDMA_COMMAND_PARAMS *pNoUdmaParams = &commandInfo.commandParams.NoneUdmaCommand;
+ MV_BOOLEAN is48bit = MV_FALSE;
+ MV_U8 channel;
+ int i=0;
+
DECLARE_BUFFER(FPSCAT_GATH, tmpSg);
if (!pDevice->df_on_line) {
@@ -1719,12 +1664,8 @@ fDeviceSendCommand(_VBUS_ARG PCommand pCmd)
pMvSataChannel = pDevice->mv;
pMvSataAdapter = pMvSataChannel->mvSataAdapter;
channel = pMvSataChannel->channelNumber;
- pAdapter = pMvSataAdapter->IALData;
- /*
- * Old RAID0 has hidden lba. Remember to clear dDeHiddenLba when
- * deleting array!
- */
+ /* old RAID0 has hidden lba. Remember to clear dDeHiddenLba when delete array! */
Lba += pDevice->dDeHiddenLba;
/* check LBA */
if (Lba+nSector-1 > pDevice->dDeRealCapacity) {
@@ -1737,7 +1678,8 @@ fDeviceSendCommand(_VBUS_ARG PCommand pCmd)
is48bit = MV_TRUE;
}
- switch (pCmd->uCmd.Ide.Command) {
+ switch (pCmd->uCmd.Ide.Command)
+ {
case IDE_COMMAND_READ:
case IDE_COMMAND_WRITE:
if (pDevice->bDeModeSetting<8) goto pio;
@@ -1757,144 +1699,125 @@ fDeviceSendCommand(_VBUS_ARG PCommand pCmd)
if (pCmd->pSgTable && pCmd->cf_physical_sg) {
FPSCAT_GATH sg1=tmpSg, sg2=pCmd->pSgTable;
- do {
- *sg1++=*sg2;
- } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
- } else if (!pCmd->pfnBuildSgl ||
- !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 0)) {
+ do { *sg1++=*sg2; } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
+ }
+ else {
+ if (!pCmd->pfnBuildSgl || !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 0)) {
pio:
- mvSataDisableChannelDma(pMvSataAdapter, channel);
- mvSataFlushDmaQueue(pMvSataAdapter, channel,
- MV_FLUSH_TYPE_CALLBACK);
-
- if (pCmd->pSgTable && pCmd->cf_physical_sg==0) {
- FPSCAT_GATH sg1=tmpSg, sg2=pCmd->pSgTable;
- do {
- *sg1++=*sg2;
- } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
- } else if (!pCmd->pfnBuildSgl ||
- !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 1)){
- pCmd->Result = RETURN_NEED_LOGICAL_SG;
- goto finish_cmd;
- }
-
- do {
- ULONG size;
- ULONG_PTR addr = tmpSg->dSgAddress;
-
- size = tmpSg->wSgSize? tmpSg->wSgSize : 0x10000;
- if (size & 0x1ff) {
- pCmd->Result = RETURN_INVALID_REQUEST;
- goto finish_cmd;
+ mvSataDisableChannelDma(pMvSataAdapter, channel);
+ mvSataFlushDmaQueue(pMvSataAdapter, channel, MV_FLUSH_TYPE_CALLBACK);
+
+ if (pCmd->pSgTable && pCmd->cf_physical_sg==0) {
+ FPSCAT_GATH sg1=tmpSg, sg2=pCmd->pSgTable;
+ do { *sg1++=*sg2; } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
}
- if (mvStorageDevATAExecuteNonUDMACommand(
- pMvSataAdapter, channel,
- (pCmd->cf_data_out) ?
- MV_NON_UDMA_PROTOCOL_PIO_DATA_OUT :
- MV_NON_UDMA_PROTOCOL_PIO_DATA_IN,
- is48bit, (MV_U16_PTR)addr,
- size >> 1, /* count */
- 0, /* features N/A */
- (MV_U16)(size>>9), /*sector count*/
- (MV_U16)((is48bit ?
- (MV_U16)((Lba >> 16) & 0xFF00) : 0 ) |
- (UCHAR)(Lba & 0xFF) ), /*lbalow*/
- (MV_U16)((Lba >> 8) & 0xFF), /* lbaMid */
- (MV_U16)((Lba >> 16) & 0xFF),/* lbaHig */
- (MV_U8)(0x40 | (is48bit ? 0 :
- (UCHAR)(Lba >> 24) & 0xFF )),/* device */
- (MV_U8)(is48bit ? (pCmd->cf_data_in ?
- IDE_COMMAND_READ_EXT :
- IDE_COMMAND_WRITE_EXT) :
- pCmd->uCmd.Ide.Command))==MV_FALSE) {
- pCmd->Result = RETURN_IDE_ERROR;
- goto finish_cmd;
+ else {
+ if (!pCmd->pfnBuildSgl || !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 1)) {
+ pCmd->Result = RETURN_NEED_LOGICAL_SG;
+ goto finish_cmd;
+ }
}
- Lba += size>>9;
- if(Lba & 0xF0000000) is48bit = MV_TRUE;
- }
- while ((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
- pCmd->Result = RETURN_SUCCESS;
+
+ do {
+ ULONG size = tmpSg->wSgSize? tmpSg->wSgSize : 0x10000;
+ ULONG_PTR addr = tmpSg->dSgAddress;
+ if (size & 0x1ff) {
+ pCmd->Result = RETURN_INVALID_REQUEST;
+ goto finish_cmd;
+ }
+ if (mvStorageDevATAExecuteNonUDMACommand(pMvSataAdapter, channel,
+ (pCmd->cf_data_out)?MV_NON_UDMA_PROTOCOL_PIO_DATA_OUT:MV_NON_UDMA_PROTOCOL_PIO_DATA_IN,
+ is48bit,
+ (MV_U16_PTR)addr,
+ size >> 1, /* count */
+ 0, /* features N/A */
+ (MV_U16)(size>>9), /*sector count*/
+ (MV_U16)( (is48bit? (MV_U16)((Lba >> 16) & 0xFF00) : 0 ) | (UCHAR)(Lba & 0xFF) ), /*lbalow*/
+ (MV_U16)((Lba >> 8) & 0xFF), /* lbaMid */
+ (MV_U16)((Lba >> 16) & 0xFF),/* lbaHigh */
+ (MV_U8)(0x40 | (is48bit ? 0 : (UCHAR)(Lba >> 24) & 0xFF )),/* device */
+ (MV_U8)(is48bit ? (pCmd->cf_data_in?IDE_COMMAND_READ_EXT:IDE_COMMAND_WRITE_EXT):pCmd->uCmd.Ide.Command)
+ )==MV_FALSE)
+ {
+ pCmd->Result = RETURN_IDE_ERROR;
+ goto finish_cmd;
+ }
+ Lba += size>>9;
+ if(Lba & 0xF0000000) is48bit = MV_TRUE;
+ }
+ while ((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
+ pCmd->Result = RETURN_SUCCESS;
finish_cmd:
- mvSataEnableChannelDma(pMvSataAdapter,channel);
- CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion,
- pCmd);
- return;
+ mvSataEnableChannelDma(pMvSataAdapter,channel);
+ CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
+ return;
+ }
}
- pPRDTable = AllocatePRDTable(pAdapter);
+ pPRDTable = (MV_SATA_EDMA_PRD_ENTRY *) AllocatePRDTable(pMvSataAdapter->IALData);
KdPrint(("pPRDTable:%p\n",pPRDTable));
if (!pPRDTable) {
pCmd->Result = RETURN_DEVICE_BUSY;
- CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion,
- pCmd);
+ CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
HPT_ASSERT(0);
return;
}
- do {
- pPRDTable[i].highBaseAddr = 0;
+ do{
+ pPRDTable[i].highBaseAddr = (sizeof(tmpSg->dSgAddress)>4 ? (MV_U32)(tmpSg->dSgAddress>>32) : 0);
pPRDTable[i].flags = (MV_U16)tmpSg->wSgFlag;
pPRDTable[i].byteCount = (MV_U16)tmpSg->wSgSize;
pPRDTable[i].lowBaseAddr = (MV_U32)tmpSg->dSgAddress;
pPRDTable[i].reserved = 0;
i++;
- } while((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
+ }while((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
- pUdmaParams->prdLowAddr = pAdapter->prdTableDmaAddr +
- ((ULONG)pPRDTable - (ULONG)pAdapter->prdTableAddr);
-
- if ((pUdmaParams->numOfSectors == 256) &&
- (pMvSataChannel->lba48Address == MV_FALSE)) {
+ pUdmaParams->prdLowAddr = (ULONG)fOsPhysicalAddress(pPRDTable);
+ if ((pUdmaParams->numOfSectors == 256) && (pMvSataChannel->lba48Address == MV_FALSE)) {
pUdmaParams->numOfSectors = 0;
}
pCmd->uScratch.sata_param.prdAddr = (PVOID)pPRDTable;
- result = mvSataQueueCommand(pMvSataAdapter, channel,
- &commandInfo);
+ result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
- if (result != MV_QUEUE_COMMAND_RESULT_OK) {
+ if (result != MV_QUEUE_COMMAND_RESULT_OK)
+ {
queue_failed:
- switch (result) {
+ switch (result)
+ {
case MV_QUEUE_COMMAND_RESULT_BAD_LBA_ADDRESS:
- MV_ERROR("IAL Error: Edma Queue command "
- "failed. Bad LBA LBA[31:0](0x%08x)\n",
- pUdmaParams->lowLBAAddress);
+ MV_ERROR("IAL Error: Edma Queue command failed. Bad LBA "
+ "LBA[31:0](0x%08x)\n", pUdmaParams->lowLBAAddress);
pCmd->Result = RETURN_IDE_ERROR;
break;
case MV_QUEUE_COMMAND_RESULT_QUEUED_MODE_DISABLED:
- MV_ERROR("IAL Error: Edma Queue command "
- "failed. EDMA disabled adapter %d "
- "channel %d\n",
- pMvSataAdapter->adapterId, channel);
+ MV_ERROR("IAL Error: Edma Queue command failed. EDMA"
+ " disabled adapter %d channel %d\n",
+ pMvSataAdapter->adapterId, channel);
mvSataEnableChannelDma(pMvSataAdapter,channel);
pCmd->Result = RETURN_IDE_ERROR;
break;
case MV_QUEUE_COMMAND_RESULT_FULL:
- MV_ERROR("IAL Error: Edma Queue command "
- "failed. Queue is Full adapter %d "
- "channel %d\n",
- pMvSataAdapter->adapterId, channel);
+ MV_ERROR("IAL Error: Edma Queue command failed. Queue is"
+ " Full adapter %d channel %d\n",
+ pMvSataAdapter->adapterId, channel);
pCmd->Result = RETURN_DEVICE_BUSY;
break;
case MV_QUEUE_COMMAND_RESULT_BAD_PARAMS:
- MV_ERROR("IAL Error: Edma Queue command "
- "failed. (Bad Params), pMvSataAdapter:"
- " %p, pSataChannel: %p.\n",
- pMvSataAdapter,
- pMvSataAdapter->sataChannel[channel]);
+ MV_ERROR("IAL Error: Edma Queue command failed. (Bad "
+ "Params), pMvSataAdapter: %p, pSataChannel: %p.\n",
+ pMvSataAdapter, pMvSataAdapter->sataChannel[channel]);
pCmd->Result = RETURN_IDE_ERROR;
break;
default:
- MV_ERROR("IAL Error: Bad result value (%d) "
- "from queue command\n", result);
+ MV_ERROR("IAL Error: Bad result value (%d) from queue"
+ " command\n", result);
pCmd->Result = RETURN_IDE_ERROR;
}
if(pPRDTable)
- FreePRDTable(pAdapter, pPRDTable);
- CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion,
- pCmd);
+ FreePRDTable(pMvSataAdapter->IALData,pPRDTable);
+ CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
}
pDevice->QueueLength++;
return;
@@ -1910,40 +1833,35 @@ queue_failed:
pCmd->uScratch.sata_param.cmd_priv = 1;
if (pMvSataChannel->lba48Address == MV_TRUE){
- pNoUdmaParams->command =
- MV_ATA_COMMAND_READ_VERIFY_SECTORS_EXT;
+ pNoUdmaParams->command = MV_ATA_COMMAND_READ_VERIFY_SECTORS_EXT;
pNoUdmaParams->isEXT = MV_TRUE;
- pNoUdmaParams->lbaHigh =
- (MV_U16)((Lba & 0xff0000) >> 16);
+ pNoUdmaParams->lbaHigh = (MV_U16)((Lba & 0xff0000) >> 16);
pNoUdmaParams->lbaMid = (MV_U16)((Lba & 0xff00) >> 8);
pNoUdmaParams->lbaLow =
- (MV_U16)(((Lba & 0xff000000) >> 16)| (Lba & 0xff));
+ (MV_U16)(((Lba & 0xff000000) >> 16)| (Lba & 0xff));
pNoUdmaParams->sectorCount = nSector;
pNoUdmaParams->device = 0x40;
- result = mvSataQueueCommand(pMvSataAdapter, channel,
- &commandInfo);
- if (result != MV_QUEUE_COMMAND_RESULT_OK) {
+ result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
+ if (result != MV_QUEUE_COMMAND_RESULT_OK){
goto queue_failed;
}
return;
}
- pNoUdmaParams->command = MV_ATA_COMMAND_READ_VERIFY_SECTORS;
- pNoUdmaParams->isEXT = MV_FALSE;
- pNoUdmaParams->lbaHigh = (MV_U16)((Lba & 0xff0000) >> 16);
- pNoUdmaParams->lbaMid = (MV_U16)((Lba & 0xff00) >> 8);
- pNoUdmaParams->lbaLow = (MV_U16)(Lba & 0xff);
- pNoUdmaParams->sectorCount = 0xff & nSector;
- pNoUdmaParams->device = (MV_U8)(0x40 |
- ((Lba & 0xf000000) >> 24));
- pNoUdmaParams->callBack = CommandCompletionCB;
- result = mvSataQueueCommand(pMvSataAdapter, channel,
- &commandInfo);
- /*
- * FIXME: how about the commands already queued? but marvel
- * also forgets to consider this
- */
- if (result != MV_QUEUE_COMMAND_RESULT_OK){
- goto queue_failed;
+ else{
+ pNoUdmaParams->command = MV_ATA_COMMAND_READ_VERIFY_SECTORS;
+ pNoUdmaParams->isEXT = MV_FALSE;
+ pNoUdmaParams->lbaHigh = (MV_U16)((Lba & 0xff0000) >> 16);
+ pNoUdmaParams->lbaMid = (MV_U16)((Lba & 0xff00) >> 8);
+ pNoUdmaParams->lbaLow = (MV_U16)(Lba & 0xff);
+ pNoUdmaParams->sectorCount = 0xff & nSector;
+ pNoUdmaParams->device = (MV_U8)(0x40 |
+ ((Lba & 0xf000000) >> 24));
+ pNoUdmaParams->callBack = CommandCompletionCB;
+ result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
+ /*FIXME: how about the commands already queued? but marvel also forgets to consider this*/
+ if (result != MV_QUEUE_COMMAND_RESULT_OK){
+ goto queue_failed;
+ }
}
break;
default:
@@ -1966,7 +1884,8 @@ hpt_probe(device_t dev)
#ifdef FOR_DEMO
|| pci_get_device(dev) == MV_SATA_DEVICE_ID_5080
#endif
- )) {
+ ))
+ {
KdPrintI((CONTROLLER_NAME " found\n"));
device_set_desc(dev, CONTROLLER_NAME);
return 0;
@@ -1983,15 +1902,27 @@ hpt_probe(device_t dev)
static int
hpt_attach(device_t dev)
{
- IAL_ADAPTER_T * pAdapter;
+ IAL_ADAPTER_T * pAdapter = device_get_softc(dev);
int rid;
union ccb *ccb;
struct cam_devq *devq;
struct cam_sim *hpt_vsim;
- printf("%s Version %s\n", DRIVER_NAME, DRIVER_VERSION);
+ printf("%s Version %s \n", DRIVER_NAME, DRIVER_VERSION);
+
+ if (!pAdapter)
+ {
+ pAdapter = (IAL_ADAPTER_T *)malloc(sizeof (IAL_ADAPTER_T), M_DEVBUF, M_NOWAIT);
+#if __FreeBSD_version > 410000
+ device_set_softc(dev, (void *)pAdapter);
+#else
+ device_set_driver(dev, (driver_t *)pAdapter);
+#endif
+ }
+
+ if (!pAdapter) return (ENOMEM);
+ bzero(pAdapter, sizeof(IAL_ADAPTER_T));
- pAdapter = device_get_softc(dev);
pAdapter->hpt_dev = dev;
rid = init_adapter(pAdapter);
@@ -1999,58 +1930,59 @@ hpt_attach(device_t dev)
return rid;
rid = 0;
- if ((pAdapter->hpt_irq = bus_alloc_resource(pAdapter->hpt_dev,
- SYS_RES_IRQ, &rid, 0, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL){
+ if ((pAdapter->hpt_irq = bus_alloc_resource(pAdapter->hpt_dev, SYS_RES_IRQ, &rid, 0, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL)
+ {
hpt_printk(("can't allocate interrupt\n"));
return(ENXIO);
}
- if(bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM,
- hpt_intr, pAdapter, &pAdapter->hpt_intr)) {
+ if(bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM, hpt_intr, pAdapter, &pAdapter->hpt_intr))
+ {
hpt_printk(("can't set up interrupt\n"));
free(pAdapter, M_DEVBUF);
return(ENXIO);
}
-#if 1
- if ((ccb = malloc(sizeof(*ccb), M_DEVBUF, M_WAITOK | M_ZERO)) != NULL) {
+
+ if((ccb = (union ccb *)malloc(sizeof(*ccb), M_DEVBUF, M_WAITOK)) != (union ccb*)NULL)
+ {
+ bzero(ccb, sizeof(*ccb));
ccb->ccb_h.pinfo.priority = 1;
ccb->ccb_h.pinfo.index = CAM_UNQUEUED_INDEX;
- } else {
+ }
+ else
+ {
return ENOMEM;
}
-#endif
/*
* Create the device queue for our SIM(s).
*/
- if((devq = cam_simq_alloc(8/*MAX_QUEUE_COMM*/)) == NULL) {
+ if((devq = cam_simq_alloc(8/*MAX_QUEUE_COMM*/)) == NULL)
+ {
KdPrint(("ENXIO\n"));
- free(ccb, M_DEVBUF);
return ENOMEM;
}
/*
* Construct our SIM entry
*/
- if ((hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll,__str(PROC_DIR_NAME),
- pAdapter, device_get_unit(pAdapter->hpt_dev), /*untagged*/1,
- /*tagged*/8, devq)) == NULL) {
- free(ccb, M_DEVBUF);
+ if ((hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll, __str(PROC_DIR_NAME),
+ pAdapter, device_get_unit(pAdapter->hpt_dev), /*untagged*/1, /*tagged*/8, devq)) == NULL) {
cam_simq_free(devq);
return ENOMEM;
}
- if(xpt_bus_register(hpt_vsim, 0) != CAM_SUCCESS) {
- free(ccb, M_DEVBUF);
+ if(xpt_bus_register(hpt_vsim, 0) != CAM_SUCCESS)
+ {
cam_sim_free(hpt_vsim, /*free devq*/ TRUE);
hpt_vsim = NULL;
return ENXIO;
}
if(xpt_create_path(&pAdapter->path, /*periph */ NULL,
- cam_sim_path(hpt_vsim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)
- != CAM_REQ_CMP) {
- free(ccb, M_DEVBUF);
+ cam_sim_path(hpt_vsim), CAM_TARGET_WILDCARD,
+ CAM_LUN_WILDCARD) != CAM_REQ_CMP)
+ {
xpt_bus_deregister(cam_sim_path(hpt_vsim));
cam_sim_free(hpt_vsim, /*free_devq*/TRUE);
hpt_vsim = NULL;
@@ -2065,14 +1997,14 @@ hpt_attach(device_t dev)
xpt_action((union ccb *)ccb);
free(ccb, M_DEVBUF);
- /* Only do this setup for the first device. */
+ /* Register shutdown handler, and start the work thread. */
if (device_get_unit(dev) == 0) {
- pAdapter->eh = EVENTHANDLER_REGISTER(shutdown_final,
- hpt_shutdown, dev, SHUTDOWN_PRI_DEFAULT);
- if (pAdapter->eh != NULL)
+ pAdapter->eh = EVENTHANDLER_REGISTER(shutdown_final,
+ hpt_shutdown, dev, SHUTDOWN_PRI_DEFAULT);
+ if (pAdapter->eh)
launch_worker_thread();
else
- printf("hptmv: shutdown event registration failed\n");
+ hpt_printk(("shutdown event registration failed\n"));
}
return 0;
@@ -2080,10 +2012,11 @@ hpt_attach(device_t dev)
static int
hpt_detach(device_t dev)
-{
+{
return (EBUSY);
}
+
/***************************************************************
* The poll function is used to simulate the interrupt when
* the interrupt subsystem is not functioning.
@@ -2103,11 +2036,11 @@ static void
hpt_intr(void *arg)
{
IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)arg;
- intrmask_t oldspl;
+ intrmask_t oldspl = lock_driver();
- oldspl = lock_driver();
/* KdPrintI(("----- Entering Isr() -----\n")); */
- if (mvSataInterruptServiceRoutine(&pAdapter->mvSataAdapter) == MV_TRUE){
+ if (mvSataInterruptServiceRoutine(&pAdapter->mvSataAdapter) == MV_TRUE)
+ {
_VBUS_INST(&pAdapter->VBus)
CheckPendingCall(_VBUS_P0);
}
@@ -2146,56 +2079,55 @@ FlushAdapter(IAL_ADAPTER_T *pAdapter)
/* flush all devices */
for (i=0; i<MAX_VDEVICE_PER_VBUS; i++) {
PVDevice pVDev = pAdapter->VBus.pVDevice[i];
- if (pVDev)
- fFlushVDev(pVDev);
+ if(pVDev) fFlushVDev(pVDev);
}
}
static int
hpt_shutdown(device_t dev)
{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = device_get_softc(dev);
- if (pAdapter == NULL)
- return (EINVAL);
-
- EVENTHANDLER_DEREGISTER(shutdown_final, pAdapter->eh);
- FlushAdapter(pAdapter);
+ IAL_ADAPTER_T *pAdapter;
+
+ pAdapter = device_get_softc(dev);
+ if (pAdapter == NULL)
+ return (EINVAL);
- return 0;
+ EVENTHANDLER_DEREGISTER(shutdown_final, pAdapter->eh);
+ FlushAdapter(pAdapter);
+ /* give the flush some time to happen,
+ *otherwise "shutdown -p now" will make file system corrupted */
+ DELAY(1000 * 1000 * 5);
+ return 0;
}
void
Check_Idle_Call(IAL_ADAPTER_T *pAdapter)
{
- int i = 0;
-
_VBUS_INST(&pAdapter->VBus)
if (mWaitingForIdle(_VBUS_P0)) {
CheckIdleCall(_VBUS_P0);
#ifdef SUPPORT_ARRAY
- for(i = 0; i < MAX_ARRAY_PER_VBUS; i++){
+ {
+ int i;
PVDevice pArray;
-
- if ((pArray = ArrayTables(i))->u.array.dArStamp == 0)
- continue;
- else if (pArray->u.array.rf_auto_rebuild) {
- KdPrint(("auto rebuild.\n"));
- pArray->u.array.rf_auto_rebuild = 0;
- hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block,
- pAdapter, pArray, DUPLICATE);
+ for(i = 0; i < MAX_ARRAY_PER_VBUS; i++){
+ if ((pArray=ArrayTables(i))->u.array.dArStamp==0)
+ continue;
+ else if (pArray->u.array.rf_auto_rebuild) {
+ KdPrint(("auto rebuild.\n"));
+ pArray->u.array.rf_auto_rebuild = 0;
+ hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
+ }
}
}
#endif
}
/* launch the awaiting commands blocked by mWaitingForIdle */
- while(pAdapter->pending_Q!= NULL) {
+ while(pAdapter->pending_Q!= NULL)
+ {
_VBUS_INST(&pAdapter->VBus)
- union ccb *ccb =
- (union ccb *)pAdapter->pending_Q->ccb_h.ccb_ccb_ptr;
-
+ union ccb *ccb = (union ccb *)pAdapter->pending_Q->ccb_h.ccb_ccb_ptr;
hpt_free_ccb(&pAdapter->pending_Q, ccb);
CallAfterReturn(_VBUS_P (DPC_PROC)OsSendCommand, ccb);
}
@@ -2204,14 +2136,17 @@ Check_Idle_Call(IAL_ADAPTER_T *pAdapter)
static void
ccb_done(union ccb *ccb)
{
- IAL_ADAPTER_T * pAdapter = (IAL_ADAPTER_T *)ccb->ccb_adapter;
- KdPrintI(("ccb_done: ccb %p status %x", ccb, ccb->ccb_h.status));
+ PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter;
+ IAL_ADAPTER_T * pAdapter = pmap->pAdapter;
+ KdPrintI(("ccb_done: ccb %p status %x\n", ccb, ccb->ccb_h.status));
+ dmamap_put(pmap);
xpt_done(ccb);
pAdapter->outstandingCommands--;
- if (pAdapter->outstandingCommands == 0) {
+ if (pAdapter->outstandingCommands == 0)
+ {
if(DPC_Request_Nums == 0)
Check_Idle_Call(pAdapter);
}
@@ -2229,124 +2164,130 @@ hpt_action(struct cam_sim *sim, union ccb *ccb)
{
intrmask_t oldspl;
IAL_ADAPTER_T * pAdapter = (IAL_ADAPTER_T *) cam_sim_softc(sim);
+ PBUS_DMAMAP pmap;
_VBUS_INST(&pAdapter->VBus)
-
- ccb->ccb_adapter = pAdapter;
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("hpt_action\n"));
- KdPrint(("hpt_action(%lx,%lx{%x})\n", (u_long)sim, (u_long)ccb,
- ccb->ccb_h.func_code));
+ KdPrint(("hpt_action(%lx,%lx{%x})\n", (u_long)sim, (u_long)ccb, ccb->ccb_h.func_code));
- switch (ccb->ccb_h.func_code) {
- case XPT_SCSI_IO: /* Execute the requested I/O operation */
- /* ccb->ccb_h.path_id is not our bus id - don't check it */
+ switch (ccb->ccb_h.func_code)
+ {
+ case XPT_SCSI_IO: /* Execute the requested I/O operation */
+ {
+ /* ccb->ccb_h.path_id is not our bus id - don't check it */
- if (ccb->ccb_h.target_lun) {
- ccb->ccb_h.status = CAM_LUN_INVALID;
- xpt_done(ccb);
- return;
- }
- if (ccb->ccb_h.target_id >= MAX_VDEVICE_PER_VBUS ||
- pAdapter->VBus.pVDevice[ccb->ccb_h.target_id]==0) {
- ccb->ccb_h.status = CAM_TID_INVALID;
- xpt_done(ccb);
- return;
- }
+ if (ccb->ccb_h.target_lun) {
+ ccb->ccb_h.status = CAM_LUN_INVALID;
+ xpt_done(ccb);
+ return;
+ }
+ if (ccb->ccb_h.target_id >= MAX_VDEVICE_PER_VBUS ||
+ pAdapter->VBus.pVDevice[ccb->ccb_h.target_id]==0) {
+ ccb->ccb_h.status = CAM_TID_INVALID;
+ xpt_done(ccb);
+ return;
+ }
- oldspl = lock_driver();
- if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
- Check_Idle_Call(pAdapter);
+ oldspl = lock_driver();
+ if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
+ Check_Idle_Call(pAdapter);
- if (mWaitingForIdle(_VBUS_P0))
- hpt_queue_ccb(&pAdapter->pending_Q, ccb);
- else
- OsSendCommand(_VBUS_P ccb);
- unlock_driver(oldspl);
+ pmap = dmamap_get(pAdapter);
+ HPT_ASSERT(pmap);
+ ccb->ccb_adapter = pmap;
+ memset((void *)pmap->psg, 0, sizeof(pmap->psg));
- /* KdPrint(("leave scsiio\n")); */
- break;
+ if (mWaitingForIdle(_VBUS_P0))
+ hpt_queue_ccb(&pAdapter->pending_Q, ccb);
+ else
+ OsSendCommand(_VBUS_P ccb);
+ unlock_driver(oldspl);
- case XPT_RESET_BUS:
- KdPrint(("reset bus\n"));
- oldspl = lock_driver();
- fResetVBus(_VBUS_P0);
- unlock_driver(oldspl);
- xpt_done(ccb);
- break;
+ /* KdPrint(("leave scsiio\n")); */
+ break;
+ }
- case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
- case XPT_EN_LUN: /* Enable LUN as a target */
- case XPT_TARGET_IO: /* Execute target I/O request */
- case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
- case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
- case XPT_ABORT: /* Abort the specified CCB */
- case XPT_TERM_IO: /* Terminate the I/O process */
- /* XXX Implement */
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
+ case XPT_RESET_BUS:
+ KdPrint(("reset bus\n"));
+ oldspl = lock_driver();
+ fResetVBus(_VBUS_P0);
+ unlock_driver(oldspl);
+ xpt_done(ccb);
+ break;
- case XPT_GET_TRAN_SETTINGS:
- case XPT_SET_TRAN_SETTINGS:
- /* XXX Implement */
- ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
- xpt_done(ccb);
- break;
+ case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */
+ case XPT_EN_LUN: /* Enable LUN as a target */
+ case XPT_TARGET_IO: /* Execute target I/O request */
+ case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */
+ case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/
+ case XPT_ABORT: /* Abort the specified CCB */
+ case XPT_TERM_IO: /* Terminate the I/O process */
+ /* XXX Implement */
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ break;
- case XPT_CALC_GEOMETRY:
- {
- struct ccb_calc_geometry *ccg;
- u_int32_t size_mb;
- u_int32_t secs_per_cylinder;
+ case XPT_GET_TRAN_SETTINGS:
+ case XPT_SET_TRAN_SETTINGS:
+ /* XXX Implement */
+ ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
+ xpt_done(ccb);
+ break;
- ccg = &ccb->ccg;
- size_mb = ccg->volume_size / ((1024L*1024L) / ccg->block_size);
+ case XPT_CALC_GEOMETRY:
+ {
+ struct ccb_calc_geometry *ccg;
+ u_int32_t size_mb;
+ u_int32_t secs_per_cylinder;
- if (size_mb > 1024 ) {
- ccg->heads = 255;
- ccg->secs_per_track = 63;
- } else {
- ccg->heads = 64;
- ccg->secs_per_track = 32;
+ ccg = &ccb->ccg;
+ size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size);
+
+ if (size_mb > 1024 ) {
+ ccg->heads = 255;
+ ccg->secs_per_track = 63;
+ } else {
+ ccg->heads = 64;
+ ccg->secs_per_track = 32;
+ }
+ secs_per_cylinder = ccg->heads * ccg->secs_per_track;
+ ccg->cylinders = ccg->volume_size / secs_per_cylinder;
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
}
- secs_per_cylinder = ccg->heads * ccg->secs_per_track;
- ccg->cylinders = ccg->volume_size / secs_per_cylinder;
- ccb->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
- case XPT_PATH_INQ: /* Path routing inquiry */
- {
- struct ccb_pathinq *cpi = &ccb->cpi;
+ case XPT_PATH_INQ: /* Path routing inquiry */
+ {
+ struct ccb_pathinq *cpi = &ccb->cpi;
- cpi->version_num = 1; /* XXX??? */
- cpi->hba_inquiry = PI_SDTR_ABLE;
- cpi->target_sprt = 0;
- /* Not necessary to reset bus */
- cpi->hba_misc = PIM_NOBUSRESET;
- cpi->hba_eng_cnt = 0;
+ cpi->version_num = 1; /* XXX??? */
+ cpi->hba_inquiry = PI_SDTR_ABLE;
+ cpi->target_sprt = 0;
+ /* Not necessary to reset bus */
+ cpi->hba_misc = PIM_NOBUSRESET;
+ cpi->hba_eng_cnt = 0;
- cpi->max_target = MAX_VDEVICE_PER_VBUS;
- cpi->max_lun = 0;
- cpi->initiator_id = MAX_VDEVICE_PER_VBUS;
+ cpi->max_target = MAX_VDEVICE_PER_VBUS;
+ cpi->max_lun = 0;
+ cpi->initiator_id = MAX_VDEVICE_PER_VBUS;
- cpi->bus_id = cam_sim_bus(sim);
- cpi->base_transfer_speed = 3300;
- strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
- strncpy(cpi->hba_vid, "HPT ", HBA_IDLEN);
- strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
- cpi->unit_number = cam_sim_unit(sim);
- cpi->ccb_h.status = CAM_REQ_CMP;
- xpt_done(ccb);
- break;
- }
+ cpi->bus_id = cam_sim_bus(sim);
+ cpi->base_transfer_speed = 3300;
+ strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
+ strncpy(cpi->hba_vid, "HPT ", HBA_IDLEN);
+ strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
+ cpi->unit_number = cam_sim_unit(sim);
+ cpi->ccb_h.status = CAM_REQ_CMP;
+ xpt_done(ccb);
+ break;
+ }
- default:
- KdPrint(("invalid cmd\n"));
- ccb->ccb_h.status = CAM_REQ_INVALID;
- xpt_done(ccb);
- break;
+ default:
+ KdPrint(("invalid cmd\n"));
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ xpt_done(ccb);
+ break;
}
/* KdPrint(("leave hpt_action..............\n")); */
}
@@ -2373,8 +2314,7 @@ hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb)
TempCCB = *ccb_Q;
- if(ccb->ccb_h.ccb_ccb_ptr == ccb)
- /*it means SCpnt is the last one in CURRCMDs*/
+ if(ccb->ccb_h.ccb_ccb_ptr == ccb) /*it means SCpnt is the last one in CURRCMDs*/
*ccb_Q = NULL;
else {
while(TempCCB->ccb_h.ccb_ccb_ptr != (char *)ccb)
@@ -2400,11 +2340,6 @@ static void hpt_worker_thread(void)
for(;;) {
while (DpcQueue_First!=DpcQueue_Last) {
ST_HPT_DPC p;
- IAL_ADAPTER_T *pAdapter;
- PVDevice pArray;
- PVBus _vbus_p;
- int i;
-
oldspl = lock_driver();
p = DpcQueue[DpcQueue_First];
DpcQueue_First++;
@@ -2415,10 +2350,7 @@ static void hpt_worker_thread(void)
oldspl = lock_driver();
DPC_Request_Nums--;
- /*
- * since we may have prevented Check_Idle_Call, do it
- * here
- */
+ /* since we may have prevented Check_Idle_Call, do it here */
if (DPC_Request_Nums==0) {
if (p.pAdapter->outstandingCommands == 0) {
_VBUS_INST(&p.pAdapter->VBus);
@@ -2427,37 +2359,54 @@ static void hpt_worker_thread(void)
}
}
unlock_driver(oldspl);
- if (SIGISMEMBER(curproc->p_siglist, SIGSTOP) == 0)
- continue;
- /* abort rebuilding process. */
- pAdapter = gIal_Adapter;
- while (pAdapter != 0) {
- _vbus_p = &pAdapter->VBus;
- for (i = 0; i < MAX_ARRAY_PER_VBUS;i++){
- if ((pArray=ArrayTables(i))->u.array.dArStamp==0)
- continue;
- if (pArray->u.array.rf_rebuilding ||
- pArray->u.array.rf_verifying ||
- pArray->u.array.rf_initializing) {
- pArray->u.array.rf_abort_rebuild = 1;
+ /*Schedule out*/
+#if (__FreeBSD_version < 500000)
+ YIELD_THREAD;
+#else
+ tsleep((caddr_t)hpt_worker_thread, PPAUSE, "sched", 1);
+#endif
+ if (SIGISMEMBER(curproc->p_siglist, SIGSTOP)) {
+ /* abort rebuilding process. */
+ IAL_ADAPTER_T *pAdapter;
+ PVDevice pArray;
+ PVBus _vbus_p;
+ int i;
+ pAdapter = gIal_Adapter;
+
+ while(pAdapter != 0){
+
+ _vbus_p = &pAdapter->VBus;
+
+ for (i=0;i<MAX_ARRAY_PER_VBUS;i++)
+ {
+ if ((pArray=ArrayTables(i))->u.array.dArStamp==0)
+ continue;
+ else if (pArray->u.array.rf_rebuilding ||
+ pArray->u.array.rf_verifying ||
+ pArray->u.array.rf_initializing)
+ {
+ pArray->u.array.rf_abort_rebuild = 1;
+ }
}
+ pAdapter = pAdapter->next;
}
- pAdapter = pAdapter->next;
}
}
+/*Remove this debug option*/
+/*
#ifdef DEBUG
if (SIGISMEMBER(curproc->p_siglist, SIGSTOP))
- tsleep(hpt_worker_thread, PPAUSE, "hptrdy", 2 * hz);
+ tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz);
#endif
-#if (__FreeBSD_version >= 500043)
+*/
+ #if (__FreeBSD_version >= 500043)
kthread_suspend_check(curproc);
-#else
+ #else
kproc_suspend_loop(curproc);
-#endif
- /* wait for something to do */
- tsleep(hpt_worker_thread, PPAUSE, "hptrdy", 2 * hz);
+ #endif
+ tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz); /* wait for something to do */
}
}
@@ -2468,6 +2417,7 @@ static struct kproc_desc hpt_kp = {
&hptdaemonproc
};
+/*Start this thread in the hpt_attach, to prevent kernel from loading it without our controller.*/
static void
launch_worker_thread(void)
{
@@ -2484,155 +2434,73 @@ launch_worker_thread(void)
for(i = 0; i < MAX_ARRAY_PER_VBUS; i++)
if ((pVDev=ArrayTables(i))->u.array.dArStamp==0)
continue;
- if (pVDev->u.array.rf_need_rebuild &&
- !pVDev->u.array.rf_rebuilding) {
- hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block,
- pAdapTemp, pVDev,
- (UCHAR)((pVDev->u.array.CriticalMembers ||
- pVDev->VDeviceType == VD_RAID_1) ?
- DUPLICATE : REBUILD_PARITY));
- }
+ else{
+ if (pVDev->u.array.rf_need_rebuild && !pVDev->u.array.rf_rebuilding)
+ hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapTemp, pVDev,
+ (UCHAR)((pVDev->u.array.CriticalMembers || pVDev->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
+ }
}
/*
- * hpt_worker_thread needs to be suspended after shutdown sync, when fs
- * sync finished.
+ * hpt_worker_thread needs to be suspended after shutdown sync, when fs sync finished.
*/
#if (__FreeBSD_version < 500043)
- EVENTHANDLER_REGISTER(shutdown_post_sync, shutdown_kproc,
- hptdaemonproc, SHUTDOWN_PRI_FIRST);
-#else
- EVENTHANDLER_REGISTER(shutdown_post_sync, kproc_shutdown,
- hptdaemonproc, SHUTDOWN_PRI_FIRST);
+ EVENTHANDLER_REGISTER(shutdown_post_sync, shutdown_kproc, hptdaemonproc, SHUTDOWN_PRI_FIRST);
+#else
+ EVENTHANDLER_REGISTER(shutdown_post_sync, kproc_shutdown, hptdaemonproc, SHUTDOWN_PRI_FIRST);
#endif
}
+/*
+ *SYSINIT(hptwt, SI_SUB_KTHREAD_IDLE, SI_ORDER_FIRST, launch_worker_thread, NULL);
+*/
-#endif /* SUPPORT_ARRAY */
-
-/* build sgl with merge function */
-#define ON64KBOUNDARY(x) (((ULONG_PTR)(x) & 0xFFFF) == 0)
-
-/* XXX */
-/* #define NOTNEIGHBORPAGE(x, y) (max(x, y) - min(x, y) > PAGE_SIZE) */
-#define NOTNEIGHBORPAGE(highvaddr, lowvaddr) \
- ((ULONG_PTR)(highvaddr) - (ULONG_PTR)(lowvaddr) != PAGE_SIZE)
-
+#endif
/********************************************************************************/
-static void
-hptmv_buffer_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+int HPTLIBAPI fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg, int logical)
{
- FPSCAT_GATH pSg;
+ union ccb *ccb = (union ccb *)pCmd->pOrgCommand;
+ bus_dma_segment_t *sgList = (bus_dma_segment_t *)ccb->csio.data_ptr;
int idx;
- if (error || nsegs == 0) {
- panic("busdma bewm");
- return;
- }
-
- pSg = *(FPSCAT_GATH *)arg;
-
- for (idx = 0; idx < nsegs; idx++) {
- pSg[idx].dSgAddress = (ULONG_PTR)segs[idx].ds_addr;
- pSg[idx].wSgSize = segs[idx].ds_len;
- pSg[idx].wSgFlag = 0;
- }
- pSg[idx - 1].wSgFlag = SG_FLAG_EOT;
-
- return;
-}
+ if(logical) {
+ if (ccb->ccb_h.flags & CAM_DATA_PHYS)
+ panic("physical address unsupported");
-static int HPTLIBAPI
-fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg, int logical)
-{
- IAL_ADAPTER_T *pAdapter;
- pPrivCommand prvCmd;
- union ccb *ccb;
- struct ccb_hdr *ccb_h;
- struct ccb_scsiio *csio;
- bus_dma_segment_t *sgList;
- int error;
-
- prvCmd = pCmd->pOrgCommand;
- pAdapter = prvCmd->pAdapter;
- ccb = prvCmd->ccb;
- ccb_h = &ccb->ccb_h;
- csio = &ccb->csio;
- sgList = (bus_dma_segment_t *)(csio->data_ptr);
-
- if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_NONE)
- return TRUE;
-
- if ((ccb_h->flags & CAM_SCATTER_VALID) != 0) {
- if((ccb_h->flags & CAM_DATA_PHYS) != 0)
- panic(KMSG_LEADING "physical address unsupported!");
-
- hptmv_buffer_callback(&pSg, sgList, csio->sglist_cnt, 0);
- return TRUE;
- }
-
- if (logical) {
- if ((ccb_h->flags & CAM_DATA_PHYS) != 0)
- panic(KMSG_LEADING "physical address unsupported\n");
-
- pSg->dSgAddress = (ULONG_PTR)csio->data_ptr;
- pSg->wSgSize = (USHORT)csio->dxfer_len;
- pSg->wSgFlag = SG_FLAG_EOT;
+ if (ccb->ccb_h.flags & CAM_SCATTER_VALID) {
+ if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
+ panic("physical address unsupported");
+
+ for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) {
+ pSg[idx].dSgAddress = (ULONG_PTR)(UCHAR *)sgList[idx].ds_addr;
+ pSg[idx].wSgSize = sgList[idx].ds_len;
+ pSg[idx].wSgFlag = (idx==ccb->csio.sglist_cnt-1)? SG_FLAG_EOT : 0;
+ }
+ }
+ else {
+ pSg->dSgAddress = (ULONG_PTR)(UCHAR *)ccb->csio.data_ptr;
+ pSg->wSgSize = ccb->csio.dxfer_len;
+ pSg->wSgFlag = SG_FLAG_EOT;
+ }
return TRUE;
}
-
- KdPrint(("use sgl (physical) ...........\n"));
-
- /*
- * XXX Hack to make this work with PAE. It will fail under
- * heavy load.
- */
- error = bus_dmamap_load(pAdapter->buf_dmat, prvCmd->buf_map,
- csio->data_ptr, csio->dxfer_len, hptmv_buffer_callback, &pSg,
- BUS_DMA_NOWAIT);
-
- if (error) {
- printf("bus_dmamap_load failed error= %d\n", error);
- return FALSE;
- }
-
-/*#ifdef DEBUG
- do {
- int size, i = 0;
- KdPrintI(("sg[%d]:0x%lx %d\n", i++, pSg[i].dSgAddress,
- pSg[i].wSgSize));
- size = pSg->wSgSize;
- if (pSg[i].wSgFlag & SG_FLAG_EOT)
- break;
- } while (i<17);
-#endif*/
-
- if ((ccb_h->flags & CAM_DIR_MASK) == CAM_DIR_IN) {
- bus_dmamap_sync(pAdapter->buf_dmat, prvCmd->buf_map,
- BUS_DMASYNC_PREREAD);
- } else {
- bus_dmamap_sync(pAdapter->buf_dmat, prvCmd->buf_map,
- BUS_DMASYNC_PREWRITE);
- }
-
- return TRUE;
+
+ /* since we have provided physical sg, nobody will ask us to build physical sg */
+ HPT_ASSERT(0);
+ return FALSE;
}
/*******************************************************************************/
ULONG HPTLIBAPI
GetStamp(void)
{
- ULONG stamp;
-
/*
* the system variable, ticks, can't be used since it hasn't yet been active
* when our driver starts (ticks==0, it's a invalid stamp value)
*/
- do {
- stamp = random();
- } while (stamp==0);
-
+ ULONG stamp;
+ do { stamp = random(); } while (stamp==0);
return stamp;
}
@@ -2641,9 +2509,8 @@ static void
SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
{
int i;
- IDENTIFY_DATA2 *pIdentify;
-
- pIdentify = (IDENTIFY_DATA2*)pVDev->u.disk.mv->identifyDevice;
+ IDENTIFY_DATA2 *pIdentify = (IDENTIFY_DATA2*)pVDev->u.disk.mv->identifyDevice;
+
inquiryData->DeviceType = T_DIRECT; /*DIRECT_ACCESS_DEVICE*/
inquiryData->AdditionalLength = (UCHAR)(sizeof(INQUIRYDATA) - 5);
#ifndef SERIAL_CMDS
@@ -2655,16 +2522,13 @@ SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
case VD_ATAPI:
case VD_REMOVABLE:
/* Set the removable bit, if applicable. */
- if ((pVDev->u.disk.df_removable_drive) ||
- (pIdentify->GeneralConfiguration & 0x80))
+ if ((pVDev->u.disk.df_removable_drive) || (pIdentify->GeneralConfiguration & 0x80))
inquiryData->RemovableMedia = 1;
/* Fill in vendor identification fields. */
- for (i = 0; i < 16; i += 2) {
- inquiryData->VendorId[i] =
- ((PUCHAR)pIdentify->ModelNumber)[i + 1];
- inquiryData->VendorId[i+1] =
- ((PUCHAR)pIdentify->ModelNumber)[i];
+ for (i = 0; i < 20; i += 2) {
+ inquiryData->VendorId[i] = ((PUCHAR)pIdentify->ModelNumber)[i + 1];
+ inquiryData->VendorId[i+1] = ((PUCHAR)pIdentify->ModelNumber)[i];
}
@@ -2672,38 +2536,29 @@ SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
for (i = 0; i < 4; i++) inquiryData->ProductId[12+i] = ' ';
/* firmware revision */
- for (i = 0; i < 4; i += 2) {
- inquiryData->ProductRevisionLevel[i] =
- ((PUCHAR)pIdentify->FirmwareRevision)[i+1];
- inquiryData->ProductRevisionLevel[i+1] =
- ((PUCHAR)pIdentify->FirmwareRevision)[i];
+ for (i = 0; i < 4; i += 2)
+ {
+ inquiryData->ProductRevisionLevel[i] = ((PUCHAR)pIdentify->FirmwareRevision)[i+1];
+ inquiryData->ProductRevisionLevel[i+1] = ((PUCHAR)pIdentify->FirmwareRevision)[i];
}
break;
default:
memcpy(&inquiryData->VendorId, "RR182x ", 8);
#ifdef SUPPORT_ARRAY
- switch(pVDev->VDeviceType) {
+ switch(pVDev->VDeviceType){
case VD_RAID_0:
- if ((pVDev->u.array.pMember[0] &&
- mIsArray(pVDev->u.array.pMember[0])) ||
- (pVDev->u.array.pMember[1] &&
- mIsArray(pVDev->u.array.pMember[1])))
- memcpy(&inquiryData->ProductId,
- "RAID 1/0 Array ", 16);
+ if ((pVDev->u.array.pMember[0] && mIsArray(pVDev->u.array.pMember[0])) ||
+ (pVDev->u.array.pMember[1] && mIsArray(pVDev->u.array.pMember[1])))
+ memcpy(&inquiryData->ProductId, "RAID 1/0 Array ", 16);
else
- memcpy(&inquiryData->ProductId,
- "RAID 0 Array ", 16);
+ memcpy(&inquiryData->ProductId, "RAID 0 Array ", 16);
break;
case VD_RAID_1:
- if ((pVDev->u.array.pMember[0] &&
- mIsArray(pVDev->u.array.pMember[0])) ||
- (pVDev->u.array.pMember[1] &&
- mIsArray(pVDev->u.array.pMember[1])))
- memcpy(&inquiryData->ProductId,
- "RAID 0/1 Array ", 16);
+ if ((pVDev->u.array.pMember[0] && mIsArray(pVDev->u.array.pMember[0])) ||
+ (pVDev->u.array.pMember[1] && mIsArray(pVDev->u.array.pMember[1])))
+ memcpy(&inquiryData->ProductId, "RAID 0/1 Array ", 16);
else
- memcpy(&inquiryData->ProductId,
- "RAID 1 Array ", 16);
+ memcpy(&inquiryData->ProductId, "RAID 1 Array ", 16);
break;
case VD_RAID_5:
memcpy(&inquiryData->ProductId, "RAID 5 Array ", 16);
@@ -2721,28 +2576,64 @@ SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
static void
hpt_timeout(void *arg)
{
- _VBUS_INST(&((IAL_ADAPTER_T*)((union ccb *)arg)->ccb_adapter)->VBus)
- intrmask_t oldspl;
-
- oldspl = lock_driver();
+ _VBUS_INST(&((PBUS_DMAMAP)((union ccb *)arg)->ccb_adapter)->pAdapter->VBus)
+ intrmask_t oldspl = lock_driver();
fResetVBus(_VBUS_P0);
unlock_driver(oldspl);
}
+static void
+hpt_io_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+ PCommand pCmd = (PCommand)arg;
+ union ccb *ccb = pCmd->pOrgCommand;
+ struct ccb_hdr *ccb_h = &ccb->ccb_h;
+ PBUS_DMAMAP pmap = (PBUS_DMAMAP) ccb->ccb_adapter;
+ IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
+ PVDevice pVDev = pAdapter->VBus.pVDevice[ccb_h->target_id];
+ FPSCAT_GATH psg = pCmd->pSgTable;
+ int idx;
+ _VBUS_INST(pVDev->pVBus)
+
+ HPT_ASSERT(pCmd->cf_physical_sg);
+
+ if (error || nsegs == 0)
+ panic("busdma error");
+
+ HPT_ASSERT(nsegs<= MAX_SG_DESCRIPTORS);
+
+ for (idx = 0; idx < nsegs; idx++, psg++) {
+ psg->dSgAddress = (ULONG_PTR)(UCHAR *)segs[idx].ds_addr;
+ psg->wSgSize = segs[idx].ds_len;
+ psg->wSgFlag = (idx == nsegs-1)? SG_FLAG_EOT: 0;
+/* KdPrint(("psg[%d]:add=%p,size=%x,flag=%x\n", idx, psg->dSgAddress,psg->wSgSize,psg->wSgFlag)); */
+ }
+/* psg[-1].wSgFlag = SG_FLAG_EOT; */
+
+ if (pCmd->cf_data_in) {
+ bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_PREREAD);
+ }
+ else if (pCmd->cf_data_out) {
+ bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_PREWRITE);
+ }
+
+ ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz);
+ pVDev->pfnSendCommand(_VBUS_P pCmd);
+ CheckPendingCall(_VBUS_P0);
+}
+
+
+
static void HPTLIBAPI
OsSendCommand(_VBUS_ARG union ccb *ccb)
{
- IAL_ADAPTER_T *pAdapter;
- struct ccb_hdr *ccb_h;
- struct ccb_scsiio *csio;
- PVDevice pVDev;
-
- pAdapter = (IAL_ADAPTER_T *)ccb->ccb_adapter;
- ccb_h = &ccb->ccb_h;
- csio = &ccb->csio;
- pVDev = pAdapter->VBus.pVDevice[ccb_h->target_id];
+ PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter;
+ IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
+ struct ccb_hdr *ccb_h = &ccb->ccb_h;
+ struct ccb_scsiio *csio = &ccb->csio;
+ PVDevice pVDev = pAdapter->VBus.pVDevice[ccb_h->target_id];
- KdPrintI(("OsSendCommand: ccb %p cdb %x-%x-%x\n",
+ KdPrintI(("OsSendCommand: ccb %p cdb %x-%x-%x\n",
ccb,
*(ULONG *)&ccb->csio.cdb_io.cdb_bytes[0],
*(ULONG *)&ccb->csio.cdb_io.cdb_bytes[4],
@@ -2759,111 +2650,144 @@ OsSendCommand(_VBUS_ARG union ccb *ccb)
switch(ccb->csio.cdb_io.cdb_bytes[0])
{
- case TEST_UNIT_READY:
- case START_STOP_UNIT:
- case SYNCHRONIZE_CACHE:
- /* FALLTHROUGH */
- ccb->ccb_h.status = CAM_REQ_CMP;
- break;
-
- case INQUIRY:
- ZeroMemory(ccb->csio.data_ptr, ccb->csio.dxfer_len);
- SetInquiryData((PINQUIRYDATA)ccb->csio.data_ptr, pVDev);
- ccb_h->status = CAM_REQ_CMP;
- break;
-
- case READ_CAPACITY:
- {
- UCHAR swip[4];
- /* Claim 512 byte blocks (big-endian). */
- ((PREAD_CAPACITY_DATA)csio->data_ptr)->BytesPerBlock = 0x20000;
- *(ULONG*)swip = pVDev->VDeviceCapacity - 1;
- ((PREAD_CAPACITY_DATA)csio->data_ptr)->LogicalBlockAddress =
- (swip[0] << 24) | (swip[1] << 16) | (swip[2] << 8) | swip[3];
- ccb_h->status = CAM_REQ_CMP;
- break;
- }
-
- case READ_6:
- case WRITE_6:
- case READ_10:
- case WRITE_10:
- case 0x13:
- case 0x2f:
- {
- UCHAR Cdb[16];
- UCHAR CdbLength;
- _VBUS_INST(pVDev->pVBus)
- PCommand pCmd;
-
- pCmd = AllocateCommand(_VBUS_P0);
- HPT_ASSERT(pCmd);
-
- CdbLength = csio->cdb_len;
- if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) {
- if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) {
- bcopy(csio->cdb_io.cdb_ptr, Cdb, CdbLength);
- } else {
- KdPrintE(("ERROR!!!\n"));
- ccb->ccb_h.status = CAM_REQ_INVALID;
- break;
- }
- } else {
- bcopy(csio->cdb_io.cdb_bytes, Cdb, CdbLength);
- }
-
- pCmd->pOrgCommand = AllocPrivCommand(pAdapter);
- if (pCmd->pOrgCommand == NULL)
- panic("command leak!");
- ((pPrivCommand)(pCmd->pOrgCommand))->ccb = ccb;
- pCmd->pVDevice = pVDev;
- pCmd->pfnCompletion = fOsCommandDone;
- pCmd->pfnBuildSgl = fOsBuildSgl;
+ case TEST_UNIT_READY:
+ case START_STOP_UNIT:
+ case SYNCHRONIZE_CACHE:
+ /* FALLTHROUGH */
+ ccb->ccb_h.status = CAM_REQ_CMP;
+ break;
- switch (Cdb[0]) {
- case READ_6:
- case WRITE_6:
- case 0x13:
- pCmd->uCmd.Ide.Lba = ((ULONG)Cdb[1] << 16) |
- ((ULONG)Cdb[2] << 8) | (ULONG)Cdb[3];
- pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[4];
+ case INQUIRY:
+ ZeroMemory(ccb->csio.data_ptr, ccb->csio.dxfer_len);
+ SetInquiryData((PINQUIRYDATA)ccb->csio.data_ptr, pVDev);
+ ccb_h->status = CAM_REQ_CMP;
break;
- default:
- pCmd->uCmd.Ide.Lba = (ULONG)Cdb[5] |
- ((ULONG)Cdb[4] << 8) | ((ULONG)Cdb[3] << 16) |
- ((ULONG)Cdb[2] << 24);
- pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[8] |
- ((USHORT)Cdb[7]<<8);
+
+ case READ_CAPACITY:
+ {
+ UCHAR swip[4];
+ /* Claim 512 byte blocks (big-endian). */
+ ((PREAD_CAPACITY_DATA)csio->data_ptr)->BytesPerBlock = 0x20000;
+ *(ULONG*)swip = pVDev->VDeviceCapacity - 1;
+ ((PREAD_CAPACITY_DATA)csio->data_ptr)->LogicalBlockAddress =
+ (swip[0] << 24) | (swip[1] << 16) | (swip[2] << 8) | swip[3];
+ ccb_h->status = CAM_REQ_CMP;
break;
}
- switch (Cdb[0]) {
case READ_6:
- case READ_10:
- pCmd->uCmd.Ide.Command = IDE_COMMAND_READ;
- pCmd->cf_data_in = 1;
- break;
-
case WRITE_6:
+ case READ_10:
case WRITE_10:
- pCmd->uCmd.Ide.Command = IDE_COMMAND_WRITE;
- pCmd->cf_data_out = 1;
- break;
case 0x13:
case 0x2f:
- pCmd->uCmd.Ide.Command = IDE_COMMAND_VERIFY;
- break;
- }
+ {
+ UCHAR Cdb[16];
+ UCHAR CdbLength;
+ _VBUS_INST(pVDev->pVBus)
+ PCommand pCmd = AllocateCommand(_VBUS_P0);
+ HPT_ASSERT(pCmd);
- ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz);
+ CdbLength = csio->cdb_len;
+ if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0)
+ {
+ if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0)
+ {
+ bcopy(csio->cdb_io.cdb_ptr, Cdb, CdbLength);
+ }
+ else
+ {
+ KdPrintE(("ERROR!!!\n"));
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ break;
+ }
+ }
+ else
+ {
+ bcopy(csio->cdb_io.cdb_bytes, Cdb, CdbLength);
+ }
- pVDev->pfnSendCommand(_VBUS_P pCmd);
- goto Command_Complished;
- }
+ pCmd->pOrgCommand = ccb;
+ pCmd->pVDevice = pVDev;
+ pCmd->pfnCompletion = fOsCommandDone;
+ pCmd->pfnBuildSgl = fOsBuildSgl;
+ pCmd->pSgTable = pmap->psg;
- default:
- ccb->ccb_h.status = CAM_REQ_INVALID;
- break;
+ switch (Cdb[0])
+ {
+ case READ_6:
+ case WRITE_6:
+ case 0x13:
+ pCmd->uCmd.Ide.Lba = ((ULONG)Cdb[1] << 16) | ((ULONG)Cdb[2] << 8) | (ULONG)Cdb[3];
+ pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[4];
+ break;
+
+ default:
+ pCmd->uCmd.Ide.Lba = (ULONG)Cdb[5] | ((ULONG)Cdb[4] << 8) | ((ULONG)Cdb[3] << 16) | ((ULONG)Cdb[2] << 24);
+ pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[8] | ((USHORT)Cdb[7]<<8);
+ break;
+ }
+
+ switch (Cdb[0])
+ {
+ case READ_6:
+ case READ_10:
+ pCmd->uCmd.Ide.Command = IDE_COMMAND_READ;
+ pCmd->cf_data_in = 1;
+ break;
+
+ case WRITE_6:
+ case WRITE_10:
+ pCmd->uCmd.Ide.Command = IDE_COMMAND_WRITE;
+ pCmd->cf_data_out = 1;
+ break;
+ case 0x13:
+ case 0x2f:
+ pCmd->uCmd.Ide.Command = IDE_COMMAND_VERIFY;
+ break;
+ }
+/*///////////////////////// */
+ if (ccb->ccb_h.flags & CAM_SCATTER_VALID) {
+ int idx;
+ bus_dma_segment_t *sgList = (bus_dma_segment_t *)ccb->csio.data_ptr;
+
+ if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS)
+ pCmd->cf_physical_sg = 1;
+
+ for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) {
+ pCmd->pSgTable[idx].dSgAddress = (ULONG_PTR)(UCHAR *)sgList[idx].ds_addr;
+ pCmd->pSgTable[idx].wSgSize = sgList[idx].ds_len;
+ pCmd->pSgTable[idx].wSgFlag= (idx==ccb->csio.sglist_cnt-1)?SG_FLAG_EOT: 0;
+ }
+
+ ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz);
+ pVDev->pfnSendCommand(_VBUS_P pCmd);
+ }
+ else {
+ int error;
+ pCmd->cf_physical_sg = 1;
+ error = bus_dmamap_load(pAdapter->io_dma_parent,
+ pmap->dma_map,
+ ccb->csio.data_ptr, ccb->csio.dxfer_len,
+ hpt_io_dmamap_callback, pCmd,
+ BUS_DMA_WAITOK
+ );
+ KdPrint(("bus_dmamap_load return %d\n", error));
+ if (error && error!=EINPROGRESS) {
+ hpt_printk(("bus_dmamap_load error %d\n", error));
+ FreeCommand(_VBUS_P pCmd);
+ ccb->ccb_h.status = CAM_REQ_CMP_ERR;
+ dmamap_put(pmap);
+ pAdapter->outstandingCommands--;
+ xpt_done(ccb);
+ }
+ }
+ goto Command_Complished;
+ }
+
+ default:
+ ccb->ccb_h.status = CAM_REQ_INVALID;
+ break;
}
ccb_done(ccb);
Command_Complished:
@@ -2871,18 +2795,14 @@ Command_Complished:
return;
}
-static void HPTLIBAPI
+static void HPTLIBAPI
fOsCommandDone(_VBUS_ARG PCommand pCmd)
{
- IAL_ADAPTER_T *pAdapter;
- pPrivCommand prvCmd;
- union ccb *ccb;
+ union ccb *ccb = pCmd->pOrgCommand;
+ PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter;
+ IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
- prvCmd = pCmd->pOrgCommand;
- pAdapter = prvCmd->pAdapter;
- ccb = prvCmd->ccb;
-
- KdPrint(("fOsCommandDone(%p, %d)", pCmd, pCmd->Result));
+ KdPrint(("fOsCommandDone(pcmd=%p, result=%d)\n", pCmd, pCmd->Result));
untimeout(hpt_timeout, (caddr_t)ccb, ccb->ccb_h.timeout_ch);
@@ -2910,16 +2830,15 @@ fOsCommandDone(_VBUS_ARG PCommand pCmd)
break;
}
- if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) {
- bus_dmamap_sync(pAdapter->buf_dmat, prvCmd->buf_map,
- BUS_DMASYNC_POSTREAD);
- } else {
- bus_dmamap_sync(pAdapter->buf_dmat, prvCmd->buf_map,
- BUS_DMASYNC_POSTWRITE);
+ if (pCmd->cf_data_in) {
+ bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_POSTREAD);
+ }
+ else if (pCmd->cf_data_in) {
+ bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_POSTWRITE);
}
- bus_dmamap_unload(pAdapter->buf_dmat, prvCmd->buf_map);
+
+ bus_dmamap_unload(pAdapter->io_dma_parent, pmap->dma_map);
- FreePrivCommand(pAdapter, prvCmd);
FreeCommand(_VBUS_P pCmd);
ccb_done(ccb);
}
@@ -2946,53 +2865,44 @@ hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T * pAdapter, void *arg, UCHAR flags)
#ifdef _RAID5N_
/*
- * Allocate memory above 16M, otherwise we may eat all low memory for ISA
- * devices.
- *
- * Busdma should be used here, not contigmalloc/free. However, this API
- * will need to be changed to use it effective.
+ * Allocate memory above 16M, otherwise we may eat all low memory for ISA devices.
+ * How about the memory for 5081 request/response array and PRD table?
*/
void
*os_alloc_page(_VBUS_ARG0)
{
- return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000,
- 0xffffffff, PAGE_SIZE, 0);
+ return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000, 0xffffffff, PAGE_SIZE, 0ul);
}
+
void
*os_alloc_dma_page(_VBUS_ARG0)
{
- return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000,
- 0xffffffff, PAGE_SIZE, 0);
+ return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000, 0xffffffff, PAGE_SIZE, 0ul);
}
-/*
- * The next two are not used right now.
- */
void
-os_free_page(_VBUS_ARG void *p)
-{
- contigfree(p, 0x1000, M_DEVBUF);
+os_free_page(_VBUS_ARG void *p)
+{
+ contigfree(p, 0x1000, M_DEVBUF);
}
void
-os_free_dma_page(_VBUS_ARG void *p)
-{
- contigfree(p, 0x1000, M_DEVBUF);
+os_free_dma_page(_VBUS_ARG void *p)
+{
+ contigfree(p, 0x1000, M_DEVBUF);
}
void
DoXor1(ULONG *p0, ULONG *p1, ULONG *p2, UINT nBytes)
{
UINT i;
- for (i = 0; i < nBytes / 4; i++)
- *p0++ = *p1++ ^ *p2++;
+ for (i = 0; i < nBytes / 4; i++) *p0++ = *p1++ ^ *p2++;
}
void
DoXor2(ULONG *p0, ULONG *p2, UINT nBytes)
{
UINT i;
- for (i = 0; i < nBytes / 4; i++)
- *p0++ ^= *p2++;
+ for (i = 0; i < nBytes / 4; i++) *p0++ ^= *p2++;
}
#endif
diff --git a/sys/dev/hptmv/global.h b/sys/dev/hptmv/global.h
index 90c62aea90d1..4e6a0d0e668f 100644
--- a/sys/dev/hptmv/global.h
+++ b/sys/dev/hptmv/global.h
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -32,11 +32,11 @@
#include <dev/hptmv/mvSata.h>
#include <dev/hptmv/mvStorageDev.h>
-#define COMPANY "HighPoint Technologies, Inc."
-#define COPYRIGHT "(c) 2000-2004. HighPoint Technologies, Inc."
+#define COMPANY "HighPoint Technologies, Inc."
+#define COPYRIGHT "(c) 2000-2004. HighPoint Technologies, Inc."
#define DRIVER_NAME "RocketRAID 182x SATA Controller driver"
-#define CONTROLLER_NAME "RocketRAID 182x SATA Controller"
-#define PROC_DIR_NAME hptmv
+#define CONTROLLER_NAME "RocketRAID 182x SATA Controller"
+#define PROC_DIR_NAME hptmv
#define HPT_INTERFACE_VERSION 0x01000003
#define SUPPORT_48BIT_LBA
@@ -45,10 +45,8 @@
#define _RAID5N_
#define MAX_QUEUE_COMM 32
#define MAX_SG_DESCRIPTORS 17
-#define MAX_VBUS 2 /*
- * One vbus per adapter in mv linux driver,
- * MAX_VBUS is defined for share code and can not be 1
- */
+#define MAX_VBUS 2 /*one vbus per adapter in mv linux driver,
+ MAX_VBUS is defined for share code and can not be 1*/
#define SET_VBUS_FOR_EACH_CONTROLLER
#define MAX_MEMBERS 8
@@ -75,42 +73,42 @@ typedef struct _Device {
UCHAR busyCount;
UCHAR df_tcq_set: 1;
- UCHAR df_tcq: 1; /* enable TCQ */
+ UCHAR df_tcq: 1; /* enable TCQ */
UCHAR df_ncq_set: 1;
- UCHAR df_ncq: 1; /* enable NCQ */
+ UCHAR df_ncq: 1; /* enable NCQ */
UCHAR df_write_cache_set: 1;
- UCHAR df_write_cache: 1; /* enable write cache */
+ UCHAR df_write_cache: 1; /* enable write cache */
UCHAR df_read_ahead_set: 1;
- UCHAR df_read_ahead: 1; /* enable read ahead */
-
+ UCHAR df_read_ahead: 1; /* enable read ahead */
+
UCHAR retryCount;
UCHAR resetCount;
UCHAR pad1;
-
+
UCHAR df_user_mode_set;
- UCHAR bDeModeSetting; /* Current Data Transfer mode: 0-4 PIO 0-4 */
- UCHAR bDeUsable_Mode; /* actual maximum data transfer mode */
+ UCHAR bDeModeSetting; /* Current Data Transfer mode: 0-4 PIO 0-4 */
+ UCHAR bDeUsable_Mode; /* actual maximum data transfer mode */
UCHAR bDeUserSelectMode;
-
+
PVBus pVBus;
ULONG dDeRealCapacity;
ULONG dDeHiddenLba;
ULONG HeadPosition;
ULONG QueueLength;
MV_SATA_CHANNEL *mv;
-} Device, *PDevice;
+}
+Device, *PDevice;
-typedef struct _SCAT_GATH {
- ULONG_PTR dSgAddress;
- USHORT wSgSize;
- USHORT wSgFlag;
+typedef struct _SCAT_GATH
+{
+ ULONG_PTR dSgAddress;
+ USHORT wSgSize;
+ USHORT wSgFlag;
} SCAT_GATH, FAR *FPSCAT_GATH;
#define OS_VDEV_EXT
-typedef struct _VDevice_Ext {
-#if defined(WIN95) && defined(SUPPORT_HOTSWAP)
- DCB * pDcb;
-#endif
+typedef struct _VDevice_Ext
+{
UCHAR gui_locked; /* the device is locked by GUI */
UCHAR reserve[3];
} VDevice_Ext, *PVDevice_Ext;
@@ -119,21 +117,12 @@ typedef struct _VDevice_Ext {
#define SG_FLAG_SKIP 0x4000
#define SG_FLAG_EOT 0x8000
-#if 0 /* MAX_VBUS==1 */
-#define _VBUS_ARG
-#define _VBUS_ARG0 void
-#define _VBUS_P
-#define _VBUS_P0
-#define _VBUS_INST(x)
-#define _vbus_(x) x
-#else
#define _VBUS_ARG0 PVBus _vbus_p
#define _VBUS_ARG PVBus _vbus_p,
#define _VBUS_P _vbus_p,
#define _VBUS_P0 _vbus_p
#define _VBUS_INST(x) PVBus _vbus_p = x;
#define _vbus_(x) (_vbus_p->x)
-#endif
/*************************************************************************
* arithmetic functions
@@ -156,34 +145,36 @@ int HPTLIBAPI os_memcmp(const void *cs, const void *ct, unsigned len);
void HPTLIBAPI os_memcpy(void *to, const void *from, unsigned len);
void HPTLIBAPI os_memset(void *s, char c, unsigned len);
unsigned HPTLIBAPI os_strlen(const char *s);
+
#ifdef NO_LIBC
#define memcmp os_memcmp
#define memcpy os_memcpy
#define memset os_memset
#define strlen os_strlen
#elif (__FreeBSD_version <= 410000)
-#define memcpy(d, s, len) bcopy((s),(d),(len))
-#define memset(d, s, len) bzero((d),(len))
+#define memcpy(d, s, len) bcopy((s),(d),(len))
+#define memset(d, s, len) bzero((d),(len))
#endif
#define ZeroMemory(a, b) memset((char *)a, 0, b)
#define MemoryCopy(a,b,c) memcpy((char *)(a), (char *)(b), (UINT)(c))
-#define farMemoryCopy(a,b,c) memcpy((char *)(a), (char *)(b), (UINT)c)
+#define farMemoryCopy(a,b,c) memcpy((char *)(a), (char *)(b), (UINT)c)
#define StrLen strlen
/*
* we don't want whole hptintf.h in shared code...
* some constants must match that in hptintf.h!
*/
-enum _driver_events_t {
+enum _driver_events_t
+{
ET_DEVICE=0,
- ET_DEVICE_REMOVED,
- ET_DEVICE_PLUGGED,
- ET_DEVICE_ERROR,
- ET_REBUILD_STARTED,
- ET_REBUILD_ABORTED,
- ET_REBUILD_FINISHED,
- ET_SPARE_TOOK_OVER,
- ET_REBUILD_FAILED,
+ ET_DEVICE_REMOVED,
+ ET_DEVICE_PLUGGED,
+ ET_DEVICE_ERROR,
+ ET_REBUILD_STARTED,
+ ET_REBUILD_ABORTED,
+ ET_REBUILD_FINISHED,
+ ET_SPARE_TOOK_OVER,
+ ET_REBUILD_FAILED,
ET_VERIFY_STARTED,
ET_VERIFY_ABORTED,
ET_VERIFY_FAILED,
@@ -195,13 +186,13 @@ enum _driver_events_t {
ET_VERIFY_DATA_ERROR,
};
+#define StallExec(x) mvMicroSecondsDelay(x)
extern void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param);
-#define StallExec(x) mvMicroSecondsDelay(x)
-#define fNotifyGUI(WhatHappen, pVDevice) \
- ioctl_ReportEvent(WhatHappen, pVDevice)
-#define DECLARE_BUFFER(type, ptr) \
- UCHAR ptr##__buf[512]; \
- type ptr=(type)ptr##__buf
+#define fNotifyGUI(WhatHappen, pVDevice) ioctl_ReportEvent(WhatHappen, pVDevice)
+#define DECLARE_BUFFER(type, ptr) UCHAR ptr##__buf[512]; type ptr=(type)ptr##__buf
+
+int HPTLIBAPI fDeReadWrite(PDevice pDev, ULONG Lba, UCHAR Cmd, void *tmpBuffer);
+void HPTLIBAPI fDeSelectMode(PDevice pDev, UCHAR NewMode);
#include <dev/hptmv/atapi.h>
#include <dev/hptmv/command.h>
@@ -209,8 +200,10 @@ extern void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param);
#include <dev/hptmv/raid5n.h>
#include <dev/hptmv/vdevice.h>
-int HPTLIBAPI fDeReadWrite(PDevice pDev, ULONG Lba, UCHAR Cmd, void *tmpBuffer);
-void HPTLIBAPI fDeSelectMode(PDevice pDev, UCHAR NewMode);
+#if defined(__FreeBSD__) && defined(HPTLIBAPI)
+#undef HPTLIBAPI
+#define HPTLIBAPI
+#endif
#ifdef SUPPORT_ARRAY
#define ArrayTables(i) ((PVDevice)&_vbus_(_ArrayTables)[i*ARRAY_VDEV_SIZE])
diff --git a/sys/dev/hptmv/gui_lib.c b/sys/dev/hptmv/gui_lib.c
index 19fd2f8362fa..13def6ba9240 100644
--- a/sys/dev/hptmv/gui_lib.c
+++ b/sys/dev/hptmv/gui_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,10 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
#include <dev/hptmv/global.h>
#include <dev/hptmv/hptintf.h>
#include <dev/hptmv/osbsd.h>
@@ -59,7 +63,8 @@ static int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk);
static int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo);
static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo);
-int check_VDevice_valid(PVDevice p)
+int
+check_VDevice_valid(PVDevice p)
{
int i;
PVDevice pVDevice;
@@ -228,7 +233,7 @@ ignore_info:
for(i = 0; i < pVDevice->u.array.bArnMember; i++)
{
- if(pVDevice->u.array.pMember[i] != NULL)
+ if(pVDevice->u.array.pMember[i] != 0)
{
pInfo->u.array.Members[pInfo->u.array.nDisk] = VDEV_TO_ID(pVDevice->u.array.pMember[i]);
pInfo->u.array.nDisk++;
@@ -318,7 +323,7 @@ static int get_disk_info(PVDevice pVDevice, PLOGICAL_DEVICE_INFO pInfo)
return 0;
}
-static int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap)
+int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap)
{
ZeroMemory(cap, sizeof(DRIVER_CAPABILITIES));
cap->dwSize = sizeof(DRIVER_CAPABILITIES);
@@ -336,9 +341,6 @@ static int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap)
cap->MaximumArrayNameLength = MAX_ARRAY_NAME - 1;
cap->SupportDedicatedSpare = 0;
-#ifdef SUPPORT_HOTSWAP
- cap->SupportHotSwap = 1;
-#endif
#ifdef SUPPORT_ARRAY
/* Stripe */
@@ -350,7 +352,7 @@ static int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap)
/* Mirror + Stripe */
#ifdef ARRAY_V2_ONLY
cap->SupportedRAIDTypes[2] = (AT_RAID1<<4)|AT_RAID0; /* RAID0/1 */
-#else
+#else
cap->SupportedRAIDTypes[2] = (AT_RAID0<<4)|AT_RAID1; /* RAID1/0 */
#endif
cap->MaximumArrayMembers[2] = MAX_MEMBERS;
@@ -362,16 +364,11 @@ static int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap)
cap->SupportedRAIDTypes[4] = AT_RAID5;
cap->MaximumArrayMembers[4] = MAX_MEMBERS;
#endif
-#if 0 /* don't let GUI create RAID 0/1. */
- /* Stripe + Mirror */
- cap->SupportedRAIDTypes[5] = (AT_RAID1<<4)|AT_RAID0;
- cap->MaximumArrayMembers[5] = 4;
#endif
-#endif /* SUPPORT_ARRAY */
return 0;
}
-static int hpt_get_controller_count(void)
+int hpt_get_controller_count(void)
{
IAL_ADAPTER_T *pAdapTemp = gIal_Adapter;
int iControllerCount = 0;
@@ -385,7 +382,7 @@ static int hpt_get_controller_count(void)
return iControllerCount;
}
-static int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo)
+int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo)
{
IAL_ADAPTER_T *pAdapTemp;
int iControllerCount = 0;
@@ -403,7 +400,7 @@ static int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo)
#endif
strcpy(pInfo->szProductID, GUI_CONTROLLER_NAME);
#define _set_product_id(x)
-#else
+#else
#define _set_product_id(x) strcpy(pInfo->szProductID, x)
#endif
_set_product_id("RocketRAID 182x SATA Controller");
@@ -416,7 +413,7 @@ static int hpt_get_controller_info(int id, PCONTROLLER_INFO pInfo)
}
-static int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo)
+int hpt_get_channel_info(int id, int bus, PCHANNEL_INFO pInfo)
{
IAL_ADAPTER_T *pAdapTemp = gIal_Adapter;
int i,iControllerCount = 0;
@@ -449,7 +446,7 @@ found:
}
-static int hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount)
+int hpt_get_logical_devices(DEVICEID * pIds, int nMaxCount)
{
int count = 0;
int i,j;
@@ -482,11 +479,11 @@ done:
return count;
}
-static int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo)
+int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo)
{
PVDevice pVDevice = ID_TO_VDEV(id);
- if((id == HPT_NULL_ID) || check_VDevice_valid(pVDevice))
+ if((id == 0) || check_VDevice_valid(pVDevice))
return -1;
#ifdef SUPPORT_ARRAY
@@ -500,15 +497,12 @@ static int hpt_get_device_info(DEVICEID id, PLOGICAL_DEVICE_INFO pInfo)
}
#ifdef SUPPORT_ARRAY
-static DEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam)
+DEVICEID hpt_create_array(_VBUS_ARG PCREATE_ARRAY_PARAMS pParam)
{
ULONG Stamp = GetStamp();
int i,j;
ULONG capacity = MAX_LBA_T;
PVDevice pArray,pChild;
-#if MAX_VBUS==1
- PVBus _vbus_p = NULL;
-#endif
int Loca = -1;
for(i = 0; i < pParam->nDisk; i++)
@@ -758,9 +752,7 @@ int old_add_disk_to_raid01(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk)
int i;
IAL_ADAPTER_T *pAdapter = gIal_Adapter;
-#if MAX_VBUS>1
if (pArray1->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;}
-#endif
if(pDisk->u.disk.dDeRealCapacity < (pArray1->VDeviceCapacity / 2))
return -1;
@@ -834,7 +826,7 @@ int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk)
PVDevice pArray = ID_TO_VDEV(idArray);
PVDevice pDisk = ID_TO_VDEV(idDisk);
- if((idArray == HPT_NULL_ID) || (idDisk == HPT_NULL_ID)) return -1;
+ if((idArray == 0) || (idDisk == 0)) return -1;
if(check_VDevice_valid(pArray) || check_VDevice_valid(pDisk)) return -1;
if(!pArray->u.array.rf_broken) return -1;
@@ -864,9 +856,7 @@ int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk)
else
if(pDisk->VDeviceCapacity < Capacity) return -1;
-#if MAX_VBUS>1
if (pArray->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;}
-#endif
for(i = 0; i < pArray->u.array.bArnMember; i++)
if((pArray->u.array.pMember[i] == NULL) || !pArray->u.array.pMember[i]->vf_online)
@@ -907,19 +897,16 @@ find:
return 0;
}
-static int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk)
+int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk)
{
PVDevice pVDevice = ID_TO_VDEV(idDisk);
DECLARE_BUFFER(PUCHAR, pbuffer);
- if(idDisk == HPT_NULL_ID || check_VDevice_valid(pVDevice))
- return -1;
+ if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1;
if (pVDevice->VDeviceType != VD_SINGLE_DISK || pVDevice->pParent)
return -1;
-#if MAX_VBUS>1
if (pVDevice->u.disk.pVBus!=_vbus_p) return -1;
-#endif
UnregisterVDevice(pVDevice);
pVDevice->VDeviceType = VD_SPARE;
@@ -931,15 +918,13 @@ static int hpt_add_spare_disk(_VBUS_ARG DEVICEID idDisk)
return 0;
}
-static int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk)
+int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk)
{
PVDevice pVDevice = ID_TO_VDEV(idDisk);
if(idDisk == 0 || check_VDevice_valid(pVDevice)) return -1;
-#if MAX_VBUS>1
if (pVDevice->u.disk.pVBus!=_vbus_p) return -1;
-#endif
pVDevice->VDeviceType = VD_SINGLE_DISK;
@@ -948,19 +933,17 @@ static int hpt_remove_spare_disk(_VBUS_ARG DEVICEID idDisk)
return 0;
}
-static int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo)
+int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO pInfo)
{
PVDevice pVDevice = ID_TO_VDEV(idArray);
- if(idArray == HPT_NULL_ID || check_VDevice_valid(pVDevice)) return -1;
+ if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1;
if (!mIsArray(pVDevice)) return -1;
/* if the pVDevice isn't a top level, return -1; */
if(pVDevice->pParent != NULL) return -1;
-#if MAX_VBUS>1
if (pVDevice->pVBus!=_vbus_p) { HPT_ASSERT(0); return -1;}
-#endif
if (pInfo->ValidFields & AAIF_NAME) {
memset(pVDevice->u.array.ArrayName, 0, MAX_ARRAY_NAME);
@@ -978,12 +961,12 @@ static int hpt_set_array_info(_VBUS_ARG DEVICEID idArray, PALTERABLE_ARRAY_INFO
return 0;
}
-static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo)
+int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO pInfo)
{
PVDevice pVDevice = ID_TO_VDEV(idDisk);
/* stop buzzer. */
- if(idDisk == HPT_NULL_ID) {
+ if(idDisk == 0) {
#ifndef FOR_DEMO
IAL_ADAPTER_T *pAdapter;
for (pAdapter=gIal_Adapter; pAdapter; pAdapter=pAdapter->next) {
@@ -1000,9 +983,7 @@ static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO
if (mIsArray(pVDevice))
return -1;
-#if MAX_VBUS>1
if (pVDevice->u.disk.pVBus!=_vbus_p) return -1;
-#endif
/* if (pInfo->ValidFields & ADIF_MODE) {
pVDevice->u.disk.bDeModeSetting = pInfo->DeviceModeSetting;
@@ -1013,7 +994,7 @@ static int hpt_set_device_info(_VBUS_ARG DEVICEID idDisk, PALTERABLE_DEVICE_INFO
}*/
return 0;
}
-#endif /* SUPPORT_ARRAY */
+#endif
#ifdef SUPPORT_HPT601
int hpt_get_601_info(DEVICEID idDisk, PHPT601_INFO pInfo)
@@ -1257,12 +1238,10 @@ int hpt_default_ioctl(_VBUS_ARG
while(pAdapter != 0)
{
pVBus = &pAdapter->VBus;
- for(i = 0; i < MAX_VDEVICE_PER_VBUS; i++)
+ for(i = 0; i < MAX_ARRAY_PER_VBUS; i++)
{
if(!(pTop = pVBus->pVDevice[i])) continue;
-#if MAX_VBUS>1
if (pTop->pVBus!=_vbus_p) return -1;
-#endif
while (pTop->pParent) pTop = pTop->pParent;
if (id==0 && pTop->vf_bootmark)
pTop->vf_bootmark = 0;
@@ -1277,10 +1256,9 @@ int hpt_default_ioctl(_VBUS_ARG
}
}
break;
-#endif /* SUPPORT_ARRAY */
+#endif
case HPT_IOCTL_RESCAN_DEVICES:
{
- fRescanAllDevice(_VBUS_P0);
if (nInBufferSize!=0) return -1;
if (nOutBufferSize!=0) return -1;
fRescanAllDevice(_VBUS_P0);
diff --git a/sys/dev/hptmv/hptintf.h b/sys/dev/hptmv/hptintf.h
index 9839a6718271..34477a258524 100644
--- a/sys/dev/hptmv/hptintf.h
+++ b/sys/dev/hptmv/hptintf.h
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -162,7 +162,7 @@ typedef DWORD DEVICEID;
* It would be better if ioctl code are the same on different platforms,
* but we must not conflict with system defined ioctl code.
************************************************************************/
-#if defined(LINUX) || defined(__FreeBSD_version)
+#if defined(LINUX) || defined(__FreeBSD_version) || defined(_MACOSX_)
#define HPT_CTL_CODE(x) (x+0xFF00)
#elif defined(_MS_WIN32_) || defined(WIN32)
@@ -327,7 +327,6 @@ typedef struct _CHANNEL_INFO {
* time represented in DWORD format
*/
#ifndef __KERNEL__
-#error "BAM"
typedef struct _TIME_RECORD {
UINT seconds:6; /* 0 - 59 */
UINT minutes:6; /* 0 - 59 */
@@ -399,7 +398,6 @@ typedef struct _HPT_ARRAY_INFO_V2 {
* ATA/ATAPI Device identify data without the Reserved4.
*/
#ifndef __KERNEL__
-#error "BAM"
typedef struct _IDENTIFY_DATA2 {
USHORT GeneralConfiguration; /* 00 00 */
USHORT NumberOfCylinders; /* 02 1 */
@@ -781,7 +779,7 @@ HPT_IOCTL_PARAM32, *PHPT_IOCTL_PARAM32;
* Returns:
* interface version. 0 when fail.
*/
-DWORD hpt_get_version(void);
+DWORD hpt_get_version();
/*-------------------------------------------------------------------------- */
@@ -807,7 +805,7 @@ int hpt_get_driver_capabilities(PDRIVER_CAPABILITIES cap);
* Returns:
* number of controllers
*/
-int hpt_get_controller_count(void);
+int hpt_get_controller_count();
/*-------------------------------------------------------------------------- */
@@ -1049,7 +1047,7 @@ int hpt_set_device_info_v2(DEVICEID idDisk, PALTERABLE_DEVICE_INFO_V2 pInfo);
* Returns:
* 0 Success
*/
-int hpt_rescan_devices(void);
+int hpt_rescan_devices();
/*-------------------------------------------------------------------------- */
/* hpt_get_601_info
@@ -1210,59 +1208,5 @@ int hpt_remove_devices(DWORD ndev, DEVICEID *pIds);
#endif
-#if BITS_PER_LONG > 32
-#define VDEV_TO_ID(pVDev) (DEVICEID)(ULONG_PTR)(pVDev)
-#define ID_TO_VDEV(id) (PVDevice)(((ULONG_PTR)gIal_Adapter & 0xffffffff00000000) | (id))
-#else
-#define VDEV_TO_ID(pVDev) (DEVICEID)(pVDev)
-#define ID_TO_VDEV(id) (PVDevice)(id)
-#endif
-
-#define INVALID_DEVICEID (-1)
-#define INVALID_STRIPSIZE (-1)
-
-#define shortswap(w) ((WORD)((w)>>8 | ((w) & 0xFF)<<8))
-
-#ifndef MinBlockSizeShift
-#define MinBlockSizeShift 5
-#define MaxBlockSizeShift 12
-#endif
-
-typedef struct _HPT_IOCTL_TRANSFER_PARAM
-{
- ULONG nInBufferSize;
- ULONG nOutBufferSize;
- UCHAR buffer[0];
-}HPT_IOCTL_TRANSFER_PARAM, *PHPT_IOCTL_TRANSFER_PARAM;
-
-typedef struct _HPT_SET_STATE_PARAM
-{
- DEVICEID idArray;
- DWORD state;
-} HPT_SET_STATE_PARAM, *PHPT_SET_STATE_PARAM;
-
-typedef struct _HPT_SET_ARRAY_INFO
-{
- DEVICEID idArray;
- ALTERABLE_ARRAY_INFO Info;
-} HPT_SET_ARRAY_INFO, *PHPT_SET_ARRAY_INFO;
-
-typedef struct _HPT_SET_DEVICE_INFO
-{
- DEVICEID idDisk;
- ALTERABLE_DEVICE_INFO Info;
-} HPT_SET_DEVICE_INFO, *PHPT_SET_DEVICE_INFO;
-
-typedef struct _HPT_ADD_DISK_TO_ARRAY
-{
- DEVICEID idArray;
- DEVICEID idDisk;
-} HPT_ADD_DISK_TO_ARRAY, *PHPT_ADD_DISK_TO_ARRAY;
-
-int check_VDevice_valid(PVDevice);
-int hpt_default_ioctl(_VBUS_ARG DWORD, PVOID, DWORD, PVOID, DWORD, PDWORD);
-
-#define HPT_NULL_ID 0
-
#pragma pack()
#endif
diff --git a/sys/dev/hptmv/hptproc.c b/sys/dev/hptmv/hptproc.c
index 997183fa2cca..a179e320d55e 100644
--- a/sys/dev/hptmv/hptproc.c
+++ b/sys/dev/hptmv/hptproc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,10 @@
#include <sys/sysctl.h>
#include <machine/stdarg.h>
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
#include <dev/hptmv/global.h>
#include <dev/hptmv/hptintf.h>
#include <dev/hptmv/osbsd.h>
@@ -45,13 +49,15 @@ int hpt_rescan_all(void);
/***************************************************************************/
static char hptproc_buffer[256];
+extern char DRIVER_VERSION[];
#define FORMAL_HANDLER_ARGS struct sysctl_oid *oidp, void *arg1, int arg2, \
struct sysctl_req *req
#define REAL_HANDLER_ARGS oidp, arg1, arg2, req
typedef struct sysctl_req HPT_GET_INFO;
-static int hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
+static int
+hpt_set_asc_info(IAL_ADAPTER_T *pAdapter, char *buffer,int length)
{
int orig_length = length+4;
PVBus _vbus_p = &pAdapter->VBus;
@@ -118,7 +124,7 @@ rebuild:
if(pVDev == _vbus_p->pVDevice[i])
{
periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId,i);
- if (periph != NULL && periph->refcount == 1)
+ if (periph != NULL && periph->refcount >= 1)
{
hpt_printk(("Can not use disk used by OS!\n"));
return -EINVAL;
@@ -138,9 +144,9 @@ loop:
unlock_driver(oldspl);
return -EINVAL;
}
- pArray->u.array.rf_auto_rebuild = 0;
- pArray->u.array.rf_abort_rebuild = 0;
- hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
+ pSubArray->u.array.rf_auto_rebuild = 0;
+ pSubArray->u.array.rf_abort_rebuild = 0;
+ hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pSubArray, DUPLICATE);
unlock_driver(oldspl);
break;
}
@@ -225,7 +231,7 @@ loop:
}
else
#endif
-#endif /* SUPPORT_ARRAY */
+#endif
if (0) {} /* just to compile */
#if DBGUG
else if (length>=9 && strncmp(buffer, "dbglevel ", 9)==0) {
@@ -239,7 +245,7 @@ loop:
else if (length>=8 && strncmp(buffer, "disable ", 8)==0) {
/* TO DO */
}
-#endif
+#endif
return -EINVAL;
}
@@ -248,7 +254,8 @@ loop:
* Since we have only one sysctl node, add adapter ID in the command
* line string: e.g. "hpt 0 rebuild start"
*/
-static int hpt_set_info(int length)
+static int
+hpt_set_info(int length)
{
int retval;
@@ -256,7 +263,7 @@ static int hpt_set_info(int length)
PUCHAR ke_area;
int err;
DWORD dwRet;
- PHPT_IOCTL_PARAM32 piop;
+ PHPT_IOCTL_PARAM piop;
#endif
char *buffer = hptproc_buffer;
if (length >= 6) {
@@ -270,14 +277,14 @@ static int hpt_set_info(int length)
return -EINVAL;
}
#ifdef SUPPORT_IOCTL
- piop = (PHPT_IOCTL_PARAM32)buffer;
+ piop = (PHPT_IOCTL_PARAM)buffer;
if (piop->Magic == HPT_IOCTL_MAGIC) {
- KdPrintE(("ioctl=%d in=%x len=%d out=%x len=%ld\n",
+ KdPrintE(("ioctl=%d in=%p len=%d out=%p len=%d\n",
piop->dwIoControlCode,
piop->lpInBuffer,
piop->nInBufferSize,
piop->lpOutBuffer,
- (u_long)piop->nOutBufferSize));
+ piop->nOutBufferSize));
/*
* map buffer to kernel.
@@ -293,28 +300,22 @@ static int hpt_set_info(int length)
return -EINVAL;
}
- err = 0;
if (piop->nInBufferSize)
- err = copyin((void*)(ULONG_PTR)piop->lpInBuffer, ke_area, piop->nInBufferSize);
+ copyin((void*)(ULONG_PTR)piop->lpInBuffer, ke_area, piop->nInBufferSize);
/*
* call kernel handler.
*/
- if (err==0)
- err = Kernel_DeviceIoControl(&gIal_Adapter->VBus,
- piop->dwIoControlCode, ke_area, piop->nInBufferSize,
- ke_area + piop->nInBufferSize, piop->nOutBufferSize, &dwRet);
+ err = Kernel_DeviceIoControl(&gIal_Adapter->VBus,
+ piop->dwIoControlCode, ke_area, piop->nInBufferSize,
+ ke_area + piop->nInBufferSize, piop->nOutBufferSize, &dwRet);
if (err==0) {
- if (piop->nOutBufferSize) {
- err = copyout(ke_area + piop->nInBufferSize, (void*)(ULONG_PTR)piop->lpOutBuffer, piop->nOutBufferSize);
- if (err) KdPrintW(("Kernel_ioctl(): copyout (1) return %d\n", err));
- }
+ if (piop->nOutBufferSize)
+ copyout(ke_area + piop->nInBufferSize, (void*)(ULONG_PTR)piop->lpOutBuffer, piop->nOutBufferSize);
- if (piop->lpBytesReturned) {
- err = copyout(&dwRet, (void*)(ULONG_PTR)piop->lpBytesReturned, sizeof(DWORD));
- if (err) KdPrintW(("Kernel_ioctl(): copyout (2) return %d\n", err));
- }
+ if (piop->lpBytesReturned)
+ copyout(&dwRet, (void*)(ULONG_PTR)piop->lpBytesReturned, sizeof(DWORD));
free(ke_area, M_DEVBUF);
return length;
@@ -335,7 +336,8 @@ static int hpt_set_info(int length)
#define shortswap(w) ((WORD)((w)>>8 | ((w) & 0xFF)<<8))
-static void get_disk_name(char *name, PDevice pDev)
+static void
+get_disk_name(char *name, PDevice pDev)
{
int i;
MV_SATA_CHANNEL *pMvSataChannel = pDev->mv;
@@ -346,7 +348,8 @@ static void get_disk_name(char *name, PDevice pDev)
name[20] = '\0';
}
-static int hpt_copy_info(HPT_GET_INFO *pinfo, char *fmt, ...)
+static int
+hpt_copy_info(HPT_GET_INFO *pinfo, char *fmt, ...)
{
int printfretval;
va_list ap;
@@ -364,28 +367,38 @@ static int hpt_copy_info(HPT_GET_INFO *pinfo, char *fmt, ...)
}
}
-static void hpt_copy_disk_info(HPT_GET_INFO *pinfo, PVDevice pVDev, UINT iChan)
+static void
+hpt_copy_disk_info(HPT_GET_INFO *pinfo, PVDevice pVDev, UINT iChan)
{
- char name[32], arrayname[16];
-
+ char name[32], arrayname[16], *status;
+
get_disk_name(name, &pVDev->u.disk);
+
+ if (!pVDev->u.disk.df_on_line)
+ status = "Disabled";
+ else if (pVDev->VDeviceType==VD_SPARE)
+ status = "Spare ";
+ else
+ status = "Normal ";
-#ifdef SUPPORT_ARRAY
- if(pVDev->pParent)
+#ifdef SUPPORT_ARRAY
+ if(pVDev->pParent) {
memcpy(arrayname, pVDev->pParent->u.array.ArrayName, MAX_ARRAY_NAME);
+ if (pVDev->pParent->u.array.CriticalMembers & (1<<pVDev->bSerialNumber))
+ status = "Degraded";
+ }
else
#endif
- arrayname[0]=0;
+ arrayname[0]=0;
hpt_copy_info(pinfo, "Channel %d %s %5dMB %s %s\n",
iChan+1,
- name, pVDev->VDeviceCapacity>>11,
- ((!pVDev->u.disk.df_on_line)? "Disabled" :
- ((pVDev->VDeviceType != VD_SPARE)?"Normal ":"Spare ")), arrayname);
+ name, pVDev->VDeviceCapacity>>11, status, arrayname);
}
#ifdef SUPPORT_ARRAY
-static void hpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray)
+static void
+hpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray)
{
int i;
char *sType=0, *sStatus=0;
@@ -438,7 +451,7 @@ static void hpt_copy_array_info(HPT_GET_INFO *pinfo, int nld, PVDevice pArray)
if (pTmpArray->u.array.rf_rebuilding) {
#ifdef DEBUG
sprintf(buf, "Rebuilding %dMB", (pTmpArray->u.array.RebuildSectors>>11));
-#else
+#else
sprintf(buf, "Rebuilding %d%%", (pTmpArray->u.array.RebuildSectors>>11)*100/((pTmpArray->VDeviceCapacity/(pTmpArray->u.array.bArnMember-1))>>11));
#endif
sStatus = buf;
@@ -463,7 +476,8 @@ out:
}
#endif
-static int hpt_get_info(IAL_ADAPTER_T *pAdapter, HPT_GET_INFO *pinfo)
+static int
+hpt_get_info(IAL_ADAPTER_T *pAdapter, HPT_GET_INFO *pinfo)
{
PVBus _vbus_p = &pAdapter->VBus;
struct cam_periph *periph = NULL;
@@ -535,7 +549,8 @@ static int hpt_get_info(IAL_ADAPTER_T *pAdapter, HPT_GET_INFO *pinfo)
return 0;
}
-static inline int hpt_proc_in(FORMAL_HANDLER_ARGS, int *len)
+static __inline int
+hpt_proc_in(FORMAL_HANDLER_ARGS, int *len)
{
int i, error=0;
@@ -552,7 +567,8 @@ static inline int hpt_proc_in(FORMAL_HANDLER_ARGS, int *len)
return (error);
}
-static int hpt_status(FORMAL_HANDLER_ARGS)
+static int
+hpt_status(FORMAL_HANDLER_ARGS)
{
int length, error=0, retval=0;
IAL_ADAPTER_T *pAdapter;
@@ -598,7 +614,7 @@ out:
SYSCTL_NODE(, OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node") \
SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \
NULL, 0, hpt_status, "A", "Get/Set " #name " state")
-#else
+#else
#define hptregister_node(name) \
SYSCTL_NODE(, OID_AUTO, name, CTLFLAG_RW, 0, "Get/Set " #name " state root node"); \
SYSCTL_OID(_ ## name, OID_AUTO, status, CTLTYPE_STRING|CTLFLAG_RW, \
diff --git a/sys/dev/hptmv/i386-elf.raid.o.uu b/sys/dev/hptmv/i386-elf.raid.o.uu
index f8d041348847..a7462b8f1ef2 100644
--- a/sys/dev/hptmv/i386-elf.raid.o.uu
+++ b/sys/dev/hptmv/i386-elf.raid.o.uu
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -25,1322 +25,1359 @@
*
* $FreeBSD$
*/
-begin 664 hptmvraid.o
-M?T5,1@$!`0D```````````$``P`!``````````````#0N````````#0`````
-M`"@`#``)`%6)Y5=64X'L%`(``(M]"(M'#(F%\/W__X!_`0"-=\0/A5<%``"`
-M?P(`#X1%!0``L0&`3@$$B`Z+1PR)1@@/ML&+5Q"+!(4`````@/D#QT8$````
-M`(E6#(E&-'0<#[8&BP2%`````(!.`02)1CB-9?1;7E_)PXUV`(U"]HV5]/W_
-M_XE&#%)J((M'$(/H"E!7Z/S___^#Q!"!O?3]___S%GA:=;EHD````(V%]/W_
-M_U#H_/___X3`6EEUHHJ%_?W__X/@`H3`=!;&1P@!BH7^_?__.D<)B$<+#X*#
-M!```:``"``"-E?3]__]2Z/S___^$P%I9#X5(!```BI6'_O__BD<$B-.#XP&#
-MX/R(T8/A`@G8"<B(TX/C!(/@\XC1@^$("=@)R(C3@^,0@^#/B-&#X2`)V`G(
-M@^`_B-&#XD`)T(/A@`G(B$<$BI7]_?__BD8!@^(!@^#^"="(1@&*A03^__\\
-M`P^$]/[__X3`=1#&!@"A`````(E&..GQ_O__B[WX_?__A?^)O>3]__\/A,S^
-M__\QT@^VG?_]__\YVGTMC8WT_?__@\$0B@$\"`^'K/[__P^VP(L$A0````"%
-MP`^$FO[__T*#P1`YVGS<BX4,_O__B87H_?__BX7P_?__,=(%8"(``(G#BT`$
-MA<!U#XN%Y/W__SE#0`^$'`$``$*#^@^-@]0```!^W(N5\/W__XN:7"(``(7;
-M="B+0PB)@EPB``!HU````&H`4^C\____BX7P_?__B4,(@\0,B[WX_?__BE-&
-M@\H!B%-&B7M`BH4(_O__@^`!T>"#XOT)PHA31F:+A0K^__]FB4-(BY7H_?__
-MB5-,BI4$_O__B!.*C0?^__^X`0```-/@B$L^9HE#1(N%`/[__\=#!`````")
-M0PR*A07^__^(0SP/MM*+!)4`````B4,TC87T_?__:A"#P"Q0C4-P4.C\____
-MC87T_?__:@2#P#Q0C8.`````4.C\____C87T_?__:A"#Z(!0C8/$````4.C\
-M____@\0DC87T_?__:D"#P$!0C8.$````4.C\____@\0,BX7H_?__.4-,=@.)
-M0TR*0P&*E?W]__\)PH/B`8/@_@G0B$,!BI4&_O__@+W__?__`8B5[_W__P^&
-MMP$```^VPHF%X/W__XM\@U"+E1S^__^%_XF5Z/W__W1@BD<!BI7]_?__"<*#
-MX@&#X/X)T(A'`0^VA1;^__^+3(=0A<D/A=/\__^)=(=0BH46_O__B$8#_D<]
-M#[8'BP2%`````(E&.(N%Z/W__SE'3(E^!`^&I/S__XE'3.F<_/__BX7P_?__
-MB[A<(@``A?]T*(M'"(N5\/W__XF"7"(``&C4````:@!7Z/S___^+A?#]__^)
-M1PB#Q`R*5T:+A?C]__^#R@&(5T:)1T"*A1C^__^#X`'1X(/B_0G"B%=&9HN%
-M&O[__V:)1TB+E>C]__^)5TR*A17^__^(1SR*E13^__^(%XN%$/[__XE'#(E?
-M!(J-%_[__[@!````T^"(3SYFB4=$#[;2BP25`````(E'-`^V`XL$A0````")
-M1SB*A>_]__^(1P.+E>#]__^-A?3]__^)?)-0_D,]@\`L:A!0C4=P4.C\____
-MC87T_?__:@2#P#Q0C8>`````4.C\____C87T_?__:A"#Z(!0C8?$````4.C\
-M____@\0DC87T_?__:D"#P$!0C8>$````4.C\____@\0,Z6;^__\/MH7O_?__
-MBU2#4(72#X5/^___B72#4/Y#/8J5[_W__XA6`P^V`XE>!(L$A0````#I-/S_
-M_VAP`0``C87T_?__:@`%D````%#H_/___X/$#.F8^___#[;`4%?H_/___UM8
-MZ6S[__^-=@"Q`^FV^O__D+$"Z:[Z__^058GE5E.+=0PQVP^V1CPYPWT/B?:+
-M5)Y0A=)T#$,YPWSSC67X6U[)PXC9N`$```#3X&8)1DA6_W4(Z/S___^)PH72
-M6%ETV\8"`X`^"`^4P(I*`<'@`X/A]PG!B$H!B%H#H0P```")0C0/M@:+!(4`
-M````B7($B4(XBD8!@^`0A,!T#(/)$(M"3(A*`8E"#(E4GE"*1D:#X/Z#R`J(
-M1D;'1DP`````_D8]4FH'Z/S___^`3D8$6U[I9O___Y!5B>575E-7BT4(B47P
-MBUT,#[8#@_@&#X0X`0``@_@&#X^+````@_@$?`J*4SPX4SUT-8GVBTL$A<EU
-M"HI#1H/@!(3`=0N-9?1;7E_)PXUV`.C\____B4-`B5T(C67T6UY?R>G\____
-M@$L!!(!C1OXQ_X32=+^-=@"+=+M0A?9T!8`^`W<*1P^VPCG'?.OKI5;_=?#H
-M_/___XI&1H/@!%F$P%YT!(!+1@2*4SSKV(UV`(/X"`^%>____XI#/8I3/#C0
-M='(/ML!`#[;2.=!T#@^W0T3WV"%#3.E8____9HM#2&:%P'1"#[?0,<GWP@$`
-M``!U"D&)T-/X@^`!=/:+1(M0A<!T"<=#3`````#KP8I31H/*!(!+`02(4T93
-M_W7PZ/S___]>7^O=BE-&B-"#X`*$P'71Z]N*0T:#X/Z`2P$$9H-[2`"(0T9T
-MA8/(`HA#1NEZ____@$L!!(![/0)T/HM#4(!C1OV%P'41BT-4QD`#`(E#4,=#
-M5`````"`.`-T$(!+1@3'0TP`````Z:7^__]3_W7PZ/S___]86NOC@&-&_NF/
-M_O__C78`58GE5U:+?0A3O@\```"-GV`B``"+0T"%P'0'BT,$A<!T$H'#U```
-M`$YYZ8UE]%M>7\G#D%-7Z/S___^*0P&#X`1:A,!9=-O'0S@`````Z])5B>57
-M5E.![`0"``"+=0R*11!6B(7S_?__Z/S___^`/@A9#X3I````BD8\,?\\`'9_
-MC78`BUR^4(7;=&V`.P,/A[,```"*4P&#XO[&0P,`QT-0`````(A3`8"]\_W_
-M_P#'0P0`````QT,X`````'4%@#X&=&QH``(``&H`C97T_?__4NC\____C87T
-M_?__4&HP:@"-0SQ0Z/S___^#Q!Q3Z/S___]8BD8\1XGZ.-!WA&C4````:@!6
-MZ/S___^+50B+@EPB``")1@B)LEPB``"#Q`S'1D``````C67T6UY?R<.+1@2%
-MP'6-BD8!@^`!"<*(4P'KJHUV``^VA?/]__]0_W2^4/]U".C\____@\0,ZY56
-M_W4(Z/S___]86ND'____C78`58GE5U93@>P,`@``BU4,BP*+6`2)G?#]__^+
-M6B"+4Q2)E>S]__^+M>S]__\/MD`#A?:+?1"+312)A>C]__^-E?3]__\/A+,`
-M``!F#[9#$(/@`0^WP#G(#X2@````#[=3+,'B"0^V6RB+C>S]__]FBT$$9H7`
-MBS$/M\AU"+D```$`C78`.<J)T'8"B<@[G>C]__]T6"G!`<8IPG4=BY7P_?__
-M#[9"/$,YPP^4P`^VP$@/MU)$(</!X@F%R77'BXWL_?__9H%Y!@"`=`N#P0B)
-MC>S]___KDF;'1_X`@+@!````C67T6UY?R<.-=@!FB4<$9L='!@``B3>#QPCK
-MEXM#&(7`B97L_?__=00QP.O345)3_W4(_]"#Q!"%P`^%//___^OGD%6)Y5=6
-M4X/L"(M%"(M0!(E5\(M=#(I0`XI+*#C*BWLD9HMS,'1B.,IS"8M%\`^W0$0!
-MQSC*=$F*0RDXPG0Z@'LT`'0D.,IV"SC"<P>+1?!F`W!$BU409HER"(EZ!(/$
-M"%M>7\G#C78`.,IVW(M-\&8#<43KTXUV`&8#<RKKP(GV9@-S+.NQB?8/MT,N
-MZZ.)]E6)Y5=64X/L"(M]#(M%"&:+=PAFQT7R```/MD@^BU\$QD<T`=/K9L='
-M,```#[9(/#'2B=CW\8M5"`^V2C[3X(E')`^V2CR)V#'2]_&(5RB(T8M5"&:+
-M0D1(9B-'!&:)1RZ+70AFBU-$9BG"9CGR<B1FB7<L,?:X`0```-/@9@E',HA/
-M*6:)=RH/MT7R@\0(6UY?R<-FB5<L9BG69L=%\@$`N@$```")]HG0T^!F"4<R
-M08M%"#I(/'03BUT(9HM#1&8YQG:Q9BG&Z]Z)]C')@'\T`'0(QD<T`.O?B?:+
-M70AFBT-$9@%',.O0C78`58GE5E.+50R+`@^V2`.X_O___]/`BUH@BW4(9B%#
-M,HI"$3P!=`.(0Q%25NC\____6&:#>S(`6G47@'L1`'4$QD,1`5/_<QQ6Z/S_
-M__^#Q`R-9?A;7LG#D%6)Y5=64X/L"(M]#(L'B47PBD`!@^`$A,`/A+D```!7
-M_W7PZ)3^__]FBT<R66:%P%L/A*$```"+3?"*43PQ]H32=!V0#[?`B?'3^(/@
-M`7481@^VPCG&?0AFBT<RZ^:)]HUE]%M>7\G#_W4(Z/S___^)PXM%\(M$L%")
-M1>R)`XE[((I7$(I#$(/B`H/@_0G0B$,0BE<0@^($@^#["="(0Q"*1PJ(0PI3
-M5_]U[.A\_?__QT,<`````,=#&`````!3_W4(BU7L_U(TBTWP@\08BE$\Z7K_
-M__^)]L9'$0)7_W<<_W4(Z/S____I<____XUV`%6)Y8M5#(M*!(I!`<#H`H!B
-M`?OWT(M1.(/@`8!A`?O^23V`248!A=)T!(7`=`+)PU'_=0C_TEA:Z_2)]E6)
-MY593BT4,BU`@BTH4A<F+71"+=11T/&8/MD(0@^`!#[?`.?!T+9"+`8M1!(E3
-M!(D#9HM!!B4`@/__@\,(@\$(9H7`=.*Z`0```(UE^%N)T%[)PXM"&(7`=00Q
-MTNOL5E-2_W4(_]"#Q!"%P+H!````==CKYHUV`%6)Y593BW4(#[8&@^@$@_@!
-M=S4QVX!^/`!T'(M$GE"%P'0@4.C7____A<!9=!5##[9&/#G#?.2X`0```(UE
-M^%M>R<,QP.OUD(I&`<#H`H/@`0^VP.OFB?95B>575E.#[`B+?0R+7R"+`XLW
-MB47PB77LBD\1@/D!=$^*4Q"(T(/@`H3`#X3/````@'L2`'4YBU7PBD)&@^`"
-MA,!U+,9#$@$QP(!^`P`/E,"+=()0A?9T$U;H2?___X7`6G5UBP>)1>R*3Q&+
-M=>R0B$L15_]U".C\____#[9.`[C^____T\!F(T,R9HE#,E]FA<!:=3N`>Q$`
-M=03&0Q$!4_]S'/]U".C\____BU7P9HM"%DB#Q`QFA<!FB4(6=1&+0AR%P'0*
-M_W(@_W4(_]!;7HUE]%M>7\G#:C"-1R1J`%#H_/___P^V3@.X`0```-/@9HE#
-M,HDW5_]U"/]6-.O1@^($A-(/A&7___]6Z)?^__^%P%EU*8![$0$/A%/___\/
-MMDX#N`$````/MU,RT^`YP@^%//___XI/$>DQ____:C!J`(U')%#H_/___^NI
-MB?95B>56BW444XM5#(7VBUT0BTH@=".+00R)`V:+0@C!X`EFB4,$9L=#!@"`
-MN`$```"-9?A;7LG#D(M1%(72="V*01"#X`&$P'0CB=&0BP&+402)4P2)`V:+
-M008E`(#__X/#"(/!"&:%P'3BZ[^+01B%P'4$,<#KN5934?]U"/_0ZZ^-=@!5
-MB>575E.+=0R+!@^V2`.X_O___]/`BUX@BWT(9B%#,HI&$3P!=`.(0Q%65^C\
-M____66:#>S(`6'4X@'L1`'4.QD,1`8L+BU%,.U8$="Q3_W,<5^C\____BP-F
-MQT`4``"#P!A0:`````!7Z/S___^#Q!B-9?1;7E_)PP^W1@B-!!")04SKR(GV
-M58GE5U93BW4,BD81/`&+?0B+7B!T-HA#$597Z/S___]3_W,<5^C\____BP-F
-MQT`4``"#P!A0:`````!7Z/S___^-9?1;7E_)PXUV`(!^"B!T&L9#$0&+"XM1
-M3#M6!'6Y#[=&"(T$$(E!3.NMBP/&1A$`BT!4B09J,&H`C48D4.C\____BD80
-M@^#]@\@$B$80QD82`,9&"C"+!E97_U`TZZ"-=@!5B>575HM5%%.+10R%THM]
-M$(M(('1"BTD,B0]FBU`(P>()9HE7!&;'1P8`@(L`@'@#`'0-9H72=!</M\*-
-M!`B)![H!````C67T6UZ)T%_)PXV!```!`.OGBT4,#[=P"(M1%,'F"872B?L/
-MA*T```"*01"#X`&$P`^$GP```(G1D(L!BU$$B5,$B0-FBT$&)0"`__^#PPB#
-MP0AFA<!TXHM%#(GYBQB-=@!FBT$$9H7`#[?0=06Z```!`(![`P!T33GR=SR#
-MP0@IUG7>@'L#``^$;?___SG/#X1E____BP&+402)5P2)!V:+008E`(#__X/'
-M"(/!"&:%P'3BZ4+___^)T&8I\`$Q9HE!!.N^.?)RLV:)<01FQT$&`(#KKHM!
-M&(7`=0<QTND<_____W445U'_=0C_T(/$$#'2A<`/A`7____I6/___XGV58GE
-M5U93BW4,BD81/`&+?0B+7B!T-HA#$597Z/S___]3_W,<5^C\____BP-FQT`4
-M``"#P!A0:`````!7Z/S___^-9?1;7E_)PXUV`(L&@'@#`'4HBP/&1A$`BT!4
-MB09J,&H`C48D4.C\____QD82`(L&5E?_4#3KR(UV``^W1@C!X`E0`T,,4/]S
-M#.C\____@\0,A<!T"<9#$0SI>?___\9#$0&+"XM13#M6!`^%9____P^W1@B-
-M!!")04SI6/___XUV`%6)Y5=64XM=#(LSBD9&@^`!A,#'1AP`````=14/MD,*
-M@_@"#X3_````@_@"?WY(="S&0Q$&4_]S'/]U".C\____@\0,C4884&@`````
-M_W4(Z/S___^-9?1;7E_)PXM#!(E&$&:+0PAFB484_W4(Z/S____&0`H@B<*+
-M0P2)0@1FBT,(@$H0`F:)0@B)6B#'0AP`````QT(8`````(M&4(D"4O]U"/]0
-M-.N7B?:#^`-U@(M#!(E&$&:+0PAFB484#[=#",'@"5!J`/]S#.C\____,?]F
-MQT,R`P"#Q`S_=0CH_/___\9`"C")PHM#!(E"!&:+0PAFB4((@$H0!(E:(,="
-M'`````#'0A@`````BT2^4(D"4O]U"$?_4#2#Q`R#_P%^N>D<____BT,$B480
-M9HM#"&:)1A3_=0CH_/___\9`"B")PHM#!(E"!&:+0PAFB4((@$H0`HE:(,="
-M'`````#'0A@`````Z3#___]5B>575E.#[!"+10B+?0R)1?"+-XI&`8/@!(3`
-M#X32`0``BD<0@^`@A,!T-&:#?A8`QT8<7!,``(E^('0+C67T6UY?R<.-=@"+
-M5?")?0R)50B-9?1;7E_)Z3?^__^-=@"+1AR%P`^%;0$``&:+1A1FA<!T(`^W
-MP(M.$(T$"(M7!#G0=A`/MT<(C000.<$/@D4!``"0BD9&@^`#9O]&%H3`#X4F
-M`0``BD<0@^`"A,`/A!@!``"+5E"`.@.+3E0/A*$```"`?DH`#Y1%[HI5[HA6
-M2F;'1S(``,9%[P#'1>0`````BTWDBT2.4(7`=!^*0`&#X`2$P'05BD<0@^`$
-MA,!U'(I%[SA%[G04C78`_D7O_T7D@'WO`7;*Z2#_____=?#H_/___VHD5U")
-MP^C\____BDWDN`$```#3X&8)1S*)>R#'0QP`````QT,8`````(M5Y(M$EE")
-M`U/_=?#_4#2#Q!CKJ(`Y`P^%5O___XM?!(M"6"M95(E%Z(M'!"M"5(M)6'A!
-MA=MX.3G8?1^%R<9%[@`/A3G___^#?>@%#X8O____QD7N`>DF____BUWHA=O&
-M1>X`=>R#^04/AQ+____KX??;Z\/WV.N[C78`QD7N`.G\_O__C78`C488QT<H
-M`````(E]#(E%"(UE]%M>7\GI_/___\9'$0)7_W<<_W7PZ/S____I-/[__XUV
-M`%6)Y5=64XMU#(M>!(M]"(!F`?N*0SV*4T9(@\H!A,`/MDX#QT-,`````(A3
-M1HA#/703B-"#X`*$P'0.@^+5A<F(4T9U!(!C`?N*0P&#X`2$P'4[BT,XA<!U
-M+(M3!(72=`Z-=@"+0@2%P(G3B<)U]>C\____B4-`B5T(C67T6UY?R>G\____
-M4U?_T%A:Z\R%R744BU-0BT-4QD(#`8E#4,9``P")4U2+4P2%TG0*BD(!@^`$
-MA,!TIHM#4(`X`W6>4U?H_/___X7`68G"7W2,Q@`#QD`#`8E8!*$,````B4(T
-MH1@```")0CB*0P&#X!"$P'0*BT),@$H!$(E"#,=&!`````"*0T:#X/Z#R`J)
-M4U2(0T;^0SU2:@?H_/___^EH____B?95B>575E.![!`"``"+10R+$(M`((MP
-M%(7VB97P_?__BTT4B87D_?__QX7L_?__$0```(V5]/W__P^$5@$``&8/MD`0
-M@^`!#[?`.<@/A$,!``"+O>3]__^`?RG_#X2E````9HM&!`^W7RS!XPEFA<`/
-MM\AU!;D```$`.<L/AO,```"+A?#]__^*0`.(A>O]__^+O>3]__^*5RB-=@`X
-ME>O]__\/A)P```"#Q@AFBT8$*<MFA<`/M\AU!;D```$`_XWL_?__.<MWU#B5
-MZ_W__W1>.<MS*8L&`=B+?1")!XG(9BG89H%^!@"`9HE'!'0XBT409L=`!@``
-M@\`(B440@\8(_XWL_?__BX7L_?__P>`#4%;_=1#H_/___[@!````C67T6UY?
-MR<-FQT<&`(#KZXM5$(L&B0)FB5H$9L="!@"`Z]B-=@"+?1"+!HM6!(E7!(D'
-MBX7P_?__@\<(BD`#B7T0B(7K_?__B[WD_?__BE<HZ33___^+A?#]__^*0`.(
-MA>O]__^+O>3]__^*5RCI-____XUV`(N=Y/W__XM#&(7`B=9U!S'`Z73___]1
-M4E/_=0C_T(/$$(7`#X64_O__Z^2058GEBTT,4XI1*(M%"#A0`XM=$'079HM!
-M*F:)0PC'0P0`````BQPDR<.-=@!FBT$L9HE#"(M!)(E#!.OH58GE5U93@^P,
-MBWT,9HM'"(M?!(MU"&:)1?**1CPQR83`B$7KQT7L`````'09C78`BU2.4(M"
-M##G#<A8IPT$/MD7K.<%RZHM%[(/$#%M>7\G#N`$```#3X&:+=S()QHE?)(A/
-M*&:)=S(/MT7RC008.T(,=C*-00''1>P!````B$<IBT7L0=/@"<9FB7<R9HM"
-M#&8IV&:)1RQF*47R9HM%\F:)1RKKH,9'*?]FBT7R9HE'+.N258GE5E.+50R+
-M`@^V2`.X_O___]/`BUH@BW4(9B%#,HI"$3P!=`.(0Q%25NC\____6&:#>S(`
-M6G47@'L1`'4$QD,1`5/_<QQ6Z/S___^#Q`R-9?A;7LG#D%6)Y5=64X/L"(M]
-M#(L'B47PBD`!@^`$A,`/A+D```!7_W7PZ,S^__]FBT<R66:%P%L/A*$```"+
-M3?"*43PQ]H32=!V0#[?`B?'3^(/@`7481@^VPCG&?0AFBT<RZ^:)]HUE]%M>
-M7\G#_W4(Z/S___^)PXM%\(M$L%")1>R)`XE[((I7$(I#$(/B`H/@_0G0B$,0
-MBE<0@^($@^#["="(0Q"*1PJ(0PI35_]U[.@(_O__QT,<`````,=#&`````!3
-M_W4(BU7L_U(TBTWP@\08BE$\Z7K___^)]L9'$0)7_W<<_W4(Z/S____I<___
-M_XUV`%6)Y8M%#(!@`?N+4`2+0CB`8@'[_DH]@$I&`87`=07)PXUV`%+_=0C_
-MT%A:Z_&)]E6)Y8M-#%.+70B+E(N\+P``A=)T"8L"B82+O"\``(G0BQPDR<.-
-M=@!5B>6+51!3BUT(BX23O"\``(M-#(D!B8R3O"\``(L<),G#B?95B>575E.#
-M[`B+10P]``@``(M5$+X`$```=T0]``0``+X`"```=S@]``(``+X`!```=RP]
-M``$``+X``@``=R`]@````+X``0``=Q2#^$`/A]P```"#^"$9]H/FX(/&0`^O
-MUH'"_P\``(E5\,%M\`S_3?"#??#_QT7L``````^$FP```)#_=0CH_/___XG#
-M,=*X`!```#'_]_;_1>PYQUES<(UV`('^``@``+@'````=T.!_@`$``"X!@``
-M`'<V@?X``@``N`4```!W*8'^``$``+@$````=QR!_H````"X`P```'</@_Y`
-M=S\QP(/^(`^7P(GV4%/_=0CHWO[__S'2N``0``!']_8!\X/$##G'<I/_3?"#
-M??#_#X5F____BT7LC67T6UY?R<.X`@```.O$OH````#I)?___XGV58GE5E.+
-M=0B+70PYGN`O``!S"3'`C67X6U[)PVH"5NA4_O__B<&%R5A:="Z)&4N#^_]T
-M)HN&W"\``#'2A<!T$(G"BP")AMPO``#_CN`O``")5)D$2X/[_W7:B<CKMXGV
-M58GE5U93BWT,BP])@_G_BW4(=">+GN`O``")]HM4CP1)BX;<+P``0X/Y_XD"
-MB9;<+P``=>>)GN`O``!J`E=6Z/S]__^-9?1;7E_)PU6)Y593BW4(BQY+@_O_
-M=!EH`!```&H`_W2>!$OH_/___X/$#(/[_W7GC67X6U[)PU6)Y5.+70B+"TF#
-M^?]T((M$BP0QTHUV`(,X`'4:0H/`!('Z_P,``';O28/Y_W7@N`$```!;R<,Q
-MP.OYD%6)Y6H0:@#_=0CH_/___\G#C78`58GEBTT,BU$,A=)T!HM!"(E""(M!
-M"(D0QT$(`````&H`4?]U".A*_?__R<-5B>564XM="(M#,(M-#(7`C7,PB4$,
-M=`F+4S"-00R)0@B)<0B)2S!;7LG#D%6)Y5=64XM%#(M8,(7;BWT0BW44=!*)
-M]CDS<P4Y>P1W*XM;#(7;=?!J`/]U".C"_/__B3B)<`10B</_=0SHDO___XG8
-MC67T6UY?R<,QP.OT58GE4XM="(I+*0^VT8T4THT4DXU"+$&(2RF)6BS&0`4`
-MQD`&`,=`'`````#'0"``````BQPDR<-5B>575E.+=0P/ME8FC4+]T?@QVP'"
-M.=.+?0A\$VH'5E?H;OS__XUE]%M>7\G#B?;_M)Z<"```5^@7_O__6%H/ME8F
-MC4+]T?A#`<(YTWSAZ\R-=@!5B>575E.#[!2*10R+512(1?-FB57PBT4(BY#@
-M+P``#[9-\P^W1?")1>2-0?W1^(T$",'B`P^O1>0YP@^#@P```(M5"('"I"\`
-M`(E5X(G/D(M%"(N8I"\``#M=X`^$+`$``(L#BU,$B5`$B0*+0Q")WH7`B1Z)
-M7@1T%HM3%(72=`.)0A"+1A")$,=&$`````"+5?!F.5,D#X3W````4_]U".@&
-M____6(M%"%J+D.`O``"-1_W1^(T$.,'B`P^O1>0YPG*,:@?_=0CH2OO__XG&
-M7U@QP(7V#X2"````BU40B58@BE7SBT7PB%8F#[95\V:)1B2-0OW1^#'_C000
-M.<>)-HEV!,=&&`````!]3V;!;?`##[=5\(E5Z(E%[/]UZ/]U".AY_/__B82^
-MG`@``%F%P%MT,HG[P>,$C1PSC8/$"```4('#1`D``.AJ_?__1U/H8_W__UD[
-M?>Q;?,")\(UE]%M>7\G#3X/__W07_[2^G`@``/]U"$_HA/S__UB#__]:=>EJ
-M!U;_=0CHLOK__S'`Z\R)]HI%\SA#)@^%_?[__P^VP(M5$(7`B1N)6P2)4R!T
-M%8VS1`D``(G'5NCX_/__@\803UEU\XG8ZY.058GE5U93@^P(BT449HE%\HM5
-M#(M]$`^V2CZ)^-/H)?\#``"+4BR-'(*+,X7V=`V0.7X@=&N+=A2%]G7T#[=%
-M\E!7BU4,#[9"/%#_=0CHXOW__X/$$(7`B<9T.XM-#(E('(L#A<")1A1T"(L3
-MC484B4(0BT4,B3.)7A"*6#R(7B8/MD@^T^\QT@^V2#R)^/?Q*--+B%XGC67T
-M6XGP7E_)PXM6!(L&B5`$B0*)=@2)-NOEC78`58GE5U93@>RT````BT4,BE`0
-MB-#0Z(G!]]&#X0&)C6#___^+30R+012%P'0+@^(!A-(/A%0"``!J`8V%9/__
-M_U#_=0S_=0B)A5S___^+50S_4AB#Q!"+C5S___]FBT$$#[?09H7`B95$____
-M=0K'A43___\```$`QX5,____`````(M-#(I11(32QX58____``````^$C0$`
-M`(M-#(N%6/___XM$@3")A5#___^*B!P*``"(C5?___^*@!T*```XA5?___\/
-MAT<!``"*E5?___^+C5#___\Z42</A!H!```/ML)FBY2!_`D``&:+A('^"0``
-M9HF%2O___XG09L'H`P^WP(/B!V:)E4C___^)A4#___^X"`````^WTF8KA4C_
-M___!X@EFB85(____9HN%2O___V8YA4C___]V!V:)A4C___^+C5#___\/MH57
-M____BX2!G`@``(N-0/___P^WM4C___^+?(@$P>8)`=>-=@"+A43___\YA4S_
-M__\/A-(```"+G43___\KG4S___\Y\W8"B?.+A6#___^%P`^$F@```%.+A4S_
-M__^+E5S___\#`E!7Z/S___^#Q`P!G4S___\IWG0$`=_KIXN%2/___V8IA4K_
-M__]T%O^%0/___S'29L>%2/___P@`Z3[___^+E5#___^*@AT*``#^A5?___\X
-MA5?___\/AK_^__^+30R*443_A5C___\/ML(YA5C___\/C'/^__]J`/]U#/]U
-M"/]5$(UE]%M>7\G#B?935XN%3/___XN-7/___P,!4.EA____B?:#A5S___\(
-MBY5<____9HM"!`^WR&:%P(F-1/___W4*QX5$____```!`,>%3/___P````#I
-M]O[__XF%7/___^F__?__D%6)Y5=64X/L%(M%"(E%\(M%$(7`BWT,=`3&1Q$+
-MQT7L`````(!_1``/A)\```"+5?"+1?"!PJPO```%I"\``(E5Z(E%Y(UV`(M5
-M[(M,ES"*028QVSC#QX'T"0```````(A%XW-"C78`#[;#P>`$C00(C9#$"```
-MBX#$"```,?:%P'45BT($A<!U#HM""(7`=0>+0@R%P'0%O@$```"%]G5(0SI=
-MXW+!,<"%P'0WBU7HBT($B1&)2@3_1>R)002)"`^V1T0Y1>P/C'O___^+1?")
-M?0R)10B#Q!1;7E_)Z59```")]HM5Y.O'N`$```#KN56)Y5=64X/L&(M=#(M%
-M"/^(Y"\``(E%\(NS]`D``(U#"(M(!(M3"(7VB4H$B1&)0`2)0P@/A)8"``"*
-M5A"(T(/@((3`#X3R````#[=3)(M%\`6D+P``B57D`U,@B57HBU`$B0.)6`2)
-M&HJ#'@H``#P!BS['@_0)````````B5,$=0J`?@H"='<\`708B$81BT7PB74,
-MB44(C67T6UY?R>FD/P``BT8$0`^W5T0/K\(Y1>AR&P-73#M5Z'0+BU7PB74,
-MB54(Z]&+1>B)1TSK[?]UY/]UZ%?_=?#HYOK__XFP]`D``(E&,(M5\(E%#(E5
-M"(/$$(UE]%M>7\GI50X```^V0R?_M(.<"```Z&7W__^%P%IU',:#'@H```P/
-MMT=$@$]&"O?8(T,@.4=,=@.)1TR*@QX*``#I3?___Y"*1D5`BDY$.,B(1D4/
-MA(H```"+5?"+@N@O``"%P'0)@+L>"@```70(C67T6UY?R<.+4QR+2B2%R746
-MA<!TZHM%\(E%"(UE]%M>7\GI_/___U+H(CT``(7`6G0+BU7PBX+H+P``Z]2+
-M0QS_<"B+0QS_<"3_=?#H_/___XM#'(M5\,=`)`````"+@N@O``!(@\0,B8+H
-M+P``ZZ&-=@"#X@2$T@^$F0```,9%[P`X3>]S4HM%\(M5\`6D+P``@<*L+P``
-MB47@B57<D`^V1>^+7(8PBH,>"@``/`''@_0)````````="Z(1A&+5=R+0@3^
-M1>^)6@2)$XE#!(D8BD7O.D9$<L96_W7PZ`$^``!>7^D`____,?^)^#I#)G(%
-MBU7@Z\J)^@^VPL'@!(V$&,0(``!01^@^]O__6(GX.D,F<N+KV\9%[P`X3>]S
-M((UV``^V1>^+7(8PBH,>"@``/`%T`XA&$?Y%[SA-[W+C@'X1`'46:"`E``!6
-M_W7PZ+_Y__^#Q`SIC?[__VH`5O]U\.A$_/__Z^N)]H"['@H```$/A)\```"+
-M1?`%K"\``(M0!(D#B5@$B1J)4P2+D_@)``"%TG55_W,8_W7PZ+WU__^+0QS'
-M0Q@`````BW@86H7_674IBU7PB[+L+P``A?8/A"/^__^)T`7L+P``4&@`````
-M4NC\____Z7;___^#P!A0:`````#_=?#KZ(J#'@H``(A"$?^S^`D``&A89@``
-M_W7PZ/S____'@_@)````````Z>C]__\Q]HGR.E,F<D.+@_@)``"%P'4:BT7P
-M!:0O``"+4`2)`XE8!(D:B5,$Z5/___^)@_0)``#'@_@)````````4_]U\.B2
-M"P``Z8#^__^0B?(/ML+!X`2-A!C$"```4$;HTO3__UB)\#I#)G+BZYU5B>6+
-M10R+`(!X*@!U`LG#QD`J`%!H2#,``/]U".C\____@\0,Z^>058GE5U93@^P(
-MBU4,BT(@BP@/MD`)BX2!G`@``(E%\(M"!"M!(,'@"0^W6@B)PL'H#(M]$,'C
-M"8'B_P\``(E%[+X`$```*=8YWG8"B=Z+112%P'0\BT7LBTWP`U2!!#G>B1=F
-MB7<$=!)FQT<&``#_1>R#QP@I\S'2Z\9FQT<&`("-9?1;7K@!````7\G#C78`
-MBTWPBT7L`U2!!%+H_/___XG"6>NYC78`58GE5U93BUT(BD,+`$,*C7,,B?:*
-M4PH/MLJ#^1\/AZ4```"X`0```-/@A4,,#Y7`#[;`A<!U%#'`@/I_=PB-0@&(
-M0PKKSEM>7\G##[;ZQD,+`8GVBE,+#[;"C0PX@_D?=R:X`0```-/@A4,,#Y7`
-M#[;`A<!T"(U"`8A#"^O6N`$```#KP8UV`(/Y/W</@^D@N`$```#3X(5&!.O0
-M@_E?=P^#Z4"X`0```-/@A48(Z[R#^7]W#X/I8+@!````T^"%1@SKJ#'`ZZJ#
-M^3]W$X/I(+@!````T^"%1@3I3O___Y"#^5]W$X/I0+@!````T^"%1@CI-O__
-M_Y"#^7]W$H/I8+@!````T^"%1@SI'O___S'`Z1W___^)]E6)Y5=64XM5#(MR
-M((I"$8M]"(L>B$8&4E?H_/___UF`?@8!6'06QD8%`HEU#(E]"(UE]%M>7\GI
-MW/W__U;HIO[__X7`6G5"@'X$`779BD8(.D,G=-$Z1@EUS`^VP,'@!(T$&(M6
-M#`F01`D``(U>#(V(1`D``(M#!`E!!(M#"`E!"(M##`E!#.N=QD8&`(EU#(E]
-M"(UE]%M>7\GK*%6)Y593BUT,BW4(QD,+`,9#"@!3Z#/^__]8B5T,B74(C67X
-M6U[)ZP!5B>575E.+70R+,XM6'`^V0PB+?()0_W4(Z/S___^).(![!`&)PEAT
-M.X!*$`3&0@HP#[9#"@-&((E"!&8/MD,+9HE""(E:(,="&"`J``#'0AS@*P``
-M4O]U"/]7-(UE]%M>7\G#@$H0`L9""B#KPXGV58GE5U93@^P(,?\QVXUV`(/[
-M'P^'\P```+@!````B-G3X(M5"(4"#Y7`#[;`A<"^`0```'42@_M_=P-#Z]*#
-MQ`A;7HGX7\G#C10>@_H?=VB(T;@!````T^"+30B%`0^5P`^VP(7`=`-&Z]V)
-M7>R)TXM%[(M-#,'H`X@$N8I%[(/@!XA$N0&Q""C!BT4,B$RX`@^VP3GP<P@I
-MQ@%%[$?KT(GQBT4,B$RX`D>#^G\/AEW____KB8UV`(/Z/W<3C4K@N`$```#3
-MX(M-"(5!!.N/D(/Z7W<5C4K`N`$```#3X(M-"(5!".ET____@_I_=Q6-2J"X
-M`0```-/@BTT(A4$,Z5K___\QP.E9____D(/[/W<7C4O@N`$```#3X(M-"(5!
-M!.D!____B?:#^U]W%XU+P+@!````T^"+50B%0@CIY?[__XGV@_M_=Q6-2Z"X
-M`0```-/@BTT(A4$,Z<G^__\QP.G(_O__C78`58GE5U93@>P8`0``BT4,BU@(
-M@'L5`(LP#X0"`0``BWL0A?]U"XE#$(UE]%M>7\G#C87T_O__QD,5`%!3Z%?^
-M__^)A>#^__\/MD,4BX2&G`@``(F%Z/[__XM#$`^V0`R+A(:<"```B87<_O__
-MBU4,#[9"#(N$AIP(```Q]ED[M>#^__^)A>3^__];?7`/MH2U]/[__P^VG+7U
-M_O__B[W<_O__BU2'!,'C"0':#[:,M?;^__^)E>S^__^+E>3^__^+?(($`=^)
-MO?#^__^+E>C^__\#7(($BX7L_O__P>$).=AT+E'_M?#^__]04^C\____@\00
-M1CNUX/[__WR0:@#_=0S_=0CHYP(``.D:____B?915U#H_/___X/$#.O6C78`
-MC87T_O__4%/H:_W__XF%X/[__P^V0Q2+A(:<"```B87H_O__BWT,#[9'#(N$
-MAIP(```Q]HF%W/[__SNUX/[__UA:?9@/MI2U]/[__P^VG+7U_O__B[WH_O__
-MBT27!,'C"0^VC+7V_O__`=B)A>S^___!X0F+A=S^__\#7)`$45/_M>S^__]&
-MB9WP_O__Z/S___^#Q`P[M>#^__]\I^DZ____B?95B>575E.![!0!``"+10R+
-M&(V%]/[__U"+10R#P`A0Z+#\__^)A>3^__^+50P/MD(8BX2#G`@``(F%Z/[_
-M_P^V0AF+A(.<"```,?:)A>#^__\[M>3^__]86GU5D`^VE+7T_O__#[:$M?7^
-M__^+O>C^__^+7)<$P>`)#[:,M?;^__\!P\'A"8F=[/[__XN]X/[__P-$EP11
-M4%-&B87P_O__Z/S___^#Q`P[M>3^__]\K&H`_W4,_W4(Z&\!``"-9?1;7E_)
-MPXUV`%6)Y5=64X'L5`$``(M%#(M8"(LPC87T_O__4%/HZ_O__XF%I/[__P^V
-M0Q2+A(:<"```B86P_O__BU4,BE(4,<E;.-%?B)6C_O__B--S((GV#[;!BWT,
-M#[94.`Q!BY26G`@``#C9B92%U/[__W+BQX6H_O__`````(N%I/[__SF%J/[_
-M_P^-L0```(GVB[VH_O__#[:<O?7^__^+A:C^__\/MKR]]O[__S')P>,)P><)
-MBH2%]/[__SJ-H_[__XB%K_[__W,C#[;P#[;!BY2%U/[__XM4L@1!`=HZC:/^
-M__^)E(6T_O__<N"+E;#^__\/MH6O_O__BT2"!`'8BY6T_O__.<)T2U?_M;C^
-M__]24.C\____@\00_X6H_O__B[VD_O__.;VH_O__?1&+50R*4A2(E:/^___I
-M4?___VH`_W4,_W4(Z!P```"-9?1;7E_)PU?_M;C^__]2Z/S___^#Q`SKM(GV
-M58GE5U93BW40BUT,A?:+?0BP#,9#!0)U`K`!B$,&4U?H9_?__UB`>P0#6G0+
-MC67T6UY?R<.-=@"+4PB+0A"%P'3KA?;'0A``````QD`%`K(,=0*R`8A0!HE%
-M#(E]"(UE]%M>7\GI(O?__XGV58GE5E-3BT4(C5`LBD`I,=N$P(MU#(A%]W0M
-MD(/['W\_N`$```"(V=/@A48@=`V`>@4"=22*0@8\`7460P^V1?>#PB0YPWS4
-MN`$```!96U[)P\9&!0*(1@8QP.OPC78`C4O@N`$```#3X(5&'.N^D%6)Y5=6
-M4X/L$(M%"(E%\(MU#("^'PH```#&1BH`=':-1BR)1>2*5BDQ_X32BUWD=!2-
-M=@"`>P4!="!'#[;"@\,D.<=\[XM%\(EU#(E%"(UE]%M>7\GI;O+__X![!`-U
-M*8M#"(!X%0!T((M0$(72=!G'0!``````QD,%`HJ&'@H``(A#!HI6*>NQQD8J
-M`8UE]%M>7\G#C48LB47DBE8IB?8Q_X32QT7H`0```(M=Y,=%[`````!T)Y"*
-M0P6$P`^$W0```#P"=#''1>@`````BD8I1XC"#[;`@\,D.<=\VHM%[(7`=;N+
-M?>B%_W2=QH8>"@```>E-____BD,&/`%TSX!^*P`/A(0```"+5AP/MD,(BT2"
-M4(I``8/@!(3`=&;'1>@`````#[9#!(/X!L9#!0'&0P8`=YC_)(4`````4_]U
-M\.CN]___6%KKA,9#!0+&0P8!4_]U\.A5]?__Z^E3_W7PZ,[Y___KWE/_=?#H
-MA_O__^O34_]U\.A$_/__Z\C&1BL!Z\;&0P8!Z4'___^(AAX*``#&AA\*```!
-MZ8;^__^04U;HZ?W__X7`6EET'P^V0P2#^`;&0P4!=Q+_)(4<````4_]U\.AJ
-M]___65B*0P4\`@^%\/[___]%[.GD_O__QD,%`L9#!@%3_W7PZ,#T___KV%/_
-M=?#H.?G__^O-4_]U\.CR^O__Z\)3_W7PZ*_[___KM\9&*P'KQHUV`%6)Y5=6
-M4X'LB`$``(M%#(NP]`D``(7VBU@<QH7-_O__``^$G2T``(M%"(M5"('"M"\`
-M`/^`Y"\``(M%#(/`"(M*!(M]#(E"!(E7"(E(!(D!9HM32&:%T@^$.RT``(I#
-M1H/@`83`=0R+1R`Y0TP/AQDM```/M](Q__?"`0```'4,1XG0B?G3^(/@`73T
-MB?N+10R(6"B+?0R%]L9'*0#&1RL`QH<>"@```,:''PH```#'A_@)````````
-M#X2U````BE80B-"#X""$P`^$+2(```^V1@J#^`(/A$8>``"#^`(/CQ\=``!(
-M=!?_=0S_=0CH\?S__S'2C67T6UZ)T%_)PXM%#(I`)C').,&(A7?^__]S1@^V
-MP<'@!`-%#(V0Q`@``(N`Q`@``#';A<!U%8M"!(7`=0Z+0@B%P'4'BWH,A?]T
-M!;L!````A=L/A:P<``!!.HUW_O__<KHQP(7`#X2)&```BU4,B;+X"0``QX+T
-M"0```````(M=#(I;*(#[!XC8#X=D"P``BU4,BEHG.-@/A'H*``"-A>3^__]0
-MZ+WG__]9_W4,Z'#H__^)A8S^__]:QD`$!HM%#,:%S_[__P"*0"8XA<_^__^(
-MA73^__\/@S`*``"+50R*6B<XG<_^__\/A!0!```/MH7/_O__P>`$`T4,C9#$
-M"```BX#$"```,<F%P'45BT($A<!U#HMZ"(7_=0>+<@R%]G0%N0$```"%R0^$
-MTP````^VA<_^___!X`2+?0P!QXN'Q`@```F%Y/[__XVWQ`@``(M&!`F%Z/[_
-M_XM&"`F%[/[__XM&#`F%\/[__XJ-S_[__XM%##I(*`^$A0```%#HG^?__UG&
-M0`0"BI7/_O__B%`(B%`)BY?$"```B5`,BU8$B5`0BU8(B5`4BU8,B5`8BXV,
-M_O__*PB#Z2S!^0*)QHT$S0`````IR(T$P<'@`RG(C03!B<+!X@\IPHT,T8/Y
-M'P^/!0D``+@!````T^`)1B"+30R*62>*02:(A73^__^-=@#^A<_^__^*A73^
-M__\XA<_^__\/@LC^____=0SH`.?__UK&0`0"B%@(B%@)B<:+A>3^__^)1@R+
-MA>C^__^)1A"+A>S^__^)1A2+A?#^__^)1AB+C8S^__\K#H/I+,'Y`HT$S0``
-M```IR(T$P<'@`RG(C03!B<+!X@\IPHT,T8/Y'P^/40@``+@!````T^`)1B"+
-M30R*22@/MM'!X@0#50R-@D0)``"+6`2+<`B(C7/^__^+0`R+BD0)``")G8C^
-M__^)A8#^__^)Q_?1BX7D_O__]],AP2.=Z/[__XFUA/[__XF-U/[__XF=V/[_
-M_XN-\/[__XN=[/[___?6]]<AWB'/B;7<_O__B;W@_O__(X)$"0``BY7H_O__
-M(Y6(_O__(YV$_O__(XV`_O__,?:%P(F%Y/[__XF5Z/[__XF=[/[__XF-\/[_
-M_W4,A=)U"(7;=02%R70%O@$```"%]@^$Q0$``(M]#(I')XB'V`D``(N%Y/[_
-M_XF'Q`D``(N%Z/[__XF'R`D``(N%[/[__XF'S`D``(N%\/[__\:'V0D```'&
-MA<_^__\`B8?0"0``BD<F.(7/_O__QX?4"0```````(B%=/[__P^#7`$``(GV
-MBHUS_O__.(W/_O__#X1_!@``BIW/_O__BW4,.EXG#X01`0``#[;#P>`$C97T
-M_O__`<(!\(NX1`D``/?7B3J-L$0)``"+7@3WTXE:!(M."/?1B4H(BT8,]]")
-M0@PCO>3^__^).B.=Z/[__XE:!".-[/[__XE*"".%\/[__XE"#(M=#/]U#.C*
-MY/__@</$"0``7L9`!`.)6`B)QHJ%S_[__XA&#(N5C/[__XGQ*PJ#Z2S!^0*-
-M!,T`````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1\/CY\%``"X`0```-/@
-MBXV,_O__"4$@#[:%S_[__\'@!(V]]/[__XT$.(L8,=*%VW47BT@$A<EU$(MX
-M"(7_=0F+6`R%VW0'B?:Z`0```(72#X6I!```BT4,BD`FB(5T_O___H7/_O__
-MBI5T_O__.)7/_O__<Q&+50R*4BB(E7/^___IIO[__XN5U/[__S'`A=)U'HN]
-MV/[__X7_=12+M=S^__^%]G4*BYW@_O__A=MT!;@!````A<`/A)/Z__^+30R*
-M62=1Z+?C__^)A7S^__]9QD`$`8NU?/[__XA>"(A>"8N%U/[__XE&#(N%V/[_
-M_XE&$(N%W/[__XE&%(N%X/[__XE&&,:%S_[__P#'A=#^__\`````BT4,BD`F
-M.(7/_O__B(5T_O__#X,C^O__C78`BU4,BE(H.)7/_O__B)5[_O__='&*C<_^
-M__^+70PZ2R=T8P^VP<'@!(V-]/[__P'!`=B-D,0(``"+@,0(```CA=3^__^)
-M`8M:!".=V/[__XE9!(MR"".UW/[__XEQ"(M2#".5X/[__XE1##')A<!U#(7;
-M=0B%]G4$A=)T!;D!````A<EU'?Z%S_[__XJ5=/[__SB5S_[__P^"8____^E^
-M^?___W4,#[:=S_[__^B?XO__6L9`!`&)QXJ%S_[__XA'"(J5>_[__\'C!(VU
-M]/[__XA7"8T<,XL#B4<,BT,$B4<0BT,(B4<4BT,,B4<8BX70_O__A<!T18L/
-M*8W0_O__BX70_O__@^@LP?@"C13%`````"G"C130P>(#*<*-%-")T<'A#RG1
-MC0S(@_D?#X^*`@``N`$```#3X`E'((M=#(I;)XB=>O[__XM%#`^VG<_^__^*
-M0"B-E?3^___!XP3_=0R-'!.(A7G^___HX>'__U[&0`0$BHUZ_O__B$@8B<:*
-MA7G^__^(1AF+`XE&"(M#!(E&#(M#"(E&$(M##(E&%(N-?/[__RL.@^DLP?D"
-MC03-`````"G(C03!P>`#*<B-!,&)PL'B#RG"C0S1@_D?B;70_O__#X_0`0``
-MN`$```#3X`E&("L^C4?4P?@"C13%`````"G"C130P>(#*<*-%-")T<'A#RG1
-MC0S(@_D?#X^%`0``N`$```#3X`E&((N5C/[__RLRC4;4P?@"C13%`````"G"
-MC130P>(#*<*-%-")T<'A#RG1C0S(@_D?#X\N`0``N`$```#3X(N-C/[__PE!
-M((M%#`^VG<_^__^*0">-E?3^___!XP3_=0R-'!.(A7C^___HQ^#__UG&0`0$
-MBHUX_O__B$@8B<:*A<_^__^(1AF+`XE&"(M#!(E&#(M#"(E&$(M##(E&%(N-
-M?/[__RL.@^DLP?D"C03-`````"G(C03!P>`#*<B-!,&)PL'B#RG"C0S1@_D?
-M#X^`````N`$```#3X`E&((N5C/[__RLRC4;4P?@"C13%`````"G"C130P>(#
-M*<*-%-")T<'A#RG1C0S(@_D??R&X`0```-/@BXV,_O__"4$@BUT,BELFB)UT
-M_O__Z3O]__^#Z2"X`0```-/@B[6,_O__"48<BT4,BD`FB(5T_O__Z1?]__^#
-MZ2"X`0```-/@"48<Z7C___^#Z2"X`0```-/@BYV,_O__"4,<Z<K^__^#Z2"X
-M`0```-/@"48<Z7/^__^#Z2"X`0```-/@"48<Z2C^__^#Z2"X`0```-/@"4<<
-MZ6[]__\/MIW/_O__P>,$C87T_O___W4,C1P#Z&??__]9QD`$`8J5S_[__XA0
-M"(A0"8L3B5`,BU,$B5`0BU,(B5`4BU,,B5`8*P:#Z"S!^`*-%,4`````*<*-
-M%-#!X@,IPHT4T(G1P>$/*=&-#,B#^1]_&[@!````T^`)1B"+30R*22:(C73^
-M___IVOK__X/I(+@!````T^`)1AR+70R*6R:(G73^___IO/K__X/I(+@!````
-MT^"+G8S^__\)0QSI6?K__XM=#/]U#.BXWO__@</$"0``7\9`!`.)6`B*G<_^
-M__^(6`R+M8S^__\K!H/H+,'X`HT4Q0`````IPHT4T,'B`RG"C130B='!X0\I
-MT8T,R(/Y'W\/N`$```#3X`E&(.DV^O__@^D@N`$```#3X(N5C/[__PE"'.D_
-M____@^D@N`$```#3X`E&'.FG]___@^D@N`$```#3X`E&'(M5#(I*)HI:)XB-
-M=/[__^GV]O__BU4,BEHGZ0/W___&A<_^__\`BDHF.(W/_O__B(UT_O__#X._
-M]/__C78`.)W/_O__=#T/MH7/_O__P>`$`T4,C9#$"```BX#$"```,<F%P'45
-MBT($A<!U#HM""(7`=0>+0@R%P'0%N0$```"%R74C_H7/_O__BIUT_O__.)W/
-M_O__#X-?]/__BW4,BEXGZYN-=@`/MIW/_O___W4,P>,$`UT,Z&_=__]?QD`$
-M`HJ5S_[__XA0"(A0"8N3Q`@``(E0#(VSQ`@``(M6!(E0$(M6"(E0%(M6#(E0
-M&(M-#(I))HB-=/[__^N(C87D_O__4.AGW/__QH7/_O__`,:%SO[__P!8BT4,
-MBD`F.(7/_O__B(5U_O__#X/##```BU4,BEHGB?8XG<_^__]T?0^VA<_^___!
-MX`0#10R-D,0(``"+@,0(```QR87`=16+0@2%P'4.BWH(A?]U!XMR#(7V=`6Y
-M`0```(7)=$`/MH7/_O__P>`$`T4,C9#$"```BX#$"```"87D_O__BT($"87H
-M_O__BT(("87L_O__BT(,"87P_O___H7._O___H7/_O__BHUU_O__.(W/_O__
-M#X)C____#[:%=?[__X/H`P^VE<[^___1^#G"#X[]!@``BWT,B)_8"0``BX7D
-M_O__B8?$"0``BX7H_O__B8?("0``BX7L_O__B8?,"0``BX7P_O__B8?0"0``
-MQH?9"0```<>'U`D```````!7Z.S;__^(6`B(6`G&0`0"BY7D_O__B5`,BY7H
-M_O__B5`0BY7L_O__B5`4BY7P_O__B5`8B<:)/"3HM-O__XF%J/[__UO&0`0&
-MBXVH_O__*PZ#Z2S!^0*-!,T`````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#
-M^1\/CR,&``"X`0```-/@"48@BT4,BD`F/`*(A73^__\/AOX"``#&A<_^__\`
-M.(7/_O__#X,3\O__C78`BIW/_O__BW4,.EXG#X1E`0``#[;3P>($B?`!T(N8
-M1`D``/?3B9W4_O__C8A$"0``BT$$]]")A=C^__^+00CWT(F%W/[__XM!#(V]
-M]/[__R.=Y/[__XT4.O?0B87@_O__B1J+A=C^__\CA>C^__^)0@2+A=S^__\C
-MA>S^__^)0@B+A>#^__\CA?#^__^)0@R)\U;HJ=K__X'#Q`D``%[&0`0#B5@(
-MB<:*A<_^__^(1@R+E:C^__^)\2L*@^DLP?D"C03-`````"G(C03!P>`#*<B-
-M!,&)PL'B#RG"C0S1@_D?#X_I`0``N`$```#3X(N-J/[__PE!(`^VA<_^___!
-MX`2-!#B+&#'2A=MU%8M(!(7)=0Z+6`B%VW4'BT@,A<ET!;H!````A=(/A1D!
-M```/MH7/_O__P>`$`T4,C9#$"```BX#$"```,<F%P'45BWH$A?]U#HMR"(7V
-M=0>+6@R%VW0%N0$```"%R74IBU4,BE(FB)5T_O___H7/_O__BHUT_O__.(W/
-M_O__#X)Q_O__Z7SP__\/MIW/_O__P>,$_W4,`UT,Z)?9__]9QD`$`HJ-S_[_
-M_XA("(A("8N3Q`@``(E0#(VSQ`@``(M6!(E0$(M6"(E0%(M6#(E0&(N-J/[_
-M_RL(@^DLP?D"B<:-!,T`````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1]_
-M&[@!````T^`)1B"+70R*6R:(G73^___I3O___X/I(+@!````T^`)1AR+10R*
-M0":(A73^___I,/____]U#`^VG<_^___HZMC__UK&0`0!BI7/_O__P>,$B%`(
-MB%`)C1P[BQ.)4`R+4P2)4!"+4PB)4!2+4PR)4!@K!H/H+,'X`HT4Q0`````I
-MPHT4T,'B`RG"C130B='!X0\IT8T,R(/Y'W\/N`$```#3X`E&(.EP_O__@^D@
-MN`$```#3X`E&'.E>_O__@^D@N`$```#3X(N=J/[__PE#'.D/_O__BUT,_W4,
-MZ$W8__^!P\0)``!9QD`$!8E8",9`%`")P8N5J/[__RL*@^DLP?D"B<>-!,T`
-M````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1\/CYD"``"X`0```-/@BXVH
-M_O__"4$@QH7/_O__`(M%#(I`)CB%S_[__XB%=/[__P^#H^[__XJ5S_[__XM-
-M##I1)P^$^0```(I'%(J=S_[__P^VT(A<.@Q`#[;3B$<4P>($B<@!T(N(1`D`
-M`/?1B8W4_O__C9A$"0``BT,$]]")A=C^__^+0PCWT(F%W/[__XM##(VU]/[_
-M_XT4,B.-Y/[___?0B87@_O__B0J+G=C^__\CG>C^__^)6@2+M=S^__\CM>S^
-M__^)<@B+A>#^__\CA?#^__^)0@PQTH7)=0R%VW4(A?9U!(7`=`6Z`0```(72
-M#X49`0``#[:%S_[__\'@!`-%#(V0Q`@``(N`Q`@``#')A<!U%8M"!(7`=0Z+
-M<@B%]G4'BUH,A=MT!;D!````A<EU*8M5#(I2)HB5=/[___Z%S_[__XJ-=/[_
-M_SB-S_[__P^"W?[__^E[[?__#[:=S_[__\'C!/]U#`-=#.B6UO__6L9`!`**
-MC<_^__^(2`B(2`F+D\0(``")4`R-L\0(``"+5@2)4!"+5@B)4!2+5@R)4!B+
-MC:C^__\K"(/I+,'Y`HG&C03-`````"G(C03!P>`#*<B-!,&)PL'B#RG"C0S1
-M@_D??QNX`0```-/@"48@BUT,BELFB)UT_O__Z4[___^#Z2"X`0```-/@"48<
-MBT4,BD`FB(5T_O__Z3#___\/MIW/_O__P>,$C87T_O___W4,C1P#Z-W5__]:
-MQD`$`8J5S_[__XA0"(A0"8L3B5`,BU,$B5`0BU,(B5`4BU,,B5`8*P>#Z"S!
-M^`*-%,4`````*<*-%-#!X@,IPHT4T(G1P>$/*=&-#,B#^1]_#[@!````T^`)
-M1R#I:O[__X/I(+@!````T^`)1QSI6/[__X/I(+@!````T^"+G:C^__\)0QSI
-M7_W__X/I(+@!````T^`)1ASIU?G___]U#.@WU?__B86D_O__QD`$`8NUI/[_
-M_XA>"(A>"8N%Y/[__XE&#(N%Z/[__XE&$(N%[/[__XE&%(N%\/[__XE&&(M]
-M#(I?)XD\).COU/__QD`$`HA8"(A8"8N5Y/[__XE0#(N5Z/[__XE0$(N5[/[_
-M_XE0%(N5\/[__XE0&(G&B3PDZ+?4__^)A:#^__]:QD`$!HN-H/[__RL.@^DL
-MP?D"C03-`````"G(C03!P>`#*<B-!,&)PL'B#RG"C0S1@_D?#X\L!```N`$`
-M``#3X`E&(,:%S_[__P"+10R*0"8XA<_^__^(A73^__\/@Q[K__^)]HJ5S_[_
-M_XM-##I1)W0[#[;"P>`$`<B-D,0(``"+@,0(```QR87`=1B+>@2%_W41BW((
-MA?9U"HM:#(7;=`B-=@"Y`0```(7)=1G^A<_^__^*A73^__\XA<_^__]RH^FZ
-MZO___HW._O__BIUT_O__BH7._O__C3P8#[:=S_[__\'C!/]U#`-=#.C`T___
-MB86<_O__6<9`!`&*E<_^__^+C9S^__^)^(A1"(A!"8N#Q`@``(E!#(VSQ`@`
-M`(M&!(E!$(M&"(E!%(M&#(E!&(M5#(I2)_]U#(B5F_[__^ALT___B864_O__
-M6L9`!`2*C9O^__^+A93^__^)^HA0&8A(&(N#Q`@``(N-E/[__XE!"(M&!(E!
-M#(M&"(E!$(M&#(E!%(G+BXVD_O__*PN#Z2S!^0*-!,T`````*<B-!,'!X`,I
-MR(T$P8G"P>(/*<*-#-&#^1\/CY@"``"X`0```-/@"4,@BYV4_O__BQLIG9S^
-M__^+A9S^__^#Z"S!^`*-%,4`````*<*-%-#!X@,IPHT4T(G1P>$/*=&-#,B#
-M^1\/CS4"``"X`0```-/@B[64_O__"48@BX6@_O__BP`IA93^__^+A93^__^#
-MZ"S!^`*-%,4`````*<*-%-#!X@,IPHT4T(G1P>$/*=&-#,B#^1\/C\P!``"X
-M`0```-/@BY6@_O__"4(@BUT,BELGB)V3_O__#[:=S_[__\'C!/]U#`-=#.@H
-MTO__6<9`!`2)QXJ%D_[__XA'&(J5S_[__XA7&8N#Q`@``(E'"(VSQ`@``(M&
-M!(E'#(M&"(E'$(M&#(E'%(N-I/[__RL/@^DLP?D"C03-`````"G(C03!P>`#
-M*<B-!,&)PL'B#RG"C0S1@_D?#X\:`0``N`$```#3X`E'((N-H/[__RLYC4?4
-MP?@"C13%`````"G"C130P>(#*<*-%-")T<'A#RG1C0S(@_D?#X_#````N`$`
-M``#3X(N=H/[__PE#(`^VG<_^___!XP3_=0P#70SH5='__UK&0`0"BI7/_O__
-MB%`(B%`)BY/$"```B5`,C;/$"```BU8$B5`0BU8(B5`4BU8,B5`8BXV@_O__
-M*PB#Z2S!^0*)QHT$S0`````IR(T$P<'@`RG(C03!B<+!X@\IPHT,T8/Y'W\;
-MN`$```#3X`E&((M-#(I))HB-=/[__^G2_/__@^D@N`$```#3X`E&'(M=#(I;
-M)HB==/[__^FT_/__@^D@N`$```#3X(NUH/[__PE&'.DU____@^D@N`$```#3
-MX`E''.G>_O__@^D@N`$```#3X(N-H/[__PE!'.DL_O__@^D@N`$```#3X(N]
-ME/[__PE''.G#_?__@^D@N`$```#3X`E#'.E@_?__@^D@N`$```#3X`E&'.G,
-M^___BW4,BEXGZ=?S__^-G>3^__]3Z&;/__]9BTT,,?8/MU$D,?^#_A\/A^<#
-M``"Y(````"GQ.=%V`HG1@_D@#X3&`P``N`$```#3X$B)\=/@"0.X(````"GP
-M.<)V$(U4%N`Q]D>)^(/#!#P#=KB+50R*4BB`^@B(E7/^__\/A'0#``"+=0R*
-MG7/^__^(GM@)``#&AMD)```!BX7D_O__B8;$"0``BX7H_O__B8;("0``BX7L
-M_O__B8;,"0``BX7P_O__B8;0"0``QX;4"0```````%;H8\___XF%R/[__UK&
-M0`0"B[W(_O__B%\(B%\)BX7D_O__B4<,BX7H_O__B4<0BX7L_O__B4<4BX7P
-M_O__B4<8BT4,BD`F/`*)_HB%=/[__P^&:`$``,:%S_[__P`XA<_^__\/@\_E
-M__^+70R!P\0)``")G<3^__^*A<_^__^+50PZ0B@/A.0```!2Z-C.__]9QD`$
-M`8J-S_[__XA("(A("8N5Y/[__XE0#(N5Z/[__XE0$(N5[/[__XE0%(N5\/[_
-M_XE0&/]U#(G&Z)G.__^)QUK&0`0#BYW$_O__*S>)6`B-3M3!^0**A<_^__^(
-M1PR-!,T`````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1\/CY4```"X`0``
-M`-/@"4<@BY7(_O__*SJ-1]3!^`*-%,4`````*<*-%-#!X@,IPHT4T(G1P>$/
-M*=&-#,B#^1]_.;@!````T^"+C<C^__\)02"+70R*6R:(G73^___^A<_^__^*
-ME73^__\XE<_^__\/@O+^___IK>3__X/I(+@!````T^"+M<C^__\)1AR+10R*
-M0":(A73^___KPH/I(+@!````T^`)1QSI8_____]U#(M=#.B?S?__B<$K#H/I
-M+,'Y`H'#Q`D``%^)Q\9`!`6)6`C&0!0`C03-`````"G(C03!P>`#*<B-!,&)
-MPL'B#RG"C0S1@_D?#X\#`0``N`$```#3X`E&(,:%S_[__P"+50R*4B8XE<_^
-M__^(E73^__\/@P'D__^*C<_^__^+70PZ2R@/A)````!3Z!G-__];QD`$`8J5
-MS_[__XA0"(A0"8N5Y/[__XE0#(N5Z/[__XE0$(N5[/[__XE0%(N5\/[__XE0
-M&"L'BE<4@^@LP?@"#[;*0HJ=S_[__XA7%(T4Q0`````IPHT4T,'B`RG"C130
-MB%PY#(G1P>$/*=&-#,B#^1]_,[@!````T^`)1R"+10R*0":(A73^___^A<_^
-M__^*C73^__\XC<_^__\/@D;____I0N/__X/I(+@!````T^`)1QR+50R*4B:(
-ME73^___KR(/I(+@!````T^`)1ASI]?[__XM-#(I!)XA!*(B%<_[__^EX_/__
-MQP/_____Z3W\__^#[B#I1OS__[@!````Z57C__^#^`,/A=OB__^-G>3^__]3
-MZ$/+__^+10Q?,?8/MU`D,?^#_A\/A^P```"Y(````"GQ.=%V`HG1@_D@#X3+
-M````N`$```#3X$B)\=/@"0.X(````"GP.<)V$(U4%N`Q]D>)^(/#!#P#=KB+
-M50S_LIP(``#H=<K__\:%S_[__P`QR8M=##I+)EX/@U?B__\/MIW/_O__P>,$
-M`UT,C8/$"```4('#1`D``.BLRO__4^BFRO__65O_=0SH6,O__UK&0`0"BI7/
-M_O__B%`(QD`)`(N5Y/[__XE0#(N5Z/[__XE0$(N5[/[__XE0%(N5\/[__XE0
-M&/Z%S_[__XJ-S_[__XM=##I+)G*'Z=GA___'`______I./___X/N(.E!____
-MBUT,BELF,<DXV8B==O[__W-&#[;!P>`$`T4,C9#$"```BX#$"```,=N%P'45
-MBT($A<!U#HM""(7`=0>+>@R%_W0%NP$```"%VP^%?P,``$$ZC7;^__]RNC'`
-MA<!T&(M]#(FW^`D``,>']`D```````#IW.'__XV=Y/[__U/HN,G__XM%#%DQ
-M]@^W4"0Q_X/^'P^'+P,``+D@````*?$YT78"B=&#^2`/A`X#``"X`0```-/@
-M2(GQT^`)`[@@````*?`YPG80C506X#'V1XGX@\,$/`-VN(M5#(I:)XB:V`D`
-M`,:"V0D```"+A>3^__^)@L0)``"+A>C^__^)@L@)``"+A>S^__^)@LP)``"+
-MA?#^__^`>B8"B8+0"0``QX+4"0````````^'XP```%*)T^C!R?__@</$"0``
-M6L9`!`7&0!0`B5@(,<G&A<_^__\`BUT,.DLFB<8/@VC@____=0SHD,G__U_&
-M0`0!BI7/_O__B%`(B%`)BY7D_O__B5`,BY7H_O__B5`0BY7L_O__B5`4BY7P
-M_O__B5`8*P:*5A2#Z"S!^`(/MLI"BIW/_O__B%84C13%`````"G"C130P>(#
-M*<*-%-"(7#$,B='!X0\IT8T,R(/Y'W\GN`$```#3X`E&(/Z%S_[__XJ%S_[_
-M_XM5##I")@^"8O___^G%W___@^D@N`$```#3X`E&'.O4_W4,Z-[(__^)A<#^
-M__]>QD`$`8N-P/[__XA9"(A9"8N%Y/[__XE!#(N%Z/[__XE!$(N%[/[__XE!
-M%(N%\/[__XE!&(M=#,:%S_[__P"*6R8XG<_^__^(G73^__\/@U3?__^+=0R!
-MQL0)``")M;S^__^*A<_^__^+50PZ0B</A-X```!2Z%W(__]9QD`$`8J-S_[_
-M_XA("(A("8N5Y/[__XE0#(N5Z/[__XE0$(N5[/[__XE0%(N5\/[__XE0&/]U
-M#(G&Z![(__^)QUK&0`0#BYV\_O__*S>)6`B-3M3!^0**A<_^__^(1PR-!,T`
-M````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1\/CXD```"X`0```-/@"4<@
-MBX7`_O__*P>#Z"S!^`*-%,4`````*<*-%-#!X@,IPHT4T(G1P>$/*=&-#,B#
-M^1]_,[@!````T^`)1R"+50R*4B:(E73^___^A<_^__^*G73^__\XG<_^__\/
-M@OC^___I.-[__X/I(+@!````T^`)1QR+30R*22:(C73^___KR(/I(+@!````
-MT^`)1QSI;____\<#_____^GU_/__@^X@Z?[\__^X`0```.F"_/__B?:%]@^$
-M<-[__X/B`H32#X1EWO__BT4,BH`<"@``B(7/_O__BTT,BI$="@``.-`/AUT!
-M``"0BIW/_O__BW4,.EXG#X0X`0``#[;SB?.-O73____!XP2-'#M3Z`/&__^+
-M10P/MX2P_`D``(M5#%^)A6S^__\/M[2R_@D``#'_@[UL_O__'P^'^PD``+H@
-M````*Y5L_O__.?)V`HGR@_H@#X35"0``B-&X`0```-/@2(J-;/[__]/@"0.X
-M(````"N%;/[__SG&=A^+A6S^__^-=##@QX5L_O__`````$>)^H/#!(#Z`W:7
-M#[:5S_[__\'B!(M%#`'0BYA$"0``]].)G>3^__^-B$0)``"+003WT(F%Z/[_
-M_XM!"/?0B87L_O__BT$,]]"-C73___^)A?#^__^-A"KT_O__C10*BSHAWXDX
-MB[7H_O__(W($B7`$BYWL_O__(UH(B5@(BXWP_O__(TH,B4@,BU4,BH7/_O__
-M.D(H#X3%"```BUT,BI,="@``_H7/_O__.)7/_O__#X:D_O__@+W-_O__``^%
-MMP```(M=#(J;'`H``#C3B)W/_O__#X<XW/__BH7/_O__BTT,.D$G=#</ML#!
-MX`2-M?3^__^-!#"+.#')A?]U%XM8!(7;=1"+>`B%_W4)BU@,A=MT!XGVN0$`
-M``"%R743_H7/_O__.)7/_O__=JWIX-O___]U#`^VG<_^___H`<7__UK&0`0!
-MBI7/_O__P>,$B%`(B%`)C1PSBQ.)4`R+4P2)4!"+4PB)4!2+4PR)4!B+30R*
-MD1T*``#KI8V%Y/[__U#H`,3__\:%S_[__P"+10R*0"8XA<_^__];B,$/@ZT'
-M``"+50R*4BB(E7/^__^*G7/^__\XG<_^__]T0XJ%S_[__XM5##I")W0U#[;`
-MP>`$`="-D,0(``"+@,0(```)A>3^__^+0@0)A>C^__^+0@@)A>S^__^+0@P)
-MA?#^___^A<_^__\XC<_^__]RH0^VC7/^___!X02-G?3^__^-#!F+,2.UY/[_
-M_XFUU/[__XM9!".=Z/[__XF=V/[__XM1"".5[/[__XF5W/[__XM!#".%\/[_
-M_XF%X/[___?6]]/WTO?0B;7D_O__B9WH_O__B97L_O__B87P_O__(S&)M>3^
-M__\C602)G>C^__\C40B)E>S^__\C00S_=0R)A?#^___HG,/__XF%N/[__UG&
-M0`0`BY7D_O__,<"%TG4>B[WH_O__A?]U%(NU[/[__X7V=0J+G?#^__^%VW0%
-MN`$```"%P`^$A@4``(M%#(M5#(I`*(B%<_[__XB"V`D``(N%Y/[__XF"Q`D`
-M`(N%Z/[__XF"R`D``(N%[/[__XF"S`D``(N%\/[__\:"V0D```'&A<_^__\`
-MBDHF.(W/_O__B8+0"0``QX+4"0```````(B-=/[__P^#1`$``(J%<_[__SB%
-MS_[__P^$#0$``(J5S_[__XM-##J1'`H```^"K@0``#J1'0H```^'H@0``#I1
-M)P^$F00```^VG<_^___!XP2-M?3^__^-'#.+A>3^__\)`XN%Z/[__PE#!(N%
-M[/[__PE#"(N%\/[__PE##/]U#.ANPO__6L9`!`&*E<_^__^(4`B(4`F+$XE0
-M#(M3!(E0$(M3"(E0%(M3#(E0&(M=#/]U#(G&@</$"0``Z#/"__]?QD`$`XE8
-M""LPBHW/_O__B$@,C4[4P?D"B<>-!,T`````*<B-!,'!X`,IR(T$P8G"P>(/
-M*<*-#-&#^1\/C\P#``"X`0```-/@"4<@BIW/_O__BW4,.EXG#X0]`P``BU4,
-MBE(FB)5T_O___H7/_O__BHUT_O__.(W/_O__<Q&+70R*6RB(G7/^___IO/[_
-M_XNUU/[__S'`A?9U'HN=V/[__X7;=12+C=S^__^%R74*BY7@_O__A=)T!;@!
-M````A<`/A#W8__^+10R+50R*0"B(A;?^__^(@O`)``"+A=3^__^)@MP)``"+
-MA=C^__^)@N`)``"+A=S^__^)@N0)``"+A>#^__^*6B>)@N@)``#&@O$)````
-MQX+L"0```````%+H#L'__XF%L/[__U_&0`0!BXVP_O__B%D(BIVW_O__B%D)
-MBX74_O__B4$,BX78_O__B4$0BX7<_O__B4$4BX7@_O__B4$8QH7/_O__`,>%
-MT/[__P````"+10R*0"8XA<_^__^(A73^__\/@W37__^*E<_^__^+30PZ42@/
-MA(P!``"*62<XV@^$@0$``%'H@<#__U[&0`0!B<>*A<_^__^(1PB(7PF+A=3^
-M__^)1PR+A=C^__^)1Q"+A=S^__^)1Q2+A>#^__^)1QB+C;C^__\K#X/I+,'Y
-M`HT$S0`````IR(T$P<'@`RG(C03!B<+!X@\IPHT,T8/Y'P^/:P$``+@!````
-MT^`)1R"+C=#^__^%R71%BQ<IE=#^__^+A=#^__^#Z"S!^`*-%,4`````*<*-
-M%-#!X@,IPHT4T(G1P>$/*=&-#,B#^1\/CPH!``"X`0```-/@"4<@BTT,BDDG
-M_W4,BUT,B(VO_O__Z*6___^!P]P)```K.%J-3]3&0`0#B5@(P?D"BIVO_O__
-MB%@,B<:)A=#^__^-!,T`````*<B-!,'!X`,IR(T$P8G"P>(/*<*-#-&#^1\/
-MCXD```"X`0```-/@"48@BX6P_O__*P:#Z"S!^`*-%,4`````*<*-%-#!X@,I
-MPHT4T(G1P>$/*=&-#,B#^1]_,[@!````T^`)1B"+10R*0":(A73^___^A<_^
-M__^*C73^__\XC<_^__\/@DK^___IN=7__X/I(+@!````T^`)1AR+50R*4B:(
-ME73^___KR(/I(+@!````T^`)1ASI;____X/I(+@!````T^`)1QSI[O[__X/I
-M(+@!````T^`)1QSIC?[__XN%N/[__RLXC4?4P?@"C13%`````"G"C130P>(#
-M*<*-%-")T<'A#RG1C0S(@_D??QZX`0```-/@BY6X_O__"4(@BDXFB(UT_O__
-MZ8#\__^#Z2"X`0```-/@BYVX_O__"4,<BT4,BD`FB(5T_O__Z5S\__^#Z2"X
-M`0```-/@"4<<Z2S\____=0SH"[[__UG&0`0!BIW/_O__B%@(B%@)BY7D_O__
-MB5`,BY7H_O__B5`0BY7L_O__B5`4BY7P_O__Z8O[___&A<_^__\`BUT,BELF
-M.)W/_O__B)UT_O__#X,1_/__BH7/_O__BU4,.H(<"@``<D<Z@AT*``!W/SI"
-M)W0Z.D(H=#4/ML#!X`2-C?3^__^-!`B+,#'2A?9U%8M8!(7;=0Z+2`B%R74'
-MBT`,A<!T!;H!````A=)U&?Z%S_[__XJ==/[__SB=S_[__W*4Z:#[____=0P/
-MMIW/_O__Z#6]__]?QD`$`8J5S_[__\'C!(VU]/[__XA0"(A0"8T<,XL3B5`,
-MBU,$B5`0BU,(B5`4BU,,B5`8BTT,BDDFB(UT_O__ZY:+30R*22B(C7/^___I
-MK?C__S'`A?]U#(7V=0B%VW4$A<ET!;@!````A<!T%<:%S?[__P&+30R*D1T*
-M``#I%/?__XMU#(J6'0H``.D&]___QP/_____Z33V__^0@ZUL_O__(.E*]O__
-MBU4,QD(H".G\TO__BD-&@^`"A,!T%HM-#(M!(#E#3'<+BD$GB$$HZ=S2__^+
-M70S&0R@(Z=#2__^+30R+42`/MT`DC0004%)3_W4(Z.R[__^+?0R#Q!"%P(E'
-M&+K_____#X0#T___Z3#2__^058GE5U93@^P(BT4(@[CD+P```W=T!:PO``"+
-M50B)1?"+@JPO```[1?!T7H'"I"\``(G'B57LB?:)^XM3!(L_B5<$B3J)6P2)
-M&XM3'(I"`8/@!(3`#X6"````,?:)\3I+)G)5BTT(BX&D+P``BW(DB5@$B0.%
-M]HM%[(E#!(F9I"\``'4-.WWP=:^-9?1;7E_)P_]R*/]R)%'H_/___XM5"(M#
-M'/^*Z"\``(/$#,=`)`````#KSXUV`(GR#[;"P>`$C808Q`@``%!&Z):Z__^)
-M\3I+)EARXHM3'.N(D%/_=0CH(]'__X7`6EETGHM-"(N!K"\``(E8!(D#BT7P
-MB4,$B9FL+P``Z7K___^)]E6)Y593BT4(BU@(BX/D+P``A<!T-XVSK"\``)!3
-MZ/S___]3Z/S___]3Z/S___^+@^0O``"#Q`R%P'7A.;.L+P``==F-9?A;,<!>
-MR<.-LZPO```YLZPO``!TZ>O`58GE5U93@^P,BT4(BT`(B<>+D*PO``"!QZPO
-M```Y^HE%\'02BTT(.4H<#X2D````BQ(Y^G7NBTWPBY&T+P``@<&T+P``.<J)
-M3>AT$HU:^(M%"#E#''01BQ([5>AU[C'`@\0,6UY?R<,Q]HI#)HGQ.,%S2HA%
-M[XGVB?$/ML'!X`2-!!B-B,0(``"+@,0(```Q_X7`=1>+002%P'40BT$(A<!U
-M"8M!#(7`=`>)]K\!````A?]U%4:)\#I%[W*[,<F%R;@!````=9CKC;D!````
-MZ^Z-=@"*0B8QVSC#B$7N<S\/ML/!X`2-!!"-B,0(``"+@,0(```Q]H7`=16+
-M002%P'4.BT$(A<!U!XM!#(7`=`6^`0```(7V=1I#.EWN<L$QR87)N`$````/
-MA3+____I_?[__[D!````Z^>)]E6)Y5=64U.+70B+2R2+10R%R8E%\(M]$(MS
-M"'4+4^BA_O__A<!:=1!75O]5\(UE]%M>7\G#C78`BT7PB4,DB7LH_X;H+P``
-MB74(C67T6UY?R>G\____B?95B>564XM=#(I#$83`BW4(=0;&0Q$!L`$\`706
-M/`9T$CP#=`Z*0Q"#X""$P'4$QD,1"_]S+%;H0;C__U/_<QQ6Z/S___^+`XM0
-M&(/$%(72=5^+ANPO``"%P'0.C8:D+P``.8:D+P``=2^!ON`O``#_````=PZ-
-MAJ0O```YAJ0O``!T!XUE^%M>R<.)=0B-9?A;7LGI_/___XV&["\``%!H````
-M`%;H_/___X/$#.O4D(/`&.OIC78`58GE5U93@>R\````BT4,BU`@BPJ)C4#_
-M__\/MD$\2(F%5/___V:+0@AFB85B____BTI,B8U<____#[9"2HF%4/___P^V
-M2DN)C4S___]FBT)2BTH49HF%8/___X7)BW409HM:4`^$;@(``&8/MD(0@^`!
-M#[?`.T44#X1:`@``B8U$____BU4,BP(/MD`#,?^)A4C___\QR9`/M\,#A5S_
-M__^)A5C___^+A4C___\YA5#___\/A`8!```/MYU@____P>,)D(N%1/___P^W
-M4`2%TG4%N@```0")T"GX.=AW#2G#@X5$____"#'_Z]@!WXN58/___V8IE6+_
-M__\/A*D```#_A5#___^+A4S___\QVSF%4/___P^$A````(N50/___P^V0CPY
-MA5#___]T+8N%0/___V:+4$1FBX5B____9CG09HF%8/___P^&2O___V:)E6#_
-M___I/O___XN%3/___X7`="W_C4S___\QP(.]3/___P`/E,")A5#___^+A4#_
-M__]FBU!$#[?"`85<____ZZ:+A53___^)A4S____KR_^%4/___^EQ____9L=&
-M_@"`N0$```"-9?1;7HG(7\G#A<ET1(N%6/___RG(B</!XPET-8M-%(7)#X3J
-M````H00```"!^P`0``")!F;'1@8```^&Q0```&;'1@0`$(/&"('K`!```'7+
-M#[>58/___XG3B94\____P>,)C78`BXU$____#[=1!(72=06Z```!`(G0*?@Y
-MV(F%./___W,OBX5$____BPB)T`'Y9BGXB0YFB48$9L=&!@``*YTX____@\8(
-M@X5$____"#'_Z["+C43___^+`0'X`=^)!F:)7@1FQT8&``"#Q@@YUW0CBU4,
-MBXU8____#[=""`.-//___P-"!#G!#X5%_O__Z?S^__^#P0@Q_XF-1/___^O0
-M9HE>!(/&".E`_____S4$````Z/S___]:Z0K___^+0A@QR87`#X30_O___W44
-MC8UD____45*)C43_____=0C_T(/$$#')A<`/A*W^___I=_W__XUV`%6)Y593
-MBU4,BD(1/`&+=0B+6B!T`XA#$5)6Z/S___^*0TE`B$-)6CI#2%ET!XUE^%M>
-MR<.*0Q&$P'4&QD,1`;`!/`%T##P&=`@\`W0$QD,1"U-6_U,<6U[KTXGV58GE
-M5U93@^Q(BT4,BE`0BSB(T(/@!(3`#X1#`@``BU4,BEI$A-O'1<``````#X1F
-M`0``BT4,BTW`BTR(,(E-O(J!'`H``(A%NXJ!'0H``#A%NP^',@$``(I5NXM-
-MO#I1)P^$$0$```^VP@^WE('\"0``#[>T@?X)``#!X`2)5:PQ_XV<",0(``"#
-M?:P?#X?%`0``NB`````K5:PY\G8"B?*#^B`/A*,!``"(T;@!````T^!(BDVL
-MT^`)`[@@````*T6L.<9V&8M%K(UT,.#'1:P`````1XGZ@\,$@/H#=JD/MD6[
-MB<*+3;S!X@2-E`I$"0``B56T#[>4@?P)``")5:P/M[2!_@D``#'_D(-]K!\/
-MARX!``")^8M5M`^VP8T<@KH@````*U6L.?)V`HGR@_H@#X0``0``B-&X`0``
-M`-/@2(I-K-/@"0.X(````"M%K#G&#X;1````BT6LC70PX,=%K`````!'B?J`
-M^@-VG8M-O(J!'0H``/Y%NSA%NP^&U/[__XM-#(I91/]%P`^VPSE%P`^,FO[_
-M_XM%"(N0H"\``(72=%2$V\=%P`````!T-HV0K"\``(M%#(M-P(M,B#"+0@2)
-M$8E*!(D(B4$$_T7`QX'T"0```````(M-#`^V040Y1<!\T/]U#/]U".CJ^?__
-MC67T6UY?R<.$V\=%P`````!T[8M-P(M%#/]TB##_=0CHT<C___]%P(M5#`^V
-M0D1;.47`7GS=Z\B+5;R*@AT*``#I0/___\<#_____^D&____D(-MK"#I&O__
-M_\<#_____^EC_O__@VVL(.ET_O__@^("A-(/A,4"``"*1T:#X`.$P'0+BU4,
-MBEI$Z7G___]J$&H`C47$4.C\____BT4,BEA$@\0,A-N(7;/'1<``````#X34
-M````BTT,BU7`BU21,(E5O(I")C').,&(1;)S1`^VP<'@!`-%O(V0Q`@``(N`
-MQ`@``#'VA<!U%8M"!(7`=0Z+0@B%P'4'BT(,A<!T!;X!````A?:X`0```'4(
-M03I-LG*\,<"%P`^%ZO[__XM5O(J2'`H``(A5NXM-O(J!'0H``#C"=T2*5;N+
-M3;PZ42=T,0^VTF:#?%7$``^%S0$```^WA)'\"0```T$@B425U&:+A)'^"0``
-M9HE$5<2*@1T*``#^1;LX1;MVO/]%P`^V1;,Y1<`/C"S___^+10S_<"S_=0CH
-MS;#__\=%P`````"+50Q;@'I$`%X/A(D```"+30B-F:0O``"+1<"+50R+3<"+
-M1((PA<F)1;P/A0@!``"+0"")0DR+5;R*@AP*``"+30R(04J*0B>(04L/MH(<
-M"@``9HN$@OP)``!FB4%0#[:"'`H``&:+A(+^"0``9HE!4L9!2`#&04D`BT,$
-MBU6\B5,$B1K_1<")0@2)$(M-#`^V040Y1<!\@(M%"(N0["\``(72=7C&1;L`
-MBD<\.$6[#X.K_?__#[9UNV:#?'7$`'4-_D6[.$6[<NSIDOW__XM<MU#_=0CH
-M_/___XM5#/Y"2,9`"B!FBU1UQ&:)4`B+5+74@$@0`HM-#(E0!,=`&!!G``#'
-M0!P@:@``B1B)2"!0_W4(_U,T@\0,BD<\ZZ0%["\``%!H`````/]U".C\____
-M@\0,Z6W___^+1;R+2""+10R+4$PYT0^&+?___P^W1T3WV"'!(<(YT0^%&___
-M_XM5O`^V@AP*``!FBX2"_@D``(M-#&8!05+I_?[__XGVBTV\9HN$D?P)``!F
-M`T$@9@.$D?X)``!F*T25U.DI_O__BT4,BEA$Z;[\__]5B>575E.#["B+10R+
-M`(E%\&:+6$0QR6:!^X``9HE=[G8&9L=%[H``BU4,BD(0@^`@A,`/A>T"``"+
-M11"*0!(/MM"+=1"(1=>+!HG6,=+W]HA5ZXM%\`^V4#R+=1"+1@2)UC'2]_:*
-M1=<HT#A%ZXA%ZG(#_D7KC5/_BW409B-6#&8ITV:+1A!F.<-FB5WL=@1FB47L
-MBT4,QD!$`,9`10`/MUWNQT7D`0```(E=V`^W^HMU$`-^"&:+1>Y((?AFBUWN
-M9BG#9CM=['8#BUWLBW78]]Z+1>0A_H7`#X2$````QT7D`````&:+5>Z+1?!F
-M.U!$<R.+30P/MDE$,<`YR(E-T'T3D(M5#(M,@C`Y<2!T4T`[1=!\[O]UV%;_
-M=?#_=0CH][#__X/$$(7`B<$/A"@!``"+10R*0$2(1<\/MM"+10R)3)`PBD7/
-MBU4,0(A"1(F1]`D``,:!'`H```C&@1T*````B?AF*?`/ME7K9HF$D?P)``!F
-MB9R1_@D``(I%ZSB!'`H``'8&B($<"@``BE7K.)$="@``<P:(D1T*``"+=1!F
-MBT809BG89BE=[&:)1A!T$0^WPP''QT7D`0```.GS_O__9H7`#X2$````_D7K
-MBD7J,=(X1>MT<HI=ZXMU\#I>/'0QBW7P9HM>1&8Y7>YS!\=%Y`$```"+11!F
-MBT`09CG89HE%[`^&H?[__V:)7>SIF/[__X!]Z@!T)?Y-ZH!]Z@`/E$7KBUWP
-M#[=#1(MU$`%&",=%Y`$```!FBUM$Z[B+11"*0!*(1>KKT_Y%Z^N),<"-9?1;
-M7E_)PXM-#(I!1$B(043^P`^$GP```(M="('#K"\``(M]"(E=X(''I"\``(MU
-M#`^V1D2+3(8PBD$F,=LXP\>!]`D```````"(1=]S08GV#[;#P>`$C00(C9#$
-M"```BX#$"```,?:%P'45BT($A<!U#HM""(7`=0>+0@R%P'0%O@$```"%]G5"
-M0SI=WW+!,<"%P'0LBU7@BT($B1&)2@2)"(E!!(M-#(I!1$B(043^P`^%=O__
-M_[C_____Z3W___^+1P2).8E/!.O5N`$```#KOP^W1>Y0BTT0_W$(_W7P_W4(
-MZ."N__^)P8/$$(7)N/____\/A`3___^+70S&0T0!B4LPB9GT"0``Z>W^__^0
-M58GEBTT0A<F+50B+10QT&,9`$0N)11#'10Q89@``B54(R>G\____D(E%#(E5
-M",GI+/?__U6)Y5=64X/L,(M%#(LXBD<!@^`$A,`/A.0!``"+7RR%VP^$M0$`
-M`(M%#(I0$(C0@^`@A,`/A78!``"#X@8/A%T!``"+10R+0`2)1<R)1>"+50P/
-MMUH(9HE=Y(I7/$J(5>8/MD\^#[;2B57(T^@QTHE%U/=UR(E%V`^V3S[3X(E%
-MW`^W=T0/KT7(BTW(`UW,#Z_.*<.-1!G_,=+W\8G!#Z_.BT7<C10!4E!7_W4(
-MZ"JK__^+50R#Q!"%P(E"+'49QT(H`````(U'&%)0Z/S___^-9?1;7E_)PXU%
-MU%#_=0S_=0CH@?O__X/$#(7`=2^+50R*0A"#X`2$P'03:!QS``!2_W4(Z"^N
-M__^#Q`SKPO]U#/]U".@3]O__6U[KLXM%#/]P+/]U".A9JO__BT4(BY!4(@``
-MBYA8(@``7SG:670BN2$"``"-=@"+10B!O-!,$0```````'0P0HG0F??Y.=IU
-MYHM5#(M%",="*``````%["\``%)0Z/S_____=0CH_/___^E(____BT4,QD`1
-M!5#_<!S_=0CH_/___^DP____BU4,QD(1`5+_<ASKYHUV`(I'1H/@`83`=1:+
-M50P/MT]$BT($#Z_!B47<Z=+^__^0BT4,QD`1!NNVC78`:@?_=0CHZJ;__XE'
-M+&@`$```:@!0Z/S___^#Q!3I*?[__XGVBU4,QD(1`NN>C78`58GE4XM=#(M#
-M+(7`=06+7?S)PU/H_/___S'26(M#+(L$D(7`=!")]L=`$`````"+0!2%P'7R
-M0H'Z_P,``';=:@?_<RS_=0CHH*;__\=#+`````"#Q`SKME6)Y5>+?0A6C8>D
-M+P``4XF'I"\``(F'J"\``(V'K"\``(F'K"\``(F'L"\``(V'M"\``(F'M"\`
-M`(F'N"\``*$`````P>`,NJNJJJKWXHG3P>L/QX>@+P```````%-H(`H``%>#
-MPR#H3*;__U-J$%>)QNA!IO__`<:A`````,'@#,'H#E!J1%?H*Z;__X/$)&H(
-M:``0``!7`<;H&:;__P'&5T;H_/___X/$$#LU`````*,$````<@B-9?1;7E_)
-MPU?H_/___XG"A=)8=.M&BX?<+P``_X?@+P``.S4`````B0*)E]PO``!RUNO,
-M58GE5U9348M%"(E%\(MU#(!F`?N+7@0/MDX#N`$```#3X(I31HG!B-"#X`*$
-MP,=#3`````")UP^$YP```&:+0TAFA<!T!6:%P74Q"<AFB4-(BT,X@&,!^X7`
-M=1"#YQ^)^(A#1HUE]%M>7\G#4_]U\/_06%H/MGM&Z^*)]HC0@\@%_DL]A,!F
-MB4M(QT-,`````(A#1GD&@^!_Z\:0@^"?B$-&4_]U\.C\____B<%?A<E8=$>*
-M5@.(40.`20$(Q@$#H0P```")030/MM*A(````(E9!(E,DU")03C'1@0`````
-MBD-&@^#^@\@*B$-&_D,]46H'Z/S___]86HM#!(7`=`R-=@")PXM`!(7`=??H
-M_/___XE#0(E="(UE]%M>7\GI_/___V:+0TAFA<`/A$O____I$/___XGV58GE
-MBU4,2E,QVX/Z_XM-"'0.B?8/M@%*`<-!@_K_=?0/ML-;R<.)]E6)Y593BUT(
-M@#L#=D>*4SPQ]H32=!*)]HM,LU"%R7441@^VPCG&?/"`8T;[C67X6U[)PY"*
-M4P&*00&#X@&#X/X)T(A!`?]TLU#H_/___UB*4SSKS(E="(UE^%M>R>L!D%6)
-MY5=64X'L!`(``(M%",>%\/W__P````"`>#P`C;7T_?__#X0L`@``BW@$A?]T
-M#XM'!(7`=`B)O?#]__^)QV@``@``:@!6Z/S___^#Q`PQP(7_QP;S%GA:=`.+
-M1T")1@2+50B`>D0`=`J`3@D"BD)'B$8*BT4(BE!`B-.*AI,```"#XP&#X/R(
-MT8/A`@G8"<B(TX/C!(/@\XC1@^$("=@)R(C3@^,0@^#/B-&#X2`)V`G(@^`_
-MB-&#XD`)T(/A@`G(B(:3````BU4(BD(!@^`!A,!T!(!."0&%_P^$C@$``(N%
-M\/W__X7`#Y3`L@(HPH7_B%8+#X2O````BT<,B48,QX:4`````````(H'B$80
-MBD<\B$81BX7P_?__A<`/A$,!``"+E?#]__^*0@.(1A**1SZ(1A.*1T:#X`*$
-MP'0$@$X4`6:+1TAFB486BT=,B488:A"-1W!0C48L4,>&F`````````#H_/__
-M_VH$C8>`````4(U&/%#H_/___VH0C8?$````4(V&@````%#H_/___X/$)&I`
-MC8>$````4(U&0%#H_/___X/$#(N%\/W__X7`=&*+E?#]__^+0@R)1AS'AIP`
-M````````B@*(1B"*0CR(1B&+50B*0@.(1B*+E?#]__^*0CZ(1B.*0D:#X`*$
-MP'0$@$XD`8N5\/W__V:+0DAFB48FBT),B48HQX:@`````````(7_=$-HD```
-M`%;H_/___V@``@``5O?8B$8(Z/S____WV%:(AI````!J,(M5"(M"3(/H"E")
-MT(/`/%#H_/___XUE]%M>7\G#BU4(B@*(1A#KLXM5".F[_O__,=+I>O[__XGV
-M58GEBT4(4X`X`W8;,<D/ME`\.=%]#XG3BU2(4(72=0I!.=E\\S'`6\G#B=#K
-MV8GV58GE5E.+=0B`/@-V+XI6/#';A-)T$HGVBT2>4(7`=1!##[;".<-\\(UE
-M^%M>R<.04.C\____6(I6/.OD@&8!_NOFB?95B>6+30B+40@QP#D,@G0(0(/X
-M!W;UR</'!((`````Z_6-=@!5B>6+10R`8`'[B44(R>G\____D%6)Y5=64X'L
-M!`0``(M]"(I7`8C0@^`$A,"-G?3]__^)_G0%@#\"=PB-9?1;7E_)PX/B_8A7
-M`6@``@``:@!3Z/S___^*!X/$##P#=!`\"(MV4`^$@0```(`^`W7P4VH@:@"-
-M1CQ0Z/S___^#Q!!F@;O^`0``5:IUL(N+R@$``(7)=!6!>P9,24Q/=$&!NW8!
-M``!'4E5"=#6)V,>%\/O__P,```"`N+X!``"`=!"#P!#_C?#[__]Y[.EL____
-MBY#*`0``A=)TYH!/`0+KX(!/`0+I4____XUV`(7V=`MF@W](`0^%</___\>%
-M\/O__P$````/MD<\.87P^___C;7T^___#XUF____5FH@:@"+E?#[__^+1)=0
-M@\`\4.C\____,=*#Q!"+!)8Q!)-"@_I_?O3_A?#[__\/MD<\.87P^___?,7I
-M)O___Y!5B>564XM="(N+2!$``(U!`;HA`@``B=:9]_Z+10R)1,L\BT40B43+
-M0(F32!$``%M>R<.058GE5U93BW4(BX9$$0``.X9($0``="N_(0(``(M<QD"+
-M3,8\0)GW_XF61!$``%-6_]%;6(N&1!$``#N&2!$``'7:C67T6UY?R<.)]E6)
-MY593BUT(BXM8(@``C4$!NB$"``")UIGW_HM%#(F$RTP1``"+11")A,M0$0``
-MB9-8(@``6U[)PXUV`%6)Y5=64XM]"(N'5"(``#N'6"(``'0^D+HA`@``BYS'
-M3!$``(NTQU`1``!`B=&9]_F+A^0O``"%P(F75"(``'4?5E?_TUB+AU0B```[
-MAU@B``!:=<.-9?1;7E_)PXUV`%?H_/___UGKV(UV`%6)Y8M5"%.+6CB%VW4*
-M,<"+7?S)PXUV`(L#B4(X:E1J`%/H_/___XG8Z^6058GEBTT(BU4,BT$XB0*)
-M43C)PY!5B>6+30B+`87`BU4,=!&+0"2)0B2+`8E0)(D1R<.)]HE2).OUC78`
-M58GE5U93BW4,BQ:%THG7="6-=@"+6B0YVG0EBT,DB4(D4_]U"/]3*%@Y^UIT
-M"(L&A<")PG7>C67T6UY?R<.)]L<&`````.O958GEBT4(@#@(=`7)PXUV`,GI
-M_/___XGV58GE4XM%"(`X"(M=#(M-$(M0"'0+45+_TXM=_,G#B?:+7?S)Z?S_
-M__^-=@!5B>575E-1BE40B%7SBT4(BW@HB@`/MMA35XA%\NC\____:@!35^C\
-M____:@!J`&H`:@!J`U-7Z/S___^#Q#`QTH7`#X2'````,=OW10P```#P#Y7#
-MA=L/A(\````QP(!]\R`/E<!(@^#P@\`TA=M0=7*+10S!Z!B#R$"+30S!Z1!0
-MBU4,#[;!4(7;#[;&4`^V50QT1XG()0#_```)T%!J`6H`:``!```QP(!]\S#_
-M=10/E,!30%`/MEWR4U?H_/___X/$-%.)QE?H_/___XGRC67T6UZ)T%_)PXGV
-M#[?"Z[V-=@"X0````.N0D`^V1?/I>/___XUV`%6)Y8I%"(G"@^(#@^`$P>(-
-MA,!T"XV"`"`#`,G#C78`C8(`(`(`Z_-5B>564U"*10QH(*$'`(A%]XMU"+L@
-MH0<`Z/S___]8D`^V1?=0Z*[___\%'`$``(D$)/]V#.C\____A,!:6;H!````
-M>1MH$"<``('#$"<``.C\____@?L_2TP`6';",=*-9?A;B=!>R<.-=@!5B>56
-M4VH`#[9%#%#H6____XG&C4`(B00DBUT(_W,,Z/S___]H&`$``(U&#%#_<PSH
-M_/___X/$&(UE^%M>R<.058GE#[9%#&H`4.@=____@\`,B00DBT4(_W`,Z/S_
-M___)PXGV58GE9H-]%`"+10QU$_=%$````/!U"JD`_P``=`N-=@"X`0```,G#
-MD&:%P'4+@WT(`;@!````=.TQP.OI58GE5U934(M=%(M#$(M-"(D!BT,4B4$$
-MBP,QTH7`BWT0B47P=06Z`0````^V1P31X`G"BT4,B[`X`@``A?9FB5$(#X0@
-M`0``@_X"#X07`0``@WL$`71Y9@^V0PX-`!(``&:)00IF#[9#"`T`$P``BU,(
-M9HE!#(G09L'H"`T`%```9HE!#HG0)0``_P"!X@````_!Z!#!ZA@-`!4``('*
-M0!8``&:)01!FB5$2C5$4BTWPA<FPR'0%L,J-=@!F#[;`#0"7__]FB0)86UY?
-MR<.)]F8/MD,/#0`2``!FB4$*9@^V0PZ+4P@-`!(``&:)00R)T,'H&`T`$P``
-M9HE!#F8/MD,(#0`3``!FB4$09@^V0PP-`!0``&:)01*)T&;!Z`@-`!0``&:)
-M012!X@``_P!F#[9##<'J$(M=\`T`%0``@<H`%0``A=MFB4$69HE1&+`E9L=!
-M&D`6C5$<#X1=____L#7I5O___XGV@WL$`0^$@@```&8/MD,.#0`1``!FB4$*
-M#[9'!,'@`V8/ML`-`!(``&:)00QF#[9#"`T`$P``BU,(9HE!#HG09L'H"`T`
-M%```9HE!$(G0)0``_P"!X@````_!Z!#!ZAB+=?`-`!4``('*0!8``(7V9HE!
-M$F:)412PQXU1%@^$TO[__[#,Z<O^__^-=@!F#[9##PT`$0``9HE!"F8/MD,.
-M#0`1``!FB4$,#[9'!,'@`V8/ML`-`!(``(M3"&:)00Z)T,'H&`T`$P``9HE!
-M$&8/MD,(#0`3``!FB4$29@^V0PP-`!0``&:)012)T&;!Z`@-`!0``&:)01:!
-MX@``_P!F#[9##<'J$(M]\('*`!4```T`%0``A?]FB4$89HE1&F;'01Q`%HU1
-M'G42@_X"L&`/A"#^__^P)ND9_O__@_X"L&$/A`[^__^P-ND'_O__C78`58GE
-M5U93@^P8BU4(#[9%#(M$@B2+>#"-AP0!``"+<@Q05HM=%.C\____B`.-AP@!
-M``!05HE%\.C\____9@^VP&:)0P*-APP!``!05HE%[.C\____9@^VP&:)0P2-
-MAQ`!``!05HE%Z.C\____9@^VP(/$(&:)0P:-AQ0!``!05HE%Y.C\____9@^V
-MP&:)0PA8@WT0`5IT*8V'&`$``%!6Z/S___^(0PJ-AQP!``!05NC\____B$,+
-MC67T6UY?R<.0C8<@`0``4%:)1=SH_/___XA%XX/(@`^VP%#_==Q6Z/S_____
-M=?!6Z/S____!X`AF"4,"_W7L5NC\____P>`(@\0D9@E#!/]UZ%;H_/___\'@
-M"&8)0P;_=>16Z/S____!X`AF"4,(#[9%XU#_==Q6Z/S___^#Q!SI6____U6)
-MY5=64X/L&(M5"`^V=0R+?+(DBT409HE%XHM',(/`,%#_<@SH_/___X/@'XT4
-MQ0`````IPHT$UXV01`(``%F#N$0"```!B57<6W0_C9A8`@``C47D4/]S!%;_
-M=0CH8?[__XU5Y/Z/40D``%)J``^W1>)0_W,<:@%6_W<H_U,8@\0L_W7<5^CH
-M#P``C67T6UY?R<-5B>575E.#["B+51`/MD4,BTT(BW2!)(E%T&:+`F:)1=QF
-MBT("9HE%WHM"!(E%X&:+1=R#X!^-%,4`````*<*-'-:-@T0"``")1=AFBT7>
-MA,#'1=0`````9L=%S@``="YFBT7>)?\```!FB47.QT74`0```&:!3<X``<>&
-M3`D```````#'AC0"````````9HM%WH/@!&:%P(V[6`(```^%D````(.[1`(`
-M``%T2_Z.40D``(U%Y%"+1>!0#[=%SE#_=QS_==3_==#_=BC_5QC_==A6Z`@/
-M``"+ODP)``"#Q"2%_W03BX9$"0``A<!T"8-X$`%T"XUV`(UE]%M>7\G#_W70
-M_W4(Z*40``#_MD0)``!6Z)D1``"#Q!"%P'7::@#_MD0)``!6Z*0%``"#Q`SK
-MQXUV`(U%Y%#_=P3_==#_=0CHZOS__X/$$.E6____B?95B>575E-0BUT(BW4,
-MBWT0:"P-``#_<PSH_/___XE%\(/(`5!H+`T``/]S#.C\____:"P-``#_<PSH
-M_/___VCP!`$`_W,,Z/S____WUB'&@\0D"?=7:/`$`0#_<PSH_/___VCP!`$`
-M_W,,Z/S___^+1?")11"+0PS'10PL#0``B44(@\04C67T6UY?R>G\____C78`
-M58GE5U93@^PDBT4(BT@,B47PBU4<#[9%#,'@`HE5[(I5$`G"B4WDBT7P#[;*
-MBW2()(M%&(7`BWT4QT7@`````(A5ZXE-W'1LA?8/A,X```"-!/T`````"T8D
-MBY[<"0``4(M&,(/`)%#_=>3H_/___X/$##G[=":+5=R)5=B-=@"+1A2-!-A0
-M_W780_]U\(/C'^B&_?__@\0,.?MUXXN&3`D``(7`=0?'1>`!````B9[<"0``
-MBT7LA<!U"XM%X(7`#X3#````#[9-ZXE-U%'HC??__XUX"(D\)/]UY.C\____
-MB<,/M\")1=#WT%!7_W7DZ/S___^)V(/@"(/$%&:%P`^$&@$``(7V=!3'ADP)
-M````````QX8T`@```````(M5\(-Z9`$/A-D```"#>F@!#X3/````BT7P@WA@
-M`0^$K@```(-X9`$/A*0```"#>&@!#X2:````BU7P@WI<`70R#[9=ZU/H]_;_
-M_P4<`0``B00D_W7DZ/S___]97E-J`&H!_W7PBTWP_U$@C67T6UY?R<-J!`^V
-M7>M3Z,/V__^-<"B)-"3_=>3H_/___U;_=>3H_/___VH9Z/S___]J`%;_=>3H
-M_/___X/$)%;_=>3H_/___VC0!P``Z/S___]3_W7PZ'<&``"#Q!3I<O___XUV
-M``^V1>M0_W7PZ'<'``!?6.E;____BDWKN``!``#3X%!0_W7PZ%3]__^#Q`SI
-M%?___XG8@^`09H7`=5N!XP`!``!FA=L/A%#___^#OC0"```!=!R#/0`````!
-M#X4Z____B74(C67T6UY?R>DF#@``QX9,"0```````,>&-`(```````#_==#_
-M==3_=?#H"/O__X/$#.N]_W74_W7PZ,P%``!8BT7P@WAD`5IT'8-X:`%T%P^V
-M1>M0:@%J`?]U\(M5\/]2(.G1_O__:@"*3=2X``$``-/@4/]U\.B?_/__@\0,
-MZ\^)]E6)Y5,/MD4,P>`""T40BUT(#[;`BTR#)(7)=#"+D40)``"%TG0+@SH!
-M=`:#>A`!=`^)10R)70B+'"3)Z>P+``")50R)30B+'"3)ZPB)10SKYHUV`%6)
-MY5=64U&+50B*&HM"*(MX#(C8BW(P@^`#B$7SC88@`0``4%>!QAP!``#H_/__
-M_U97@^,$Z/S____`ZP*)Q@^V3?.#XP&X``$``-/@2_?0@>,``/__4('#%``#
-M`%-7Z/S___^)\H/$'(32>".)\(/@`83`#X62````BU4,BT(4@_@!=%N#^`%R
-M3X/X`G0)D(UE]%M>7\G#@^9@B?`\0'7OBU4,BUH@A=MU$FH`4HGV_W4(Z`P!
-M``"#Q`SKTXM%#(/`%%#_=0CH5````(7`6EEUOFH!_W4,Z]=J`.OWC78`@^9`
-MB?"$P'0CBT4,@\`44/]U".@H````2%]:==6+50R+<B"%]G6)ZZ*-=@!J`?]U
-M#/]U".BK````Z7+___^)]E6)Y5=64XMU#(%^#/\```"+?0AW"C'`C67T6UY?
-MR<.+%H/Z`71,,<"#^@%RZH/Z`G0'N`$```#KWC';D(M&"`^W$%*#P`*)1@B+
-M1S`%``$``%"+1RC_<`Q#Z/S___^#Q`R!^_\```!VTX%N#``!``#KP#';BT<P
-M!0`!``!0BT<H_W`,Z/S___^+5@AFB0*#P@*)5@A#6('[_P```%IVU>O(C78`
-M58GE5U93@^P4BUT,C7WD5X/#%/]S!(MU",=%X``````/M@90_W8HZ#3W__^#
-MQ!"#?1`!#X3W````5VH`:@#_<R#_=>`/M@90_W8H_U,<_W4,5NBY"```@\0D
-M@WT0`0^$L````(N&1`D``(7`="^#>!`!='Z+CC@"``"%R71*#[8&4/]V*.BZ
-M"0``BYY$"0``6(7;6G0'BWL0A?]T"XUE]%M>7\G#C78`C4,44%-6Z'T*``"+
-M6PB#Q`R%VW3@BTL0A<ETY.O7B?8/M@90_W8HZ$`)``"+1C"#P"A0BT8H_W`,
-MZ/S___]J`>C\____@\04ZXQ05NCG"@``A<!;7W6>:@#_MD0)``!6Z//^__^#
-MQ`SKBXGV@ST``````0^%0____U;H<0H``%CI-____XUV`,=%X`$```#'ADP)
-M````````Z?/^__^)]E6)Y5=64U.+70B+0RB+>`R+0S")QH/&*%97B47PZ/S_
-M__^#X`1:60^$2`$``&H"5E?H_/___U97Z/S___]HT`<``.C\____#[8#4/]S
-M*.C5`0``@\0@QH,\`@```,:#4`D```#&@U$)````QX/8"0```````,>#W`D`
-M``````#'@S0"````````QX/4"0``(````#'`C78`B82#5`D``$"#^!]^\XV3
-M1`(``+@?````QP(!````@\(X2'GTBT7PQX-$"0```````,>#2`D```````#'
-M@TP)````````@\`(:@!05^C\____BT7P:!@!``"#P`Q05^C\____@\08BT7P
-M_W,8@\`04%?H_/___XM#'"4`_/__4(M%\(/`%%!7Z/S___^+1?!J`(/`&%!7
-MZ/S___^#Q"2+1?#_<R"#P!Q05^C\____BT7P:@"#P"!05^C\____BT,D,,!0
-MBT7P@\`D4%?H_/___XUE]%M>N`$```!?R<-J`E97Z/S___^#Q`SIT/[__XGV
-M58GE5U93@^P8BT449HE%XHM%#(7`=6J+70B^'P```)"+NT0"``"%_W51@[M4
-M`@```719BX-<`@``B[MT`@``BY-P`@``B57<C57D4E"+50@/M@)0_W(HZ#3T
-M__^-1>10:@`/MT7B4%?_=1"+50@/M@)0_W(H_U7<@\0L@\,X3GF?C67T6UY?
-MR<.-=@"+@UP"``"+NW@"``"+DW0"``#KI56)Y5=64U`/MG4,B?"#X`2+70B_
-M`P```,#H`B'W@WM<`8A%\P^$D@```(-[8`$/A(@```")^@^VPL'@"(!]\P!T
-M<@5T`0,`4/]S#.C\____B<&)\`^VT`^V1!-ZP>`%)>````"!X1____\)P0^V
-MA!."````P>`+@>'_Y___)0`8```)R(GZ4`^VPL'@"(!]\P!T&05T`0,`4/]S
-M#.C\____@\04C67T6UY?R<,%=`$"`.OED`5T`0(`ZXR0B?H/ML+!X`B`??,`
-M=$8%#`$#`%#_<PSH_/___XG!B?J#X?P/ML*#R0'!X`B`??,`4709!0P!`P!0
-M_W,,Z/S___^#Q!3I+____XUV``4,`0(`Z^60!0P!`@#KN)!5B>575E,/MG4,
-MBUT(5NC9[O__B30D4XUX*.BA[___:@17_W,,Z/S___]7_W,,Z/S___]J&>C\
-M____@\0@:@!7_W,,Z/S___]7_W,,Z/S___]64^B0_O__B74,B5T(@\0<C67T
-M6UY?R>D3[___C78`58GE5U934,9%\@"0QD7S`(I5\XI%\HTT@H'F_P```%;H
-M5^[__XU8*(G'QP0D`@```(M%"%/_<`SH_/___U.+50C_<@SH_/___U;_=0CH
-M/O___VH`BT4(4_]P#.C\____@\0H:!\!``!7BU4(_W(,Z/S___]J`(U'!%"+
-M10C_<`SH_/___VH`C4<(4(M5"/]R#.C\____@\0D:@"-1PQ0BT4(_W`,Z/S_
-M__]J`(U'$%"+50C_<@SH_/___VH`C4<44(M%"/]P#.C\____@\0D:@"-1QA0
-MBU4(_W(,Z/S___]J`(U''%"+10C_<`SH_/___VH`C4<D4(M5"/]R#.C\____
-M@\0D:@"-1R!0BT4(_W`,Z/S___]J`(U'+%"+50C_<@SH_/___VB\````C4<T
-M4(M%"/]P#.C\_____D7S@\0D@'WS`P^&Q?[__S';@'WR``^5PTN!XP``__^!
-MPP```P!J`(U##%"+50C_<@SH_/___VH`C4,04(M%"/]P#.C\____:@"-0Q10
-MBU4(_W(,Z/S___^#Q"1J`(U#&%"+10C_<`R#PR#H_/___U.+50C_<@SH_/__
-M_R4<'!P<#0,#`P-04XM%"/]P#.C\_____D7R@\0@@'WR`0^&+O[__XUE]%M>
-M7\G#B?95B>5H___/#VAL!`$`BT4(_W`,Z/S____)PXGV58GE4XM="(M#!##`
-M/0``@%!T(6@L#0``_W,,Z/S___^#R`%0:"P-``#_<PSH_/___X/$%&@`#0``
-M_W,,Z/S___\E__\`_U!H``T``/]S#.C\____:@!H!`T``/]S#.C\____@\0@
-M:@!H.`P``/]S#.C\____:/\``0!H!!T``/]S#.C\____:@!H9!T``/]S#.C\
-M____@\0D:@!H*`P``/]S#.C\____:@!H6!T``/]S#.C\____:@!H7!T``/]S
-M#.C\____@\0D:@!H0!T``/]S#.C\____:@!H1!T``/]S#.C\____:@!H2!T`
-M`/]S#.C\____@\0D:@!H4!T``/]S#.C\____BUW\R<.-=@!5B>6+30R+50C'
-M00@`````BX)("0``B4$,BX)("0``A<!T`XE("(N"1`D``(7`B8I("0``=0:)
-MBD0)``#)PXGV58GEBTT,4XM1"(72BUT(=4N+00R%P(F#2`D``'0'QT`(````
-M`(M1"(M!#(7`=26%THF31`D``'0'QT(,`````,=!"`````#'00P`````BQPD
-MR<.0B5`(Z^>-=@"+00R)0@SKQ%6)Y5=64XM=$(L#A<"+?0B+=0QU,VH@C4,$
-M4(U&%%#H_/___XL#@\0,B4805E?H*?___\<&`````/Z'/`(``(UE]%M>7\G#
-MD&HDC4,$4(U&%%#H_/____Z'4`D``.O%D%6)Y593BW4,BT80A<"+70AT!OZ+
-M4`D``%93Z!W___^+@]0)```/ME8$B92#5`D``,<&`0```$")@]0)``#^BSP"
-M``"-9?A;7LG#B?95B>6*10@\`W82#[;(C4P)`K@!````T^#)PXGV#[;(C4P)
-M`>OLC78`58GE5U93#[9]#(GX#[;PBUT(5NC`____"4-4B30DZ,WI__\%'`$`
-M`(D$)/]S#.C\____B?F#X0.X``$``-/@@^<$]]!0B?B$P`^5P`^VP$@E``#_
-M_P44``,`4/]S#.C\_____W-4:&0=``#_<PSH_/___XM##,=%#&0=``")10B#
-MQ""-9?1;7E_)Z?S___^058GE#[9%#%-0Z#K___^+70CWT"-#5(E#5(D$)&AD
-M'0``_W,,Z/S___^+7?S)PXGV58GE5U934HI5#(M%"`^VRHM<B"2)3?")T8MX
-M#(/A`[@!`0``T^"#X@3WT(MS,,>#-`(```$```!0,<"$T@^5P$@E``#__P44
-M``,`4%?H_/___VH`BT,P@\`(4%?H_/____]U\/]U".AD____@\0@C88<`0``
-M4%?H_/___X/&*,>#0`(```$```!J`597Z/S___^-9?1;7E_)PXGV58GE5U93
-M48MU"`^V10R)1?"+1(8DBU@PBWX,QX`T`@```````(/#*&H"4U?H_/___U-7
-MZ/S___^+5?")50R)=0B#Q!2-9?1;7E_)Z53^__]5B>564XM="(M#*(MP#/]U
-M$/]U#%.+@]@)``#!X`4#0Q!0Z%'I__^+D]@)``!"BT,<@^(?B9/8"0``)0#\
-M___!X@4)T/Z#40D``(E%$(M#,(/`%(E%#(EU"(/$$(UE^%M>R>G\____D%6)
-MY5-J`&H":@"+70A3Z"7W__]3Z)?U__]3Z/S___^#Q!A(=`>+7?S)PXGV#[8#
-MQX-,"0```0```%#_<RCHJOW__UM8Z]^)]E6)Y5=64X/L'(M5"(M"*(MZ,(M8
-M#(V''`$``%!3BW4,B47LZ/S___^#X,%:@\84,=(\0%ET"HUE]%M>B=!?R<.#
-M?@0!#X1&`0``]T80`/\`_W41]T84`/\`_W4(9O=&&`#_=`0QTNO.C8<$`0``
-MB47HC8<(`0``B47DC8<,`0``B47@C8<0`0``B47<C8<4`0``B478#[9&$%#_
-M=>A3Z/S___\/MD824/]UY%/H_/___P^V1A10_W7@4^C\____@\0D#[9&%E#_
-M==Q3Z/S___\/MD884/]UV%/H_/___P^V1AI0C8<8`0``4%/H_/___X/$)`^V
-M1AM0_W7L4^C\____@\0,@SX"=`JZ`0```.DC____C8<@`0``4%/H_/___VID
-M:@I74^C\____@\08,=*%P`^$_O[___]U[%/H_/___X/@B5HQTCP(60^%YO[_
-M_\=%\`````"!QP`!``"-=@"+1@@/MQ!2@\`"B48(5U/H_/____]%\(/$#(%]
-M\/\```!VW8%N#``!``#I>O___Y`/MD814(V'!`$``%!3B47HZ/S___\/MD83
-M4(V'"`$``%!3B47DZ/S___\/MD854(V'#`$``%!3B47@Z/S___^#Q"0/MD87
-M4(V'$`$``%!3B47<Z/S___\/MD894(V'%`$``%!3B478Z/S___^#Q!CID?[_
-M_U6)Y5=64U"+70C'0U0`````:@!H9!T``/]S#.C\_____W,,Z/S___^#Q!`Q
-MTH3`B$,$=$:+0R"%P,=#7`````#'0V``````QT-D`````,=#:`````#'0VP`
-M````QT-P`````,=#=`````#&0W@!=`AF@7L&@5!T##'2C67T6UZ)T%_)PP^V
-M0P4QTH/X`73K@_@!#XY3`@``@_@"#X0^`@``QT-H`0```#'V,?^)\HGP@^(#
-M@^`$P>((A,`/A!,"``"-@G0!`P!0_W,,Z/S___^)PH'BX````"4`&```P>@+
-MP>H%B%0[>HB$.X(```!&65B)\$<\!W:T4^@6]O__4^CX]___4^@.^/__:@!H
-M\`0!`/]S#.C\____:"P-``#_<PSH_/___XG'@\0@@^?^5V@L#0``_W,,Z/S_
-M__^#Q`QH``T``/]S#.C\____B<>#YS!86@^$<@$``(M#1*G@`P"`=`@E'_S_
-M?XE#1(-[7`$/A#T!``"#>V`!#X0S`0``@WMD`0^$*0$``(-[:`$/A!\!```Q
-M]C'_D%=31NCL\___68GQ1X#Y!UAV[O]S1&@`#```_W,,Z/S_____<TAH*`P`
-M`/]S#.C\_____W-,:%P=``#_<PSH_/___S'V@\0D,?^)\(3`#Y7`#[;`2"4`
-M`/___W2[$`4,``,`4/]S#.C\____B?$QP(3)#Y7`2"4``/___W2[&`40``,`
-M4/]S#$;H_/___XGP@\081SP!=K+'0U15JP8`,?8Q_XGV5U-&Z.#C__^)\5A'
-M@/D'6G;N:%##``#H_/___X-[9`%>=!"#>V@!=`JZ`0```.D+_O__,?\Q]L=%
-M\`````")]O]U\%/H_/___X7`6EEU#+@``0``BDWPT^`)QT:)\/]%\#P'=MM7
-M:`#_``!3Z._I__^#Q`SKLXM#1*D0````#X33_O__@^#OB4-$Z<C^__^#8T3/
-MZ;_^__^-@G0!`@#IZ/W__\=#9`$```#IO?W__X7`#X6N_?__QT-@`0```.FI
-M_?__D%6)Y6H`BT4(:&0=``#_<`SH_/___[@!````R<-5B>7'!0`````!````
-MR<.058GEQP4``````````,G#D%6)Y593BW4(#[9%#(M<AB2%VW0P4.@ZXO__
-M6HE#,(ES*,>#3`D```````#'@S0"````````B5T(C67X6U[)Z>7O__^0C67X
-M6S'`7LG#C78`58GEBT4(#[95#(M4D"0QP(72=`PQP(.Z3`D```$/E<#)PXGV
-M58GEBD4,B<*#X@.#X`16P>((A,!3BW4(C9H``0,`=0:-F@`!`@!3_W8,Z/S_
-M__^#X`]9@_@!6G0;@_@!<@6#^`-T"3'`C67X6U[)P[@!````Z_*04_]V#.C\
-M____:$`-`P#H_/___U/_=@SH_/___X/@#X/$%.O&58GE5U93@^P4BD4,B$7S
-M@^`#B$7GBD7S@^`$P.@"BW4(#[9]\XA%YHM4OB2+1@R)1>PQP(72#X1$`0``
-MBT(P@[I,"0```8E%Z`^$+P$``%=6Z.;A__^+7>AJ!(/#*%/_=>SH_/___U/_
-M=>SH_/___VH9Z/S___^#Q"!J`%/_=>SH_/___U/_=>SH_/___U=6Z,_P__\/
-MMD7GP>`(,?^#Q!R)1>"`?>8`#X0N`0``BT7@!0@!`P!0_W8,Z/S___^)PX/C
-M\`^V1>>#RP'!X`B`?>8`4P^$]P````4(`0,`4/]V#.C\____#[9%Y\'@"(/$
-M%(!]Y@`/A,D````%"`$#`%#_=@SH_/___VH9Z/S___\/MD7G@^/PP>`(@'WF
-M`%,/A),````%"`$#`%#_=@SH_/___P^V1>?!X`B#Q!B`?>8`=&T%"`$#`%#_
-M=@SH_/___VC0!P``Z/S___\/MEWS4U;H_/___X/$%(7`=1M'@_\##X4M____
-M4U;H?N#__S'`C67T6UY?R<.+1>@%'`$``%#_=>SH_/___X/@P%D\0%]UU5-6
-MZ%/@__^X`0```.O0!0@!`@#KD9`%"`$"`.EH____B?8%"`$"`.DR____B?8%
-M"`$"`.D$____B?:+1>`%"`$"`.G-_O__C78`58GE5U934XM5"`^V10R+7((D
-M,<F%VP^V=11T98M2#(.[3`D```&)5?"+>S!T>E?_=?#H_/___XG"6(M%$(7`
-M6752C4;_,<D\'W<VB?$/ML&#XL!("<*!R@`"``#'@S@"````````@WL,`70?
-M@>+__O__4E?_=?#H_/___[D!````C67T6UZ)R%_)PX'*``$``.O?D,>#.`(`
-M``$```"!XL#]___KP(GV,<GKU56)Y0^V30Q3BUT(BU2+)#'`A=)T'X.Z3`D`
-M``%T'L>"3`D```$```!14^AQ]?__N`$```"+7?S)PXUV`#'`Z_15B>4/MDT,
-M4XM="(M4BR0QP(72=0>+7?S)PXGVQX),"0```````%%3Z,_U__^X`0```.OA
-M58GEBT4(4P^V50R+7)`D,<"%VW0A@[M,"0```70>:@!J`O]U$%/HC>W__U/H
-M_^O__[@!````BUW\R<.0,<#K]E6)Y8M%"`^V50R+5)`DA=*X_P```'0'#[:"
-M/`(``,G#58GE5E.+50@/MD4,BW(,BU2")#')A=)T'(M:,(/#+%-6Z/S___]:
-M@WT0`5ET)C')@^`"=0N-9?A;B<A>R<.)]FH`4U;H_/___X/$#+D!````Z^*0
-M,<F#X`)UVFH"Z^.058GE5U934XI=#(C8@^`$#[9U$(C:@^(#P.@"]\;X````
-M#[9]%'4(]\?\````=`TQP(UE]%M>7\G#C78`#[;2P>((A,!T:H'"=`$#`(E5
-M\/]U\(M%"/]P#.C\____B?+!X@6!XN`````E'____PG0B?K!X@LE_^?__X'B
-M`!@```G"4O]U\(M5"/]R#.C\____#[;#B?F+50B(C`*"````B?&(3`)Z@\04
-MN`$```#K@I"!PG0!`@#KE%6)Y5=64[\#````BET,(=^#XP3`ZP(/E<`/ML!(
-M)0``__\%&``#`%"+=0C_=@SH_/___XGY#[;1C4H8N@$```#3X@G"B=B#X`%(
-M)0``__^#XP%2!1@``P!+4('C``#___]V#('#&``#`.C\____4_]V#.C\____
-M@\0<C67T6UZX`0```%_)PY!5B>575E-6BD4,B$7SBE7S@^`#B$7R@^($#[9%
-M\U"+?0C`Z@)7B=;H+.S__XGP@^`!2"4``/__!1@``P!0_W<,Z/S___\/MEWR
-MC4L8NO[____3PB'"B?"#X`%()0``__]2!1@``P!0_W<,Z/S___^)\(/@`4@E
-M``#__P48``,`4/]W#.C\____B=B)\L'@"(/$)(32=%8%"`$#`%#_=PSH_/__
-M_X/@\(/(`5")\@^V1?+!X`B$TG0L!0@!`P!0_W<,Z/S___\/MD7S4%?HA^O_
-M_X/$'(UE]%M>N`$```!?R<.-=@`%"`$"`.O2D`4(`0(`ZZB058GE5U93@^P(
-M#[9]#(M%"(M`#(GZB47P#[;"BU4(BUR")(GZB?B#X@.#X`3!X@B$P(MU$`^$
-M$`$``(V"=`$#`%"+10C_<`SH_/___XE&6%F%VU@/A.D```"+4S")5>R)^@^V
-MPE#_=0CH_/___XD&7X7`6@^$O````(N#3`D``(E&+(N#.`(``(E&,(J#/`(`
-M`(A&-#'2B?:*1!IJB$0R!$*#^B=V\O]U[/]U\.C\____B48XBT7L@\`04/]U
-M\.C\____B48\BT7L@\`44/]U\.C\____B49`BT7L@\`84/]U\.C\____B49$
-MBT7L@\0@@\`<4/]U\.C\____B49(BT7L@\`@4/]U\.C\____B49,BT7L@\`D
-M4/]U\.C\____B490BT7L@\`H4/]U\.C\____B494C67T6UZX`0```%_)P\<&
-M`````.OKC8)T`0(`Z>O^__^-=@!5B>6#[#"+11")1=2+112)1=R+11AFB47@
-MBT4<9HE%XHM%((E%Y(M%)(E%Z(M%*(U5T(E%[(M%+%*)1?`/MD4,4/]U",=%
-MT`````#H_/___\G#B?95B>575E.#[`B*10P/MOB(1?.+10B+=+@DA?:X!```
-M``^$L````(N.3`D``(7)#X1$`0``@+X\`@``'P^$3P$``(N&U`D``$B+G(94
-M"0``B8;4"0``C03=`````"G8C83&1`(``(E%[(A8!(M%$(L0A=(/A<````")
-MQX/'!(.^.`(```(/A*(````/MT<,#[=7#E#_=PA2_W8(Z!7:__^)1P2#Q!!(
-M=&*`OE`)````=4B+AC0"``"%P'0C_W40_W7L5N@Q[O__5_]U[%;HI_#__X/$
-M&#'`C67T6UY?R<,/MEWS4_]U".AQ[___4_]U".B8[___@\00Z\+_=1#_=>Q6
-MZ//M__^#Q`SKRHM&"(7`=9>+AM0)``")G(94"0``0(F&U`D``+@#````ZZK'
-M1P0!````Z7#_____=1#_=>Q6Z+3M__^#Q`R`OCP"```!=82#OC0"```!="G_
-M=>Q6Z,;P__^%P%I9#X5H_____W7L5NCC[?__C78`N`$```#I5/___U?_=0CH
-MG>___UM?Z\J0N`(```#I//___XGV58GE5U93@^P4BT4(BT`,:&`=``!0B47D
-MZ/S___^+50B)QHM25%DQP(76B57P6W0U]\8```0`#X4=`0``QD7K`,=%X```
-M``#WQO\!``!U(<'N"/Y%Z]'N_T7@@'WK`7;GN`$```"-9?1;7E_)PXUV`#';
-M@'WK``^5PTN!XP``__]J[X'#%``#`%/_=>3H_/___U/_=>3H_/___XE%[/?0
-M@\@04%/_=>3H_/___X/$(#'`@'WK``^5P$@E``#__P4(``,`4/]UY.C\____
-MB<=8QD7J`%H/MDWJNP`!``"X`0```-/CT^")\B-=[(/B`2-%['4$A=)T&O]U
-M[%)0B?B#X!]04?]UX/]U".BRWO__@\0<A=MT&(M%X,'@`@I%Z@^VP%#HX>S_
-M_X5%\%MU%_Y%ZL'N`L'O"(!]Z@-VF.D1____C78`#[9%ZE#_=>#_=0CH0.'_
-M_X/$#.O4:%@=``#_=>3H_/___XG#]]!0:%@=``#_=>3H_/___VH`4VH`_W4(
-MBU4(_U(@@\0DZ:[^__^)]E6)Y6H`BT4(:&0=``#_<`SH_/___[@!````R<-5
-MB>6+10C_<%1H9!T``/]P#.C\____N`$```#)PXUV`%6)Y5=64XM]$#';.?MS
-M)HM%#(VP'`$``%;_=0CH_/___X3`6EEY&/]U%$/H_/___SG[6'+C,<"-9?1;
-M7E_)PX/@`8/P`0^VP.OMB?95B>53:@"+70B+0S`%(`$``%"+0RC_<`SH_/__
-M_XM#,`4@`0``4(M#*/]P#.C\____BUW\R<.)]E6)Y5-J`HM="(M#,`4@`0``
-M4(M#*/]P#.C\____BT,P!1P!``!0BT,H_W`,Z/S___^+7?S)PXGV58GE5U93
-M4XM5"(M"*(MP##';BT(P@[HT`@```8E%\'1#BWWP@<<@`0``5U;H_/___ZF!
-M````6EEU8(GV5U;H_/___ZF!````6EET(HG80V8]MPMW#VCH`P``Z/S___]8
-MZ]J)]C'`C67T6UY?R<-J9&H*_W7P5NC\____BT7P!1P!``!05NC\____@^#!
-M@\08/$`/E,`/ML#KS&HRZ[R)]E6)Y5=6BT4(4P^V50R+7)`D,<"%VW1'BT,H
-M@[M,"0```8MX#(MS,'0S4^C\____:.$```"-AAP!``!05^C\____:F1H$"<`
-M`%97Z/S___^#Q""%P'424^C\____,<"-9?1;7E_)PXGV4^C\____N`$```#K
-MZ8UV`%6)Y593BTT(#[95#(M$D20Q]H7`=$=H[````&H`:@!J`&H`:@!J`&@`
-M`0``C5@T4VH`:@%24>C\____,?:#Q#2%P'09]H.@````X'0+,<F`N_X!``"E
-M=`Z^`0```(UE^%N)\%[)PS'2B=B)]D(""$!F@?K_`7;U,?:$R77@Z]F058GE
-M#[95#(M%"(M$D"2%P'02@[A,"0```70)B44(R>G\____,<#)PU6)Y6CO````
-M:@`/MD4@4`^V11Q0#[9%&%`/MD444`^V11!0:@!J`&H`:@`/MD4,4/]U".C\
-M____R<.)]E6)Y5=64X/L'(M%"(E%\(M%$(E%[(M%%(E%Z(M%&(E%Y(M%'(E%
-MX(M%(&:)1=Z+121FB47<BD4XB$7;#[9=#(M%\(M$F"2%P(M]*(MU+(M-,(I5
-M-'4*@\0<6UXQP%_)PP^V1=N)13@/ML*)130/M\&)13`/M\:)12P/M\>)12@/
-MMT7<B44D#[=%WHE%((E=#(/$'%M>7\GI_/___U6)Y5=64X/L<(M5(&:)5>2+
-M52AFB57$BU4P9HE5I(I5.(M%"(M-)(A5H@^V50R+7)`D9HE-U(M-+&:)3;2+
-M<`R*332+>S!3B$VCZ!G]__]:,=*%P'4*C67T6UZ)T%_)PU/H_/___X-]%`%8
-M#X3'`0``]T7D`/\```^%^@```/=%U`#_```/A>T```#W1<0`_P``#X7@````
-M]T6T`/\```^%TP```(V'!`$``(V7"`$``(E%E(E5D(V/#`$``(V'$`$``(V7
-M%`$``/=%I`#_``")38R)18B)580/A9D````/MD7D4/]UE%;H_/___P^V1=10
-M_W605NC\____#[9%Q%#_=8Q6Z/S___^#Q"0/MD6T4/]UB%;H_/___P^V1:10
-M_W6$5NC\____#[9%HU"-AQ@!``!05NC\____@\0D#[9%HE"-CQP!``!15HE-
-MF.C\____BTT0@\0,A<EU,VID:/"Z!`!75NC\____@\00A<!U#E/H_/___Y`Q
-MTNG7_O__4^C\____N@$```#IQ_[__VID:/"Z!`!75NC\____@\00A<!TS?]U
-MF%;H_/___X/@"%F$P%ITN\=%G`````"+11PY19QS,H!]G`!T4X-]$`%T,HM5
-MG(M-&`^W!%%0C8<``0``4%;H_/___X/$#/]%G(M%'#E%G'+.:F1H4,,``.E@
-M____C8<``0``4%;H_/___XM5G(M-&&:)!%%86NO.:F1H4,,``%=6Z/S___^#
-MQ!"%P'68Z3G___^+3>0/ML50C8<$`0``4%:)193H_/___XM5U`^VQE"-CP@!
-M``!15HE-D.C\____BU7$#[;&4(V/#`$``%%6B4V,Z/S___^+5;2#Q"0/ML90
-MC8\0`0``45:)38CH_/___XM5I`^VQE"-CQ0!``!15HE-A.C\____@\08Z2G^
-M__^)]E6)Y5=64XM="(M#*(MS,(MX#&H&C88@`0``4%?H_/___XM#,`4@`0``
-M4%?H_/___VH*Z/S___]3Z/S___]H]`$``.C\____@\0@:/0!``#H_/___VCT
-M`0``Z/S___]H]`$``.C\____,=N#Q`R!QAP!``"05E?H_/___X3`6EFZ`0``
-M`'D6:/0!``!#Z/S___^!^P\G``!9=MHQTHUE]%M>B=!?R<.)]E6)Y5.+70A3
-MZ$O___](6G07:/0!``#H_/___UB)70B+7?S)Z3#___^X`0```(M=_,G#B?95
-MB>564VB@````H0````"+0!@%```$`%"+=0A6Z/S___^[!````(/$#*$`````
-MBT`0!0``!`!05NC\____64M8>>>[!0```)"A`````(M`%`4```0`4%;H_/__
-M_UA+6GGGNP0```"A`````(M`$`4```0`4%;H_/___UE+6'GGC67X6U[)PXGV
-M58GE4VB`````H0````"+0`P%```$`%"+70A3Z/S___]HL````*$`````BT`8
-M!0``!`!04^C\____BUW\R<.)]E6)Y593BW4(5N@J____:@"A`````(M`"`4`
-M``0`4%;H_/___Z$`````BP`%```$`%!6Z/S___^(PU;H@?___P^VVXUE^(G8
-M6U[)PY!5B>575E-H+`T``(M="%/H_/___XG'@\@!4&@L#0``4^C\____:/`$
-M`0!3Z/S___^)QH/@8H/$'&:#^&)T%XGP@\AB#[;`4&CP!`$`4^C\____@\0,
-M:```!`!3Z/S___]86E/HA/[__VH'H0````"+0`@%```$`%!3Z/S___]J$:$`
-M````BP`%```$`%!3Z/S___]J!:$`````BT`(!0``!`!04^C\____@\0H:A&A
-M`````(L`!0``!`!04^C\____4^BM_O__5FCP!`$`4^C\____:/`$`0!3Z/S_
-M__^#Q"17:"P-``!3Z/S___^#Q`R-9?1;7E_)PU6)Y5=64V@L#0``BUT(4^C\
-M____B<>#R`%0:"P-``!3Z/S___]H\`0!`%/H_/___XG&@^!B@\0<9H/X8G07
-MB?"#R&(/ML!0:/`$`0!3Z/S___^#Q`QH```$`%/H_/___UE84^B,_?__:@>A
-M`````(M`"`4```0`4%/H_/___VH`H0````"+``4```0`4%/H_/___VH%H0``
-M``"+0`@%```$`%!3Z/S___^#Q"AJ`*$`````BP`%```$`%!3Z/S___]3Z+7]
-M__]6:/`$`0!3Z/S___]H\`0!`%/H_/___X/$)%=H+`T``%/H_/___X/$#(UE
-M]%M>7\G#58GE4XM="%/H[_S__VH*H0````"+0`@%```$`%!3Z/S___]J`*$`
-M````BP`%```$`%!3Z/S___]3Z$;]__^#Q"!H`0`$`%/H_/___X/@`EJ$P%FZ
-M_____W0*B="+7?S)PXUV`%/HDOS__VH!H0````"+``4```0`4%/H_/___U/H
-M__S__VIDZ/S___]H`0`$`%/H_/___X/@`C'2@\0@A,`/E<)*Z[.058GE5U93
-M@^P(BT4(BU@,BWT,:"P-``!3B?J(5?/H_/___XE%[(/(`5!H+`T``%/H_/__
-M_VCP!`$`4^C\____B<:#X&*#Q!QF@_AB=!>)\(/(8@^VP%!H\`0!`%/H_/__
-M_X/$#&@```0`4^C\____6%J+10B)^HA0>0^V1?-0:`#@!0!3Z/S___]6:/`$
-M`0!3Z/S___]H\`0!`%/H_/___X/$(/]U[&@L#0``4^C\____@\0,C67T6UY?
-MR<-5B>6`?1``BU4(BDT,=!VX`0```-/@"$)Y#[9">8E%#(E5",GI_/___XUV
-M`+C^____T\`@0GGKX56)Y5=64X/L#&@L#0``BW4(5L9%\P#H_/___XE%Z(/(
-M`5!H+`T``%;H_/___VCP!`$`5NC\____B47LBT7L@^!B@\0<9H/X8G08BD7L
-M@\AB#[;`4&CP!`$`5NC\____@\0,:```!`!6Z/S___]96V@```0`5NC\____
-MB<-F@?M5JEA:=%)HL````*$`````BT`8!0``!`!05NC\_____W7L:/`$`0!6
-MZ/S___]H\`0!`%;H_/___X/$(/]UZ&@L#0``5NC\____#[9%\X/$#(UE]%M>
-M7\G#,?^-=@"%_W@CC5\!D&B@````H0````"+0!@%```$`%!6Z/S___^#Q`Q+
-M=>&!_\@````/CYT```!H```$`%;H_/___XG#:+````"A`````(M`&`4```0`
-M4%;H_/___X/$%&:!^U6J=1%'@?_'````?I3I./___XUV`&BP````H0````"+
-M0!@%```$`%!6Z/S___]H```$`%;H_/___X/$%&8]5:H/A03___]6QD7S`>B=
-M^O__/#Y;#X7Q_O__5NC*_/__A<!9#X7B_O__QD7S`NG9_O__:@'H_/___UCI
-M5O___XUV`%6)Y593BW4(,=N)]E;'!0````"(````Z"C^__^$P%EU'E;'!0``
-M``"D````Z!/^__^$P%IU"4.!^^<#``!^S8UE^%L/ML!>R<,`````````````
-M``````````````0`````````````````````````````````````````````
+begin 644 hptmvraid.o
+M?T5,1@$!`0D```````````$``P`!``````````````#(O@```````#0`````
+M`"@`#``)`%6)Y5=64X'L'`(``(M]"(M'#(F%Y/W__XUWQ+`"@'\!`'4*@'\"
+M`1G`@^`"0(@&QT8$`````(!.`02+1PR)1@B+5Q")5@P/M@:+!(4`````B48T
+M@#X#=2R-0O:)1@R-E>C]__]2:B"+1Q"#Z`I05^C\____@\00@;WH_?__\Q9X
+M6G07D`^V!HL$A0````")1CB`3@$$Z;8$``"#[`AHD````(V-Z/W__U'H_/__
+M_X/$$(3`=<_VA?']__\"="+&1P@!BH7R_?__B$<+.D<)<Q"#[`@/ML!05^C\
+M____@\00@^P(:``"``"-A>C]__]0Z/S___^#Q!"$P'0>@^P$:'`!``!J`(V%
+MZ/W__P60````4.C\____@\00BI5[_O__B-.#XP&*1P2#X/R(T8/A`@G8"<B(
+MTX/C!(/@\XC1@^$("=@)R(C3@^,0@^#/B-&#X2`)V`G(B-&#X4"#X#^#XH`)
+MR`G0B$<$BI7Q_?__@^(!BD8!@^#^"="(1@&`O?C]__\##X3\_O__@+WX_?__
+M`'40Q@8`H0````")1CCIKP,``(.][/W__P`/A-;^__^Z``````^VA?/]__^)
+MP8/X`'XONP````")T,'@!(V]Z/W__P'X@'@0"`^'I_[__P^V0!"#/(,`#X29
+M_O__0CG1?]:+A0#^__^)A=S]__^Z`````(T$4HT$P(N-Y/W__XV<P6`B``"#
+M>P0`=0^+0T`[A>S]__\/A"$!``!"@_H/?M*+O>3]__^+GUPB``"%VW0?BT,(
+MB8=<(@``@^P$:-@```!J`%/H_/___XE["(/$$(N%[/W__XE#0(I32H/*`8A3
+M2F8/MH7\_?__@^`!T>"#XOT)PHA32F:+A?[]__]FB4-,BX7<_?__B4-0BH7X
+M_?__B`.*A?O]__^(0SX/MLBX`0```-/@9HE#2,=#!`````"+A?3]__^)0PR*
+MA?G]__^(0SP/M@.+!(4`````B4,T@^P$:A"-A>C]__^#P"Q0C4-T4.C\____
+M@\0,:@2-A>C]__^#P#Q0C8.$````4.C\____@\0,:A"-A>C]__^#Z(!0C8/(
+M````4.C\____@\0,:D"-A>C]__^#P$!0C8.(````4.C\____@\00BY7<_?__
+M.5-0=@.)4U#VA?']__\!=`2`2P$!BHWZ_?__B(WC_?__@+WS_?__`0^&HP$`
+M``^VP8M\@U2+A1#^__^)A=S]__^%_P^%/0$``(N5Y/W__XNZ7"(``(7_="6+
+M1PB)@EPB``"#[`1HV````&H`5^C\____BXWD_?__B4\(@\00BX7L_?__B4=`
+MBE=*@\H!B%=*9@^VA0S^__^#X`'1X(/B_0G"B%=*9HN%#O[__V:)1TR+A=S]
+M__^)1U"*A0G^__^(1SR*A0C^__^(!XE?!(N%!/[__XE'#(J%"_[__XA'/@^V
+MR+@!````T^!FB4=(#[8'BP2%`````(E'-`^V`XL$A0````")1SB*E>/]__^(
+M5P,/ML*)?(-4_D,]@^P$:A"-A>C]__^#P"Q0C4=T4.C\____@\0,:@2-A>C]
+M__^#P#Q0C8>$````4.C\____@\0,:A"-A>C]__^#Z(!0C8?(````4.C\____
+M@\0,:D"-A>C]__^#P$!0C8>(````4.C\____@\00]H7Q_?__`70$@$\!`0^V
+MA0K^__^#?(=4`'5?B72'5(J%"O[__XA&`_Y'/8E^!`^V!XL$A0````")1CB+
+MC=S]__\Y3U!V-(E/4.LO#[:%X_W__X-\@U0`=2&)=(-4B5X$_D,]BH7C_?__
+MB$8##[8#BP2%`````(E&.)"-9?1;7E_)PU6)Y593BW4,NP`````/MD8\B<*#
+M^``/CJ@```"#?)Y4`'0*0SG:?_3IEP```+@!````B-G3X&8)1DR#[`A6_W4(
+MZ/S___^)PH/$$(7`='7&``.(6`.)<`2`/@@/E,#!X`.*2@&#X?<)P8A*`:$,
+M````B4(T#[8&BP2%`````(E"./9&`1!T#HC(@\@0B$(!BT),B4(,B52>5(I&
+M2H/@_H/("HA&2L=&4`````#^1CV#[`A2:@?H_/___X!.2@2#Q!"-=@"-9?A;
+M7LG#D%6)Y5=64X/L#(MU#`^V!H/X!G1\@_@&?PN#^`0/C%(!``#K$(/X"`^$
+MNP```.E"`0``B?:*1CTZ1CP/A30!``"`3@$$@&9*_K\`````@'X\``^$'0$`
+M`)"+7+Y4A=MT((`[`W8;@^P(4_]U".C\____@\00]D-*!'0&@$Y*!(GV1P^V
+M1CPY^'_/Z>8```")]H!.`02`?CT"=0J`9DK^Z=$```"0@&9*_8-^5`!U$8M&
+M6,9``P")1E3'1E@`````BT94@#@#=1&#[`A6_W4(Z/S___^#Q!")]H!.2@3'
+M1E``````Z8P```"*1CTZ1CQU'(!.`02*1DJ#X/Z(1DIF@WY,`'1D@\@"B$9*
+MZUP/MD8]0`^V5CPYT'5/9H-^3`!T(;D`````#[=&3(G"J`%U"4&)T-/XJ`%T
+M]X-\CE0`=1_K!O9&2@)U%X!.`02`3DH$@^P(5O]U".C\____@\00QT90````
+M`(UV``^W1DCWV"%&4(UV`(-^!`!U&O9&2@1T%.C\____B49`@^P,5NC\____
+M@\00C67T6UY?R<-5B>575E.#[`R+?0B^`````(UV`(T$=HT$P(V<QV`B``"#
+M>T``="&#>P0`=1N#[`A35^C\____@\00]D,!!'0(QT,X`````)!&@_X/?L:-
+M9?1;7E_)PXGV58GE5U93@>PH`@``BWT,BD40B(7G_?__5^C\____@\00@#\(
+M=1*#[`A7_W4(Z/S___^#Q!"-=@"^`````(!_/``/AL4```"0@WRW5``/A*T`
+M``"+1+=4@#@#=B"#[`0/MH7G_?__4/]TMU3_=0CH_/___X/$$.F%````D(M<
+MMU3&0P,`QT,$`````,=#4`````"`8P'^QT,X`````("]Y_W__P!U#H`_!G4)
+M@W\$`'0RC78`@^P$:``"``!J`(V5Z/W__U+H_/___XV%Z/W__U!J,&H`C4,\
+M4.C\____@\0@ZQ&*5P&#X@&*0P&#X/X)T(A#`8/L#%/H_/___X/$$$:)\CA7
+M/`^'//___X/L!&C8````:@!7Z/S___^+50B+@EPB``")1PB)NEPB``#'1T``
+M````@\00C67T6UY?R<-5B>575E.![!P"``"+50R+?1"+312+`HM8!(F=Y/W_
+M_XM:((M3%(F5X/W__P^V0`.)A=S]__^-E>C]__^#O>#]__\`=`QF#[9#$(/@
+M`3G(=2:)E>#]__^#>Q@`=!!14E/_=0C_4QB#Q!"%P'4*N`````#IE@````^W
+M0RS!X`D/MG,HB?:+E>#]__^+&KD```$`9H-Z!`!T!`^W2@2)PCG(=@*)RCNU
+MW/W__W409HE7!&;'1P8``(D?@\<(D"G1`=,IT'4A1HN5Y/W__P^V0CPYQG4%
+MO@````"+E>3]__\/MT)(P>`)A<EULXN=X/W__V:!>P8`@'0+@\,(B9W@_?__
+MZX)FQT?^`("X`0```(UE]%M>7\G#C78`58GE5U93BT4(BTT,BW@$BW$DBE`#
+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
+MR<.058GE5U93@^P,BWT0BTT4BU4,BT(@A<ET0XM0#(D7BTT,9HM!",'@"6:)
+M1P1FQT<&`("+`8!X`P`/A/(```"-@@```0!F@W\$`'0'#[='!(T$`HD'Z=<`
+M``"-=@")^XM5#`^W<@C!Y@F#>!0`=";V0!`!=""+2!20BP&+402)`XE3!(/#
+M"(U!!H/!"&:#.`!YY^LUD+H`````@W@8``^$D@```%%74/]U"/]0&(/$$+H`
+M````A<!T?>L.9HEQ!&;'008`@.L]B?:)^8GVN@```0!F@WD$`'0$#[=1!(M=
+M#(L#@'@#`'01.?)V$0$QB=!F*?!FB4$$ZPLY\G.^@\$(*=9UR8M5#(L"@'@#
+M`'0B.<]T'HGVBP&+402)!XE7!(/'"(U!!H/!"&:#.`!YYXUV`+H!````B="-
+M9?1;7E_)PY!5B>575E.#[`R+?0B+=0R+7B"`?A$!=`B*1A&(0Q'K<(L&@'@#
+M`'4LQD81`(L#BT!8B0:#[`1J,&H`C48D4.C\____QD82`(/$"(L&5E?_4#3K
+M<)"#[`0/MT8(P>`)4`-##%#_<PSH_/___X/$$(7`=`;&0Q$,ZQC&0Q$!BPN+
+M45`[5@1U"@^W1@@!T(E!4)"#[`A65^C\____@\0,4_]S'%?H_/___XL#9L=`
+M%```@\0,BP.#P!A0:`````!7Z/S___^-9?1;7E_)PY!5B>575E.#[`R+?0B+
+M70R+,\=&'`````#V1DH!#X5:`0``#[9#"H/X`@^$^0```(/X`G\0@_@!#X27
+M````Z3H!``")]H/X`P^%+P$``(M#!(E&$&:+0PAFB484@^P$#[=#",'@"5!J
+M`/]S#.C\____9L=#,@,`QT7P`````(/$$(/L#%?H_/___XG"QD`*,(M#!(E"
+M!&:+0PAFB4((@$H0!(E:(,="'`````#'0A@`````BTWPBT2.5(D"@\0(4E?_
+M4#2#Q!#_1?"#??`!?K'IO````(M#!(E&$&:+0PAFB484@^P,5^C\____B<+&
+M0`H@BT,$B4($9HM#"&:)0@B`2A`"B5H@QT(<`````,="&`````"+1E2)`H/$
+M"%)7_U`T@\00ZVJ)]HM#!(E&$&:+0PAFB484@^P,5^C\____B<+&0`H@BT,$
+MB4($9HM#"&:)0@B`2A`"B5H@QT(<`````,="&`````"+1E2)`H/$"%)7_U`T
+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
+MPXGV58GE4XM="(M-#(N4B_PO``"%TG0)BP*)A(O\+P``B=!;R<.058GE4XM=
+M"(M-#(M5$(N$D_PO``")`8F,D_PO``!;R<-5B>575E.#[`R+10R[`(```#T`
+M0```=V%FNP!`/0`@``!W5F:[`"`]`!```'=+9KL`$#T`"```=T!FNP`(/0`$
+M``!W-6:[``0]``(``'<J9KL``CT``0``=Q]FNP`!/8````!W%&:[@`"#^$!W
+M"X/X(1G;@^/@@\-`BT40#Z_#!?\/``#!Z`R)1?#'1>P`````N`````"!^P`0
+M```/A]8```#_3?"#??#_#X3&````D(/L#/]U".C\____B<;_1>R_`````(/$
+M$+@`$```N@````#W\X/X``^&BP```(UV`+@*````@?L`0```=U>P"8'[`"``
+M`'=-L`B!^P`0``!W0[`'@?L`"```=SFP!H'[``0``'<OL`6!^P`"``!W);`$
+M@?L``0``=QNP`X'[@````'<1L`*#^T!W"H/[(`^7P`^VP)!05O]U".B2_O__
+M`=Z#Q`Q'N``0``"Z`````/?S.?@/AWC_____3?"#??#_#X4[____BT7LC67T
+M6UY?R<-5B>564XMU"(M=#+@`````.9XH,```<DIJ`E;H'/[__XG!@\0(A<!T
+M-XD82X/[_W0OC78`N@````"#OB0P````=!2+EB0P``"+`HF&)#```/^.*#``
+M`(E4F01+@_O_==2)R(UE^%M>R<.-=@!5B>564XM="(MU#(L.28/Y_W0?D(M4
+MC@2+@R0P``")`HF3)#```/^#*#```$F#^?]UXFH"5E/HN?W__XUE^%M>R<.)
+M]E6)Y593BW4(BQY+@_O_=!R#[`1H`!```&H`_W2>!.C\____@\002X/[_W7D
+MC67X6U[)PY!5B>53BUT(BPM)@_G_=">+1(L$N@````"#.`!T![@`````ZQ="
+M@\`$@?K_`P``=NA)@_G_==FX`0```%O)PXGV58GE@^P,:A!J`/]U".C\____
+MR<-5B>6+30R#>0P`=`F+40R+00B)0@B+40B+00R)`L=!"`````!J`%'_=0CH
+M^?S__\G#C78`58GE4XM5"(M-#(U:,(M",(E!#(7`=`F+4C"-00R)0@B)60B)
+M"UO)PU6)Y5=64XM]$(MU%(M%#(M8,(7;=!F)]CDS<PPY>P1V![@`````ZR.+
+M6PR%VW7I:@#_=0CH;_S__XG#B3B)<`10_W4,Z(____^)V(UE]%M>7\G#D%6)
+MY5.+30B*42D/MMJ-!-T`````*=B-7($L0HA1*8D+QD,%`,9#!@#&0P<`B=A;
+MR<.-=@!5B>575E.+?0B+=0R[``````^V5B:-0OW1^`'"@_H`?B.-=@#_M)ZL
+M!P``5^@?_O__@\0(0P^V5B:-0OW1^`'".=I_X&H'5E?H]_O__XUE]%M>7\G#
+MC78`58GE5U93@^P<BWT0BD4,B$7SBU449HE5\(M%"(N8*#```,'C`P^WR@^V
+M5?.-0OW1^`'"#Z_*.<L/@]H````/ME7SB57DB=")5>`/MU7PC4#]T?@#1>2)
+MTP^OV)"+10@%Y"\``(M5"#F"Y"\```^$PP```(NRY"\``(M6!(L&B5`$B0*)
+M-HEV!(-^$`!T'H-^%`!T"8M6%(M&$(E"$(M6$(M&%(D"QT80`````(M%\&8Y
+M1B1U0XI5\SA6)G4[B3:)=@2)?B"_`````(-]Y`!^(8M=X)"#[`R)^,'@!(V$
+M,%0(``!0Z,?]__^#Q!!'.?M_XXGPZ1,!``!6_W4(Z*?^__^#Q`B+50B+@B@P
+M``#!X`,YV`^"1/___VH'_W4(Z*;Z__^)QH/$"+@`````A?8/A-<```#K"K@`
+M````Z<L```")-HEV!(E^((M%\&:)1B2*5?.(5B;'1A@`````OP`````/ME7S
+MC4+]T?@!PH/Z``^.E````(M%\&;!Z`,/M\")1>@/ME7SC4+]T?@!PHE5[/]U
+MZ/]U".CQ^___B82^K`<``(/$"(7`=3-/@___=!F0_[2^K`<``/]U".@Y_/__
+M@\0(3X/__W7H:@=6_W4(Z!GZ__^X`````.LQB?:#[`R)^\'C!`'SC8/4!P``
+M4.B^_/__@<-4"```B1PDZ+#\__^#Q!!'.7WL?X>)\(UE]%M>7\G#D%6)Y5=6
+M4X/L#(M]$(M%%&:)1?*+50P/MDH^B?C3Z"7_`P``BU(LC1R"BS.%]G0@D#E^
+M('43BU8$BP:)4`2)`HDVB78$B?#K:XMV%(7V=>$/MT7R4%>+50P/MD(\4/]U
+M".B'_?__B<:#Q!"%P'1#BTT,B4@<BP.)1A2%P'0(BQ.-1A2)0A")7A"),XM%
+M#(I8/(A>)@^V2#Z)^-/HBTT,#[91/(G1N@````#W\2C32XA>)XGPC67T6UY?
+MR<.058GE5U93@>S,````BT4,BE`0B-#0Z(/P`8G!@^$!B8U4____BT4,@W@4
+M`'0%]L(!=""-E5C___^)E5#___]J`5+_=0S_=0B+30S_41B#Q!#K#(M%#(M`
+M%(F%4/___\>%./___P```0"+E5#___]F@WH$`'0*#[=*!(F-./___\>%0/__
+M_P````#'A4S___\`````BT4,@'A$``^$W`$``(N53/___XM-#(M4D3")E43_
+M__^*BBP)``"(C4O___\XBBT)```/@I@!``"*A4O___^+E43___\X0B</A&4!
+M```/ML")T6:+E((,"0``9HN$@0X)``!FB84^____B=!FP>@##[?`B84T____
+M@^('9HF5//___P^WPHG"P>()N`@```!F*X4\____9HF%//___V:+A3[___]F
+M.84\____=@=FB84\____#[>%//___XG&P>8)#[:%2____XN-1/___XN$@:P'
+M``")UXN--/___P-\B`20BX4X____.85`____=3*#A5#___\(QX4X____```!
+M`(N54/___V:#>@0`=`H/MTH$B8TX____QX5`____`````(N=./___RN=0/__
+M_SGS=@*)\X.]5/___P!T(8/L!%.+A4#___^+E5#___\#`E!7Z/S___^#Q!#K
+M'XUV`(/L!%-7BX5`____BXU0____`P%0Z/S___^#Q!`!G4#___\IWG0'`=_I
+M5____XN%//___V8IA3[___]T&?^%-/___[H`````9L>%//___P@`Z>O^___^
+MA4O___^*E4O___^+C43___\XD2T)```/@VC^____A4S___^+50P/MD)$.X5,
+M____#X\D_O__@^P$:@#_=0S_=0C_51"-9?1;7E_)PXGV58GE5U93@^P,@WT0
+M`'0'BT4,QD`1"\=%\`````"+50R`>D0`#X3!````BT4(!>PO``")1>R+50B!
+MPN0O``")5>B-=@"+1?"+50R+7((PQX,$"0```````(G?L0"`>R8`=D&)]@^V
+MP<'@!`'XC9#4!P``O@````"#N-0'````=12#>@0`=0Z#>@@`=0B#>@P`=`>)
+M]KX!````A?9U(4$X3R9WP;@`````A<!T'(M5[(M"!(E:!(D3B4,$B1CK&K@!
+M````Z^.-=@"+5>B+0@2)6@2)$XE#!(D8_T7PBU4,#[9"1#M%\`^/6?___X/L
+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
+M0Q2+A(:L!P``B87<_O__BU4,#[9"#(N$AJP'``")A=C^__^[`````(/$"#N=
+MS/[__WUB#[:$G>G^__^)P<'A"0^VA)WJ_O__B<;!Y@D/MI2=Z/[__XG(B[W<
+M_O__`T27!(F%X/[__XG(B[W8_O__`T27!(F%Y/[__X/L!%90_[7@_O__Z/S_
+M__^#Q!!#.YW,_O__?)Z#[`1J`/]U#/]U".AJ`@``C67T6UY?R<.)]E6)Y5=6
+M4X'L+`$``(M%#(L8C87H_O__4(M%#(/`"%#H1/S__XF%V/[__XM5#`^V0AB+
+MA(.L!P``B87<_O__#[9"&8N$@ZP'``")A=3^__^^`````(/$"#NUV/[__WU=
+MD`^VA+7I_O__P>`)#[:,M>K^___!X0D/MIRUZ/[__XG"B[W<_O__`U2?!(F5
+MX/[__XN5U/[__P-$F@2)A>3^__^#[`114/^UX/[__^C\____@\001CNUV/[_
+M_WRD@^P$:@#_=0S_=0CHE`$``(UE]%M>7\G#58GE5U93@>Q\`0``BT4,BS"+
+M6`B-A>C^__]04^AS^___B864_O__#[9#%(N$AJP'``")A:3^__^Q`(/$"(M5
+M#(!Z%`!V)(I:%(UV``^VP8M]#`^V5`<,BY26K`<``(F4A<C^__]!.,MWXL>%
+MF/[__P````"+A93^__\YA9C^__\/C>X```")]HN5F/[__P^VA)7I_O__B<?!
+MYPD/MH25ZO[__\'@"8F%H/[__XJ,E>C^__^(C9_^__^Q`(M=#(![%`!V,0^V
+MM9_^__^*0Q2(A8?^__\/ML&+E(7(_O__BURR!(T4'XF4A:C^__]!.(V'_O__
+M=]\/MI6?_O__B?B+C:3^__\#1)$$.86H_O__=2"#[`3_M:#^____M:S^__^)
+M^`-$D010Z/S___^#Q!#K+/^UH/[___^UK/[___^UJ/[__P^VA9_^__^+G:3^
+M__\#?(,$5^C\____@\00_X68_O__B[V4_O__.;V8_O__#XP4____@^P$:@#_
+M=0S_=0CH"````(UE]%M>7\G#58GE5U93@^P4BWT(BUT,BW40QD,%`H/^`1G`
+M@^#U@\`,B$,&4U?HC?;__X/$$(![!`-U,(M#"(M0$(72=";'0!``````QD(%
+M`H/^`1G`@^#U@\`,B$(&@^P(4E?H5_;__X/$$(UE]%M>7\G#58GE5E.+70B+
+M=0P/MDX'A<ET29`/MI1+O`8``(T$U0`````IT(U$@RR`>`4"=`FX`````.LK
+MB?:`>`8!=!+&1@4"BD`&B$8&N`````#K$I`/MHQ+O08``(7)=;BX`0```%M>
+MR<.-=@!5B>575E.#[!R+?0S&1RH`@+\O"0```'1[O@````"-7RR`?RD`=$F0
+M@'L%`74V@'L$`W4EBT,(@'@5`'0<@W@0`'06QT`0`````,9#!0**ARX)``"(
+M0P;K"\9'*@'I]P$``(GV1H/#'`^V1RDY\'^X@^P(5_]U".@L\?__Z=@!``"*
+M0P:(ARX)``#&AR\)```!ZX:0QT7P`````,=%[`$```"^`````(U?+(!_*0`/
+MA'P!``"`>P4`#X66````4U?HT_[__X/$"(7`='S&0P4!BT4(B47HB=H/MD,$
+M@_@&=V?_)(4`````@^P(4_]UZ.B<]___@\00ZT^#[`A3_W7HZ*OY__^#Q!#K
+M/H/L"%/_=>CHMOO__X/$$.LM@^P(4_]UZ.AY_/__@\00ZQS&1RL!QD(%`L9"
+M!@&#[`A2_W7HZ*#T__^#Q!"0@'L%`G4,_T7PC78`@'L%`G0.QT7L`````.FZ
+M````B?:`>P8!#X2N````@'\K``^$!?___XM''`^V4PB+1)!4]D`!!`^$B```
+M`,=%[`````#&0P4!QD,&`(M%"(E%Y(G:#[9#!(/X!G=O_R2%'````(/L"%/_
+M=>3HS/;__X/$$.M7@^P(4_]UY.C;^/__@\00ZT:#[`A3_W7DZ.;Z__^#Q!#K
+M-8/L"%/_=>3HJ?O__X/$$.LDQD<K`<9"!0+&0@8!@^P(4O]UY.C0\___@\00
+MZP?&0P8!C78`1H/#'`^V1RDY\`^/A/[__X-]\``/A5K^__^#?>P`=!7&ARX)
+M```!@^P(5_]U".A5[___ZP3&1RH!C67T6UY?R<.-=@!5B>575E.![&P!``"+
+M10R+6!R+N`0)``#&A;'^__\`A?]U,0^W0"2+30R+42`!T%!24_]U".C"Y___
+MBW4,B488@\00N/____^#?A@`#X09*P``B?:+10C_@"PP``"+10R#P`B+50B!
+MPO0O``"+2@2)0@2+=0R)5@B)2`2)`6:#>TP`=$#V0TH!=0B+0U`[1B!W)[X`
+M````#[=#3(G"J`%U#HUV`$:)T(GQT_BH`73UB?.+10R(6"CK+HM5#,9"*`CK
+M)8GV]D-*`G06BT-0BTT,.T$@=PN*02>(02CK"HUV`(M=#,9#*`B+=0S&1BD`
+MQH:\!@```,9&*P#&ABX)````QH8O"0```,>&"`D```````"%_P^$7Q,``/9'
+M$"`/A&D)```/MD<*@_@"#X2&!0``@_@"?PZ#^`$/A$0!``#I%2H``(/X`P^%
+M#"H``(/L#(V=V/[__U/H,>;__X/$$+\`````BT4,#[=P)+,`@_\?=U(/ML.-
+ME(78_O__B;VL_O__N2`````I^3GQ=@*)\8/Y('4(QP+_____ZQ*X`0```-/@
+M2(J-K/[__]/@"0*X(````"GX.?!S%(UT/N"_`````.L#@^\@0X#[`W:@@^P,
+MBUT,_[.L!P``Z#OE___&A;/^__\`@\00@'LF``^&9RD``(/L#`^VG;/^___!
+MXP0#70R-@]0'``!0Z'_E__^!PU0(``")'"3H<>7__X/$$/]U#.@JYO__@\0$
+MQD`$`HJ5L_[__XA0",9`"0"+E=C^__^)4`R+E=S^__^)4!"+E>#^__^)4!2+
+ME>3^__^)4!C^A;/^__^*C;/^__^+70PX2R8/AWO____IW2@``+@!````ZTV+
+M=0RQ`(!^)@!V/0^VP<'@!`'PC9#4!P``NP````"#N-0'````=1*#>@0`=0R#
+M>@@`=0:#>@P`=`6[`0```(7;=;=!.$XF=\.X`````(7`=!B+=0R)O@@)``#'
+MA@0)````````Z8T1``"#[`R-G=C^__]3Z)+D__^#Q!"_`````(M%#`^W<"2S
+M`(/_'W=2#[;#C92%V/[__XF]J/[__[D@````*?DY\78"B?&#^2!U",<"____
+M_^L2N`$```#3X$B*C:C^___3X`D"N"`````I^#GP<Q2-=#[@OP````#K`X/O
+M($.`^P-VH(M=#(![*`AU!HI#)XA#*(MU#(I>*(B>Z`@``,:&Z0@```&+A=C^
+M__^)AM0(``"+A=S^__^)AM@(``"+A>#^__^)AMP(``"+A>3^__^)AN`(``#'
+MAN0(````````5NB#Y/__@\0$QD`$`HA8"(A8"8N5V/[__XE0#(N5W/[__XE0
+M$(N5X/[__XE0%(N5Y/[__XE0&(G'@'XF`@^'5`$``(GS@</4"```5N@XY/__
+M@\0$QD`$!8E8",9`%`")A<#^__^+'_Z#O`8```^VL[P&``")PBG:@^HLP?H"
+MC032C03"C03"C03"B<'!X0\!R(T$PO?8B(1SO`8``(I'!XB$<[T&``")\(A'
+M!\:%L_[__P"+50R`>B8`#X;1)@``BHVS_O__BUT,.$LH#X2H````4^BQX___
+M@\0$QD`$`8J5L_[__XA0"(A0"8N5V/[__XE0#(N5W/[__XE0$(N5X/[__XE0
+M%(N5Y/[__XE0&(N-P/[__XI1%`^VRHJ=L_[__XNUP/[__XA<#@Q"B%84BQ[^
+M@[P&```/MK.\!@``*=B#Z"S!^`*-%,"-%-"-%-"-%-")T<'A#P'*C130]]J(
+ME'.\!@``B[W`_O__BD<'B(1SO08``(GPB$<'_H6S_O__BI6S_O__BTT,.%$F
+M#X<N____Z?HE``#&A;/^__\`BUT,@'LF``^&YB4``('#U`@``(F=I/[__XJ%
+ML_[__XM5##A"*`^$`@$``%+HNN+__X/$!,9`!`&*C;/^__^(2`B(2`F+E=C^
+M__^)4`R+E=S^__^)4!"+E>#^__^)4!2+E>3^__^)4!B)A<3^____=0SH=>+_
+M_X/$!,9`!`.+G:3^__^)6`B*E;/^__^(4`R)A<#^__^+&/Z#O`8```^VL[P&
+M``"+E<3^__\IVH/J+,'Z`HT$THT$PHT$PHT$PHG!P>$/`<B-!,+WV(B$<[P&
+M``"+C<#^__^*00>(A'.]!@``B?.(60>+'_Z#O`8```^VL[P&``")RBG:@^HL
+MP?H"C032C03"C03"C03"B<'!X0\!R(T$PO?8B(1SO`8``(I'!XB$<[T&``")
+M\(A'!_Z%L_[__XJ5L_[__XM-##A1)@^'U/[__^FI)```N`$```#K4HMU#+$`
+M@'XF`'9"C78`#[;!P>`$`?"-D-0'``"[`````(.XU`<```!U%(-Z!`!U#H-Z
+M"`!U"(-Z#`!T!XGVNP$```"%VW6R03A.)G?!N`````"%P'08BUT,B;L("0``
+MQX,$"0```````.E4#0``@^P,C9W8_O__4^A9X/__@\00OP````"+10P/MW`D
+MLP"#_Q]W4@^VPXV4A=C^__^)O:#^__^Y(````"GY.?%V`HGQ@_D@=0C'`O__
+M___K$K@!````T^!(BHV@_O__T^`)`K@@````*?@Y\',4C70^X+\`````ZP.#
+M[R!#@/L#=J"+70R*0R>(@^@(``#&@^D(````BX78_O__B8/4"```BX7<_O__
+MB8/8"```BX7@_O__B8/<"```BX7D_O__B8/@"```QX/D"````````(![)@(/
+MAP`!``"+70R!P]0(``#_=0SH1.#__X/$!,9`!`6)6`C&0!0`B87`_O__QH6S
+M_O__`(MU#(!^)@`/AB0C``#_=0SH%.#__X/$!,9`!`&*E;/^__^(4`B(4`F+
+ME=C^__^)4`R+E=S^__^)4!"+E>#^__^)4!2+E>3^__^)4!B+C<#^__^*410/
+MMLJ*G;/^__^+M<#^__^(7`X,0HA6%(L>_H.\!@``#[:SO`8``"G8@^@LP?@"
+MC13`C130C130C130B='!X0\!RHT4T/?:B)1SO`8``(N]P/[__XI'!XB$<[T&
+M``")\(A'!_Z%L_[__XJ5L_[__XM-##A1)@^'/O___^E=(@``BW4,BEXG5NA)
+MW___@\0$QD`$`8A8"(A8"8N5V/[__XE0#(N5W/[__XE0$(N5X/[__XE0%(N5
+MY/[__XE0&(F%O/[__\:%L_[__P"`?B8`#X8)(@``B?>!Q]0(``"*A;/^__^+
+M50PX0B</A`8!``!2Z.'>__^#Q`3&0`0!BHVS_O__B$@(B$@)BY78_O__B5`,
+MBY7<_O__B5`0BY7@_O__B5`4BY7D_O__B5`8B87$_O___W4,Z)S>__^#Q`3&
+M0`0#B7@(BIVS_O__B%@,B87`_O__BQC^@[P&```/MK.\!@``BY7$_O__*=J#
+MZBS!^@*-!-*-!,*-!,*-!,*)P<'A#P'(C03"]]B(A'.\!@``BY7`_O__BD('
+MB(1SO08``(GQB$H'BQK^@[P&```/MK.\!@``BY6\_O__*=J#ZBS!^@*-!-*-
+M!,*-!,*-!,*)P<'A#P'(C03"]]B(A'.\!@``BY7`_O__BD('B(1SO08``(GQ
+MB$H'_H6S_O__BIVS_O__BW4,.%XF#X?0_O__Z<P@``"%_P^$Y`D``/9'$`(/
+MA-H)``"+10R*@"P)``"(A;/^__^+50PX@BT)```/@H<!``"*C;/^__^+70PX
+M2R</A%H!``"#[`P/MMF)V,'@!(VT!6C___]6Z*;<__^#Q!")M9S^__^+=0P/
+MMY2>#`D```^WO)X."0``O@````"0@_H?=U>)\0^VP8N-G/[__XT<@8F5F/[_
+M_[D@````*=$Y^78"B?F#^2!U"<<#_____^L3D+@!````T^!(BHV8_O__T^`)
+M`[@@````*=`Y^',6C7P7X+H`````ZP.#ZB!&B?.`^P-VF0^VG;/^__^)VHG8
+MP>`$BW4,C9PP5`@``(L+]]&)C=C^__^+0P3WT(F%W/[__XM#"/?0B87@_O__
+MBT,,]]")A>3^__^)UL'F!(V<->C^__^-E#5H____(PJ)"XM"!".%W/[__XE#
+M!(M""".%X/[__XE#"(M"#".%Y/[__XE##(J%L_[__XM5##A"*'4MN@````"#
+M.P!U$H-[!`!U#(-["`!U!H-[#`!T!;H!````A=)T",:%L?[__P&0_H6S_O__
+MBHVS_O__BUT,.(LM"0``#X-Y_O__@+VQ_O__``^$9`<``(/L#(V%V/[__U#H
+M+=O__\:%L_[__P"#Q!"+=0R`?B8`=G>)]HJ%L_[__XM5##A"*'13.$(G=$X/
+MMM#!X@0#50R-BM0'``"+A=C^__\+@M0'``")A=C^__^+A=S^__\+002)A=S^
+M__^+A>#^__\+00B)A>#^__^+A>3^__\+00R)A>3^___^A;/^__^*C;/^__^+
+M70PX2R9WBXMU#`^V?BC!YP2-G#WH_O__B[78_O__(S.)M<C^__^+C=S^__\C
+M2P2)C<S^__^+E>#^__\C4PB)E=#^__^+A>3^__\C0PR)A=3^___WUHFUV/[_
+M__?1B8W<_O__]]*)E>#^___WT(F%Y/[__R,SB;78_O__(TL$B8W<_O__(U,(
+MB97@_O__(T,,B87D_O___W4,Z-#:__^#Q`3&0`0`B86T_O__N`````"#O=C^
+M__\`=1N#O=S^__\`=1*#O>#^__\`=0F#O>3^__\`=`6X`0```(7`#X0\`@``
+MBWT,BD<HB(?H"```BX78_O__B8?4"```BX7<_O__B8?8"```BX7@_O__B8?<
+M"```BX7D_O__B8?@"```QH?I"````<>'Y`@```````#&A;/^__\`@'\F``^&
+MI@(``(J%L_[__XM5##A"*`^$KP$``#B"+`D``'<-.((M"0``<@4X0B=U1_]U
+M#.@`VO__@\0$QD`$`8J-L_[__XA("(A("8N5V/[__XE0#(N5W/[__XE0$(N5
+MX/[__XE0%(N5Y/[__XE0&(F%Q/[__^MW#[:-L_[__\'A!(V<#>C^__^+A=C^
+M__\+`XD#BX7<_O__"T,$B4,$BX7@_O__"T,(B4,(BX7D_O__"T,,B4,,_W4,
+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
+M__^+A>3^__\APXF=U/[__\'F!(M-#(VT#E0(``"+C=C^__\C#HF-V/[__R-^
+M!(F]W/[__R-6"(F5X/[__R-&#(F%Y/[__[@`````A<EU$87_=0V%TG4)@[WD
+M_O__`'0%N`$```"%P`^$N@(``(M=#(I#)XB#Z`@``(N%V/[__XF#U`@``(N%
+MW/[__XF#V`@``(N%X/[__XF#W`@``(N%Y/[__XF#X`@``,:#Z0@```''@^0(
+M````````QH6S_O__`(![)@`/AEP"``"!P]0(``")G9#^__^*A;/^__^+50PX
+M0BAU=E+H?,/__X/$!,9`!`.+C9#^__^)2`B*G;/^__^(6`R+M;3^__^+'OZ#
+MO`8```^VL[P&```IV(/H+,'X`HT4P(T4T(T4T(T4T(G1P>$/`<J-%-#WVHB4
+M<[P&``"+O;3^__^*1P>(A'.]!@``B?"(1P?IM0$``)"*E;/^__^+30PX42</
+MA*(!```/MOK!YP2-C#WH_O__BUT,C90?5`@``(L"]]")`8M"!/?0B4$$BT((
+M]]")00B+0@SWT(E!#(L!(X78_O__B0&+000CA=S^__^)002+00@CA>#^__^)
+M00B+00PCA>3^__^)00Q3Z)'"__^#Q`3&0`0#B[60_O__B7`(BI6S_O__B%`,
+MB87`_O__BXVT_O__BQG^@[P&```/MK.\!@``B<(IVH/J+,'Z`HT$THT$PHT$
+MPHT$PHG!P>$/`<B-!,+WV(B$<[P&``"+E;3^__^*0@>(A'.]!@``B?&(2@>-
+MA#WH_O__N@````"#.`!U$H-X!`!U#(-X"`!U!H-X#`!T!;H!````A=(/A)<`
+M```/MH6S_O__P>`$C9P%Z/[___]U#.C6P?__@\0$QD`$`8J5L_[__XA0"(A0
+M"8L3B5`,BU,$B5`0BU,(B5`4BU,,B5`8BXW`_O__BQG^@[P&```/MK.\!@``
+M*=B#Z"S!^`*-%,"-%-"-%-"-%-")T<'A#P'*C130]]J(E'.\!@``B[W`_O__
+MBD<'B(1SO08``(GPB$<'C78`_H6S_O__BI6S_O__BTT,.%$F#X>P_?__N```
+M``"#O<C^__\`=1N#O<S^__\`=1*#O=#^__\`=0F#O=3^__\`=`6X`0```(7`
+M#X02!```BW4,BEXG5NC^P/__@\0$QD`$`8A8"(A8"8N5R/[__XE0#(N5S/[_
+M_XE0$(N5T/[__XE0%(N5U/[__XE0&(F%O/[__\>%N/[__P````#&A;/^__\`
+M@'XF``^&M`,``(J%L_[__XM5##A"*`^$B@,``#A")P^$@0,```^VP,'@!(V<
+M!>C^__\!T(V(U`<``(N5R/[__R.0U`<``(D3BX7,_O__(T$$B4,$BX70_O__
+M(T$(B4,(BX74_O__(T$,B4,,N`````"#.P!U$H-[!`!U#(-["`!U!H-[#`!T
+M!;@!````A<`/A!$#``"+30R*22B(C8_^__\/MH6S_O__P>`$C9P%Z/[___]U
+M#.C\O___@\0$QD`$`8J5L_[__XA0"(J-C_[__XA("8L3B5`,BU,$B5`0BU,(
+MB5`4BU,,B5`8B87$_O__@[VX_O__`'11BQC^@[P&```/MK.\!@``BY6X_O__
+M*=J#ZBS!^@*-!-*-!,*-!,*-!,*)P<'A#P'(C03"]]B(A'.\!@``B[W$_O__
+MBD<'B(1SO08``(GPB$<'BU4,BE(GB)6._O__BTT,BDDHB(V-_O__#[:]L_[_
+M_\'G!(V</>C^____=0SH.[___X/$!,9`!`2*E8[^__^(4!B*C8W^__^(2!F+
+M$XE0"(M3!(E0#(M3"(E0$(M3#(E0%(F%P/[__XF%N/[__XL8_H.\!@``#[:S
+MO`8``(N5O/[__RG:@^HLP?H"C032C03"C03"C03"B<'!X0\!R(T$PO?8B(1S
+MO`8``(N5P/[__XI"!XB$<[T&``")\8A*!XL:_H.\!@``#[:SO`8``(N5Q/[_
+M_RG:@^HLP?H"C032C03"C03"C03"B<'!X0\!R(T$PO?8B(1SO`8``(N5P/[_
+M_XI"!XB$<[T&``")\8A*!XNUM/[__XL>_H.\!@``#[:SO`8``(N5P/[__RG:
+M@^HLP?H"C032C03"C03"C03"B<'!X0\!R(T$PO?8B(1SO`8``(N5M/[__XI"
+M!XB$<[T&``")\8A*!XM=#(I;)XB=C/[__XV</>C^____=0SHZ[W__X/$!,9`
+M!`2*E8S^__^(4!B*C;/^__^(2!F+$XE0"(M3!(E0#(M3"(E0$(M3#(E0%(F%
+MP/[__XL8_H.\!@``#[:SO`8``(N5O/[__RG:@^HLP?H"C032C03"C03"C03"
+MB<'!X0\!R(T$PO?8B(1SO`8``(N]P/[__XI'!XB$<[T&``")\(A'!XN5M/[_
+M_XL:_H.\!@``#[:SO`8``(GZ*=J#ZBS!^@*-!-*-!,*-!,*-!,*)P<'A#P'(
+MC03"]]B(A'.\!@``BXVT_O__BD$'B(1SO08``(GSB%D'D/Z%L_[__XJ%L_[_
+M_XM5##A")@^'3/S__X/L"/]U#/]U".@VTO__N`````"-9?1;7E_)PY!5B>57
+M5E.#[`R+10B#N"PP```##X</`0``!>PO``"+50@Y@NPO```/A/L```")1>R+
+MBNPO``")3?"-=@"+7?"+`XE%\(M3!(L#B5`$B0*)&XE;!(M#'/9``00/A8@`
+M``")W[X`````@'LF`'8FC78`@^P,B?(/ML+!X`2-A#C4!P``4.B0N___@\00
+M1HGQ.$\F=]V+50B!PN0O``"+30B+@>0O``")6`2)`XE3!(F9Y"\``(M#'(-X
+M)`!T8(/L!/]P*(M#'/]P)%'H_/___XM#',=`)`````"+10C_B#`P``"#Q!#K
+M-HGV@^P(4_]U".B8T___@\00A<!T+8M5"('"["\``(M-"(N!["\``(E8!(D#
+MB5,$B9GL+P``D(M%[#E%\`^%%/___XUE]%M>7\G#58GE4X/L!(M%"(M8"(.[
+M+#````!U#HV#["\``#F#["\``'0S@^P,4^C\____B1PDZ/S___^)'"3H_/__
+M_X/$$(.[+#````!UVXV#["\``#F#["\``'7-N`````"+7?S)PXUV`%6)Y5=6
+M4X/L!(M%"(M`"(E%\(N(["\```7L+P``.<@/A($```"-=@"+50@Y41QU:(G/
+MLP"`>28`=D&)]@^VP\'@!`'XC9#4!P``O@````"#N-0'````=12#>@0`=0Z#
+M>@@`=0B#>@P`=`>)]KX!````A?9U&4,X7R9WP;@`````A<!T%+@!````Z:T`
+M``"X`0```.OKC78`BPF+1?`%["\``#G(=8*+1?"+B/0O```%]"\``#G(='Z-
+M0?B+50@Y4!QU98G#O@````"`>"8`=D&)\@^VPL'@!`'8C9#4!P``OP````"#
+MN-0'````=1*#>@0`=0R#>@@`=0:#>@P`=`6_`0```(7_=1A&B?`X0R9WO[@`
+M````A<!T#K@!````ZQJX`0```.ONBPF+1?`%]"\``#G(=8*X`````(/$!%M>
+M7\G#D%6)Y5=64X/L#(M="(M]$(MS"(-[)`!U#5/HGO[__X/$!(7`=0N#[`A7
+M5O]5#.L9D(M%#(E#)(E[*/^&,#```(/L#%;H_/___XUE]%M>7\G#58GE5E.+
+M=0B+70R`>Q$`=03&0Q$!@'L1`709@'L1!G03@'L1`W0-]D,0('4'QD,1"XUV
+M`/]S+%;HQ[C__XD<)/]S'%;H_/___XL#@\00@W@8`'08@^P$@\`84&@`````
+M5NC\____@\00ZUV0@[XT,````'0KC8;D+P``.8;D+P``=!V#[`2-AC0P``!0
+M:`````!6Z/S___^#Q!#K*XUV`(&^*#```/\```!W'(V&Y"\``#F&Y"\``'4.
+M@^P,5NC\____@\00B?:-9?A;7LG#D%6)Y5=64X'LS````(M]$(M%#(M0((L*
+MB8TT____#[9!/$B)A4C___]FBTH(9HF-5O___XM"3(F%4/___P^V2DJ)C43_
+M__\/MD)+B85`____9HM*4F:)C53___]FBUI0@WH4`'0-9@^V0A"#X`$[111U
+M.+D`````@WH8``^$?P(``(V%6/___XF%./____]U%%!2_W4(_U(8@\00N0``
+M``"%P`^$6`(``.L)BU(4B94X____O@````"+50R+`@^V0`.)A3S___^Y````
+M``^WPP.%4/___XF%3/___XN%//___SF%1/___P^%%P$``(7)=%*+A4S___\I
+MR(G#P>,)=$.#?10`=`>A`````.L1@^P,_S4`````Z/S___^#Q!")!V;'1P8`
+M`('[`!````^&OP```&;'1P0`$(/'"('K`!```'6]#[>=5/___\'C"8UV`(N-
+M./___P^W402%TG4%N@```0")T"GP.=AR,8GPBXTX____`P&)!V:)7P1FQT<&
+M``"#QP@!WCG6=4:^`````(/!"(F-./___^LVB?:)\(N-./___P,!B0>)T&8I
+M\&:)1P1FQT<&``"#QPB)T"GP*<.#P0B)C3C___^^`````.N`#[>-5/___P.-
+M3/___XM5#`^W0@@#0@0YR`^$!@$``.M/9HE?!(/'".E&____C78``=[K/`^W
+MG53____!XPF)]HN%./___P^W4`2%TG4%N@```0")T"GP.=AWU8G0*?`IPX.%
+M./___PB^`````.O1D(N55/___V8IE5;___\/A*(```"[`````/^%1/___XN%
+M0/___SF%1/___W4(_X5$____B?:+E33___\/MD(\.X5$____=4*#O4#___\`
+M=`C_C4#____K#(N%2/___XF%0/___X.]0/___P`/E,`/ML")A43___^+E33_
+M__\/MT)(`850____B?:+A33___]FBT!(9HF%5/___V:+E5;___]F.=`/AN/]
+M__]FB954____Z=?]__]FQT?^`("Y`0```(G(C67T6UY?R<.)]E6)Y593BW4(
+MBU4,BUH@@'H1`70&BD(1B$,1@^P(4E;H_/___XI#24"(0TF#Q!`Z0TAU+8![
+M$0!U!,9#$0&`>Q$!=!"`>Q$&=`J`>Q$#=`3&0Q$+@^P(4U;_4QR#Q!")]HUE
+M^%M>R<.058GE5U93@^PLBT4,BP")1>R+50SV0A`$#X3T`0``QT7P`````(!Z
+M1``/A'L!``"+3?"+70R+3(LPB4WHBIDL"0``B%WG.)DM"0``#X)&`0``C78`
+MBD7GBU7H.$(G#X0?`0``#[;`B<+!X@2+3>B-E`K4!P``B57@#[>4@0P)```/
+MM[2!#@D``+\`````C78`@_H?=U.)^P^VPXM-X(T<@8E5W+D@````*=$Y\78"
+MB?&#^2!U"\<#_____^L2C78`N`$```#3X$B*3=S3X`D#N"`````IT#GP<QF-
+M=!;@N@````#K!HUV`(/J($>)^X#[`W:=#[9%YXG"P>`$BTWHC80(5`@``(E%
+MV`^WG)$,"0``#[>TD0X)``"_`````(GV@_L?=U.)^@^VPHM-V(T4@8E=U+D@
+M````*=DY\78"B?&#^2!U"\<"_____^L2C78`N`$```#3X$B*3=33X`D"N"``
+M```IV#GP<QB-=![@NP````#K!HUV`(/K($>)^#P#=I[^1>>*5>>+3>@XD2T)
+M```/@[W^____1?"+70P/MD-$.T7P#X^%_O__BT4(@[C@+P````^$/@,``,=%
+M\`````"+50R`>D0`=#6)PH'"["\``(M-\(M=#(M,BS#'@00)````````BT($
+MB4H$B1&)002)"/]%\`^V0T0[1?!_TX/L"/]U#/]U".BO^?__Z1T#``"+70SV
+M0Q`"#X39`@``BT4(!3@P``")1="+?0B!QU@P``"+5>SV0DH##X6X`@``@^P$
+M:A!J`%?H_/___\=%\`````"#Q!"`>T0`#X3_````BTWPBUT,BTR+,(E-Z(G.
+ML0"`?B8`=D8/ML'!X`0!\(V0U`<``+L`````@[C4!P```'42@WH$`'4,@WH(
+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
+M_/___\=')`````"+10C_B#`P``"#Q!"+5@2)5=1FBT8(9HE%V(I'/$B(1=H/
+MMD\^B=#3Z(E%R`^V7=JZ`````/?SB47,#[9//M/@B470#[='2`^OPXE%M`^W
+M3=@#3@0/KUW0*=F-3`'_B<BZ`````/=UM(G!#[='2`^OR.LND/9'2@%T&L9&
+M$0:#[`16_W8<_W4(Z/S____I"@$``(GV#[=/2(G(#Z]&!(E%T(M%T(T4`5)0
+M5_]U".BZJO__B48L@\00A<!U',=&*`````"#[`A6C4<84.C\____Z<<```"-
+M=@"#[`2-1<A05O]U".B@^O__@\00A<!T;?]V+/]U".@6JO__BT4(BY!4(@``
+M@\0(.9!8(@``=">Y(0(``)"+10B!O-!,$0```````'140HG0F??YBT4(.9!8
+M(@``==_'1B@`````@^P(5HM%"`4T,```4.C\____@\0$_W4(Z/S____K09#V
+M1A`$="N#[`1H+',``%;_=0CHJ:W__X/$$.LDQD81!8/L!%;_=AS_=0CH_/__
+M_^L/@^P(5O]U".BW]/__@\00C67T6UY?R<-5B>53@^P$BUT,@WLL`'1.@^P,
+M4^C\____N@````"#Q!"-=@"+0RR+!)"%P'00B?;'0!``````BT`4A<!U\D*!
+M^O\#``!VW6H'_W,L_W4(Z$"F___'0RP`````@\0,BUW\R<.058GE5U93@^P0
+MBWT(QX?@+P```````(V'Y"\``(F'Y"\``(F'Z"\``(V'["\``(F'["\``(F'
+M\"\``(V']"\``(F']"\``(F'^"\``*$`````P>`,NJNJJJKWXHG3P>L/4V@P
+M"0``5^CDI?__B<:#Q`R#PR!3:A!7Z-.E__\!QH/$#*$`````P>`,P>@.4&I$
+M5^BZI?__`<:#Q`QJ"&@`$```5^BHI?__`<:)/"3H_/___Z,`````@\001CLU
+M`````',QD(/L#%?H_/___XG"@\00A<!T'HN')#```(D"B9<D,```_X<H,```
+M1CLU`````'+1D(UE]%M>7\G#58GE5U93@^P,BWT(BW4,BUX$#[9.`[@!````
+MB<+3XH!F`?O'0U``````]D-*`G0,9H-[3`!T$NL*C78`9H-[3`!T+6:%4TQU
+M)V8)4TR`8P'[@WLX`'0-@^P(4U?_4SB#Q!")]H!C2A_ILP```(UV`(I#2F:)
+M4TS^2SW'0U``````@\@%B$-*A,!Y#8/@?XA#2NF*````B?:`8TJ?@^P(4U?H
+M_/___XG"@\00A<!T3,8``XI&`XA"`XE:!(!*`0BA#````(E"-*$@````B4(X
+MQT8$``````^V0@.)5(-4BD-*@^#^@\@*B$-*_D,]@^P(4FH'Z/S___^#Q!"#
+M>P0`=`R-=@"+6P2#>P0`=??H_/___XE#0(/L#%/H_/___XGVC67T6UY?R<-5
+MB>53BTT(NP````"+50Q*@_K_=`^-=@`/M@$!PT%*@_K_=?0/ML-;R<.)]E6)
+MY593BW4(@#X#=D:[`````(!^/`!T-8-\GE0`="6+3)Y4BE8!@^(!BD$!@^#^
+M"="(00&#[`S_=)Y4Z/S___^#Q!"00P^V1CPYV'_+@&9*^^L)@^P,5N@(````
+MC67X6U[)PY!5B>575E.![!P"``#'A>3]__\`````C;7H_?__BT4(@'@\``^$
+M.@(``(MX!(7_=`^#?P0`=`F)O>3]__^+?P2#[`1H``(``&H`5NC\____QP;S
+M%GA:@\00N`````"%_W0#BT=`B48$BU4(@'I$`'0*@$X)`HI"1XA&"HM%"(I0
+M0(C3@^,!BH:3````@^#\B-&#X0()V`G(B-.#XP2#X/.(T8/A"`G8"<B(TX/C
+M$(/@SXC1@^$@"=@)R(C1@^%`@^`_@^*`"<@)T(B&DP```(M5"/9"`0%T!(!.
+M"0&P`(7_=`R#O>3]__\!&<"#P`*(1@N%_P^$N@```(M'#(E&#,>&E```````
+M``"*!XA&$(I'/(A&$8.]Y/W__P!T"XN5Y/W__XI"`^L)BU4(BD(#C78`B$82
+MBD<^B$83]D=*`G0$@$X4`6:+1TQFB486BT=0B488QX:8`````````(/L!&H0
+MC4=T4(U&+%#H_/___X/$#&H$C8>$````4(U&/%#H_/___X/$#&H0C8?(````
+M4(V&@````%#H_/___X/$#&I`C8>(````4(U&0%#H_/___X/$$(.]Y/W__P!T
+M7HN5Y/W__XM"#(E&',>&G`````````"*`HA&((I"/(A&(8M5"(I"`XA&(HN5
+MY/W__XI"/HA&(_9"2@)T!(!.)`&+E>3]__]FBT),9HE&)HM"4(E&*,>&H```
+M``````"%_W4+BU4(B@*(1A"-=@!HD````%;H_/____?8B$8(:``"``!6Z/S_
+M___WV(B&D````%9J,(M5"(M"3(/H"E")T(/`/%#H_/___XUE]%M>7\G#D%6)
+MY8M-"(G(@#D#=B^X`````(!Y/`!T$`^V43R#?(%4`'4,0#G"?_2X`````.L-
+M@^P,_W2!5.C\____D,G#B?95B>564XMU"(`^`W8ONP````"`?CP`="B#?)Y4
+M`'01@^P,_W2>5.C\____@\00B?9##[9&/#G8?]_K!9"`9@'^C67X6U[)PY!5
+MB>6+30B+40BX`````(GV.0R"=0O'!((`````ZPB)]D"#^`=VZLG#58GEBT4,
+M@&`!^U#H_/___\G#B?95B>575E.![!P$``"+?0B-M>C]__^)^XI'`:@$#X09
+M`0``@#\"#X80`0``@^#]B$<!@^P$:``"``!J`%;H_/___X/$$(`_`W1XC87H
+M^___D(M;5(`_"'5DA=MT!V:#?TP!=5F)P\>%Y/O__P$````/MD<\@_@!?EI3
+M:B!J`(N5Y/O__XM$EU2#P#Q0Z/S___^Z`````(/$$(L$EC,$DXD$ED*#^G]^
+M\?^%Y/O__P^V1SP[A>3[__]_O^L7D(`[`W6/5FH@:@"-0SQ0Z/S___^#Q!!F
+M@;[^`0``5:IU7H.^R@$```!T&X%^!DQ)3$]T#(&^=@$``$=254)U!H!/`0+K
+M.L>%Y/O__P````"+A>3[___!X`0!\("XO@$``(!U#8.XR@$```!T!(!/`0+_
+MA>3[__^#O>3[__\#?M"-9?1;7E_)PY!5B>564XM-"(N92!$``(U#`;XA`@``
+MF??^B=:+10R)1-D\BY%($0``BT40B4310(FQ2!$``%M>R<.-=@!5B>575E.#
+M[`R+=0B+AD01```[AD@1``!T-K\A`@``D(N&1!$``(M,QCR+7,9`0)GW_XF6
+M1!$``(/L"%-6_]&#Q!"+AD01```[AD@1``!UT(UE]%M>7\G#58GE5E.+30B+
+MF5@B``"-0P&^(0(``)GW_HG6BT4,B8393!$``(N16"(``(M%$(F$T5`1``")
+ML5@B``!;7LG#D%6)Y5=64X/L#(M="(N#5"(``#N#6"(``'16B?:+@U0B``"+
+MM,-,$0``B[S#4!$``$"Z(0(``(G1F??YB9-4(@``@[LL,````'0.@^P,4^C\
+M____@\00B?:#[`A74__6@\00BX-4(@``.X-8(@``=:R-9?1;7E_)PU6)Y5.#
+M[`2+50BX`````(-Z.`!T%XM:.(L#B4(X@^P$:E1J`%/H_/___XG8BUW\R<.-
+M=@!5B>6+30B+50R+03B)`HE1.,G#D%6)Y8M-"(M5#(,Y`'02BP&+0"2)0B2+
+M`8E0).L&C78`B5(DB1')PY!5B>575E.#[`R+=0R#/@!T-8L^D(L&BU@D.=AU
+M"\<&`````.L+C78`BQ:+0R2)0B2#[`A3_W4(_U,H@\00.?MT!8,^`'7.C67T
+M6UY?R<.)]E6)Y8/L"(M%"(`X"'4.@^P,4.C\____@\00B?;)PXGV58GE4X/L
+M!(M%"(M=#(M-$(M0"(`X"'40@^P$45-0Z/S____K"HUV`(/L"%%2_].+7?S)
+MPU6)Y5=64X/L%(M%"(I5$(A5\XMX*(H`B$7R#[;84U?H_/___X/$#&H`4U?H
+M_/___X/$#&H`:@!J`&H`:@-35^C\____@\0@N@````"%P`^$F````/=%#```
+M`/`/E<`/MLB#[`R%R704N"0```"`??,@=`VX-````.L&B?8/MD7S4+A`````
+MA<EU"8M%#,'H&(/(0%"+70S!ZQ`/ML-0BU4,#[;&4`^V50P/M\*%R70)B=@E
+M`/\```G04&H!:@!H``$``/]U%%&`??,P#Y3`#[;`0%`/MEWR4U?H_/___XG&
+M@\0X4U?H_/___XGRB="-9?1;7E_)PXGV58GEBD4(B<*#X@.)T<'A#8V1`"``
+M`*@$=`J-@0`@`P#K"(GVC8(```(`R<-5B>564X/L'(MU"(I%#(A%]V@@H0<`
+MZ/S___^[(*$'`(/$$)"#[`@/MD7W4.BC____!1P!``")!"3_=@SH_/___X/$
+M$(3`>`BX`0```.LDD(/L#&@0)P``Z/S___^#Q!"!PQ`G``"!^S]+3`!VMK@`
+M````C67X6U[)PXGV58GE5E.+70B#[`1J``^V10Q0Z$'___^)QHU`"(D$)/]S
+M#.C\____@\0,:!@!``"-1@Q0_W,,Z/S___^#Q!"-9?A;7LG#C78`58GE@^P,
+M:@`/MD4,4.C^_O__@\`,B00DBT4(_W`,Z/S____)PXUV`%6)Y8M%#&:#?10`
+M=1/W11````#P=0JI`/\``'0+C78`N`$```#K&9!FA<!U"[@!````@WT(`70(
+MN`````"-=@#)PXGV58GE5U93BUT(BWT0BW44N0````"-4PJ+1A")`XM&%(E#
+M!(,^`'4"L0$/MD<$T>`)P6:)2PB+10R#N#@"````=`^#N#@"```"#X5&`0``
+MB?:#?@0!#X7&````9@^V1@^`S!%FB0*#P@)F#[9&#H#,$6:)`H/"`@^V1P3!
+MX`,E^````(#,$F:)`H/"`F8/MD8+@,P39HD"@\("9@^V1@B`S!-FB0*#P@)F
+M#[9&#(#,%&:)`H/"`F8/MD8)@,P49HD"@\("9@^V1@V`S!5FB0*#P@)F#[9&
+M"H#,%6:)`H/"`F;'`D`6@\("@SX`=1FP8(M-#(.Y.`(```(/A((!``"P)NE[
+M`0``L&&+30R#N3@"```"#X1I`0``L#;I8@$``(GV9@^V1@Z`S!%FB0*#P@(/
+MMD<$P>`#)?@```"`S!)FB0*#P@)F#[9&"(#,$V:)`H/"`F8/MD8)@,P49HD"
+M@\("9@^V1@J`S!5FB0*#P@*+1@@E````#\'H&`U`%@``9HD"@\("@SX!&<"#
+MX/N#Z#3I[0```)"#?@0!#X6&````9@^V1@^`S!)FB0*#P@)F#[9&#H#,$F:)
+M`H/"`F8/MD8+@,P39HD"@\("9@^V1@B`S!-FB0*#P@)F#[9&#(#,%&:)`H/"
+M`F8/MD8)@,P49HD"@\("9@^V1@V`S!5FB0*#P@)F#[9&"H#,%6:)`H/"`F;'
+M`D`6@\("@SX!&<"#X/"#P#7K79!F#[9&#H#,$F:)`H/"`F8/MD8(@,P39HD"
+M@\("9@^V1@F`S!1FB0*#P@)F#[9&"H#,%6:)`H/"`HM&""4````/P>@8#4`6
+M``!FB0*#P@*#/@$9P(/@_H/H-HUV`&8/ML`-`)?__V:)`EM>7\G#C78`58GE
+M5U93@^PDBU4(BUT4BW(,#[9%#(M$@B2+>#"-AP0!``!05NC\____B`.#Q`B-
+MAP@!``")1?!05NC\____9@^VP&:)0P*#Q`B-APP!``")1>Q05NC\____9@^V
+MP&:)0P2#Q`B-AQ`!``")1>A05NC\____9@^VP&:)0P:#Q`B-AQ0!``")1>10
+M5NC\____9@^VP&:)0PB#Q!"#?1`!#X6+````@^P(C8<@`0``B47<4%;H_/__
+M_XA%XX/$#(/(@`^VP%#_==Q6Z/S___^#Q`C_=?!6Z/S____!X`AF"4,"@\0(
+M_W7L5NC\____P>`(9@E#!(/$"/]UZ%;H_/___\'@"&8)0P:#Q`C_=>16Z/S_
+M___!X`AF"4,(@\0,#[9%XU#_==Q6Z/S___^#Q!")]H/L"(V'&`$``%!6Z/S_
+M__^(0PJ#Q`B-AQP!``!05NC\____B$,+C67T6UY?R<.)]E6)Y5=64X/L-(M%
+M$&:)1=8/ME4,B570BT4(BWR0)(M',(/`,%"+50C_<@SH_/___X/@'XT4Q0``
+M```IPHVTUT0"``"#Q!"#/@%T08U>%(U%V%#_<P3_==#_=0CH0/[___Z/40D`
+M`(/$#(U5V%)J``^W1=90_W,<:@'_==#_=RC_4QB#Q!A65^B,$0``C67T6UY?
+MR<-5B>575E.#[#R+51"*10R(1<_'1<@`````#[;`BTT(BW2!)&;'1<8``&:+
+M`F:)1="-3=!FBT("9HE!`HM"!(E!!&:+1=")PX/C'XT$W0`````IV(V<QD0"
+M``!FBT$"A,!T+L=%R`$```!FBT$")?\```!FB47&9H%-Q@`!QX9,"0``````
+M`,>&-`(```````"->Q2-1=!FBT`"J`1T&HU%V%#_=P0/MD7/4/]U".A:_?__
+M@\00C78`@SL!#X23````_HY1"0``@^P$C4784(U%T(M`!%`/MT7&4/]W'/]U
+MR`^V1<^)1<!0_W8H_U<8@\084U;HC!```(/$$(.^3`D```!T4(.^1`D```!T
+M1XN&1`D``(-X$`%U.X/L"/]UP/]U".A!$@``@\0(_[9$"0``5N@Z$P``@\00
+MA<!U%X/L!&H`_[9$"0``5N@R!@``@\00C78`C67T6UY?R<-5B>564XM="(/L
+M"&@L#0``_W,,Z/S___^)QH/$#(/(`5!H+`T``/]S#.C\____@\0(:"P-``#_
+M<PSH_/___X/$"&CP!`$`_W,,Z/S___^+50SWTB'0"T40@\0,4&CP!`$`_W,,
+MZ/S___^#Q`AH\`0!`/]S#.C\____@\0,5F@L#0``_W,,Z/S___^-9?A;7LG#
+MC78`58GE5U93@^P<BT4(BT`,B47LQT7H``````^V10R-#(4`````B$WSBD40
+M"$7S#[9%\XM5"(MT@B2#?1@`=&N%]@^$S0```(N>W`D``(/L!(M%%,'@`PM&
+M)%"+1C"#P"10_W7LZ/S___^#Q!`[711T(P^V??.#[`2+1A2-!-A05_]U".B)
+M_?__0X/C'X/$$#M=%'7A@[Y,"0```'4'QT7H`0```(F>W`D``(-]'`!U"H-]
+MZ``/A`,"``"#[`@/MD7S4.AF]___@\`(B47DB00D_W7LZ/S___^)QX/$#`^W
+MV(G8]]!0_W7D_W7LZ/S___^#Q!#VPP@/A!@!``"%]G04QX9,"0```````,>&
+M-`(```````"+30B#>60!=`:#>6@!=1J#[`2X``$``(I-\]/@4%#_=0CH,_[_
+M_X/$$(M%"(-X8`%T#(-X9`%T!H-X:`%U%8/L"`^V1?-0_W4(Z#,)``"#Q!#K
+M>HM5"(-Z7`%T!H-Z8`%U:X/L!&H$#[9=\U/HJ/;__XUP*(DT)/]U[.C\____
+M@\0(5O]U[.C\____QP0D&0```.C\____@\0,:@!6_W7LZ/S___^#Q`A6_W7L
+MZ/S____'!"30!P``Z/S___^#Q`A3_W4(Z(`'``"#Q!"0@^P(#[9=\U/H/_;_
+M_P4<`0``B00D_W7LZ/S___^#Q!!3:@!J`?]U"(M-"/]1(.FI````]\<0````
+M=%&#[`@/MD7S4/]U".@Q!P``@\00BT4(@WAD`70&@WAH`74;@^P$:@"X``$`
+M`(I-\]/@4/]U".@7_?__@\00#[9%\U!J`6H!_W4(BU4(_U(@ZU`/M\?VQ`%T
+M2(.^-`(```%U*,>&3`D```````#'AC0"````````@^P$4`^V1?-0_W4(Z-KZ
+M__^#Q!"#/0`````!=0Z#[`Q6Z'4/``"#Q!")]HUE]%M>7\G#58GE4X/L!(M=
+M"`^V10S!X`(+11`/MM"+3),DA<EU#8/L"%)3Z*<-``#K19"+D40)``"%TG42
+M@^P(#[;`4%/HC0T``.LKC78`@SH!=`:#>A`!=!&#[`@/ML!04^AP#0``ZPZ)
+M]H/L"%)1Z`H```")]HM=_,G#C78`58GE5U93@^PDBU4(BT(HBW`,BUHPB@J#
+MX0.)SP^V`H/@!,'H`HA%V(V#(`$``%!6Z/S___^#Q`B!PQP!``!35NC\____
+MB,.#Q`RX``$``(GYT^#WT%"`?=@!&<`E``#__P44``,`4%;H_/___X/$$(3;
+M#X@0`0``]L,!=!>#[`1J`?]U#/]U".C'`0``Z?8```")]HM5#(M"%(/X`70M
+M@_@!<A"#^`(/A(4```#IU@```(GV@^P$:@#_=0S_=0CHD`$``(/$$.F\````
+M]L-`=$^#[`B+10R#P!10_W4(Z*T```"#Q!"#^`%U((M-#(-Y(``/A9````"#
+M[`1J`%'_=0CH3@$``(/$$.M]@^P$:@'_=0S_=0CH.0$``(/$$.MH@^P$:@'_
+M=0S_=0CH)`$``.M6#[;#J$!T3Z@@=4N+10R#>"``=1.#[`1J`%#_=0CH``$`
+M`(/$$.LO@^P(BT4,@\`44/]U".@E````@\00A<!U%H/L!&H!_W4,_W4(Z-(`
+M``"#Q!"-=@"-9?1;7E_)PU6)Y5=64X/L#(M]"(MU#+@`````@7X,_P````^&
+MF````(L6@_H!=%&X`````(/Z`0^"@P```(/Z`G5YNP````"#[`2+1@@/MQ!2
+M@\`"B48(BT<P!0`!``!0BT<H_W`,Z/S___^#Q!!#@?O_````=M"!;@P``0``
+MZSN[`````(GV@^P(BT<P!0`!``!0BT<H_W`,Z/S___^+5@AFB0*#1@@"@\00
+M0X'[_P```';3@6X,``$``+@!````C67T6UY?R<.-=@!5B>575E.#[!R+=0B_
+M`````(M=#(/#%(U%V%#_<P0/M@90_W8HZ&+V__^#Q!"#?1`!=1%FOP$`QX9,
+M"0```````(UV`(/L!(U%V%!J`&H`_W,@5P^V!E#_=BC_4QR#Q!C_=0Q6Z)L)
+M``"#Q!"#?1`!=1:#/0`````!=0V#[`Q6Z!@,``"#Q!"0@[Y$"0````^$NP``
+M`(N&1`D``(-X$`%U+X/L"%!6Z$4,``"#Q!"%P`^%F@```(/L!&H`_[9$"0``
+M5N@Y____@\00Z8$```"0@[XX`@```'4S@^P(#[8&4/]V*.@<"@``@\0(BT8P
+M@\`H4(M&*/]P#.C\____QP0D`0```.C\____@\00@^P(#[8&4/]V*.@9"@``
+MBYY$"0``@\00A=MT*(-[$`!U(HGV@^P$C4,44%-6Z/H*``"+6PB#Q!"%VW0(
+M@WL0`'3BB?:-9?1;7E_)PU6)Y5=64X/L%(M="(M#*(MX#(M#,(E%\(G&@\8H
+M5E?H_/___X/$$*@$=#:#[`1J`E97Z/S___^#Q`A65^C\____QP0DT`<``.C\
+M____@\0(#[8#4/]S*.@8`@``@\00ZQ6#[`1J`HM%\(/`*%!7Z/S___^#Q!#&
+M@SP"````QH-0"0```,:#40D```#'@]@)````````QX/<"0```````,>#-`(`
+M``````#'@]0)```@````N@````")E)-4"0``0H/Z'W[SN@````")]HT$U0``
+M```IT,>$PT0"```!````0H/Z'W[FQX-$"0```````,>#2`D```````#'@TP)
+M````````@^P$:@"+1?"#P`A05^C\____@\0,:!@!``"+1?"#P`Q05^C\____
+M@\0,_W,8BT7P@\`04%?H_/___X/$#(M#'"4`_/__4(M%\(/`%%!7Z/S___^#
+MQ`QJ`(M%\(/`&%!7Z/S___^#Q`S_<R"+1?"#P!Q05^C\____@\0,:@"+1?"#
+MP"!05^C\____@\0,BT,DL`!0BT7P@\`D4%?H_/___[@!````C67T6UY?R<.-
+M=@!5B>575E.#["R+=0B+111FB476@WT,``^%F@```+L`````B?:-!-T`````
+M*=B-!,:#N$0"````=72#N%0"```!=1J+D%P"``"+N'@"``"+@'0"``")1=#K
+M)(UV`(T$W0`````IV(T$QHN07`(``(NX=`(``(N`<`(``(E%T(U%V%!2#[8&
+M4/]V*.CR\O__@\0,C4784&H`#[=%UE!7_W40#[8&4/]V*/]5T(/$($.#^Q\/
+MCFW___^-9?1;7E_)PY!5B>575E.#[!R+70@/MG4,B?"#X`3!Z`*(1=B_`P``
+M`"'W@WM<`70&@WM@`75K@^P(B?H/ML*)PL'B"(V"#`$``(!]V`!T"8V"#`$#
+M`.L&D`4```(`4/]S#.C\____B<&#X?R#R0&#Q`Q1B?H/ML*)PL'B"(V"#`$`
+M`(!]V`!T"(V"#`$#`.L%!0```@!0_W,,Z/S___^#Q!"#[`B)^@^VPHG"P>((
+MC8)T`0``@'W8`'0*C8)T`0,`ZP>)]@4```(`4/]S#.C\____B<&`X1^)\@^V
+MP@^V5!AZP>(%@>+@````"=&`Y></MH08@@```,'@"R4`&```"<&#Q`Q1B?H/
+MML*)PL'B"(V"=`$``(!]V`!T"8V"=`$#`.L&D`4```(`4/]S#.C\____@\00
+MC67T6UY?R<.-=@!5B>575E.#[`R+70@/MG4,5NB"[?__@^P$C7@H5E/H9>[_
+M_X/$#&H$5_]S#.C\____@\0(5_]S#.C\____QP0D&0```.C\____@\0,:@!7
+M_W,,Z/S___^#Q`A7_W,,Z/S___^#Q`A64^A;_O__@\0(5E/HR>W__XUE]%M>
+M7\G#D%6)Y5=64X/L#,9%\@#&1?,`C78`BD7RBE7SC1R"#[;;4^CR[/__B<=J
+M`HUP*%:+10C_<`SH_/___X/$"%:+50C_<@SH_/___X/$"%/_=0CH+/___X/$
+M#&H`5HM%"/]P#.C\____@\0,:!\!``!7BU4(_W(,Z/S___^#Q`QJ`(U'!%"+
+M10C_<`SH_/___X/$#&H`C4<(4(M5"/]R#.C\____@\0,:@"-1PQ0BT4(_W`,
+MZ/S___^#Q`QJ`(U'$%"+50C_<@SH_/___X/$#&H`C4<44(M%"/]P#.C\____
+M@\0,:@"-1QA0BU4(_W(,Z/S___^#Q`QJ`(U''%"+10C_<`SH_/___X/$#&H`
+MC4<D4(M5"/]R#.C\____@\0,:@"-1R!0BT4(_W`,Z/S___^#Q`QJ`(U'+%"+
+M50C_<@SH_/___X/$#&B\````C4<T4(M%"/]P#.C\____@\00_D7S@'WS`P^&
+MK/[__X!]\@$9VX'C``#__X'#```#`(/L!&H`C4,,4(M5"/]R#.C\____@\0,
+M:@"-0Q!0BT4(_W`,Z/S___^#Q`QJ`(U#%%"+50C_<@SH_/___X/$#&H`C4,8
+M4(M%"/]P#.C\____@\0(@\,@4XM5"/]R#.C\____)1P<'!P-`P,#`X/$#%!3
+MBT4(_W`,Z/S___^#Q!#^1?*`??(!#X8'_O__C67T6UY?R<.)]E6)Y8/L#&C_
+M_\\/:&P$`0"+10C_<`SH_/___\G#C78`58GE4X/L!(M="(M#!+``/0``@%!T
+M)X/L"&@L#0``_W,,Z/S___^#R`&#Q`Q0:"P-``#_<PSH_/___X/$$(/L"&@`
+M#0``_W,,Z/S___\E__\`_X/$#%!H``T``/]S#.C\____@\0,:@!H!`T``/]S
+M#.C\____@\0,:@!H.`P``/]S#.C\____@\0,:/\``0!H!!T``/]S#.C\____
+M@\0,:@!H9!T``/]S#.C\____@\0,:@!H*`P``/]S#.C\____@\0,:@!H6!T`
+M`/]S#.C\____@\0,:@!H7!T``/]S#.C\____@\0,:@!H0!T``/]S#.C\____
+M@\0,:@!H1!T``/]S#.C\____@\0,:@!H2!T``/]S#.C\____@\0,:@!H4!T`
+M`/]S#.C\____BUW\R<.-=@!5B>6+50B+30S'00@`````BX)("0``B4$,@[I(
+M"0```'0)BX)("0``B4@(B8I("0``@[I$"0```'4&B8I$"0``R<.)]E6)Y5.+
+M70B+30R#>0@`=1B+00R)@T@)``"%P'04QT`(`````.L+B?:+40B+00R)0@R#
+M>0P`=1F+00B)@T0)``"%P'05QT`,`````.L,C78`BU$,BT$(B4((QT$(````
+M`,=!#`````!;R<.)]E6)Y5=64X/L#(M]"(MU#(M=$(,[`'49@^P$:B"-0P10
+MC4844.C\____@\00ZQV)]H/L!&HDC4,$4(U&%%#H_/____Z'4`D``(/$$(L#
+MB4805E?H^?[__\<&`````/Z'/`(``(UE]%M>7\G#D%6)Y593BUT(BW4,@WX0
+M`'0&_HM0"0``5E/H"O___XN#U`D```^V5@2)E(-4"0``0(F#U`D``,<&`0``
+M`/Z+/`(``(UE^%M>R<.-=@!5B>6*10@\`W82#[;(C4P)`K@!````T^#K$(GV
+M#[;(C4P)`;@!````T^#)PU6)Y593BW4(#[9=#%/HPO___X/L!`E&5%/H`NC_
+M_P4<`0``B00D_W8,Z/S___^#Q`R)V8/A`[@``0``T^#WT%"#XP3!^P*#^P$9
+MP"4``/__!10``P!0_W8,Z/S___^#Q`S_=E1H9!T``/]V#.C\____@\0(:&0=
+M``#_=@SH_/___XUE^%M>R<-5B>53@^P$BUT(#[9%#%#H./____?0(T-4B4-4
+M4&AD'0``_W,,Z/S___^+7?S)PY!5B>575E.#[!"*70R+10B+0`R)1?`/MM.+
+M10B+=)`DBWXPQX8T`@```0```(/B!,'J`HG9@^$#N`$!``#3X/?04(#Z`1G`
+M)0``__\%%``#`%#_=?#H_/___X/$#&H`BT8P@\`(4/]U\.C\____@\0(#[;;
+M4_]U".A4____@\0(C8<<`0``4/]U\.C\____QX9``@```0```(/$#&H!@\<H
+M5_]U\.C\____C67T6UY?R<.-=@!5B>575E.#[!"+10B+>`P/MG4,BT2P)(M8
+M,,>`-`(```````!J`H/#*%-7Z/S___^#Q`A35^C\____@\0(5O]U".A._O__
+MC67T6UY?R<.)]E6)Y593BUT(BT,HBW`,_W40_W4,4XN#V`D``,'@!0-#$%#H
+MF>?__XN3V`D``$*#XA^)D]@)``#^@U$)``"#Q`R+0QPE`/S__\'B!0G04(M#
+M,(/`%%!6Z/S___^-9?A;7LG#B?95B>53@^P$BUT(:@!J`FH`4^A:]O__B1PD
+MZ)[T__^)'"3H_/___X/$$(/X`74>QX-,"0```0```(/L"`^V`U#_<RCHF?W_
+M_X/$$(GVBUW\R<.-=@!5B>575E.#[!2+50B+?0R#QQ2+0BB+<`R+6C"-@QP!
+M``!05NC\____)<$```"#Q!"Z`````(/X0`^%T@$``(-_!`%U<(/L!`^V1Q%0
+MC8,$`0``4%;H_/___X/$#`^V1Q-0C8,(`0``4%;H_/___X/$#`^V1Q50C8,,
+M`0``4%;H_/___X/$#`^V1Q=0C8,0`0``4%;H_/___X/$#`^V1QE0C8,4`0``
+M4%;H_/___X/$$.LTB?9F]T<0`/]U(&;W1Q(`_W489O='%`#_=1!F]T<6`/]U
+M"&;W1Q@`_W0*N@````#I*@$``(/L!`^V1Q!0C8,$`0``4%;H_/___X/$#`^V
+M1Q)0C8,(`0``4%;H_/___X/$#`^V1Q10C8,,`0``4%;H_/___X/$#`^V1Q90
+MC8,0`0``4%;H_/___X/$#`^V1QA0C8,4`0``4%;H_/___X/$#`^V1QI0C8,8
+M`0``4%;H_/___X/$#`^V1QM0C8,<`0``4%;H_/___X/$$(,_`@^%A````(/L
+M"(V#(`$``%!6Z/S___]J9&H*4U;H_/___X/$(+H`````A<!T9(/L"(V#'`$`
+M`%!6Z/S___\EB0```(/$$+H`````@_@(=4+'1?``````@<,``0``D(/L!(M'
+M"`^W$%*#P`*)1PA35NC\____@\00_T7P@7WP_P```';:@6\,``$``+H!````
+MB?:)T(UE]%M>7\G#B?95B>575E.#[!"+=0C'1E0`````:@!H9!T``/]V#.C\
+M____QT9<`````,=&8`````#'1F0`````QT9H`````,=&;`````#'1G``````
+MQT9T`````,9&>`&#Q!"X`````(-^(``/A',"``"X`````&:!?@:!4`^%8@(`
+M``^V5@6#^@$/A%4"``"#^@%_!H72=`GK&8/Z`G0+ZQ+'1F`!````ZQ#'1F0!
+M````ZP?'1F@!````LP"#[`@/MM.)T(/@`\'@"(V(=`$``/;"!'0'!70!`P#K
+M!HV!```"`%#_=@SH_/___P^VRXG"@>+@````P>H%B%0Q>B4`&```P>@+B(0Q
+M@@```(/$$$.`^P=VIX/L#%;H8O7__XDT).AJ]___B30DZ(+W__^#Q`QJ`&CP
+M!`$`_W8,Z/S___^#Q`AH+`T``/]V#.C\____B<>#Y_Z#Q`Q7:"P-``#_=@SH
+M_/___X/$"&@`#0``_W8,Z/S___^#Q!"H,'0YBT9$J>`#`(!T""4?_/]_B49$
+M@WY<`702@WY@`70,@WYD`70&@WYH`743BT9$J!!T#(/@[XE&1.L$@V9$S[,`
+M@^P(#[;#4%;H__+__X/$$$.`^P=VZH/L!/]V1&@`#```_W8,Z/S___^#Q`S_
+M=DAH*`P``/]V#.C\____@\0,_W9,:%P=``#_=@SH_/___[,`@\00@^P$#[;#
+M_W2&$(#[`1G`)0``__\%#``#`%#_=@SH_/___X/$#`^VP_]TAAB`^P$9P"4`
+M`/__!1```P!0_W8,Z/S___^#Q!!#@/L!=K/'1E15JP8`LP")]H/L"`^VPU!6
+MZ,OA__^#Q!!#@/L'=NJ#[`QH4,,``.C\____@\00@WYD`70&@WYH`75$OP``
+M``"S`(UV`(/L"`^VPXE%\%!6Z/S___^#Q!"%P'4+9K@``8I-\-/@"<=#@/L'
+M=MB#[`17:`#_``!6Z/WG__^#Q!"X`0```)"-9?1;7E_)PU6)Y8/L#&H`:&0=
+M``"+10C_<`SH_/___[@!````R<.058GEQP4``````0```,G#D%6)Y<<%````
+M``````#)PY!5B>564XMU"(I5#`^VPHM<AB2X`````(7;="P/ML)0Z$C@__^#
+M[`B)0S")<RC'@TP)````````QX,T`@```````%/HX>[__XUE^%M>R<.)]E6)
+MY0^V50R+10B+5)`DN`````"%TG0-@[I,"0```0^5P`^VP,G#B?95B>564XMU
+M"(I%#(G"@^(#B='!X0B-D0`!``"H!'0)C9D``0,`ZP>0C9H```(`@^P(4_]V
+M#.C\____@^`/@\00@_@!=`^#^`%R0H/X`W0UZSN-=@"#[`A3_W8,Z/S____'
+M!"1`#0,`Z/S___^#Q`A3_W8,Z/S___^#X`^#Q!"#^`-U"9"X`0```.L&D+@`
+M````C67X6U[)PU6)Y5=64X/L+(M]"(I%#(A%\X/@`XA%YP^V5?.)T(/@!(G&
+MP>X"BU27)(M/#(E-[+@`````A=(/A!\"``"+0C")1>BX`````(.Z3`D```$/
+MA`<"``"#[`@/ME7SB57<4E?HYM___X/$#&H$BUWH@\,H4_]U[.C\____@\0(
+M4_]U[.C\____QP0D&0```.C\____@\0,:@!3_W7LZ/S___^#Q`A3_W7LZ/S_
+M__^#Q`C_==Q7Z-3O___'1>``````@\00#[9%YXG!P>$(B4W4@<$(`0``B4W8
+MP>`(B470@^P(BU74C8((`0,`B?&$R74)BU78C8(```(`4/]W#.C\____B<.#
+MX_"#RP&#Q`Q3BT70C9`(`0``C8`(`0,`B?&$R74&C8(```(`4/]W#.C\____
+M@\0(#[9%YXG"P>((C8((`0``B?&$R70+C8((`0,`ZPB-=@`%```"`%#_=PSH
+M_/___\<$)!D```#H_/___X/C\(/$#%,/MD7GB<+!X@B-@@@!``")\83)=`J-
+M@@@!`P#K!XGV!0```@!0_W<,Z/S___^#Q`@/MD7GB<+!X@B-@@@!``")\83)
+M=`J-@@@!`P#K!XGV!0```@!0_W<,Z/S____'!"30!P``Z/S___^#Q`@/MEWS
+M4U?H_/___X/$$(7`=1[_1>"#?>`##X7=_O__@^P(4U?H^MW__[@`````ZTN#
+M[`B+1>@%'`$``%#_=>SH_/___R7`````@\00@_A`=!6#[`@/MD7S4%?HQ-W_
+M_[@`````ZQ6#[`@/MD7S4%?HK]W__[@!````B?:-9?1;7E_)PU6)Y5=64X/L
+M#(M5"`^V=10/MD4,BUR")+D`````A=L/A(L```"+4@R)5?"+>S"Y`````(.[
+M3`D```%T=(/L"%?_=?#H_/___XG"@\00@WT0`'4IC4;_N0`````\'W=1QX,X
+M`@```````(/BP(GQ#[;!2`G"@,X"ZQ.-=@#'@S@"```!````@>+`_?__@WL,
+M`74&@,X!ZP20@.;^@^P$4E?_=?#H_/___[D!````C78`B<B-9?1;7E_)PXGV
+M58GE4X/L!(M="(I-#`^VP8M4@R2X`````(72="JX`````(.Z3`D```%T',>"
+M3`D```$```"#[`@/ML%04^B2]/__N`$```"+7?S)PU6)Y5.#[`2+70B*50P/
+MML*Y`````(-\@R0`="`/MM*+1),DQX!,"0```````(/L"%)3Z`7U__^Y`0``
+M`(G(BUW\R<.058GE4X/L!`^V50R+10B+7)`DN`````"%VW0HN`````"#NTP)
+M```!=!IJ`&H"_W404^CFZ___B1PDZ"KJ__^X`0```(M=_,G#58GE#[95#(M%
+M"(M4D"2X_P```(72=`</MH(\`@``R<-5B>564XM5"(MR#`^V10R+1((DN@``
+M``"%P'18BU@P@^P(C4,L4%;H_/___X/$$(-]$`%U'[H`````J`)U-H/L!&H"
+MC4,L4%;H_/___X/$$.L=B?:Z`````*@"=!>#[`1J`(U#+%!6Z/S___^#Q!"Z
+M`0```(G0C67X6U[)PXUV`%6)Y5=64X/L#(I=#`^V=1`/MGT4B-J#X@.)V(/@
+M!,'H`O?&^````'4(]\?\````=`NX`````.F)````D`^VTHG1P>$(C9%T`0``
+MA,!T#H'!=`$#`(E-\.L,C78`@<(```(`B57P@^P(_W7PBT4(_W`,Z/S___\D
+M'XGRP>(%@>+@````"="`Y.>)^L'B"X'B`!@```G0@\0,4/]U\(M5"/]R#.C\
+M____#[;#B?F+50B(C!""````B?&(3!!Z@\00N`$```"-9?1;7E_)PU6)Y5=6
+M4X/L%(MU"(I=#+\#````(=^#XP3!ZP*`^P$9P"4``/__!1@``P!0_W8,Z/S_
+M__^)^0^VT8U*&+H!````T^()T(/$#%"`^P$9P"4``/__!1@``P!0_W8,Z/S_
+M__^#Q`B`^P$9P"4``/__!1@``P!0_W8,Z/S___^#Q!"X`0```(UE]%M>7\G#
+M58GE5U93@^P4BW4(#[9]#(GX@^`#B$7SB?@/MM")T(/@!(G#P>L"4E;H;NK_
+M_X/$"(#[`1G`)0``__\%&``#`%#_=@SH_/___P^V3?.#P1BZ_O___]/"(="#
+MQ`Q0@/L!&<`E``#__P48``,`4/]V#.C\____@\0(@/L!&<`E``#__P48``,`
+M4/]V#.C\____@\0(#[9%\XG"P>((C8((`0``A-MT"HV""`$#`.L'B?8%```"
+M`%#_=@SH_/___X/@\(/(`8/$#%`/MD7SB<+!X@B-@@@!``"$VW0)C8((`0,`
+MZP:0!0```@!0_W8,Z/S___^#Q`B)^@^VPE!6Z)OI__^#Q!"X`0```(UE]%M>
+M7\G#C78`58GE5U93@^P4BWT(BW40BD4,B$7SBT<,B47L#[9%\XM<AR2)PH/B
+M`XG1P>$(C9%T`0``J`1T"(V!=`$#`.L&C8(```(`4/]W#.C\____B498@\00
+MA=MU$,<&`````+@!````Z?\```"+0S")1>B#[`@/MD7S4%?H_/___XD&@\00
+MN`$```"#/@`/A-@```"+@TP)``")1BR+@S@"``")1C"*@SP"``"(1C2Z````
+M`)"*1!-JB$06!$*#^B=V\H/L"/]UZ/]U[.C\____B48X@\0(BT7H@\`04/]U
+M[.C\____B48\@\0(BT7H@\`44/]U[.C\____B49`@\0(BT7H@\`84/]U[.C\
+M____B49$@\0(BT7H@\`<4/]U[.C\____B49(@\0(BT7H@\`@4/]U[.C\____
+MB49,@\0(BT7H@\`D4/]U[.C\____B490@\0(BT7H@\`H4/]U[.C\____B494
+MN`$```"-9?1;7E_)PY!5B>6#[#S'1<@`````BT40B47,BT44B474BT489HE%
+MV(M%'&:)1=J+12")1=R+122)1>"+12B)1>2+12R)1>B-1<A0#[9%#%#_=0CH
+M_/___\G#B?95B>575E.#[`R*10R(1?,/ML"+50B+=((DN`0```"%]@^$BP$`
+M`+@!````@[Y,"0````^$>0$``+@"````@+X\`@``'P^$9P$``(N&U`D``$B)
+MAM0)``"+O(94"0``C03]`````"GXC83&1`(``(E%[(GZB%`$BT40@S@`#X7.
+M````B<.#PP2#OC@"```"=0S'0P0!````ZT>-=@`/MT,,#[=3#E#_<PA2_W8(
+MZ/O6__^#Q!")0P2#^`%U)(-^"`!U'HN&U`D``(F\AE0)``!`B8;4"0``N`,`
+M``#IT0```("^4`D```!U4X.^-`(```!U(H/L"`^V7?-3_W4(Z/KM__^#Q`A3
+M_W4(Z![N__^#Q!"-=@"#[`3_=1#_=>Q6Z&WL__^#Q`R+11"#P`10_W7L5NCZ
+M[O__@\00ZW&0@^P$_W40_W7L5NA%[/__@\00ZUR#[`3_=1#_=>Q6Z#'L__^#
+MQ!"`OCP"```!=4&#OC0"```!=1.#[`@/MD7S4/]U".A<[O__@\00@^P(_W7L
+M5NA5[___@\00A<!U$O]U[%;H6>S__[@!````ZP>)]K@`````C67T6UY?R<.-
+M=@!5B>575E.#["2+10B+0`R)1>1H8!T``%#H_/___XG&BU4(BU)4B57P@\00
+MN`````"%U@^$9P$``/?&```$`'0X@^P(:%@=``#_=>3H_/___XG#@\0,]]!0
+M:%@=``#_=>3H_/___VH`4VH`_W4(BU4(_U(@@\0@B?;&1>L`]\;_`0``#X0`
+M`0``@'WK`1G;@>,``/__@<,4``,`@^P$:N]3_W7DZ/S___^#Q`A3_W7DZ/S_
+M__^)QX/$#/?0@\@04%/_=>3H_/___X/$"(!]ZP$9P"4``/__!0@``P!0_W7D
+MZ/S___^)1>"S`(/$$`^V1>N)1=B0#[;+N``!``#3X"'XB47LN`$```#3X(GR
+M@^(!(?AU!(72="&#[`174E"+1>"#X!]0#[;#4`^V1>M0_W4(Z'?;__^#Q""#
+M?>P`=#:+5=B)5=R)T,'@`@G8#[;`4.@XZ___@\0$A47P=!B#[`0/ML-0_W7<
+M_W4(Z`+>__^#Q!"-=@#![@+!;>`(0X#[`P^&;____^L$D,'N"-'N_D7K@'WK
+M`0^&XO[__[@!````C67T6UY?R<.058GE@^P,:@!H9!T``(M%"/]P#.C\____
+MN`$```#)PY!5B>6#[`R+10C_<%1H9!T``/]P#.C\____N`$```#)PU6)Y5=6
+M4X/L#(MU$(M]%+L`````.?-S.8/L"(M%#`4<`0``4/]U".C\____@\00A,!X
+M#:@!#Y3`#[;`ZQF-=@"#[`Q7Z/S___^#Q!!#.?-RQ[@`````C67T6UY?R<.)
+M]E6)Y5.#[`B+70AJ`(M#,`4@`0``4(M#*/]P#.C\____@\0(BT,P!2`!``!0
+MBT,H_W`,Z/S___^+7?S)PU6)Y5.#[`B+70AJ`HM#,`4@`0``4(M#*/]P#.C\
+M____@\0(BT,P!1P!``!0BT,H_W`,Z/S___^+7?S)PU6)Y5=64X/L#(MU"(M&
+M*(M`#(E%\(M^,+L`````N`````"#OC0"```!#X2M````@^P(C8<@`0``4/]U
+M\.C\____@\00J(%T$(/L#&HRZ/S___^#Q!"-=@"#[`B-AR`!``!0_W7PZ/S_
+M__^#Q!"H@70XB=A#9CVW"W<H@^P(#[8&4/]V*.C\____@\00A<!T3(/L#&CH
+M`P``Z/S___^#Q!#KMK@`````ZS-J9&H*5_]U\.C\____@\0(C8<<`0``4/]U
+M\.C\____)<$```"#Q!"#^$`/E,`/ML"-=@"-9?1;7E_)PU6)Y5=64X/L#`^V
+M50R+10B+7)`DN`````"%VW1KBT,HBW@,BW,PN`````"#NTP)```!=%2#[`Q3
+MZ/S___^#Q`QHX0```(V&'`$``%!7Z/S___]J9&@0)P``5E?H_/___X/$((7`
+M=1&#[`Q3Z/S___^X`````.L1D(/L#%/H_/___[@!````B?:-9?1;7E_)PU6)
+MY593BTT(BE4,#[;"BT2!)+X`````A<!T<8U8-(/L#&CL````:@!J`&H`:@!J
+M`&H`:``!``!3:@!J`0^VPE!1Z/S___^#Q$"^`````(7`=#KV@Z````#@="RQ
+M`+X!````@+O^`0``I74AN@`````/M\("#!A"9H'Z_P%V\KX`````A,EU!;X!
+M````B?"-9?A;7LG#C78`58GE@^P(#[95#(M%"(M4D"2X`````(72=!>X````
+M`(.Z3`D```%T"8/L#%+H_/___\G#D%6)Y8/L%&CO````:@`/MD4@4`^V11Q0
+M#[9%&%`/MD444`^V11!0:@!J`&H`:@`/MD4,4/]U".C\____R<.-=@!5B>57
+M5E.#[`R*10R(1?.+32!FB4WPBT4D9HE%[HM-*&:)3>R+?2R+=3"*732*13B(
+M1>L/MD7SN@````"+30B#?($D`'0^@^P,#[9%ZU`/ML-0#[?&4`^WQU`/MT7L
+M4`^W1>Y0#[=%\%#_=1S_=1C_=13_=1`/MD7S4/]U".C\____B<*)T(UE]%M>
+M7\G#B?95B>575E.#['B+10B+52!FB578BTTD9HE-R(M5*&:)5;B+32QFB4VH
+MBU4P9HE5F(I--(A-EXI5.(A5E@^V50R+7)`DBW`,BWLP4^BA_/__@\00N@``
+M``"%P`^$K0(``(/L#%/H_/___X/$$(-]%`%U>X/L!(M-V`^VQ5"-AP0!``!0
+M5NC\____@\0,BU7(#[;&4(V'"`$``%!6Z/S___^#Q`R+3;@/ML50C8<,`0``
+M4%;H_/___X/$#(M5J`^VQE"-AQ`!``!05NC\____@\0,BTV8#[;%4(V'%`$`
+M`%!6Z/S___^#Q!#K/8UV`/=%V`#_``!U)_=%R`#_``!U'O=%N`#_``!U%?=%
+MJ`#_``!U#/=%F`#_``!T#8UV`+H`````Z>8!``"#[`0/MD784(V'!`$``%!6
+MZ/S___^#Q`P/MD7(4(V'"`$``%!6Z/S___^#Q`P/MD6X4(V'#`$``%!6Z/S_
+M__^#Q`P/MD6H4(V'$`$``%!6Z/S___^#Q`P/MD684(V'%`$``%!6Z/S___^#
+MQ`P/MD674(V'&`$``%!6Z/S___^#Q`P/MD664(V''`$``%!6Z/S___^#Q!"#
+M?1``=3MJ9&CPN@0`5U;H_/___X/$$(7`=1.#[`Q3Z/S___^Z`````.DB`0``
+M@^P,4^C\____N@$```#I#P$``&ID:/"Z!`!75NC\____@\00A<!U$X/L#%/H
+M_/___[H`````Z><```"#[`B-AQP!``!05NC\____@\00J`AU$X/L#%/H_/__
+M_[H`````Z;T```#'19``````BT4<.460<VJ-EP`!``")58R`?9``=15J9&A0
+MPP``5U;H_/___X/$$(7`=&N#?1`!=1N#[`C_=8Q6Z/S___^+39"+51AFB01*
+M@\00ZQJ#[`2+39"+51@/MP1*4/]UC%;H_/___X/$$/]%D(M-'#E-D'*?:F1H
+M4,,``%=6Z/S___^#Q!"%P'4@@^P,4^C\____N@````#K'X/L#%/H_/___[H`
+M````ZP^#[`Q3Z/S___^Z`0```)")T(UE]%M>7\G#B?95B>575E.#[!"+70B+
+M0RB+<`R+>S!J!HV'(`$``%!6Z/S___^#Q`B+0S`%(`$``%!6Z/S____'!"0*
+M````Z/S___^)'"3H_/___\<$)/0!``#H_/___\<$)/0!``#H_/___\<$)/0!
+M``#H_/___\<$)/0!``#H_/___[L`````@\00B?:#[`B-AQP!``!05NC\____
+M@\00A,!X";@!````ZR")]H/L#&CT`0``Z/S___^#Q!!#@?L/)P``=L>X````
+M`(UE]%M>7\G#B?95B>53@^P0BUT(4^@D____@\00N@$```"#^`%T%X/L#&CT
+M`0``Z/S___^)'"3H`O___XG"B="+7?S)PY!5B>564XMU"(/L!&B@````H00`
+M``"+0!@%```$`%!6Z/S___^[`````(/$$(/L"*$$````BT`0!0``!`!05NC\
+M____@\000X/[!'[@NP````"-=@"#[`BA!````(M`%`4```0`4%;H_/___X/$
+M$$.#^P5^X+L`````C78`@^P(H00```"+0!`%```$`%!6Z/S___^#Q!!#@_L$
+M?N"-9?A;7LG#D%6)Y5.#[`B+70AH@````*$$````BT`,!0``!`!04^C\____
+M@\0,:+````"A!````(M`&`4```0`4%/H_/___XM=_,G#58GE5E.+=0B#[`Q6
+MZ`?___^#Q`QJ`*$$````BT`(!0``!`!05NC\____@\0(H00```"+``4```0`
+M4%;H_/___XC#B30DZ'+___\/MMN)V(UE^%M>R<.)]E6)Y5=64X/L%(M="&@L
+M#0``4^C\____B<>#Q`R#R`%0:"P-``!3Z/S___^#Q`AH\`0!`%/H_/___XG&
+M@^!B@\00@_AB=!J#[`2)\(/(8@^VP%!H\`0!`%/H_/___X/$$(/L"&@```0`
+M4^C\____B1PDZ$K^__^#Q`QJ!Z$$````BT`(!0``!`!04^C\____@\0,:A&A
+M!````(L`!0``!`!04^C\____@\0,:@6A!````(M`"`4```0`4%/H_/___X/$
+M#&H1H00```"+``4```0`4%/H_/___XD<).B$_O__@\0,5FCP!`$`4^C\____
+M@\0(:/`$`0!3Z/S___^#Q`Q7:"P-``!3Z/S___^#Q!"-9?1;7E_)PY!5B>57
+M5E.#[!2+70AH+`T``%/H_/___XG'@\0,@\@!4&@L#0``4^C\____@\0(:/`$
+M`0!3Z/S___^)QH/@8H/$$(/X8G0:@^P$B?"#R&(/ML!0:/`$`0!3Z/S___^#
+MQ!"#[`AH```$`%/H_/___XD<).@R_?__@\0,:@>A!````(M`"`4```0`4%/H
+M_/___X/$#&H`H00```"+``4```0`4%/H_/___X/$#&H%H00```"+0`@%```$
+M`%!3Z/S___^#Q`QJ`*$$````BP`%```$`%!3Z/S___^)'"3H;/W__X/$#%9H
+M\`0!`%/H_/___X/$"&CP!`$`4^C\____@\0,5V@L#0``4^C\____@\00C67T
+M6UY?R<.058GE4X/L$(M="%/H@/S__X/$#&H*H00```"+0`@%```$`%!3Z/S_
+M__^#Q`QJ`*$$````BP`%```$`%!3Z/S___^)'"3HZ_S__X/$"&@!``0`4^C\
+M____@\00NO____^H`G50@^P,4^@D_/__@\0,:@&A!````(L`!0``!`!04^C\
+M____B1PDZ*C\___'!"1D````Z/S___^#Q`AH`0`$`%/H_/___]'H@^`!@\00
+M@_@!&=*)T(M=_,G#B?95B>575E.#[!2+?0B*10R(1?.+7PQH+`T``%/H_/__
+M_XE%[(/$#(/(`5!H+`T``%/H_/___X/$"&CP!`$`4^C\____B<:#X&*#Q!"#
+M^&)T&H/L!(GP@\AB#[;`4&CP!`$`4^C\____@\00@^P(:```!`!3Z/S___^#
+MQ`R*1?.(1WD/ML!0:`#@!0!3Z/S___^#Q`Q6:/`$`0!3Z/S___^#Q`AH\`0!
+M`%/H_/___X/$#/]U[&@L#0``4^C\____@\00C67T6UY?R<.-=@!5B>6#[`B+
+M50B*30R`?1``=`ZX`0```-/@"$)YZPR)]KC^____T\`@0GF#[`@/MD)Y4%+H
+M_/___\G#B?95B>575E.#[!2+?0C&1?,`:"P-``!7Z/S___^)1>B#Q`R#R`%0
+M:"P-``!7Z/S___^#Q`AH\`0!`%?H_/___XE%[(/@8H/$$(/X8G0;@^P$BD7L
+M@\AB#[;`4&CP!`$`5^C\____@\00@^P(:```!`!7Z/S___^#Q`AH```$`%?H
+M_/___X/$$&8]5:H/A?4```"^`````(UV`+L`````.?-_)XUV`(/L!&B@````
+MH00```"+0!@%```$`%!7Z/S___^#Q!!#.?-^W('^R````'X0@^P,:@'H_/__
+M_X/$$(UV`(/L"&@```0`5^C\____B<.#Q`QHL````*$$````BT`8!0``!`!0
+M5^C\____@\009H'[5:IU%$:!_L<````/CG7___]F@?M5JG1;@^P$:+````"A
+M!````(M`&`4```0`4%?H_/___X/$"&@```0`5^C\____@\009CU5JG4HQD7S
+M`8/L#%?H2OK__X/$$#P^=12#[`Q7Z,+\__^#Q!"%P'4$QD7S`H/L!&BP````
+MH00```"+0!@%```$`%!7Z/S___^#Q`S_=>QH\`0!`%?H_/___X/$"&CP!`$`
+M5^C\____@\0,_W7H:"P-``!7Z/S___^#Q!`/MD7SC67T6UY?R<-5B>564XMU
+M"+L`````C78`QP4$````B````(/L#%;H_?W__X/$$(3`=2/'!00```"D````
+M@^P,5NCC_?__@\00A,!U"4.!^^<#``!^PP^VP(UE^%M>R<,`````````````
+M``````````````````````0`````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
-M`````````0```````0`!``$``@`!``,``0`$``$`!0`!``8``0````$``"`!
-M``!``0``8`$``(`!``"@`0``P`$`DC0``(4T``"%-```I30``+`T``"[-```
-MQC0``"<U```)-0``"34``#HU``!%-0``4#4``%LU````1T-#.B`H1TY5*2`S
-M+C(N,2!;1G)E94)31%T@,C`P,C$Q,3D@*')E;&5A<V4I```N<WEM=&%B`"YS
-M=')T86(`+G-H<W1R=&%B`"YR96PN=&5X=``N<F5L+F1A=&$`+F)S<P`N<F5L
-M+G)O9&%T80`N8V]M;65N=```````````````````````````````````````
-M````````````````'P````$````&`````````#0````9MP`````````````$
-M`````````!L````)```````````````\U0``$!$```H````!````!`````@`
-M```I`````0````,`````````8+<``,```````````````"``````````)0``
-M``D``````````````$SF``"`````"@````,````$````"````"\````(````
-M`P`````````@N```!```````````````!``````````X`````0````(`````
-M````(+@``#@```````````````0`````````-`````D``````````````,SF
-M``!P````"@````8````$````"````$`````!``````````````!8N```+P``
-M`````````````0`````````1`````P``````````````A[@``$D`````````
-M``````$``````````0````(``````````````+"Z```0#0``"P```&$````$
-M````$`````D````#``````````````#`QP``?`T``````````````0``````
-M`````````````````````````0``````````````!`#Q_P``````````````
-M``,``0`````````````````#``,``````````````````P`%``@```"`"@``
-MC@````(``0`9````$`L``.D````"``$`+````/@-``!6`````@`!`#D```!<
-M$P``;`$```(``0!&````N!D``#P````"``$`50```/09``"T`````@`!`&8`
-M```@'```)0````(``0!R````2!P``"(````"``$`?0````0````$`````0`#
-M`(H```!L'```.@$```(``0":````J!T``%X````"``$`HP````@>``!,````
-M`@`!`*L```!4'@``,`````(``0"S````A!X``#L````"``$`O@```,`>```1
-M`````@`!`,8```#4'@``+`````(``0#8`````!\``"L````"``$`YP```"P?
-M``!0`````@`!`/(```!\'P``.`````(``0#_````M!\``%$````"``$`"P$`
-M``@@``#+`0```@`!`!@!``#4(0``L0````(``0`E`0``B"(``)<"```"``$`
-M+P$``"`E``#P`````@`!`#X!``!89@``M0````(``0!)`0``$"8``.@#```"
-M``$`50$``&0U``#W+0```@`!`&,!``#$9```.@$```(``0!O`0``^"D``"<`
-M```"``$`>0$``$@S```9`@```@`!`(L!```@*@``I0````(``0"<`0``R"H`
-M`!8!```"``$`J0$``.`K``"<`````@`!`+8!``"D+```;@````(``0##`0``
-M?"P``"@````"``$`S@$``!0M``!E`0```@`!`-D!``!\+@``P@$```(``0#E
-M`0``;#(``&H````"``$`\P$``$`P``#%`````@`!```"```(,0``8@$```(`
-M`0`-`@``V#(``&\````"``$``````````````````P`&`!X"```09P``#0,`
-M``(``0`N`@``(&H``%H````"``$`10(``'QJ```\!0```@`!`%`"``"X;P``
-M8P,```(``0!<`@``'',``#0````"``$`;`(``&!X``!V`@```@`!`'D"``#@
-M?P``*`````(``0"*`@``=(```#\````"``$`GP(``+2````B`````@`!`+("
-M``#8@```/`````(``0"_`@``%($``+4"```"``$`U0(``,R#```\`0```@`!
-M`.P"```(A0``E`````(``0`$`P``?)4``$H````"``$`$@,``)R%``!.`0``
-M`@`!`"4#``!,EP``4`````(``0`T`P``3)@```0"```"``$`2`,``&R,``!&
-M`0```@`!`%L#``#LA@``D0````(``0!J`P``@(<``-("```"``$`?@,``-R/
-M```7`0```@`!`(P#``#TD```;0````(``0">`P``!)@``$8````"``$`JP,`
-M`%2*``!1`````@`!`,$#``"`E@``+@````(``0#8`P``J(H``!X!```"``$`
-MZP,``,B+``"A`````@`!`/L#``"PE@``F@````(``0`(!```G)<``&<````"
-M``$`&P0``+2-``"&`0```@`!`"P$```\CP``H`````(``0`Z!```9)$``.8!
-M```"``$`2P0``$R3```:`````@`!`&0$``!HDP``#0$```(``0![!```>)0`
-M`#X````"``$`D`0``+B4``!D`````@`!`*0$```<E0``7P````(``0"O!```
-MR)4``"4````"``$`P00``/"5``"/`````@`!`-<$``!(J@``G@````(``0#O
-M!```F*\``*8````"``$`_`0``(@````<`````0`#``8%``"D````'`````$`
-M`P`0!0``=+```(8````"``$`&04````````$`````0`%`"$%``#\L```/@``
-M``(``0`I!0``/+$``$L````"``$`-`4``'BS``"G`````@`!`#P%```4M0``
-MN0$```(``0`````````````````#``@`5`4```````"#!0``$@`!`&`%```@
-M````)````!$``P!O!0``8````"0````1``,`?P4`````````````$````(P%
-M``#8=P``)@```!(``0"5!0`````````````0````GP4`````````````$```
-M`*D%`````````````!````"W!0``A`4``+L````2``$`P04`````````````
-M$````,X%`````````````!````#@!0``0`8``*4!```2``$`\`4`````````
-M````$````/D%````>```7P```!(``0`'!@``Z`<``%`````2``$`&@8``'![
-M```3````$@`!`"@&```X"```(0$``!(``0`U!@``3'L``"$````2``$`1P8`
-M`%QU``!8````$@`!`%(&``!<"0``(P$``!(``0!E!@``_`L``%<````2``$`
-M=@8``"!^```3````$@`!`((&``#,?```,P```!(``0"2!@``5`P``.T````2
-M``$`I`8``/1]```K````$@`!`+0&``!$#0``.@```!(``0#'!@``@`T``'4`
-M```2``$`V08``%`.``!.`0``$@`!`.\&``"@#P``@0```!(``0`,!P``)!``
-M`(8````2``$`(`<``%Q^``!(````$@`!`"X'``"L$```H0```!(``0!%!P``
-M4!$``$8!```2``$`70<``)@2``#!````$@`!`','`````````````!````!]
-M!P``R!0```D"```2``$`CP<``#1^```E````$@`!`*`'``#4%@``(@$``!(`
-M`0"S!P``^!<``+\!```2``$`Q`<``*@:``!7````$@`!`-0'````&P``[0``
-M`!(``0#E!P``\!L``"X````2``$`]P<````````$````$0`#``<(````````
-M`````!`````5"```7&,```H!```2``$`*`@`````````````$````#L(````
-M`````````!````!""``````````````0````20@``&AD``!<````$@`!`%4(
-M`````````````!````!W"```B'T``&D````2``$`A0@```!F``!6````$@`!
-M`)<(``!0<P``"0(``!(``0"I"```H'8``#8!```2``$`O`@``+1U``#L````
-M$@`!`,X(`````````````!````#@"``````````````0````\P@``-AZ```N
-M````$@`!``()```(>P``0@```!(``0`1"0``A'L``$<!```2``$`(`D```!]
-M``!*````$@`!`#$)``!,?0``.0```!(``0`^"0``I'X``!8````2``$`20D`
-M`+Q^```I````$@`!`%D)``#H?@``]0```!(``0!E"0``4*$``#0````2``$`
-M?0D``(2A``!`````$@`!`)$)```(K```.@```!(``0"L"0``1*P``)P````2
-M``$`T0D``!"A``!`````$@`!`.@)```(@```:0```!(``0#_"0``````````
-M```0````$PH`````````````$````"0*`````````````!`````W"@``A```
-M``0````1``,`2@H`````````````$````%P*`````````````!````!N"@``
-M```````````0````@`H`````````````$````)$*``!`L```,@```!(``0"@
-M"@``C*D``$H````2``$`N@H``%":``#_`@``$@`!`,P*``#0M@``20```!(`
-M`0#B"@```)X``'@````2``$``0L``%"=```<````$@`!`!<+``!LG0``#P``
-M`!(``0`I"P``?)T```\````2``$`/`L``(R=``!-````$@`!`%,+``#<G0``
-M(@```!(``0!G"P``>)X``.D!```2``$`?@L``&2@``"L````$@`!`),+``#$
-MH0``(````!(``0"J"P``Y*$``%\````2``$`RPL``$2B``"X````$@`!`.4+
-M``#\H@``AP```!(``0#^"P``A*,``/,````2``$`%@P``'BD``!5`0``$@`!
-M`"T,``#0I0``4@```!(``0!$#```)*8``)H!```2``$`5PP``,"G``".`0``
-M$@`!`'4,``!0J0``'````!(``0"0#```;*D``!T````2``$`K0P``-BI```V
-M````$@`!`,<,```0J@``-@```!(``0#B#```Z*H``'4````2``$`_PP``&"K
-M``!_````$@`!`!T-``#@JP``*````!(``0`\#0``X*P``+8"```2``$`4@T`
-M`(BQ``#X````$@`!`%D-``"`L@``^````!(``0!A#0``(+0``+P````2``$`
-M;PT``-RT```X````$@`!``!R86ED+F,`4W1R:7!E1V5T0V]M;6%N9`!3=')I
-M<&53<&QI=$-O;6UA;F0`27-61&5V3VYL:6YE`$1O0V]N=')O;$-M9`!*0D]$
-M1V5T0V]M;6%N9`!*0D]$4W!L:71#;VUM86YD`%]?:'!T7V%L;&]C`%]?:'!T
-M7V9R964`9V%R8F%G95]A9&1R`&EN:71?:&5A<%]B;&]C:P!C8E]A;&QO8P!C
-M8E]F<F5E`&-B7WIE<F\`8V)?:7-?>F5R;P!C9E]I;FET`')E;6]V95]R86YG
-M95]L;V-K`&%D9%]R86YG95]L;V-K`&QO8VM?<F%N9V4`7U]A;&QO8U]T87-K
-M`&9R965?<W1R:7!E`&%L;&]C7W-T<FEP90!?7V=E=%]S=')I<&4`9&%T85]X
-M9F5R`')E861?>&9E<E]D;VYE`')A:60U7V1O;F4`<W1R:7!E7V1O;F4`:&%N
-M9&QE7W-T<FEP90!R86ED-5]D:7)T>0!T87-K7V1O;F4`<W1R:7!E7V-H96-K
-M7W1A<VL`<G=?=&%S:U]B=6EL9'-G;`!R=U]G971?<F%N9V4`<G=?=&%S:U]D
-M;VYE`%]?9&]?<G=?=&%S:P!D;U]R=U]T87-K`&=E=%]S;&EC97,`9&]?>&]R
-M7W1A<VL`>&]R7W1A<VM?9&]N90!D;U]X;W(R7W1A<VL`9&]?>&]R;E]T87-K
-M`&-H96-K7V1E<&5N9&5N8WD`9&ER96-T7W)E861?<V=L`&1I<F5C=%]R96%D
-M7V-O;7!L971I;VX`:&%N9&QE7V-M9`!G971?<W1R:7!E<P!W<FET95]X9F5R
-M7V1O;F4`4WEN8T1I<VM);F9O`&=E=$5D;6%296=/9F9S970`=6YM87-K161M
-M84EN=&5R<G5P=',`;6%S:T5D;6%);G1E<G)U<'1S`&ES17AT0V]M;6%N9`!W
-M<FET945D;6%297%U97-T16YT<GD`9'5M<$%T841E=FEC95)E9VES=&5R<P!H
-M86YD;&5%9&UA1F%I;&5D0V]M;6%N9`!R96UO=F5#;VUM86YD`&AA;F1L945D
-M;6%297-P;VYS90!D96%C=&EV871E161M80!S96YD3F]N955D;6%#;VUM86YD
-M`&-O;7!L971E4$E/0V]M;6%N9`!3971'4$E/0W1R;%)E9P!H86YD;&5%9&UA
-M26YT97)R=7!T`%]F:7A0:'E087)A;7,`7V-H86YN96Q(87)D4F5S970`7V1O
-M075T;T9L=7-H`&AA;F1L941E=FEC94EN=&5R<G5P=`!D:7-A8FQE4V%$979)
-M;G1E<G)U='!S`&AA;F1L95!)3TEN=&5R<G5P=`!T<F%N<V9E<E!)3T1A=&$`
-M86-T:79A=&5%9&UA`$5D;6%297%1=65U94EN<V5R=`!R97-E=$5D;6%#:&%N
-M;F5L`&9L=7-H1&UA475E=64`<F5V97)T4V%T84A#4F5G<P!R979E<G1&;&%S
-M:$EN=&5R9F%C95)E9W,`<F5V97)T4$-)26YT97)F86-E4F5G<P!C;VUM86YD
-M<U%U975E061D5&%I;`!C;VUM86YD<U%U975E4F5M;W9E`&%D9$-O;6UA;F0`
-M4V%$979);G1E<G)U='!":70`96YA8FQE4V%$979);G1E<G)U='!S`&ES4W1O
-M<F%G941E=E)E861Y1F]R4$E/`%]D;U-O9G1297-E=`!?861D<DUA<#$`7V%D
-M9')-87`R`$5N=&5R-C`Q`&%D9')-87``17AI=#8P,0!G971?-C`Q7VED`'-E
-M=%]C=&P`7U]C:&5C:U]P<F]T96-T7V-I<F-U:70`9D-H96-K07)R87D`<&9N
-M4V5N9$-O;6UA;F0`<&9N1&5V:6-E1F%I;&5D`&9$95)E8617<FET90!#:&5C
-M:U-U;0!O<U]M96US970`;W-?;65M8W!Y`&9$95-E;&5C=$UO9&4`9D%D9%-P
-M87)E`$=E=%-P87)E1&ES:P!I;V-T;%]297!O<G1%=F5N=`!&:7AU<$%R<F%Y
-M4W1A=&4`1V5T4W1A;7``4WEN8T%R<F%Y26YF;P!#:&5C:T%R<F%Y0W)I=&EC
-M86P`9D]S1&ES:T9A:6QE9`!F1&5L971E07)R87D`56YR96=I<W1E<E9$979I
-M8V4`<F%I9#5?9G)E90!3=')I<&5"=6EL9%-G5&%B;&4`9E)!240P365M8F5R
-M1&]N90!&<F5E0V]M;6%N9`!#86QL069T97)2971U<FX`9E)!240P4V5N9$-O
-M;6UA;F0`06QL;V-A=&5#;VUM86YD`&9204E$,$UE;6)E<D9A:6QE9`!204E$
-M,4)U:6QD4V=486)L90!204E$,4UE;6)E<D-O;7!L971I;VX`4D%)1#%);FET
-M4F5B=6EL9$)U:6QD4V=486)L90!204E$,4EN:71#;VUP;&5T:6]N`$1O5V%I
-M=&EN9TQI<W0`4D%)1#%296)U:6QD0V]M<&QE=&EO;@!204E$,59E<FEF>4)U
-M:6QD4V=486)L90!204E$,59E<FEF>4-O;7!L971I;VX`;W-?;65M8VUP`&92
-M04E$,5-E;F1#;VUM86YD`$%D9%1O5V%I=&EN9TQI<W0`9E)!240Q365M8F5R
-M1F%I;&5D`$I"3T1"=6EL9%-G5&%B;&4`9DI"3T1-96UB97)$;VYE`&9*0D]$
-M4V5N9$-O;6UA;F0`9DI"3T1-96UB97)&86EL960`;G5M7W)A:60U7W!A9V5S
-M`&]S7V%L;&]C7W!A9V4`9FQU<VA?<W1R:7!E7V-A8VAE`&9/<U!H>7-I8V%L
-M061D<F5S<P!$;UAO<C$`1&]8;W(R`&9L=7-H7W)A:60U`&9#;VUP;&5T94%L
-M;$-O;6UA;F1S4WEN8VAR;VYO=7-L>0!#:&5C:TED;&5#86QL`&9L=7-H7W)A
-M:60U7V%S>6YC`&9204E$-5-E;F1#;VUM86YD`&9204E$-4UE;6)E<D9A:6QE
-M9`!I;FET7W)A:60U7VUE;6]R>0!O<U]A;&QO8U]D;6%?<&%G90!F1&5V:6-E
-M4V5N9$-O;6UA;F0`9D=E=$9I<G-T0VAI;&0`9E)E<V5T0F]O=$UA<FL`9D-H
-M96-K0F]O=&%B;&4`0VAE8VM096YD:6YG0V%L;`!#86QL5VAE;DED;&4`9D9L
-M=7-H5D1E=@!F1FQU<VA61&5V07-Y;F,`;79296%D5W)I=&4`;793871A1&ES
-M86)L94-H86YN96Q$;6$`;793871A1FQU<VA$;6%1=65U90!M=E-T;W)A9V5$
-M979!5$%3971&96%T=7)E<P!M=E-T;W)A9V5$979!5$%%>&5C=71E3F]N541-
-M04-O;6UA;F0`;793871A16YA8FQE0VAA;FYE;$1M80!W86ET1F]R0G5S>4%F
-M=&5R2%)E<V5T`&UV36EC<F]396-O;F1S1&5L87D`359?4D5'7U)%041?0EE4
-M10!-5E]214=?5U))5$5?1%=/4D0`;79!=71O1FQU<VA/;D5R<F]R`$U67U)%
-M1U]74DE415]"651%`$U67U)%1U]214%$7T173U)$`$U67U)%1U]74DE415]7
-M3U)$`$U67U)%1U]214%$7U=/4D0`7V1O3793;V9T4F5S970`=V%I=%=H:6QE
-M4W1O<F%G941E=DES0G5S>0!M=E-A=&%);FET061A<'1E<@!C:&5C:U]P<F]T
-M96-T7V-I<F-U:70`;793871A27-3=&]R86=E1&5V:6-E0V]N;F5C=&5D`&UV
-M4V%T85-H=71D;W=N061A<'1E<@!M=D5N86)L94%U=&]&;'5S:`!M=D1I<V%B
-M;&5!=71O1FQU<V@`;793871A0V]N9FEG=7)E0VAA;FYE;`!M=E-A=&%296UO
-M=F5#:&%N;F5L`&UV4V%T84-H86YN96Q(87)D4F5S970`;793871A0V]N9FEG
-M161M84UO9&4`;793871A3G5M3V9$;6%#;VUM86YD<P!M=E-A=&%#:&%N;F5L
-M4V5T161M84QO;W!"86-K36]D90!M=E-A=&%3971#:&%N;F5L4&AY4&%R86US
-M`&UV4V%T84-H86YN96Q0:'E3:'5T9&]W;@!M=E-A=&%#:&%N;F5L4&AY4&]W
-M97)/;@!M=E-A=&%'971#:&%N;F5L4W1A='5S`&UV4V%T85%U975E541M84-O
-M;6UA;F0`;793871A475E=65#;VUM86YD`&UV4V%T84EN=&5R<G5P=%-E<G9I
-M8V52;W5T:6YE`&UV4V%T84UA<VM!9&%P=&5R26YT97)R=7!T`&UV4V%T855N
-M;6%S:T%D87!T97));G1E<G)U<'0`96YA8FQE4W1O<F%G941E=DEN=&5R<G5P
-M=`!D:7-A8FQE4W1O<F%G941E=DEN=&5R<G5P=`!M=E-T;W)A9V5$979!5$%)
-M9&QE26UM961I871E`&UV4W1O<F%G941E=D%404ED96YT:69Y1&5V:6-E`&UV
-M4W1O<F%G941E=D%405-O9G1297-E=$1E=FEC90!E>&5C=71E3F]N541-04-O
-M;6UA;F0`0F5E<$]N`$)E97!/9F8`<V5T7V9A:6Q?;&5D<P!S971?9F%I;%]L
-M960`1@````%B``!B`````6,``)`````"9```L`````)E``#J`````F4``'`!
-M```!8P``M@$```%B```I`@```F8``*T"```!8@``Q0(```)G``#=`@```F<`
-M`/4"```"9P``$`,```)G``"P`P```6,``/D#```"9@``>00```%B``"&!```
-M`6,``+0$```"9P``S`0```)G``#D!````F<``/\$```"9P``-P4```%C``!4
-M!0```F8``&8%```":```O@4```)J``#E!0```6(``/(%```!8P``,`8```)K
-M``"1!@```FT``-0&```";```7P<```)I``#4!P```FD``!\(```";```,@@`
-M``%P``!2"````G(``*((```!<```O`@```)F``#0"````F0``-D(```";@``
-M\0@```)F``!`"0```G$``$X)```"<P``*`P```)V``!%#````G<``,`,```"
-M>0``!PT```%U```.#0```70``#@-```"=P``R`X```)V``#X#@```G<``#(/
-M```"9@``F`\```)F``!1$````G8``'@0```"=P``B1````%_``"/$````G<`
-M`,@0```"=@``TA````)W``#C$````7\``.D0```"=P``+!$```)F``"T$@``
-M`G8``+X2```"=P``SQ(```%_``#5$@```G<````3```"9@``)!,```*#``"9
-M$P```G<``*43```!?P``K1,```)W``#+$P```GD``.T3```!@```]!,```%]
-M```I%````F8``#P4```">0``7A0```%^``!E%````7T``)84```">0``N!0`
-M``&"``"_%````8$``/P4```!`@``Z14```)Y``#T%0```F<```P6```!?```
-M$Q8```%[``"F%@```80``,@6```"=P``1!<```)M``"6%P```FH``*T7```!
-M8@``M1<```%C``#M%P```FL```T9```"9P``U!H```)V``#Q&@```G<``&P;
-M```">0``LQL```&(``"Z&P```8<``.0;```"=P``]!P```*,``!Q'@```F8`
-M`,L>```"9@``/"0```)G``#")P```G<``+PH```!`@``1"D```%_``!**0``
-M`G<``%@I```!?P``<2D```$"``!Y*0```G<```XJ```!`@``%BH```)W``"\
-M*@```HX``/HK```"=@``OBP```)Y``#N+````0(``/4L```!`@``:"\```*/
-M``"0+P```I```"HP```"D```X3````*0```7,@```H\``&$R```"D```@30`
-M``$N```%-0```2X``/5C```"=P``AF0```*-``",9````I(``))D```"DP``
-MF68```)W``#X9@```7\``/YF```"=P``[F@```$#``#9:0```0,``-YI```"
-MC@``.VH```)V```&;0```F8``.1N```">0``#&\```$"```3;P```0(``#)O
-M```!?P``.F\```)W```V<P```0(``!)T```!E0``''0```*%``!,=````0(`
-M`*)T```!E@``NW0```&5``#'=````H4``,]T```"C0``YW0```)W``!"=0``
-M`F8``'%U```"D0``]'4```&+```N=@```8L``%AV```"F```878```&+``!F
-M=@```0,``'9V```"F```D'8```&+``!'=P```FH``&%W```!8@``;'<```%C
-M``"4=P```FL``*YW```";0``2G@```)N``"H>````F8``,=Y```"9P``V7D`
-M``)G``#N>0```F<```-Z```"9P``@7H```)E``"1>@```F4``+%Z```"9```
-M.GL```*;``##>P```F8``.I[```"9```GWP```)D``#J?0```I(``!=^```"
-M9@``!G\```*B```/?P```J,``"!_```"I```IG\```*E``"R?P```J8``"*`
-M```"J```/H````*I``!9@````J@``)2````"J@``I8````*J``#0@````JH`
-M`/*#```"J0``!(0```*I```<A````JD``#2$```"J0``3X0```*I``!LA```
-M`JD``'R$```"J0``F(0```*I``"KA````JP``+2$```"J0``Q(0```*I``#7
-MA````JD``.>$```"J0``_(0```*L```NA0```JT```6'```"K0``&8<```*J
-M```FAP```JT``#.'```"K0``2H<```*J``!7AP```JT``.R'```"J@``78@`
-M``*M``!QB````JH``/6(```"J0``)XD```*J```PB0```JT``#>)```"J```
-M0HD```*J``!.B0```JT``%B)```"J```Q(D```&K``#4B@```JD``-Z*```"
-MJ0``"(L```*J```BC````JX``$R,```"KP``3HT```*M``!5C0```J@``(*-
-M```!JP``THT```*M``#FC0```JH``.V-```"K0``]XT```*H``"9C@```JH`
-M`*N.```"J@``OHX```*J``#4C@```JH``...```"J@``]HX```*J```%CP``
-M`JH``!B/```"J@``+H\```*J```HD````JT``'F0```"J@``L)````*M``#5
-MD````JH``!J1```"J@``(Y$```*M```JD0```J@``#B1```"J@``09$```*M
-M``"=D0```JH``*F1```"K0``P)$```*J``#4D0```JH``.61```"J@``]I$`
-M``*J```*D@```JH``!N2```"J@``+)(```*J``!`D@```JH``%&2```"J@``
-M8I(```*J``!VD@```JH``(>2```"J@``FY(```*J``#2D@```JH``..2```"
-MJ@``])(```*J```+DP```JH``!>3```"K0``+I,```*J``!@DP```JH``(23
-M```"K0``E9,```*J``"EDP```JT``+B3```"J@``QY,```*J``#9DP```JH`
-M`.N3```"J@``^I,```*J```,E````JH``!N4```"J@``*I0```*J```\E```
-M`JH``$N4```"J@``6I0```*J``!LE````JH``#R5```"9P``;Y4```)G```?
-ME@```JD``$^6```"J@``7Y8```*J``"EE@```JH``/Z6```"J@``#9<```*J
-M```HEP```JD``#Z7```"J@``>9<```*J``"`EP```JT``!^8```"L```<)@`
-M``*I``#KF````JP``/F8```"K```!YD```*L```8F0```JP``":9```"K```
-M.)D```*L``!)F0```JP``&B9```"J0``<YD```*Q``")F0```JD``+R9```"
-MK@``[9D```*L```"F@```JP``!>:```"K```+YH```*L``!$F@```JP``&R:
-M```"J@``=)H```*S```<FP```JT``&6;```"J@``<IL```*M``"(FP```JH`
-M`)B;```"K0``!IP```*J```6G````JH``":<```"J@``3YP```*J``!QG```
-M`JH``*2<```"J```T9P```*T``!AG0```JH``'&=```!JP``@9T```&K```K
-MG@```JT``%F>```"K0``8YX```*H``!LG@```JT``-N>```"J@``Y)X```*M
-M``#KG@```J@``/F>```"J@```I\```*M```SGP```JT``%N?```"J@``?9\`
-M``*M``"$GP```J@``*>?```"J@``Q9\```*M``#/GP```J@``-J?```"IP``
-M#:````*I``"7H````JT``-R@```"J@``!J(```*M```IH@```JH``)VB```"
-MK0``T*(```*J```KHP```JT``&:C```"J@``;Z,```*M``#%HP```JT``.^C
-M```"J@``"*0```*M```DI````JT``$:D```"J@``P*0```*M``#AI````K0`
-M`"6E```"K0``-Z4```*M``!)I0```JT``%NE```"K0``<*4```*M``""I0``
-M`JT``)2E```"K0``IJ4```*M```<I@```L,``-FG```"K0``3:@```*J``!6
-MJ````JT``&BH```"J@``B*@```*M```BJ0```JT``#2I```"J@``8:D```*J
-M``!^J0```JH``*FI```"J0``N*D```*H``#QJ0```JP```6J```"J0``*:H`
-M``*L```]J@```JD``'6J```"J0``AZH```*I``"CJ@```J@``+^J```"L0``
-MSJH```*I```3JP```L@``"6K```"K```,ZL```*Q``!`JP```L<``%*K```"
-MQP``EZL```*E```\K````J4``$*M```"R```R:T```*L``#7K0```JP``.6M
-M```"K```]JT```*L```$K@```JP``!:N```"K```+JX```*L``!&K@```K$`
-M`%.N```"QP``8:X```+'``!YK@```K$``(FN```"J0``Q:X```*N``#LK@``
-M`J\```BO```"L0``*Z\```*L``!"KP```JP``%FO```"K```<Z\```*L``"*
-MKP```JP``+6O```"K```Q*\```*I``#+KP```J@``-&O```"QP``VZ\```*H
-M``#HKP```J@``/*O```"J```_*\```*H```/L````JD``"6P```"J```5[``
-M``*H``!_L````00``)&P```"K```GK````$$``"ML````JD``+VP```!!```
-MS+````*I``#;L````00``.JP```"J0``!K$```$$```8L0```JP``"*Q```!
-M!```,;$```*L``!-L0```00``%RQ```"K```8;$```$$``!OL0```JD``)BQ
-M```"K0``J;$```*J``"TL0```JT``-:Q```"K@``Y+$```*M``#SL0```00`
-M``*R```"K```";(```$$```7L@```JP``!ZR```!!```+;(```*L```WL@``
-M`00``$6R```"K```5[(```*J``!BL@```JT``'&R```"J@``D+(```*M``"A
-ML@```JH``*RR```"K0``SK(```*N``#<L@```JT``.NR```!!```^K(```*L
-M```!LP```00```^S```"K```%K,```$$```ELP```JP``"^S```!!```/;,`
-M``*L``!/LP```JH``%JS```"K0``:;,```*J``"(LP```00``)>S```"K```
-MGK,```$$``"LLP```JP``,"S```"J0``Y;,```$$``#SLP```JP```"T```"
-MJ```"[0```*I```^M````JT``%"T```"J@``6[0```*M``!]M````JX``(NT
-M```"K0``I;0```*L``"QM````JH``+RT```"K0``S;0```*J```KM0```JT`
-M`#VU```"J@``2+4```*M``!OM0```JX``'VU```"K0``BK4```*O``"?M0``
-M`00``*ZU```"K```O+4```*J``#'M0```JT``-BU```"J@``_K4```$$```-
-MM@```JP``"JV```"KP``-K8```$$``!%M@```JP``&JV```!!```>;8```*L
-M``"$M@```J\``,.V```"J```W[8```$$``#CM@```0,``/2V```!!```^+8`
-M``$#``"C!@```FX``+@6```"A0``5A<```)N``"8)P```HT``%)F```"C0``
-M[&8```*-```_<P```G<``,!W```";@``?WL```)R``"V?@```I$``.%^```"
-ME```>8<```*J``![E@```JT``/^7```"J@```*P```*P``#<K````LP```&U
-M```"SP``(`````&9```D`````9D``"@````!F0``+`````&9```P`````8D`
-M`#0````!>```.`````&$``!``````94``&`````!<```9`````%P``!H````
-M`7```&P````!<```<`````&*``!T`````7H``'@````!A@``@`````&6````
-M`````0(```0````!`@``"`````$"```,`````0(``!`````!`@``%`````$"
-M```8`````0(``!P````!`@``(`````$"```D`````0(``"@````!`@``+```
-5``$"```P`````0(``#0````!`@``
+M`````````````````0```````0`!``$``@`!``,``0`$``$`!0`!``8``0``
+M``$``"`!``!``0``8`$``(`!``"@`0``P`$`1#8``/PU``#\-0``#38``!XV
+M```O-@``0#8``!0W``#,-@``S#8``-TV``#N-@``_S8``!`W````1T-#.B`H
+M1TY5*2`S+C0N,B!;1G)E94)31%T@,C`P-#`W,C@``"YS>6UT86(`+G-T<G1A
+M8@`N<VAS=')T86(`+G)E;"YT97AT`"YR96PN9&%T80`N8G-S`"YR96PN<F]D
+M871A`"YC;VUM96YT````````````````````````````````````````````
+M`````````````!\````!````!@`````````T````$[T`````````````!```
+M```````;````"0``````````````--L``*@1```*`````0````0````(````
+M*0````$````#`````````&"]``#````````````````@`````````"4````)
+M``````````````#<[```@`````H````#````!`````@````O````"`````,`
+M````````(+X```@```````````````0`````````.`````$````"````````
+M`""^```X```````````````$`````````#0````)``````````````!<[0``
+M<`````H````&````!`````@```!``````0``````````````6+X``"4`````
+M``````````$`````````$0````,``````````````'V^``!)````````````
+M```!``````````$````"``````````````"HP```$`T```L```!A````!```
+M`!`````)`````P``````````````N,T``'P-``````````````$`````````
+M``````````````````````$```````````````0`\?\````````````````#
+M``$``````````````````P`#``````````````````,`!0`(````<`H``'\`
+M```"``$`&0```/`*``#V`````@`!`"P```#\#0``9`````(``0`Y````G!,`
+M`*H!```"``$`1@```)P9```U`````@`!`%4```#4&0``LP````(``0!F````
+M'!P``",````"``$`<@```$`<```@`````@`!`'T`````````!`````$`!0"*
+M````8!P``(`!```"``$`F@```.`=``!I`````@`!`*,```!,'@``0@````(`
+M`0"K````D!X``#,````"``$`LP```,0>```^`````@`!`+X````$'P``%```
+M``(``0#&````&!\``#$````"``$`V````$P?```H`````@`!`.<```!T'P``
+M4P````(``0#R````R!\``#$````"``$`_P```/P?``!5`````@`!``L!``!4
+M(```$P(```(``0`8`0``:"(``+L````"``$`)0$``"0C``"2`@```@`!`"\!
+M``"X)0```0$```(``0`^`0``%&8``,\````"``$`20$``+PF```\!````@`!
+M`%4!``!X-P``<RL```(``0!C`0``@&0``$,!```"``$`;P$``/@J```N````
+M`@`!`'D!```4-0``80(```(``0"+`0``*"L``*X````"``$`G`$``-@K```C
+M`0```@`!`*D!``#\+```I@````(``0"V`0``T"T``'8````"``$`PP$``*0M
+M```I`````@`!`,X!``!(+@``?`$```(``0#9`0``Q"\``!H"```"``$`Y0$`
+M`$`T``!L`````@`!`/,!``#@,0``U`````(``0```@``M#(``(P!```"``$`
+M#0(``*PT``!E`````@`!``````````````````,`!@`>`@``Y&8```H#```"
+M``$`+@(``/!I``!G`````@`!`$4"``!8:@``-P4```(``0!0`@``D&\``)P#
+M```"``$`7`(``"QS```[`````@`!`&P"``#$>```:P(```(``0!Y`@``D(``
+M`"P````"``$`B@(``#B!``!%`````@`!`)\"``"`@0``)0````(``0"R`@``
+MJ($``$(````"``$`OP(``.R!``"1`@```@`!`-4"``"`A```7@$```(``0#L
+M`@``X(4``)0````"``$`!`,``/B7``!)`````@`!`!(#``!TA@``7`$```(`
+M`0`E`P``W)D``$X````"``$`-`,``.2:```:`@```@`!`$@#``#TC0``6`$`
+M``(``0!;`P``T(<``)$````"``$`:@,``&2(``#$`@```@`!`'X#``#XD@``
+M?P````(``0"0`P``P)$``#4!```"``$`G@,``)":``!1`````@`!`*L#```H
+MBP``=0````(``0#!`P``^)@``"\````"``$`V`,``*"+``"0`0```@`!`.L#
+M```PC0``P0````(``0#[`P``*)D``+$````"``$`"`0``"R:``!B`````@`!
+M`!L$``!,CP``L0$```(``0`L!````)$``+\````"``$`.@0``'B3```.`@``
+M`@`!`$L$``"(E0``'0````(``0!D!```J)4``#$!```"``$`>P0``-R6``!"
+M`````@`!`)`$```@EP``:@````(``0"D!```C)<``&L````"``$`KP0``$28
+M```L`````@`!`,$$``!PF```B`````(``0#7!```>*X``.0````"``$`[P0`
+M`*"T``#*`````@`!`/P$``"(````'`````$``P`&!0``I````!P````!``,`
+M$`4``*BU``"C`````@`!`!D%```$````!`````$`!0`A!0``3+8``$0````"
+M``$`*04``)"V``!6`````@`!`#0%```8N0``N@````(``0`\!0``W+H``.`!
+M```"``$``````````````````P`(`%0%````````6`4``!(``0!@!0``(```
+M`"0````1``,`;P4`````````````$````'P%``!@````)````!$``P",!0``
+M-'@``"H````2``$`E04`````````````$````*,%`````````````!````"M
+M!0`````````````0````MP4``%@%``#+````$@`!`,$%`````````````!``
+M``#.!0`````````````0````X`4``"0&``"<`0``$@`!`/`%````````````
+M`!````#Y!0``8'@``&,````2``$`!P8``,`'``!6````$@`!`!H&``#@>P``
+M$@```!(``0`H!@``&`@``$`!```2``$`-08``+A[```H````$@`!`$<&``"L
+M=0``8P```!(``0!2!@``6`D``!4!```2``$`908``.@+``!@````$@`!`'8&
+M``"X?@``$P```!(``0""!@``.'T``#D````2``$`D@8``$@,`````0``$@`!
+M`*0&``"$?@``,0```!(``0"T!@``2`T``$(````2``$`QP8``(P-``!O````
+M$@`!`-D&``!@#@``9`$``!(``0#O!@``Q`\``(`````2``$`#`<``$00``"4
+M````$@`!`"`'``#T?@``3@```!(``0`N!P``V!```+<````2``$`10<``)`1
+M```_`0``$@`!`%T'``#0$@``RP```!(``0!S!P`````````````0````?0<`
+M`$@5``"P`0``$@`!`(\'``#,?@``)P```!(``0"@!P``^!8``"L!```2``$`
+MLP<``"08``!V`0``$@`!`,0'``"(&@``8````!(``0#4!P``Z!H````!```2
+M``$`Y0<``.@;```R````$@`!`/<'````````!````!$``P`'"```````````
+M```0````%0@``.QB```P`0``$@`!`"@(`````````````!`````["```````
+M```````0````0@@`````````````$````$D(```<9```80```!(``0!5"```
+M```````````0````=P@```Q^``!X````$@`!`(4(``#$90``4````!(``0"7
+M"```:',``$0"```2``$`J0@```QW```H`0``$@`!`+P(```0=@``_````!(`
+M`0#."``````````````0````X`@`````````````$````/,(```P>P``/@``
+M`!(``0`""0``<'L``$<````2``$`$0D``/1[``!#`0``$@`!`"`)``!T?0``
+M6````!(``0`Q"0``S'T``#\````2``$`/@D``$1_```>````$@`!`$D)``!D
+M?P``-````!(``0!9"0``F'\``/8````2``$`90D``*"D``!#````$@`!`'T)
+M``#DI```2````!(``0"1"0``N+```#T````2``$`K`D``/BP``".````$@`!
+M`-$)``!4I```3````!(``0#H"0``O(```'H````2``$`_PD`````````````
+M$````!,*`````````````!`````D"@`````````````0````-PH``(0````$
+M````$0`#`$H*`````````````!````!<"@`````````````0````;@H`````
+M````````$````(`*`````````````!````"1"@``;+4``#L````2``$`H`H`
+M`*"M``!>````$@`!`+H*````G0``Y`(``!(``0#,"@``G*```)@````2``$`
+MZPH``.2?```?````$@`!``$+```$H```#P```!(``0`3"P``%*````\````2
+M``$`)@L``"2@``!.````$@`!`#T+``!TH```)@```!(``0!1"P``-*$``&0"
+M```2``$`:`L``)BC``"Z````$@`!`'T+```LI0``(````!(``0"4"P``3*4`
+M`'T````2``$`M0L``,RE``#,````$@`!`,\+``"8I@``C````!(``0#H"P``
+M)*<``!$!```2``$```P``#BH``!O`0``$@`!`!<,``"HJ0``4@```!(``0`N
+M#```_*D``+D!```2``$`00P``+BK``"G`0``$@`!`%\,``!@K0``'P```!(`
+M`0!Z#```@*T``"`````2``$`EPP```"N```\````$@`!`+$,```\K@``/```
+M`!(``0#,#```7*\``)`````2``$`Z0P``.RO``"5````$@`!``<-``"$L```
+M,P```!(``0`F#0``B+$``!8#```2``$`/`T``.BV```7`0``$@`!`$,-````
+MN```%P$``!(``0!+#0``U+D``,D````2``$`60T``*"Z```Z````$@`!`&8-
+M``"\O```5P```!(``0``<F%I9"YC`%-T<FEP94=E=$-O;6UA;F0`4W1R:7!E
+M4W!L:71#;VUM86YD`$ES5D1E=D]N;&EN90!$;T-O;G1R;VQ#;60`2D)/1$=E
+M=$-O;6UA;F0`2D)/1%-P;&ET0V]M;6%N9`!?7VAP=%]A;&QO8P!?7VAP=%]F
+M<F5E`&=A<F)A9V5?861D<@!I;FET7VAE87!?8FQO8VL`8V)?86QL;V,`8V)?
+M9G)E90!C8E]Z97)O`&-B7VES7WIE<F\`8V9?:6YI=`!R96UO=F5?<F%N9V5?
+M;&]C:P!A9&1?<F%N9V5?;&]C:P!L;V-K7W)A;F=E`%]?86QL;V-?=&%S:P!F
+M<F5E7W-T<FEP90!A;&QO8U]S=')I<&4`7U]G971?<W1R:7!E`&1A=&%?>&9E
+M<@!R96%D7WAF97)?9&]N90!R86ED-5]D;VYE`'-T<FEP95]D;VYE`&AA;F1L
+M95]S=')I<&4`<F%I9#5?9&ER='D`=&%S:U]D;VYE`'-T<FEP95]C:&5C:U]T
+M87-K`')W7W1A<VM?8G5I;&1S9VP`<G=?9V5T7W)A;F=E`')W7W1A<VM?9&]N
+M90!?7V1O7W)W7W1A<VL`9&]?<G=?=&%S:P!G971?<VQI8V5S`&1O7WAO<E]T
+M87-K`'AO<E]T87-K7V1O;F4`9&]?>&]R,E]T87-K`&1O7WAO<FY?=&%S:P!C
+M:&5C:U]D97!E;F1E;F-Y`&1I<F5C=%]R96%D7W-G;`!D:7)E8W1?<F5A9%]C
+M;VUP;&5T:6]N`&AA;F1L95]C;60`9V5T7W-T<FEP97,`=W)I=&5?>&9E<E]D
+M;VYE`%-Y;F-$:7-K26YF;P!G971%9&UA4F5G3V9F<V5T`'5N;6%S:T5D;6%)
+M;G1E<G)U<'1S`&UA<VM%9&UA26YT97)R=7!T<P!I<T5X=$-O;6UA;F0`=W)I
+M=&5%9&UA4F5Q=65S=$5N=')Y`&1U;7!!=&%$979I8V5296=I<W1E<G,`:&%N
+M9&QE161M849A:6QE9$-O;6UA;F0`<F5M;W9E0V]M;6%N9`!H86YD;&5%9&UA
+M4F5S<&]N<V4`9&5A8W1I=F%T945D;6$`<V5N9$YO;F559&UA0V]M;6%N9`!C
+M;VUP;&5T95!)3T-O;6UA;F0`4V5T1U!)3T-T<FQ296<`:&%N9&QE161M84EN
+M=&5R<G5P=`!?8VAA;FYE;$AA<F1297-E=`!?9FEX4&AY4&%R86US`%]D;T%U
+M=&]&;'5S:`!H86YD;&5$979I8V5);G1E<G)U<'0`9&ES86)L95-A1&5V26YT
+M97)R=71P<P!H86YD;&5024]);G1E<G)U<'0`=')A;G-F97)024]$871A`&%C
+M=&EV871E161M80!%9&UA4F5Q475E=65);G-E<G0`<F5S971%9&UA0VAA;FYE
+M;`!F;'5S:$1M85%U975E`')E=F5R=%-A=&%(0U)E9W,`<F5V97)T1FQA<VA)
+M;G1E<F9A8V5296=S`')E=F5R=%!#24EN=&5R9F%C95)E9W,`8V]M;6%N9'-1
+M=65U94%D9%1A:6P`8V]M;6%N9'-1=65U95)E;6]V90!A9&1#;VUM86YD`%-A
+M1&5V26YT97)R=71P0FET`&5N86)L95-A1&5V26YT97)R=71P<P!I<U-T;W)A
+M9V5$979296%D>49O<E!)3P!?9&]3;V9T4F5S970`7V%D9')-87`Q`%]A9&1R
+M36%P,@!%;G1E<C8P,0!A9&1R36%P`$5X:70V,#$`9V5T7S8P,5]I9`!S971?
+M8W1L`%]?8VAE8VM?<')O=&5C=%]C:7)C=6ET`&9#:&5C:T%R<F%Y`'!F;E-E
+M;F1#;VUM86YD`&9$95)E8617<FET90!P9FY$979I8V5&86EL960`0VAE8VM3
+M=6T`9D1E4V5L96-T36]D90!O<U]M96US970`;W-?;65M8W!Y`&9!9&13<&%R
+M90!'9713<&%R941I<VL`:6]C=&Q?4F5P;W)T179E;G0`1FEX=7!!<G)A>5-T
+M871E`$=E=%-T86UP`%-Y;F-!<G)A>4EN9F\`0VAE8VM!<G)A>4-R:71I8V%L
+M`&9/<T1I<VM&86EL960`9D1E;&5T94%R<F%Y`%5N<F5G:7-T97)61&5V:6-E
+M`')A:60U7V9R964`4W1R:7!E0G5I;&139U1A8FQE`&9204E$,$UE;6)E<D1O
+M;F4`1G)E94-O;6UA;F0`0V%L;$%F=&5R4F5T=7)N`&9204E$,%-E;F1#;VUM
+M86YD`$%L;&]C871E0V]M;6%N9`!F4D%)1#!-96UB97)&86EL960`4D%)1#%"
+M=6EL9%-G5&%B;&4`4D%)1#%-96UB97)#;VUP;&5T:6]N`%)!240Q26YI=%)E
+M8G5I;&1"=6EL9%-G5&%B;&4`4D%)1#%);FET0V]M<&QE=&EO;@!$;U=A:71I
+M;F=,:7-T`%)!240Q4F5B=6EL9$-O;7!L971I;VX`4D%)1#%697)I9GE"=6EL
+M9%-G5&%B;&4`4D%)1#%697)I9GE#;VUP;&5T:6]N`&]S7VUE;6-M<`!F4D%)
+M1#%396YD0V]M;6%N9`!!9&14;U=A:71I;F=,:7-T`&9204E$,4UE;6)E<D9A
+M:6QE9`!*0D]$0G5I;&139U1A8FQE`&9*0D]$365M8F5R1&]N90!F2D)/1%-E
+M;F1#;VUM86YD`&9*0D]$365M8F5R1F%I;&5D`&YU;5]R86ED-5]P86=E<P!O
+M<U]A;&QO8U]P86=E`&9L=7-H7W-T<FEP95]C86-H90!F3W-0:'ES:6-A;$%D
+M9')E<W,`1&]8;W(R`$1O6&]R,0!F;'5S:%]R86ED-0!F0V]M<&QE=&5!;&Q#
+M;VUM86YD<U-Y;F-H<F]N;W5S;'D`0VAE8VM)9&QE0V%L;`!F;'5S:%]R86ED
+M-5]A<WEN8P!F4D%)1#5396YD0V]M;6%N9`!F4D%)1#5-96UB97)&86EL960`
+M:6YI=%]R86ED-5]M96UO<GD`;W-?86QL;V-?9&UA7W!A9V4`9D1E=FEC95-E
+M;F1#;VUM86YD`&9'971&:7)S=$-H:6QD`&9297-E=$)O;W1-87)K`&9#:&5C
+M:T)O;W1A8FQE`$-H96-K4&5N9&EN9T-A;&P`0V%L;%=H96Y)9&QE`&9&;'5S
+M:%9$978`9D9L=7-H5D1E=D%S>6YC`&UV4F5A9%=R:71E`&UV4V%T841I<V%B
+M;&5#:&%N;F5L1&UA`&UV4V%T849L=7-H1&UA475E=64`;793=&]R86=E1&5V
+M051!4V5T1F5A='5R97,`;793=&]R86=E1&5V051!17AE8W5T94YO;E5$34%#
+M;VUM86YD`&UV4V%T845N86)L94-H86YN96Q$;6$`=V%I=$9O<D)U<WE!9G1E
+M<DA297-E=`!M=DUI8W)O4V5C;VYD<T1E;&%Y`$U67U)%1U]214%$7T)95$4`
+M359?4D5'7U=2251%7T173U)$`&UV075T;T9L=7-H3VY%<G)O<@!-5E]214=?
+M5U))5$5?0EE410!-5E]214=?4D5!1%]$5T]21`!-5E]214=?5U))5$5?5T]2
+M1`!-5E]214=?4D5!1%]73U)$`%]D;TUV4V]F=%)E<V5T`'=A:717:&EL95-T
+M;W)A9V5$979)<T)U<WD`;793871A26YI=$%D87!T97(`;793871A27-3=&]R
+M86=E1&5V:6-E0V]N;F5C=&5D`&UV4V%T85-H=71D;W=N061A<'1E<@!M=D5N
+M86)L94%U=&]&;'5S:`!M=D1I<V%B;&5!=71O1FQU<V@`;793871A0V]N9FEG
+M=7)E0VAA;FYE;`!M=E-A=&%296UO=F5#:&%N;F5L`&UV4V%T84-H86YN96Q(
+M87)D4F5S970`;793871A0V]N9FEG161M84UO9&4`;793871A3G5M3V9$;6%#
+M;VUM86YD<P!M=E-A=&%#:&%N;F5L4V5T161M84QO;W!"86-K36]D90!M=E-A
+M=&%3971#:&%N;F5L4&AY4&%R86US`&UV4V%T84-H86YN96Q0:'E3:'5T9&]W
+M;@!M=E-A=&%#:&%N;F5L4&AY4&]W97)/;@!M=E-A=&%'971#:&%N;F5L4W1A
+M='5S`&UV4V%T85%U975E541M84-O;6UA;F0`;793871A475E=65#;VUM86YD
+M`&UV4V%T84EN=&5R<G5P=%-E<G9I8V52;W5T:6YE`&UV4V%T84UA<VM!9&%P
+M=&5R26YT97)R=7!T`&UV4V%T855N;6%S:T%D87!T97));G1E<G)U<'0`96YA
+M8FQE4W1O<F%G941E=DEN=&5R<G5P=`!D:7-A8FQE4W1O<F%G941E=DEN=&5R
+M<G5P=`!M=E-T;W)A9V5$979!5$%)9&QE26UM961I871E`&UV4W1O<F%G941E
+M=D%404ED96YT:69Y1&5V:6-E`&UV4W1O<F%G941E=D%405-O9G1297-E=$1E
+M=FEC90!E>&5C=71E3F]N541-04-O;6UA;F0`0F5E<$]N`$)E97!/9F8`<V5T
+M7V9A:6Q?;&5D<P!S971?9F%I;%]L960`8VAE8VM?<')O=&5C=%]C:7)C=6ET
+M`$P````!8@``<`````)C``"*`````60``*H````"90``V0````)F``#P````
+M`F4``!(!```"9P``E0$```%D``#"`0```6(``%0"```"9P``UP(```%B``#R
+M`@```F@```T#```":```*`,```)H``!#`P```F@``+X#```"9P``0P0```%B
+M``!0!````60``'X$```":```F00```)H``"T!````F@``,\$```":```"@4`
+M``%D``!(!0```60``)H%```":@``Q04```%B``#2!0```60```X&```":P``
+MD08```)L``#S!@```FD``'L'```":0``I0<```)M``"Q!P```FX``/,'```"
+M;````P@```%P```R"````G(``$8(```"<P``AP@```)Q``"Q"````7```-X(
+M```"9P``\@@```)C```1"0```FX``#`)```"9P``&0P```)V```Z#````G<`
+M`&X,```"=P``F@P```)W``#+#````GD``!(-```!=0``&0T```%T``#+#@``
+M`F<``!T/```"9P``7@\```)V``"3#P```G<``'D0```"=@``K1````)W``##
+M$````7\``,D0```"=P``%1$```)G``!:$0```G8``&<1```"=P``?1$```%_
+M``"#$0```G<```\3```"9P``-Q,```*#``!F$P```G8``',3```"=P``B1,`
+M``%_``"/$P```G<```@4```"9P``(10```)Y``!#%````7X``$H4```!?0``
+M@Q0```)Y``"E%````8```*P4```!?0``UQ0```)Y``#Y%````8(````5```!
+M@0``)14```)W```T%0```7\``#H5```"=P``:Q4```)W``!]%0```0(``,\5
+M```!A```W!4```*%``">%@```GD``*T6```":```R!8```%\``#/%@```7L`
+M`)47```":@``K1<```%B``"U%P```60``.P7```":P``#!@```)M```8&```
+M`FX``(D9```":```N1H```)V``#:&@```G<```X;```"=P``.AL```)W``!K
+M&P```GD``+(;```!B```N1L```&'```7'0```HP``*\>```"9P``$A\```)G
+M```()0```F@``"DE```":```%RD```$"```#*@```0(```LJ```"=P``1BH`
+M``%_``!.*@```G<``&\J```!?P``=2H```)W``"]*@```G<``.@J```"C0``
+M$BL```$"```:*P```G<``)LK```"C@``&2T```)V``#M+0```GD``"8N```!
+M`@``,"X```$"``#4,````H\````Q```"D```MC$```*/``",,@```H\``-LS
+M```"CP``"30```*0``#X-0```2X``,@V```!+@``MF,```)W``!%9````HT`
+M`$UD```"D@``560```*3```(9@```HT``%EF```"=P``<&8```%_``!V9@``
+M`G<``*)F```!?P``J&8```)W``#39@```HT``.MG```!!```]F<```$$``#[
+M9P```HX``!!J```"=@``H6P```)G``#!;@```7\``,=N```"=P``^&X```)Y
+M```>;P```0(``"5O```!`@``1W,```$"``!-<P```G<``(MS```"=P``LG,`
+M``)G``#:<P```G<``/US```"=P``D70```)W``#'=````94``-1T```"A0``
+M)G4```&6``!`=0```94``%)U```"A0``774```*-``!N=0```0(``(]U```"
+M=P``P74```*1``!==@```8L``)-V```!BP``OG8```*8``##=@```00``,UV
+M```!BP``V78```*8``#]=@```8L``*YW```":@``S'<```%B``#4=P```60`
+M``!X```":P``&G@```)M```F>````FX``)QX```";@``#WD```)G```M>@``
+M`F@``$)Z```":```6GH```)H``!O>@```F@``/-Z```"90```WL```)E```C
+M>P```F,``&=[```"F@``EWL```*;``#L>P```G(``#%\```"9P``@'P```)C
+M``"_?````F,``%M^```"D@``JGX```)G``!7?P```I$``(-_```"E```N'\`
+M``*B``#$?P```J,``-A_```"I```<H````*E``!^@````J8``-.````"J```
+M^8````*I```5@0```J@``%N!```"J@``;X$```*J``"?@0```JH``*:$```"
+MJ0``NX0```*I``#6A````JD``/&$```"J0``#(4```*I```TA0```JD``$J%
+M```"K```5H4```*I``!IA0```JD``'R%```"J0``CX4```*I``"GA0```JP`
+M`+R%```"J0``SX4```*I```,A@```JT``.2'```"K0``^H<```*J```*B```
+M`JT``!J(```"K0``-8@```*J``!%B````JT``%:(```"J@``R(@```*J```W
+MB0```JT``$^)```"J@``\HD```*J``#^B0```JT```J*```"J```&(H```*J
+M```DB@```JT``#"*```"J```78H```*I```+BP```:L``-&+```"J0``X8L`
+M``*I```)C````JH``)"-```"K@``PXT```*O``!HC@```:L``.V.```"K0``
+M^8X```*H``!LCP```JT``'^/```"J@``B8\```*M``"5CP```J@``+N/```"
+MJ@``7I````*J``!SD````JH``(:0```"J@``GY````*J``"QD````JH``,20
+M```"J@``UI````*J``#LD````JH``!J2```"K0``4I(```*J``"&D@```JT`
+M`.:2```"J@``)9,```*J```QDP```JT``#V3```"J```2Y,```*J``!7DP``
+M`JT``*V3```"J@``O),```*M``#9DP```JH``.V3```"J@```90```*J```5
+ME````JH``"F4```"J@``/90```*J``!1E````JH``&64```"J@``>90```*J
+M``"-E````JH``*&4```"J@``M90```*J``#,E````JH```*5```"J@``%I4`
+M``*J```JE0```JH``#Z5```"J@``4)4```*M``!JE0```JH``)^5```"J@``
+MRI4```*M``#>E0```JH``/&5```"K0``!Y8```*J```9E@```JH``"N6```"
+MJ@``0)8```*J``!2E@```JH``&26```"J@``=I8```*J``"(E@```JH``)J6
+M```"J@``K)8```*J``"^E@```JH``-"6```"J@``L9<```)H``#*EP```F@`
+M`)J8```"J0``RI@```*J``#=F````JH``.V8```"K0``'ID```*J``!]F0``
+M`JH``)&9```"J@``LID```*I``#-F0```JH```B:```"J@``$IH```*M``"#
+MF@```JH``+*:```"L```")L```*I```YFP```JP``$Z;```"K```8YL```*L
+M``!XFP```JP``(V;```"K```VYL```*L``#PFP```JP```6<```"K```&IP`
+M``*L```OG````JP``$2<```"K```69P```*L``!UG````JD``("<```"L0``
+MG)P```*I``#3G````JX``!Z=```"J@``WYT```*M```TG@```JH``$2>```"
+MK0``6IX```*J``!JG@```JT``-F>```"J@``[)X```*J``#_G@```JH``":?
+M```"J@``2)\```*J``!_GP```J@``*B?```"LP``^)\```*J```)H````:L`
+M`!F@```!JP``TJ````*M``#XH````JT```2A```"J```$*$```*M``"JH0``
+M`JH``+:A```"K0``PJ$```*H``#0H0```JH``-RA```"K0``,:(```*M``!A
+MH@```JH``)*B```"K0``GJ(```*H``#2H@```JH```*C```"K0``#J,```*H
+M```<HP```J<``%6C```"J0``W*,```*M```\I````JH``'2E```"K0``E:4`
+M``*J``"TI0```JH``#ZF```"K0``;Z8```*J``#(I@```JT``/6F```"J@``
+M$*<```*M``!IIP```JT``)6G```"J@``L*<```*M``#>IP```JT``!*H```"
+MJ@``@J@```*M``"PJ````K,```"I```"K0``%:D```*M```JJ0```JT``#^I
+M```"K0``5*D```*M``!IJ0```JT``'ZI```"K0``DZD```*M``#TJ0```L(`
+M`-&K```"K0``!*P```*M```9K````JH``%RL```"J@``:*P```*M``!\K```
+M`JH``)BL```"K0``=*T```*J``"5K0```JH``,BM```"J0``Y:T```*H```<
+MK@```JP``#.N```"J0``6*X```*L``!OK@```JD``+6N```"J0``QJX```*H
+M``#>K@```JD``/VN```"LP``$:\```*H```JKP```K$``#RO```"J0``E:\`
+M``+'``"JKP```JP``+BO```"L0``R*\```+&``#9KP```L8``"ZP```"I0``
+ML;````*P``#OL````J4``':Q```"RP``[+$```+'```,L@```JP``".R```"
+MK```.K(```*L``!1L@```JP``&BR```"K```O[(```*L``#4L@```JP``.FR
+M```"K```_K(```*L```3LP```JP``"BS```"K```/;,```*L``!4LP```K$`
+M`&2S```"Q@``=[,```+&``"/LP```K$``)^S```"Q@``N;,```*I``#)LP``
+M`L8``/^S```"L0``&+0```*O```^M````JX``%JT```"L0``:K0```+&``!Z
+MM````L8``(JT```"Q@``P+0```*L``#2M````JD``-ZT```"J```YK0```+&
+M``#RM````J@``/ZT```"J```"K4```*H```6M0```J@``#"U```"J0``3;4`
+M``*H``"2M0```J@``+FU```!!```R+4```*L``#8M0```00``.>U```"J0``
+M`+8```$$```/M@```JD``"BV```!!```-[8```*I``!<M@```00``&NV```"
+MK```>+8```$$``"'M@```JP``*>V```!!```MK8```*L``"^M@```00``,RV
+M```"J0``^[8```*M```/MP```JH``!VW```"K0``0;<```*N``!2MP```JT`
+M`&2W```!!```<[<```*L``!]MP```00``(NW```"K```E;<```$$``"DMP``
+M`JP``*ZW```!!```O+<```*L``#3MP```JH``.&W```"K0``\+<```*J```3
+MN````JT``">X```"J@``-;@```*M``!9N````JX``&JX```"K0``?+@```$$
+M``"+N````JP``)6X```!!```H[@```*L``"MN````00``+RX```"K```QK@`
+M``$$``#4N````JP``.NX```"J@``^;@```*M```(N0```JH``"ZY```!!```
+M/;D```*L``!'N0```00``%6Y```"K```:[D```*I``"*N0```00``)BY```"
+MK```K+D```*H``"ZN0```JD``/"Y```"K0``!;H```*J```3N@```JT``#>Z
+M```"K@``2+H```*M``!@N@```JP``&^Z```"J@``?;H```*M``".N@```JH`
+M`-2Z```"S@``\[H```*M```(NP```JH``!:[```"K0``/+L```*N``!-NP``
+M`JT``%N[```"KP``B;L```$$``"8NP```JP``+*[```"J```QKL```*O``#5
+MNP```00``.2[```"K```#[P```$$```>O````JP``"R\```"KP``:KP```$$
+M``!YO````JP``(J\```"J@``F+P```*M``"IO````JH``,Z\```!!```TKP`
+M``$#``#HO````00``.R\```!`P``(`````&9```D`````9D``"@````!F0``
+M+`````&9```P`````8D``#0````!>```.`````&$``!``````94``&`````!
+M<```9`````%P``!H`````7```&P````!<```<`````&*``!T`````7H``'@`
+M```!A@``@`````&6`````````0(```0````!`@``"`````$"```,`````0(`
+M`!`````!`@``%`````$"```8`````0(``!P````!`@``(`````$"```D````
+D`0(``"@````!`@``+`````$"```P`````0(``#0````!`@``
`
end
diff --git a/sys/dev/hptmv/ioctl.c b/sys/dev/hptmv/ioctl.c
index c75c98fd1942..5c3796a68d4b 100644
--- a/sys/dev/hptmv/ioctl.c
+++ b/sys/dev/hptmv/ioctl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,17 @@
#include <sys/kernel.h>
#include <sys/malloc.h>
+#if (__FreeBSD_version < 500000)
+#include <sys/proc.h>
+#include <sys/kthread.h>
+#include <sys/wait.h>
+#include <sys/sysproto.h>
+#endif
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
#include <dev/hptmv/global.h>
#include <dev/hptmv/hptintf.h>
#include <dev/hptmv/osbsd.h>
@@ -60,7 +71,8 @@ static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd);
static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd,
FPSCAT_GATH pSgTable, int logical);
-static void get_disk_location(PDevice pDev, int *controller, int *channel)
+static void
+get_disk_location(PDevice pDev, int *controller, int *channel)
{
IAL_ADAPTER_T *pAdapTemp;
int i, j;
@@ -75,7 +87,8 @@ static void get_disk_location(PDevice pDev, int *controller, int *channel)
}
}
-static int event_queue_add(PHPT_EVENT pEvent)
+static int
+event_queue_add(PHPT_EVENT pEvent)
{
int p;
p = (event_queue_tail + 1) % MAX_EVENTS;
@@ -88,7 +101,8 @@ static int event_queue_add(PHPT_EVENT pEvent)
return 0;
}
-static int event_queue_remove(PHPT_EVENT pEvent)
+static int
+event_queue_remove(PHPT_EVENT pEvent)
{
if (event_queue_head != event_queue_tail)
{
@@ -100,7 +114,8 @@ static int event_queue_remove(PHPT_EVENT pEvent)
return -1;
}
-void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param)
+void HPTLIBAPI
+ioctl_ReportEvent(UCHAR event, PVOID param)
{
HPT_EVENT e;
ZeroMemory(&e, sizeof(e));
@@ -142,14 +157,15 @@ void HPTLIBAPI ioctl_ReportEvent(UCHAR event, PVOID param)
}
}
-static int hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
+static int
+hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
{
PVDevice pArray = ID_TO_VDEV(id);
BOOLEAN del_block0 = (options & DAF_KEEP_DATA_IF_POSSIBLE)?0:1;
int i;
PVDevice pa;
- if((id== HPT_NULL_ID) || check_VDevice_valid(pArray))
+ if ((id==0) || check_VDevice_valid(pArray))
return -1;
if(!mIsArray(pArray)) return -1;
@@ -176,7 +192,8 @@ static int hpt_delete_array(_VBUS_ARG DEVICEID id, DWORD options)
/* just to prevent driver from sending more commands */
static void HPTLIBAPI nothing(_VBUS_ARG void *notused){}
-static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter)
+intrmask_t
+lock_driver_idle(IAL_ADAPTER_T *pAdapter)
{
intrmask_t oldspl;
_VBUS_INST(&pAdapter->VBus)
@@ -185,6 +202,12 @@ static intrmask_t lock_driver_idle(IAL_ADAPTER_T *pAdapter)
KdPrint(("outstandingCommands is %d, wait..\n", pAdapter->outstandingCommands));
if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
unlock_driver(oldspl);
+/*Schedule out*/
+#if (__FreeBSD_version < 500000)
+ YIELD_THREAD;
+#else
+ tsleep(lock_driver_idle, PPAUSE, "switch", 1);
+#endif
oldspl = lock_driver();
}
CheckIdleCall(_VBUS_P0);
@@ -218,7 +241,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
pArray = ID_TO_VDEV(idArray);
- if((idArray == HPT_NULL_ID) || check_VDevice_valid(pArray))
+ if((idArray == 0) || check_VDevice_valid(pArray))
return -1;
if(!mIsArray(pArray))
@@ -231,7 +254,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
if(pArray == _vbus_p->pVDevice[i])
{
periph = hpt_get_periph(pAdapter->mvSataAdapter.adapterId, i);
- if (periph != NULL && periph->refcount == 1)
+ if (periph != NULL && periph->refcount >= 1)
{
hpt_printk(("Can not delete a mounted device.\n"));
return -1;
@@ -388,7 +411,7 @@ int Kernel_DeviceIoControl(_VBUS_ARG
{
PVDevice pArray = ID_TO_VDEV(((PHPT_ADD_DISK_TO_ARRAY)lpInBuffer)->idArray);
pAdapter=(IAL_ADAPTER_T *)pArray->pVBus->OsExt;
- if(pArray->u.array.rf_rebuilding == HPT_NULL_ID)
+ if(pArray->u.array.rf_rebuilding == 0)
{
DWORD timeout = 0;
oldspl = lock_driver();
@@ -417,7 +440,8 @@ int Kernel_DeviceIoControl(_VBUS_ARG
return 0;
}
-static int hpt_get_event(PHPT_EVENT pEvent)
+static int
+hpt_get_event(PHPT_EVENT pEvent)
{
intrmask_t oldspl = lock_driver();
int ret = event_queue_remove(pEvent);
@@ -425,7 +449,8 @@ static int hpt_get_event(PHPT_EVENT pEvent)
return ret;
}
-static int hpt_set_array_state(DEVICEID idArray, DWORD state)
+static int
+hpt_set_array_state(DEVICEID idArray, DWORD state)
{
IAL_ADAPTER_T *pAdapter;
PVDevice pVDevice = ID_TO_VDEV(idArray);
@@ -433,8 +458,7 @@ static int hpt_set_array_state(DEVICEID idArray, DWORD state)
DWORD timeout = 0;
intrmask_t oldspl;
- if(idArray == HPT_NULL_ID || check_VDevice_valid(pVDevice))
- return -1;
+ if(idArray == 0 || check_VDevice_valid(pVDevice)) return -1;
if(!mIsArray(pVDevice))
return -1;
if(!pVDevice->vf_online || pVDevice->u.array.rf_broken) return -1;
@@ -474,7 +498,7 @@ static int hpt_set_array_state(DEVICEID idArray, DWORD state)
case MIRROR_REBUILD_ABORT:
{
for(i = 0; i < pVDevice->u.array.bArnMember; i++) {
- if(pVDevice->u.array.pMember[i] != NULL && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1)
+ if(pVDevice->u.array.pMember[i] != 0 && pVDevice->u.array.pMember[i]->VDeviceType == VD_RAID_1)
hpt_set_array_state(VDEV_TO_ID(pVDevice->u.array.pMember[i]), state);
}
@@ -585,7 +609,8 @@ static int hpt_set_array_state(DEVICEID idArray, DWORD state)
return 0;
}
-static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical)
+int HPTLIBAPI
+R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable, int logical)
{
ULONG bufferSize = SECTOR_TO_BYTE(pCmd->uCmd.R1Control.nSectors);
if (pCmd->uCmd.R1Control.Command==CTRL_CMD_VERIFY)
@@ -648,13 +673,15 @@ static int HPTLIBAPI R1ControlSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSgTable,
}
static int End_Job=0;
-static void HPTLIBAPI thread_io_done(_VBUS_ARG PCommand pCmd)
+void HPTLIBAPI
+thread_io_done(_VBUS_ARG PCommand pCmd)
{
End_Job = 1;
wakeup((caddr_t)pCmd);
}
-void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
+void
+hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags)
{
DWORD timeout = 0;
ULONG capacity = pArray->VDeviceCapacity / (pArray->u.array.bArnMember-1);
@@ -714,7 +741,9 @@ retry_cmd:
#define MAX_REBUILD_SECTORS 0x40
/* take care for discontinuous buffer in R1ControlSgl */
+ unlock_driver(oldspl);
buffer = malloc(SECTOR_TO_BYTE(MAX_REBUILD_SECTORS), M_DEVBUF, M_NOWAIT);
+ oldspl = lock_driver();
if(!buffer) {
FreeCommand(_VBUS_P pCmd);
hpt_printk(("can't allocate rebuild buffer\n"));
@@ -783,11 +812,9 @@ retry_cmd:
result = pCmd->Result;
FreeCommand(_VBUS_P pCmd);
- if (buffer) {
- free(buffer, M_DEVBUF);
- /* beware of goto retry_cmd below */
- buffer = NULL;
- }
+ unlock_driver(oldspl);
+ if (buffer) free(buffer, M_DEVBUF);
+ oldspl = lock_driver();
KdPrintI(("cmd finished %d", result));
switch(result)
@@ -918,6 +945,12 @@ fail:
/* put this to have driver stop processing system commands quickly */
if (!mWaitingForIdle(_VBUS_P0)) CallWhenIdle(_VBUS_P nothing, 0);
unlock_driver(oldspl);
+ /*Schedule out*/
+#if (__FreeBSD_version < 500000)
+ YIELD_THREAD;
+#else
+ tsleep(hpt_rebuild_data_block, PPAUSE, "switch", 1);
+#endif
oldspl = lock_driver();
}
diff --git a/sys/dev/hptmv/mv.c b/sys/dev/hptmv/mv.c
index 474b3d5ddb23..f9f41ffb75da 100644
--- a/sys/dev/hptmv/mv.c
+++ b/sys/dev/hptmv/mv.c
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,51 +27,68 @@
*/
#include <sys/param.h>
#include <sys/systm.h>
+
+#include <sys/time.h>
#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <machine/resource.h>
+
+#if __FreeBSD_version >= 500043
+#include <machine/pci_cfgreg.h>
+#endif
+
+#if (__FreeBSD_version < 500043)
+#include <sys/bus_private.h>
+#endif
-#include <vm/vm.h>
-#include <vm/pmap.h>
-#include <vm/vm_extern.h>
+#if (__FreeBSD_version < 500000)
+#include <machine/clock.h>
+#endif
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
#include <dev/hptmv/global.h>
#include <dev/hptmv/hptintf.h>
#include <dev/hptmv/mvOs.h>
#include <dev/hptmv/osbsd.h>
+
void HPTLIBAPI
MV_REG_WRITE_BYTE(MV_BUS_ADDR_T base, MV_U32 offset, MV_U8 val)
-{
- mv_reg_write_byte(base, offset, val);
+{
+ writeb((void *)((ULONG_PTR)base + offset), val);
}
void HPTLIBAPI
MV_REG_WRITE_WORD(MV_BUS_ADDR_T base, MV_U32 offset, MV_U16 val)
-{
- mv_reg_write_word(base, offset, val);
+{
+ writew((void *)((ULONG_PTR)base + offset), val);
}
void HPTLIBAPI
MV_REG_WRITE_DWORD(MV_BUS_ADDR_T base, MV_U32 offset, MV_U32 val)
{
- mv_reg_write_dword(base, offset, val);
+ writel((void *)((ULONG_PTR)base + offset), val);
}
-MV_U8
-HPTLIBAPI MV_REG_READ_BYTE(MV_BUS_ADDR_T base, MV_U32 offset)
+MV_U8 HPTLIBAPI
+MV_REG_READ_BYTE(MV_BUS_ADDR_T base, MV_U32 offset)
{
- return (mv_reg_read_byte(base, offset));
+ return readb((void *)((ULONG_PTR)base + offset));
}
-MV_U16
-HPTLIBAPI MV_REG_READ_WORD(MV_BUS_ADDR_T base, MV_U32 offset)
+MV_U16 HPTLIBAPI
+MV_REG_READ_WORD(MV_BUS_ADDR_T base, MV_U32 offset)
{
- return (mv_reg_read_word(base, offset));
+ return readw((void *)((ULONG_PTR)base + offset));
}
-MV_U32
-HPTLIBAPI MV_REG_READ_DWORD(MV_BUS_ADDR_T base, MV_U32 offset)
+MV_U32 HPTLIBAPI
+MV_REG_READ_DWORD(MV_BUS_ADDR_T base, MV_U32 offset)
{
- return (mv_reg_read_dword(base, offset));
+ return readl((void *)((ULONG_PTR)base + offset));
}
int HPTLIBAPI
@@ -86,29 +103,26 @@ os_memcpy(void *to, const void *from, unsigned len)
memcpy(to, from, len);
}
-void
-HPTLIBAPI os_memset(void *s, char c, unsigned len)
+void HPTLIBAPI
+os_memset(void *s, char c, unsigned len)
{
memset(s, c, len);
}
-unsigned
-HPTLIBAPI os_strlen(const char *s)
+unsigned HPTLIBAPI
+os_strlen(const char *s)
{
return strlen(s);
}
-void HPTLIBAPI mvMicroSecondsDelay(MV_U32 msecs)
+void HPTLIBAPI
+mvMicroSecondsDelay(MV_U32 msecs)
{
DELAY(msecs);
}
-/*
- * XXX
- *
- * The binary raid.obj requires this function!
- */
-ULONG_PTR HPTLIBAPI fOsPhysicalAddress(void *addr)
+ULONG_PTR HPTLIBAPI
+fOsPhysicalAddress(void *addr)
{
return (ULONG_PTR)(vtophys(addr));
}
diff --git a/sys/dev/hptmv/mvOs.h b/sys/dev/hptmv/mvOs.h
index 2c0a5f4b1c66..ef78c94644f5 100644
--- a/sys/dev/hptmv/mvOs.h
+++ b/sys/dev/hptmv/mvOs.h
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,19 +28,6 @@
#ifndef __INCmvOsBsdh
#define __INCmvOsBsdh
-/* Taken out of the Makefile magic */
-#define __KERNEL__ 1
-#define KERNEL 1
-#define _KERNEL 1
-#define _FREEBSD_ 1
-
-/*
- * This binary object core for this driver is only for x86, so this constant
- * will not change.
- */
-#define BITS_PER_LONG 32
-#define DRIVER_VERSION "1.1"
-
#if DBG
#define MV_DEBUG_LOG
#endif
@@ -49,22 +36,24 @@
#define ENABLE_WRITE_CACHE
/* Typedefs */
-#define HPTLIBAPI __attribute__((regparm(0)))
+/*#define HPTLIBAPI __attribute__((regparm(0))) */
+#define HPTLIBAPI
#define FAR
+#define SS_SEG
#ifdef FASTCALL
#undef FASTCALL
#endif
#define FASTCALL HPTLIBAPI
#define PASCAL HPTLIBAPI
-typedef u_short USHORT;
-typedef u_char UCHAR;
-typedef u_char *PUCHAR;
-typedef u_short *PUSHORT;
-typedef u_char BOOLEAN;
-typedef u_short WORD;
-typedef u_int UINT, BOOL;
-typedef u_char BYTE;
+typedef unsigned short USHORT;
+typedef unsigned char UCHAR;
+typedef unsigned char *PUCHAR;
+typedef unsigned short *PUSHORT;
+typedef unsigned char BOOLEAN;
+typedef unsigned short WORD;
+typedef unsigned int UINT, BOOL;
+typedef unsigned char BYTE;
typedef void *PVOID, *LPVOID;
typedef void *ADDRESS;
@@ -72,23 +61,28 @@ typedef int LONG;
typedef unsigned int ULONG, *PULONG, LBA_T;
typedef unsigned int DWORD, *LPDWORD, *PDWORD;
typedef unsigned long ULONG_PTR, UINT_PTR, BUS_ADDR;
+typedef unsigned long long HPT_U64;
typedef enum mvBoolean{MV_FALSE, MV_TRUE} MV_BOOLEAN;
#define FALSE 0
#define TRUE 1
+#ifndef NULL
+#define NULL 0
+#endif
+
/* System dependant typedefs */
-typedef void MV_VOID;
-typedef uint32_t MV_U32;
-typedef uint16_t MV_U16;
-typedef uint8_t MV_U8;
-typedef void *MV_VOID_PTR;
-typedef MV_U32 *MV_U32_PTR;
-typedef MV_U16 *MV_U16_PTR;
-typedef MV_U8 *MV_U8_PTR;
-typedef char *MV_CHAR_PTR;
-typedef void *MV_BUS_ADDR_T;
+typedef void MV_VOID;
+typedef unsigned int MV_U32;
+typedef unsigned short MV_U16;
+typedef unsigned char MV_U8;
+typedef void *MV_VOID_PTR;
+typedef MV_U32 *MV_U32_PTR;
+typedef MV_U16 *MV_U16_PTR;
+typedef MV_U8 *MV_U8_PTR;
+typedef char *MV_CHAR_PTR;
+typedef void *MV_BUS_ADDR_T;
/* System dependent macro for flushing CPU write cache */
#define MV_CPU_WRITE_BUFFER_FLUSH()
@@ -101,12 +95,9 @@ typedef void *MV_BUS_ADDR_T;
#define MV_LE32_TO_CPU(x) (x)
/* System dependent register read / write in byte/word/dword variants */
-extern void HPTLIBAPI MV_REG_WRITE_BYTE(MV_BUS_ADDR_T base, MV_U32 offset,
- MV_U8 val);
-extern void HPTLIBAPI MV_REG_WRITE_WORD(MV_BUS_ADDR_T base, MV_U32 offset,
- MV_U16 val);
-extern void HPTLIBAPI MV_REG_WRITE_DWORD(MV_BUS_ADDR_T base, MV_U32 offset,
- MV_U32 val);
+extern void HPTLIBAPI MV_REG_WRITE_BYTE(MV_BUS_ADDR_T base, MV_U32 offset, MV_U8 val);
+extern void HPTLIBAPI MV_REG_WRITE_WORD(MV_BUS_ADDR_T base, MV_U32 offset, MV_U16 val);
+extern void HPTLIBAPI MV_REG_WRITE_DWORD(MV_BUS_ADDR_T base, MV_U32 offset, MV_U32 val);
extern MV_U8 HPTLIBAPI MV_REG_READ_BYTE(MV_BUS_ADDR_T base, MV_U32 offset);
extern MV_U16 HPTLIBAPI MV_REG_READ_WORD(MV_BUS_ADDR_T base, MV_U32 offset);
extern MV_U32 HPTLIBAPI MV_REG_READ_DWORD(MV_BUS_ADDR_T base, MV_U32 offset);
@@ -121,25 +112,9 @@ typedef struct mvOsSemaphore
ULONG_PTR HPTLIBAPI fOsPhysicalAddress(void *addr);
/* Semaphore init, take and release */
-static __inline int
-mvOsSemInit(MV_OS_SEMAPHORE *p)
-{
- return (MV_TRUE);
-}
-
-static __inline int
-mvOsSemTake(MV_OS_SEMAPHORE *p)
-{
- return (MV_TRUE);
-}
-
-static __inline int
-mvOsSemRelease(MV_OS_SEMAPHORE *p)
-{
- return (MV_TRUE);
-}
-
-#define MV_MAX_SEGMENTS 255
+#define mvOsSemInit(p) (MV_TRUE)
+#define mvOsSemTake(p) (MV_TRUE)
+#define mvOsSemRelease(p) (MV_TRUE)
/* Delay function in micro seconds resolution */
void HPTLIBAPI mvMicroSecondsDelay(MV_U32);
@@ -148,7 +123,7 @@ void HPTLIBAPI mvMicroSecondsDelay(MV_U32);
#ifdef MV_DEBUG_LOG
int mvLogMsg(MV_U8, MV_CHAR_PTR, ...);
#define _mvLogMsg(x) mvLogMsg x
-#else
+#else
#define mvLogMsg(x...)
#define _mvLogMsg(x)
#endif
@@ -156,16 +131,17 @@ int mvLogMsg(MV_U8, MV_CHAR_PTR, ...);
/*************************************************************************
* Debug support
*************************************************************************/
-#ifdef DEBUG
-#define HPT_ASSERT(x) \
- KASSERT((x), ("ASSERT fail at %s line %d", __FILE__, __LINE__))
-
+#if DEBUG
+#define HPT_ASSERT(x) do { if (!(x)) { \
+ printf("ASSERT fail at %s line %d", __FILE__, __LINE__); \
+ while (1); \
+ }} while (0)
extern int hpt_dbg_level;
#define KdPrintI(_x_) do{ if (hpt_dbg_level>2) printf _x_; }while(0)
#define KdPrintW(_x_) do{ if (hpt_dbg_level>1) printf _x_; }while(0)
#define KdPrintE(_x_) do{ if (hpt_dbg_level>0) printf _x_; }while(0)
#define KdPrint(x) KdPrintI(x)
-#else
+#else
#define HPT_ASSERT(x)
#define KdPrint(x)
#define KdPrintI(x)
@@ -173,4 +149,4 @@ extern int hpt_dbg_level;
#define KdPrintE(x)
#endif
-#endif /* __INCmvOsBsdh */
+#endif
diff --git a/sys/dev/hptmv/mvSata.h b/sys/dev/hptmv/mvSata.h
index 4a5c75c81d60..bf77fbfcb234 100644
--- a/sys/dev/hptmv/mvSata.h
+++ b/sys/dev/hptmv/mvSata.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 MARVELL SEMICONDUCTOR ISRAEL, LTD.
+ * Copyright (c) 2004-2005 MARVELL SEMICONDUCTOR ISRAEL, LTD.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/hptmv/mvStorageDev.h b/sys/dev/hptmv/mvStorageDev.h
index 5d533fedb866..48aad93651f9 100644
--- a/sys/dev/hptmv/mvStorageDev.h
+++ b/sys/dev/hptmv/mvStorageDev.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 MARVELL SEMICONDUCTOR ISRAEL, LTD.
+ * Copyright (c) 2004-2005 MARVELL SEMICONDUCTOR ISRAEL, LTD.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/sys/dev/hptmv/osbsd.h b/sys/dev/hptmv/osbsd.h
index d81229ec8754..a07f51dbc8d7 100644
--- a/sys/dev/hptmv/osbsd.h
+++ b/sys/dev/hptmv/osbsd.h
@@ -1,5 +1,5 @@
-/*-
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+/*
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,24 @@
#include <sys/bus.h>
#include <sys/resource.h>
#include <sys/eventhandler.h>
+#include <sys/devicestat.h>
+#if (__FreeBSD_version < 500043)
+#include <stddef.h>
+#include <sys/buf.h>
+#endif
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+
+#if (__FreeBSD_version < 600030)
+#include <machine/bus_memio.h>
+#endif
#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/bus.h>
+
#include <sys/rman.h>
#include <cam/cam.h>
@@ -43,15 +57,19 @@
#include <cam/cam_sim.h>
#include <cam/cam_xpt_sim.h>
#include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
+
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
+
+
extern intrmask_t lock_driver(void);
extern void unlock_driver(intrmask_t spl);
typedef struct
{
- UCHAR status; /* 0 nonbootable; 80h bootable */
+ UCHAR status; /* 0 nonbootable; 80h bootable */
UCHAR start_head;
USHORT start_sector;
UCHAR type;
@@ -98,8 +116,8 @@ typedef struct _READ_CAPACITY_DATA {
/****************************************/
/* Bits for HD_ERROR */
-#define NM_ERR 0x02 /* media present */
-#define ABRT_ERR 0x04 /* Command aborted */
+#define NM_ERR 0x02 /* media present */
+#define ABRT_ERR 0x04 /* Command aborted */
#define MCR_ERR 0x08 /* media change request */
#define IDNF_ERR 0x10 /* ID field not found */
#define MC_ERR 0x20 /* media changed */
@@ -107,213 +125,195 @@ typedef struct _READ_CAPACITY_DATA {
#define WP_ERR 0x40 /* write protect */
#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
-#define REQUESTS_ARRAY_SIZE (9 * MV_EDMA_REQUEST_QUEUE_SIZE) /* 9 K bytes */
-#define RESPONSES_ARRAY_SIZE (12*MV_EDMA_RESPONSE_QUEUE_SIZE) /* 3 K bytes */
+#define REQUESTS_ARRAY_SIZE (9 * MV_EDMA_REQUEST_QUEUE_SIZE) /* 9 K bytes */
+#define RESPONSES_ARRAY_SIZE (12 * MV_EDMA_RESPONSE_QUEUE_SIZE) /* 3 K bytes */
-#define PRD_ENTRIES_PER_CMD (MAX_SG_DESCRIPTORS+1)
-#define PRD_ENTRIES_SIZE (MV_EDMA_PRD_ENTRY_SIZE*PRD_ENTRIES_PER_CMD)
-#define PRD_TABLES_FOR_VBUS (MV_SATA_CHANNELS_NUM*MV_EDMA_QUEUE_LENGTH)
+#define PRD_ENTRIES_PER_CMD (MAX_SG_DESCRIPTORS+1)
+#define PRD_ENTRIES_SIZE (MV_EDMA_PRD_ENTRY_SIZE*PRD_ENTRIES_PER_CMD)
+#define PRD_TABLES_FOR_VBUS (MV_SATA_CHANNELS_NUM*MV_EDMA_QUEUE_LENGTH)
-typedef enum _SataEvent {
- SATA_EVENT_NO_CHANGE = 0,
+typedef enum _SataEvent
+{
+ SATA_EVENT_NO_CHANGE = 0,
SATA_EVENT_CHANNEL_CONNECTED,
SATA_EVENT_CHANNEL_DISCONNECTED
} SATA_EVENT;
typedef ULONG_PTR dma_addr_t;
-typedef struct _MV_CHANNEL {
+typedef struct _MV_CHANNEL
+{
unsigned int maxUltraDmaModeSupported;
unsigned int maxDmaModeSupported;
unsigned int maxPioModeSupported;
- MV_BOOLEAN online;
+ MV_BOOLEAN online;
} MV_CHANNEL;
-struct _privCommand;
+typedef struct _BUS_DMAMAP
+{ struct _BUS_DMAMAP *next;
+ struct IALAdapter *pAdapter;
+ bus_dmamap_t dma_map;
+ SCAT_GATH psg[MAX_SG_DESCRIPTORS];
+} BUS_DMAMAP, *PBUS_DMAMAP;
-typedef struct IALAdapter {
+typedef struct IALAdapter
+{
struct cam_path *path;
- device_t hpt_dev; /* bus device */
- struct resource *hpt_irq; /* interrupt */
- void *hpt_intr; /* interrupt handle */
+
+ bus_dma_tag_t io_dma_parent; /* I/O buffer DMA tag */
+ PBUS_DMAMAP pbus_dmamap_list;
+ PBUS_DMAMAP pbus_dmamap;
+
+ device_t hpt_dev; /* bus device */
+ struct resource *hpt_irq; /* interrupt */
struct resource *mem_res;
- bus_space_handle_t mem_bsh;
- bus_space_tag_t mem_btag;
- bus_dma_tag_t parent_dmat;
- bus_dma_tag_t req_dmat;
- bus_dmamap_t req_map;
- bus_dma_tag_t resp_dmat;
- bus_dmamap_t resp_map;
- bus_dma_tag_t prd_dmat;
- bus_dmamap_t prd_map;
- bus_dma_tag_t buf_dmat;
-
- struct IALAdapter *next;
+ void *hpt_intr; /* interrupt handle */
+ struct IALAdapter *next;
- MV_SATA_ADAPTER mvSataAdapter;
- MV_CHANNEL mvChannel[MV_SATA_CHANNELS_NUM];
- MV_U8 *requestsArrayBaseAddr;
- MV_U8 *requestsArrayBaseAlignedAddr;
- dma_addr_t requestsArrayBaseDmaAddr;
- dma_addr_t requestsArrayBaseDmaAlignedAddr;
- MV_U8 *responsesArrayBaseAddr;
- MV_U8 *responsesArrayBaseAlignedAddr;
- dma_addr_t responsesArrayBaseDmaAddr;
- dma_addr_t responsesArrayBaseDmaAlignedAddr;
- SATA_EVENT sataEvents[MV_SATA_CHANNELS_NUM];
+ MV_SATA_ADAPTER mvSataAdapter;
+ MV_CHANNEL mvChannel[MV_SATA_CHANNELS_NUM];
+ MV_U8 *requestsArrayBaseAddr;
+ MV_U8 *requestsArrayBaseAlignedAddr;
+ dma_addr_t requestsArrayBaseDmaAddr;
+ dma_addr_t requestsArrayBaseDmaAlignedAddr;
+ MV_U8 *responsesArrayBaseAddr;
+ MV_U8 *responsesArrayBaseAlignedAddr;
+ dma_addr_t responsesArrayBaseDmaAddr;
+ dma_addr_t responsesArrayBaseDmaAlignedAddr;
+ SATA_EVENT sataEvents[MV_SATA_CHANNELS_NUM];
struct callout_handle event_timer_connect;
struct callout_handle event_timer_disconnect;
- struct _VBus VBus;
- struct _VDevice VDevices[MV_SATA_CHANNELS_NUM];
- PCommand pCommandBlocks;
- struct _privCommand *pPrivateBlocks;
- TAILQ_HEAD(, _privCommand) PrivCmdTQH;
- PUCHAR prdTableAddr;
- ULONG prdTableDmaAddr;
- void* pFreePRDLink;
+ struct _VBus VBus;
+ struct _VDevice VDevices[MV_SATA_CHANNELS_NUM];
+ PCommand pCommandBlocks;
+ PUCHAR prdTableAddr;
+ PUCHAR prdTableAlignedAddr;
+ void* pFreePRDLink;
- union ccb *pending_Q;
+ union ccb *pending_Q;
- MV_U8 outstandingCommands;
+ MV_U8 outstandingCommands;
- UCHAR status;
- UCHAR ver_601;
- UCHAR beeping;
+ UCHAR status;
+ UCHAR ver_601;
+ UCHAR beeping;
eventhandler_tag eh;
-} IAL_ADAPTER_T;
-
-typedef struct _privCommand {
- TAILQ_ENTRY(_privCommand) PrivEntry;
- IAL_ADAPTER_T *pAdapter;
- union ccb *ccb;
- bus_dmamap_t buf_map;
-} *pPrivCommand;
+}
+IAL_ADAPTER_T;
extern IAL_ADAPTER_T *gIal_Adapter;
/*entry.c*/
typedef void (*HPT_DPC)(IAL_ADAPTER_T *,void*,UCHAR);
+
int hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T *pAdapter, void *arg, UCHAR flags);
-void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray,
- UCHAR flags);
+void hpt_rebuild_data_block(IAL_ADAPTER_T *pAdapter, PVDevice pArray, UCHAR flags);
void Check_Idle_Call(IAL_ADAPTER_T *pAdapter);
-int Kernel_DeviceIoControl(_VBUS_ARG DWORD dwIoControlCode, PVOID lpInBuffer,
- DWORD nInBufferSize, PVOID lpOutBuffer, DWORD nOutBufferSize,
- PDWORD lpBytesReturned);
void fRescanAllDevice(_VBUS_ARG0);
int hpt_add_disk_to_array(_VBUS_ARG DEVICEID idArray, DEVICEID idDisk);
+int Kernel_DeviceIoControl(_VBUS_ARG
+ DWORD dwIoControlCode, /* operation control code */
+ PVOID lpInBuffer, /* input data buffer */
+ DWORD nInBufferSize, /* size of input data buffer */
+ PVOID lpOutBuffer, /* output data buffer */
+ DWORD nOutBufferSize, /* size of output data buffer */
+ PDWORD lpBytesReturned /* byte count */
+ );
+
#define __str_direct(x) #x
#define __str(x) __str_direct(x)
#define KMSG_LEADING __str(PROC_DIR_NAME) ": "
-#define hpt_printk(_x_) do { \
- printf(KMSG_LEADING); \
- printf _x_ ; \
-} while (0)
+#define hpt_printk(_x_) do { printf(KMSG_LEADING); printf _x_ ; } while (0)
#define DUPLICATE 0
#define INITIALIZE 1
#define REBUILD_PARITY 2
#define VERIFY 3
-/**********************************************************/
+/***********************************************************/
+
static __inline struct cam_periph *
hpt_get_periph(int path_id,int target_id)
{
- struct cam_periph *periph = NULL;
- struct cam_path *path;
- int status;
+ struct cam_periph *periph = NULL;
+ struct cam_path *path;
+ int status;
- status = xpt_create_path(&path, NULL, path_id, target_id, 0);
- if (status == CAM_REQ_CMP) {
- periph = cam_periph_find(path, NULL);
+ status = xpt_create_path(&path, NULL, path_id, target_id, 0);
+ if (status == CAM_REQ_CMP) {
+ periph = cam_periph_find(path, "da");
xpt_free_path(path);
- if (periph != NULL) {
- if (strncmp(periph->periph_name, "da", 2))
- periph = NULL;
- }
- }
+
+ }
return periph;
}
-static __inline void
-FreePrivCommand(IAL_ADAPTER_T *pAdapter, pPrivCommand prvCmd)
-{
- TAILQ_INSERT_TAIL(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry);
-}
+#if (__FreeBSD_version < 500000)
+#define YIELD_THREAD yield(curproc, 0)
+#endif
-static __inline pPrivCommand
-AllocPrivCommand(IAL_ADAPTER_T *pAdapter)
-{
- pPrivCommand prvCmd;
+#ifdef __i386__
+#define BITS_PER_LONG 32
+#define VDEV_TO_ID(pVDev) (DEVICEID)(pVDev)
+#define ID_TO_VDEV(id) (PVDevice)(id)
+#else /*Only support x86_64(AMD64 and EM64T)*/
+#define BITS_PER_LONG 64
+#define VDEV_TO_ID(pVDev) (DEVICEID)(ULONG_PTR)(pVDev)
+#define ID_TO_VDEV(id) (PVDevice)(((ULONG_PTR)gIal_Adapter & 0xffffffff00000000) | (id))
+#endif
- prvCmd = TAILQ_FIRST(&pAdapter->PrivCmdTQH);
- if (prvCmd == NULL)
- return NULL;
+#define INVALID_DEVICEID (-1)
+#define INVALID_STRIPSIZE (-1)
- TAILQ_REMOVE(&pAdapter->PrivCmdTQH, prvCmd, PrivEntry);
- return (prvCmd);
-}
+#define shortswap(w) ((WORD)((w)>>8 | ((w) & 0xFF)<<8))
-static __inline void
-mv_reg_write_byte(MV_BUS_ADDR_T base, MV_U32 offset, MV_U8 val)
-{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = base;
- bus_space_write_1(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val);
-}
+#ifndef MinBlockSizeShift
+#define MinBlockSizeShift 5
+#define MaxBlockSizeShift 12
+#endif
-static __inline void
-mv_reg_write_word(MV_BUS_ADDR_T base, MV_U32 offset, MV_U16 val)
+#pragma pack(1)
+typedef struct _HPT_IOCTL_TRANSFER_PARAM
{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = base;
- bus_space_write_2(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val);
-}
+ ULONG nInBufferSize;
+ ULONG nOutBufferSize;
+ UCHAR buffer[0];
+}HPT_IOCTL_TRANSFER_PARAM, *PHPT_IOCTL_TRANSFER_PARAM;
-static __inline void
-mv_reg_write_dword(MV_BUS_ADDR_T base, MV_U32 offset, MV_U32 val)
+typedef struct _HPT_SET_STATE_PARAM
{
- IAL_ADAPTER_T *pAdapter;
+ DEVICEID idArray;
+ DWORD state;
+} HPT_SET_STATE_PARAM, *PHPT_SET_STATE_PARAM;
- pAdapter = base;
- bus_space_write_4(pAdapter->mem_btag, pAdapter->mem_bsh, offset, val);
-}
-
-static __inline MV_U8
-mv_reg_read_byte(MV_BUS_ADDR_T base, MV_U32 offset)
+typedef struct _HPT_SET_ARRAY_INFO
{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = base;
- return (bus_space_read_1(pAdapter->mem_btag, pAdapter->mem_bsh,
- offset));
-}
+ DEVICEID idArray;
+ ALTERABLE_ARRAY_INFO Info;
+} HPT_SET_ARRAY_INFO, *PHPT_SET_ARRAY_INFO;
-static __inline MV_U16
-mv_reg_read_word(MV_BUS_ADDR_T base, MV_U32 offset)
+typedef struct _HPT_SET_DEVICE_INFO
{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = base;
- return (bus_space_read_2(pAdapter->mem_btag, pAdapter->mem_bsh,
- offset));
-}
+ DEVICEID idDisk;
+ ALTERABLE_DEVICE_INFO Info;
+} HPT_SET_DEVICE_INFO, *PHPT_SET_DEVICE_INFO;
-static __inline MV_U32
-mv_reg_read_dword(MV_BUS_ADDR_T base, MV_U32 offset)
+typedef struct _HPT_ADD_DISK_TO_ARRAY
{
- IAL_ADAPTER_T *pAdapter;
-
- pAdapter = base;
- return (bus_space_read_4(pAdapter->mem_btag, pAdapter->mem_bsh,
- offset));
-}
+ DEVICEID idArray;
+ DEVICEID idDisk;
+} HPT_ADD_DISK_TO_ARRAY, *PHPT_ADD_DISK_TO_ARRAY;
+
+int check_VDevice_valid(PVDevice);
+int hpt_default_ioctl(_VBUS_ARG DWORD, PVOID, DWORD, PVOID, DWORD, PDWORD);
+
+#define HPT_NULL_ID 0
+
+#pragma pack()
#endif
diff --git a/sys/dev/hptmv/raid5n.h b/sys/dev/hptmv/raid5n.h
index 07101c8f2650..135177a9bbbc 100644
--- a/sys/dev/hptmv/raid5n.h
+++ b/sys/dev/hptmv/raid5n.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -110,12 +110,15 @@ struct r5_global_data {
PUCHAR page_base_virt;
PUCHAR page_current;
#endif
- struct free_heap_block *free_heap_slots[8];
+ struct free_heap_block *free_heap_slots[10];
struct free_page *free_pages;
UINT num_free_pages;
UINT active_stripes;
UINT num_flushing;
PCommand cache_wait_list;
+
+ LBA_T __start[MAX_MEMBERS];
+ USHORT __sectors[MAX_MEMBERS];
};
diff --git a/sys/dev/hptmv/readme.txt b/sys/dev/hptmv/readme.txt
index df03e97efe81..6d21e98c98b8 100644
--- a/sys/dev/hptmv/readme.txt
+++ b/sys/dev/hptmv/readme.txt
@@ -1,10 +1,14 @@
RocketRAID 182x Driver for FreeBSD
-Copyright (C) 2003-2004 HighPoint Technologies, Inc. All rights reserved.
+Copyright (C) 2004-2005 HighPoint Technologies, Inc. All rights reserved.
$FreeBSD$
#############################################################################
Revision History:
+ v1.12 2005-6-10
+ Fix over 4G memory support on amd64.
+ Fix disk flush problem.
+
v1.1 2004-9-23
Fix activity LED problem.
Cleanup diagnostic code.
@@ -36,22 +40,124 @@ Revision History:
PRODUCT, INCLUDING THE COSTS OF REPAIRING, REPLACING, OR RECOVERING
SUCH HARDWARE, OR DATA.
-2. Build the driver
----------------------
+
+2. Rebuild the kernel with RR182x support
+--------------------------------------------
+
1) Install kernel source package and building tools.
- 2) Extract the driver files to somewhere.
+ 2) Extract the driver files under the kernel source tree:
+
+ # cd /usr/src/sys/
+ # tar xvzf /your/path/to/rr182x-opensource-v1.12-bsd.tgz
+
+ 3) Update the kernel configuration file to include the HighPoint source.
+ Assume the configure file is GENERIC, and new kernel configure file is
+ MYKERNEL:
+
+ # cd i386/conf (or amd64/conf for AMD64)
+ # cp GENERIC MYKERNEL
+
+ 4) Edit MYKERNEL, and add the following line under "RAID controllers
+ interfaced to the SCSI subsystem":
+
+ device hptmv #HighPoint RocketRAID 182x
+
+ 5) For i386 system, edit /usr/src/sys/conf/files.i386 and append the lines
+ shown below:
- 3) Run "make" to build the driver.
+ hptmvraid.o optional hptmv \
+ dependency "$S/dev/hptmv/i386-elf.raid.o.uu" \
+ compile-with "uudecode < $S/dev/hptmv/i386-elf.raid.o.uu" \
+ no-implicit-rule
+ dev/hptmv/gui_lib.c optional hptmv
+ dev/hptmv/hptproc.c optional hptmv
+ dev/hptmv/ioctl.c optional hptmv
+ dev/hptmv/entry.c optional hptmv
+ dev/hptmv/mv.c optional hptmv
+
+ For amd64 system, edit /usr/src/sys/conf/files.amd64 and append the lines
+ shown below:
+
+ hptmvraid.o optional hptmv \
+ dependency "$S/dev/hptmv/amd64-elf.raid.o.uu" \
+ compile-with "uudecode < $S/dev/hptmv/amd64-elf.raid.o.uu" \
+ no-implicit-rule
+
+ dev/hptmv/gui_lib.c optional hptmv
+ dev/hptmv/hptproc.c optional hptmv
+ dev/hptmv/ioctl.c optional hptmv
+ dev/hptmv/entry.c optional hptmv
+ dev/hptmv/mv.c optional hptmv
+
+ Note FreeBSD 5.3/5.4 i386 already have a built-in RR182x driver, you should
+ replace the old configuration lines with the lines listed above.
+
+
+ 6) Rebuild and install the kernel:
+
+ a) for FreeBSD 5.x-i386:
-3. Using the driver
----------------------
- 1) Copy the driver module to /modules/ (FreeBSD 4.x) or /boot/kernel/
- (FreeBSD 5.x).
-
- 2) The driver can't be loaded by kldload command on a running system.
- Please load the driver during system booting stage. e.g:
+ # cd /usr/src/sys/i386/conf/
+ # /usr/sbin/config MYKERNEL
+ # cd ../compile/MYKERNEL/
+ # make depend
+ # make
+ # make install
+
+ b) for FreeBSD 5.x-amd64:
+
+ # cd /usr/src/sys/amd64/conf/
+ # /usr/sbin/config MYKERNEL
+ # cd ../compile/MYKERNEL/
+ # make depend
+ # make
+ # make install
+
+ c) for FreeBSD 4.x:
+
+ # cd /usr/src/sys/i386/conf/
+ # /usr/sbin/config MYKERNEL
+ # cd ../../compile/MYKERNEL/
+ # make depend
+ # make
+ # make install
+
+ If the driver was previously configured as an auto-loaded module by
+ /boot/defaults/loader.conf, please remove the entry hptmv_load="YES"
+ from loader.conf to prevent the driver from being loaded twice.
+
+ 7) Reboot from the new kernel.
+
+
+3. Build/Load the driver as a kernel module
+------------------------------------------------
+
+ 1) Install kernel source package and building tools.
+
+ 2) Extract the driver files under the kernel source tree:
+
+ # cd /usr/src/sys/
+ # tar xvzf /your/path/to/rr182x-opensource-v1.12-bsd.tgz
+
+
+ 4) Build the driver module:
+
+ # cd modules/hptmv
+ # make
+
+ 5) Copy the driver module to the kernel module directory
+
+ For FreeBSD 4.x:
+
+ # cp hptmv.ko /modules/
+
+ For FreeBSD 5.x:
+
+ # cp hptmv.ko /boot/kernel/
+
+ 6) Reboot and load the driver under loader prompt. e.g:
BTX loader 1.00 BTX version is 1.01
Console: internal video/keyboard
@@ -71,11 +177,18 @@ Revision History:
Type '?' for a list of commands, 'help' for more detailed help.
ok load hptmv
/modules/hptmv.ko text=0xf571 data=0x2c8+0x254
- ok autoboot
+ ok boot
+
+ For FreeBSD 5.x, you can select 6 on the boot menu to get a loader prompt.
- Please refer to the installation guide in HighPoint FreeBSD driver release
- package for more information.
-
+ 7) You can add a below line into /boot/defaults/loader.conf to load the
+ driver automatically:
+
+ hptmv_load="YES"
+
+ Please refer to the installation guide in HighPoint FreeBSD driver release
+ package for more information.
+
#############################################################################
Technical support and service
diff --git a/sys/dev/hptmv/vdevice.h b/sys/dev/hptmv/vdevice.h
index c9a613618548..8d06f1032109 100644
--- a/sys/dev/hptmv/vdevice.h
+++ b/sys/dev/hptmv/vdevice.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2004 HighPoint Technologies, Inc.
+ * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -250,8 +250,8 @@ struct fdisk_partition_table
UCHAR endhead; /* ending head number */
UCHAR endsect; /* ending sector number */
UCHAR endcyl; /* also a 10 bit nmbr, with same high 2 bit trick */
- UINT relsect; /* first sector relative to start of disk */
- UINT numsect; /* number of sectors in partition */
+ ULONG relsect; /* first sector relative to start of disk */
+ ULONG numsect; /* number of sectors in partition */
};
typedef struct _Master_Boot_Record