The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/hptmv/entry.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2004-2005 HighPoint Technologies, Inc.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29  
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/kernel.h>
   33 #include <sys/bus.h>
   34 #include <sys/malloc.h>
   35 #include <sys/resource.h>
   36 #include <sys/time.h>
   37 #include <sys/callout.h>
   38 #include <sys/signalvar.h>
   39 #include <sys/eventhandler.h>
   40 #include <sys/proc.h>
   41 #include <sys/kthread.h>
   42 
   43 #if (__FreeBSD_version >= 500000)
   44 #include <sys/mutex.h>
   45 #include <sys/module.h>
   46 #endif
   47 
   48 #if (__FreeBSD_version >= 500000)
   49 #include <dev/pci/pcireg.h>
   50 #include <dev/pci/pcivar.h>
   51 #else 
   52 #include <pci/pcireg.h>
   53 #include <pci/pcivar.h>
   54 #include <sys/wait.h>
   55 #include <sys/sysproto.h>
   56 #endif
   57 
   58 #ifndef __KERNEL__
   59 #define __KERNEL__
   60 #endif
   61 
   62 #include <dev/hptmv/global.h>
   63 #include <dev/hptmv/hptintf.h>
   64 #include <dev/hptmv/osbsd.h>
   65 #include <dev/hptmv/access601.h>
   66 
   67 
   68 #ifdef DEBUG
   69 #ifdef DEBUG_LEVEL
   70 int hpt_dbg_level = DEBUG_LEVEL;
   71 #else 
   72 int hpt_dbg_level = 0;
   73 #endif
   74 #endif
   75 
   76 #define MV_ERROR printf
   77 
   78 /*
   79  * CAM SIM entry points
   80  */
   81 static int      hpt_probe (device_t dev);
   82 static void launch_worker_thread(void);
   83 static int      hpt_attach(device_t dev);
   84 static int      hpt_detach(device_t dev);
   85 static int      hpt_shutdown(device_t dev);
   86 static void hpt_poll(struct cam_sim *sim);
   87 static void hpt_intr(void *arg);
   88 static void hpt_async(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg);
   89 static void hpt_action(struct cam_sim *sim, union ccb *ccb);
   90 
   91 static device_method_t driver_methods[] = {
   92         /* Device interface */
   93         DEVMETHOD(device_probe,         hpt_probe),
   94         DEVMETHOD(device_attach,        hpt_attach),
   95         DEVMETHOD(device_detach,        hpt_detach),
   96 
   97         DEVMETHOD(device_shutdown,      hpt_shutdown),
   98         DEVMETHOD_END
   99 };
  100 
  101 static driver_t hpt_pci_driver = {
  102         __str(PROC_DIR_NAME),
  103         driver_methods,
  104         sizeof(IAL_ADAPTER_T)
  105 };
  106 
  107 static devclass_t       hpt_devclass;
  108 
  109 #define __DRIVER_MODULE(p1, p2, p3, p4, p5, p6) DRIVER_MODULE(p1, p2, p3, p4, p5, p6)
  110 __DRIVER_MODULE(PROC_DIR_NAME, pci, hpt_pci_driver, hpt_devclass, 0, 0);
  111 MODULE_DEPEND(PROC_DIR_NAME, cam, 1, 1, 1);
  112 
  113 #define ccb_ccb_ptr spriv_ptr0
  114 #define ccb_adapter ccb_h.spriv_ptr1
  115 
  116 static void SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev);
  117 static void HPTLIBAPI OsSendCommand (_VBUS_ARG union ccb * ccb);
  118 static void HPTLIBAPI fOsCommandDone(_VBUS_ARG PCommand pCmd);
  119 static void ccb_done(union ccb *ccb);
  120 static void hpt_queue_ccb(union ccb **ccb_Q, union ccb *ccb);
  121 static void hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb);
  122 static void     hptmv_free_edma_queues(IAL_ADAPTER_T *pAdapter);
  123 static void     hptmv_free_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
  124 static void     handleEdmaError(_VBUS_ARG PCommand pCmd);
  125 static int      hptmv_init_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
  126 static int      fResetActiveCommands(PVBus _vbus_p);
  127 static void     fRegisterVdevice(IAL_ADAPTER_T *pAdapter);
  128 static int      hptmv_allocate_edma_queues(IAL_ADAPTER_T *pAdapter);
  129 static void     hptmv_handle_event_disconnect(void *data);
  130 static void     hptmv_handle_event_connect(void *data);
  131 static int      start_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum);
  132 static void     init_vdev_params(IAL_ADAPTER_T *pAdapter, MV_U8 channel);
  133 static int      hptmv_parse_identify_results(MV_SATA_CHANNEL *pMvSataChannel);
  134 static int HPTLIBAPI fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg,
  135     int logical);
  136 static MV_BOOLEAN CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter,
  137     MV_U8 channelNum, MV_COMPLETION_TYPE comp_type, MV_VOID_PTR commandId,
  138     MV_U16 responseFlags, MV_U32 timeStamp,
  139     MV_STORAGE_DEVICE_REGISTERS *registerStruct);
  140 static MV_BOOLEAN hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter,
  141     MV_EVENT_TYPE eventType, MV_U32 param1, MV_U32 param2);
  142 
  143 #define ccb_ccb_ptr spriv_ptr0
  144 #define ccb_adapter ccb_h.spriv_ptr1
  145 
  146 IAL_ADAPTER_T *gIal_Adapter = 0;
  147 IAL_ADAPTER_T *pCurAdapter = 0;
  148 static MV_SATA_CHANNEL gMvSataChannels[MAX_VBUS][MV_SATA_CHANNELS_NUM];
  149 
  150 typedef struct st_HPT_DPC {
  151         IAL_ADAPTER_T *pAdapter;
  152         void (*dpc)(IAL_ADAPTER_T *, void *, UCHAR);
  153         void *arg;
  154         UCHAR flags;
  155 } ST_HPT_DPC;
  156 
  157 #define MAX_DPC 16
  158 UCHAR DPC_Request_Nums = 0; 
  159 static ST_HPT_DPC DpcQueue[MAX_DPC];
  160 static int DpcQueue_First=0;
  161 static int DpcQueue_Last = 0;
  162 
  163 char DRIVER_VERSION[] = "v1.16";
  164 
  165 #if (__FreeBSD_version >= 500000)
  166 static struct mtx driver_lock;
  167 intrmask_t lock_driver()
  168 {
  169 
  170         intrmask_t spl = 0;
  171         mtx_lock(&driver_lock);
  172         return spl;
  173 }
  174 void unlock_driver(intrmask_t spl)
  175 {
  176         mtx_unlock(&driver_lock);
  177 }
  178 #else 
  179 static int driver_locked = 0;
  180 intrmask_t lock_driver()
  181 {
  182         intrmask_t spl = splcam();
  183 loop:
  184         while (driver_locked)
  185                 tsleep(&driver_locked, PRIBIO, "hptlck", hz);
  186         atomic_add_int(&driver_locked, 1);
  187         if (driver_locked>1) {
  188                 atomic_subtract_int(&driver_locked, 1);
  189                 goto loop;
  190         }
  191         return spl;
  192 }
  193 
  194 void unlock_driver(intrmask_t spl)
  195 {
  196         atomic_subtract_int(&driver_locked, 1);
  197         if (driver_locked==0) {
  198                 wakeup(&driver_locked);
  199         }
  200         splx(spl);
  201 }
  202 #endif
  203 
  204 /*******************************************************************************
  205  *      Name:   hptmv_free_channel
  206  *
  207  *      Description:    free allocated queues for the given channel
  208  *
  209  *      Parameters:     pMvSataAdapter - pointer to the RR18xx controler this 
  210  *                                      channel connected to. 
  211  *                      channelNum - channel number. 
  212  *     
  213  ******************************************************************************/
  214 static void
  215 hptmv_free_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
  216 {
  217         HPT_ASSERT(channelNum < MV_SATA_CHANNELS_NUM);
  218         pAdapter->mvSataAdapter.sataChannel[channelNum] = NULL;
  219 }
  220 
  221 static void failDevice(PVDevice pVDev)
  222 {
  223         PVBus _vbus_p = pVDev->pVBus;
  224         IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)_vbus_p->OsExt;
  225         
  226         pVDev->u.disk.df_on_line = 0;
  227         pVDev->vf_online = 0;
  228         if (pVDev->pfnDeviceFailed) 
  229                 CallWhenIdle(_VBUS_P (DPC_PROC)pVDev->pfnDeviceFailed, pVDev);
  230 
  231         fNotifyGUI(ET_DEVICE_REMOVED, pVDev);
  232 
  233 #ifndef FOR_DEMO
  234         if (pAdapter->ver_601==2 && !pAdapter->beeping) {
  235                 pAdapter->beeping = 1;
  236                 BeepOn(pAdapter->mvSataAdapter.adapterIoBaseAddress);
  237                 set_fail_led(&pAdapter->mvSataAdapter, pVDev->u.disk.mv->channelNumber, 1);
  238         }
  239 #endif
  240 }
  241 
  242 int MvSataResetChannel(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channel);
  243 
  244 static void
  245 handleEdmaError(_VBUS_ARG PCommand pCmd)
  246 {
  247         PDevice pDevice = &pCmd->pVDevice->u.disk;
  248         MV_SATA_ADAPTER * pSataAdapter = pDevice->mv->mvSataAdapter;
  249 
  250         if (!pDevice->df_on_line) {
  251                 KdPrint(("Device is offline"));
  252                 pCmd->Result = RETURN_BAD_DEVICE;
  253                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);   
  254                 return;
  255         }
  256 
  257         if (pCmd->RetryCount++>5) {
  258                 hpt_printk(("too many retries on channel(%d)\n", pDevice->mv->channelNumber));
  259 failed:
  260                 failDevice(pCmd->pVDevice);
  261                 pCmd->Result = RETURN_IDE_ERROR;
  262                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);   
  263                 return;
  264         }
  265 
  266         /* reset the channel and retry the command */
  267         if (MvSataResetChannel(pSataAdapter, pDevice->mv->channelNumber))
  268                 goto failed;
  269 
  270         fNotifyGUI(ET_DEVICE_ERROR, Map2pVDevice(pDevice));
  271 
  272         hpt_printk(("Retry on channel(%d)\n", pDevice->mv->channelNumber));
  273         fDeviceSendCommand(_VBUS_P pCmd);
  274 }
  275 
  276 /****************************************************************
  277  *      Name:   hptmv_init_channel
  278  *
  279  *      Description:    allocate request and response queues for the EDMA of the 
  280  *                                      given channel and sets other fields.
  281  *
  282  *      Parameters:     
  283  *              pAdapter - pointer to the emulated adapter data structure
  284  *              channelNum - channel number. 
  285  *      Return: 0 on success, otherwise on failure
  286  ****************************************************************/
  287 static int
  288 hptmv_init_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
  289 {
  290         MV_SATA_CHANNEL *pMvSataChannel;
  291         dma_addr_t    req_dma_addr;
  292         dma_addr_t    rsp_dma_addr;
  293 
  294         if (channelNum >= MV_SATA_CHANNELS_NUM)
  295         {
  296                 MV_ERROR("RR18xx[%d]: Bad channelNum=%d",
  297                                  pAdapter->mvSataAdapter.adapterId, channelNum);
  298                 return -1;
  299         }
  300 
  301         pMvSataChannel = &gMvSataChannels[pAdapter->mvSataAdapter.adapterId][channelNum];
  302         pAdapter->mvSataAdapter.sataChannel[channelNum] = pMvSataChannel;
  303         pMvSataChannel->channelNumber = channelNum;
  304         pMvSataChannel->lba48Address = MV_FALSE;
  305         pMvSataChannel->maxReadTransfer = MV_FALSE;
  306 
  307         pMvSataChannel->requestQueue = (struct mvDmaRequestQueueEntry *)
  308                                                                    (pAdapter->requestsArrayBaseAlignedAddr + (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE));
  309         req_dma_addr = pAdapter->requestsArrayBaseDmaAlignedAddr + (channelNum * MV_EDMA_REQUEST_QUEUE_SIZE);
  310 
  311 
  312         KdPrint(("requestQueue addr is 0x%llX", (HPT_U64)(ULONG_PTR)req_dma_addr));
  313 
  314         /* check the 1K alignment of the request queue*/
  315         if (req_dma_addr & 0x3ff)
  316         {
  317                 MV_ERROR("RR18xx[%d]: request queue allocated isn't 1 K aligned,"
  318                                  " dma_addr=%llx channel=%d\n", pAdapter->mvSataAdapter.adapterId,
  319                                  (HPT_U64)(ULONG_PTR)req_dma_addr, channelNum);
  320                 return -1;
  321         }
  322         pMvSataChannel->requestQueuePciLowAddress = req_dma_addr;
  323         pMvSataChannel->requestQueuePciHiAddress = 0;
  324         KdPrint(("RR18xx[%d,%d]: request queue allocated: 0x%p",
  325                           pAdapter->mvSataAdapter.adapterId, channelNum,
  326                           pMvSataChannel->requestQueue));
  327         pMvSataChannel->responseQueue = (struct mvDmaResponseQueueEntry *)
  328                                                                         (pAdapter->responsesArrayBaseAlignedAddr + (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE));
  329         rsp_dma_addr = pAdapter->responsesArrayBaseDmaAlignedAddr + (channelNum * MV_EDMA_RESPONSE_QUEUE_SIZE);
  330 
  331         /* check the 256 alignment of the response queue*/
  332         if (rsp_dma_addr & 0xff)
  333         {
  334                 MV_ERROR("RR18xx[%d,%d]: response queue allocated isn't 256 byte "
  335                                  "aligned, dma_addr=%llx\n",
  336                                  pAdapter->mvSataAdapter.adapterId, channelNum, (HPT_U64)(ULONG_PTR)rsp_dma_addr);
  337                 return -1;
  338         }
  339         pMvSataChannel->responseQueuePciLowAddress = rsp_dma_addr;
  340         pMvSataChannel->responseQueuePciHiAddress = 0;
  341         KdPrint(("RR18xx[%d,%d]: response queue allocated: 0x%p",
  342                           pAdapter->mvSataAdapter.adapterId, channelNum,
  343                           pMvSataChannel->responseQueue));
  344 
  345         pAdapter->mvChannel[channelNum].online = MV_TRUE;
  346         return 0;
  347 }
  348 
  349 /******************************************************************************
  350  *      Name: hptmv_parse_identify_results
  351  *
  352  *      Description:    this functions parses the identify command results, checks
  353  *                                      that the connected deives can be accesed by RR18xx EDMA,
  354  *                                      and updates the channel stucture accordingly.
  355  *
  356  *      Parameters:     pMvSataChannel, pointer to the channel data structure.
  357  *
  358  *      Returns:        =0 ->success, < 0 ->failure.
  359  *
  360  ******************************************************************************/
  361 static int
  362 hptmv_parse_identify_results(MV_SATA_CHANNEL *pMvSataChannel)
  363 {
  364         MV_U16  *iden = pMvSataChannel->identifyDevice;
  365 
  366         /*LBA addressing*/
  367         if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x200))
  368         {
  369                 KdPrint(("IAL Error in IDENTIFY info: LBA not supported\n"));
  370                 return -1;
  371         }
  372         else
  373         {
  374                 KdPrint(("%25s - %s\n", "Capabilities", "LBA supported"));
  375         }
  376         /*DMA support*/
  377         if (! (iden[IDEN_CAPACITY_1_OFFSET] & 0x100))
  378         {
  379                 KdPrint(("IAL Error in IDENTIFY info: DMA not supported\n"));
  380                 return -1;
  381         }
  382         else
  383         {
  384                 KdPrint(("%25s - %s\n", "Capabilities", "DMA supported"));
  385         }
  386         /* PIO */
  387         if ((iden[IDEN_VALID] & 2) == 0)
  388         {
  389                 KdPrint(("IAL Error in IDENTIFY info: not able to find PIO mode\n"));
  390                 return -1;
  391         }
  392         KdPrint(("%25s - 0x%02x\n", "PIO modes supported",
  393                           iden[IDEN_PIO_MODE_SPPORTED] & 0xff));
  394 
  395         /*UDMA*/
  396         if ((iden[IDEN_VALID] & 4) == 0)
  397         {
  398                 KdPrint(("IAL Error in IDENTIFY info: not able to find UDMA mode\n"));
  399                 return -1;
  400         }
  401 
  402         /* 48 bit address */
  403         if ((iden[IDEN_SUPPORTED_COMMANDS2] & 0x400))
  404         {
  405                 KdPrint(("%25s - %s\n", "LBA48 addressing", "supported"));
  406                 pMvSataChannel->lba48Address = MV_TRUE;
  407         }
  408         else
  409         {
  410                 KdPrint(("%25s - %s\n", "LBA48 addressing", "Not supported"));
  411                 pMvSataChannel->lba48Address = MV_FALSE;
  412         }
  413         return 0;
  414 }
  415 
  416 static void
  417 init_vdev_params(IAL_ADAPTER_T *pAdapter, MV_U8 channel)
  418 {
  419         PVDevice pVDev = &pAdapter->VDevices[channel];
  420         MV_SATA_CHANNEL *pMvSataChannel = pAdapter->mvSataAdapter.sataChannel[channel];
  421         MV_U16_PTR IdentifyData = pMvSataChannel->identifyDevice;
  422 
  423         pMvSataChannel->outstandingCommands = 0;
  424 
  425         pVDev->u.disk.mv         = pMvSataChannel;
  426         pVDev->u.disk.df_on_line = 1;
  427         pVDev->u.disk.pVBus      = &pAdapter->VBus;
  428         pVDev->pVBus             = &pAdapter->VBus;
  429 
  430 #ifdef SUPPORT_48BIT_LBA
  431         if (pMvSataChannel->lba48Address == MV_TRUE)
  432                 pVDev->u.disk.dDeRealCapacity = ((IdentifyData[101]<<16) | IdentifyData[100]) - 1;
  433         else
  434 #endif
  435         if(IdentifyData[53] & 1) {
  436         pVDev->u.disk.dDeRealCapacity = 
  437           (((IdentifyData[58]<<16 | IdentifyData[57]) < (IdentifyData[61]<<16 | IdentifyData[60])) ? 
  438                   (IdentifyData[61]<<16 | IdentifyData[60]) :
  439                                 (IdentifyData[58]<<16 | IdentifyData[57])) - 1;
  440         } else
  441                 pVDev->u.disk.dDeRealCapacity = 
  442                                  (IdentifyData[61]<<16 | IdentifyData[60]) - 1;
  443 
  444         pVDev->u.disk.bDeUsable_Mode = pVDev->u.disk.bDeModeSetting = 
  445                 pAdapter->mvChannel[channel].maxPioModeSupported - MV_ATA_TRANSFER_PIO_0;
  446 
  447         if (pAdapter->mvChannel[channel].maxUltraDmaModeSupported!=0xFF) {
  448                 pVDev->u.disk.bDeUsable_Mode = pVDev->u.disk.bDeModeSetting = 
  449                         pAdapter->mvChannel[channel].maxUltraDmaModeSupported - MV_ATA_TRANSFER_UDMA_0 + 8;
  450         }
  451 }
  452 
  453 static void device_change(IAL_ADAPTER_T *pAdapter , MV_U8 channelIndex, int plugged)
  454 {
  455         PVDevice pVDev;
  456         MV_SATA_ADAPTER  *pMvSataAdapter = &pAdapter->mvSataAdapter;
  457         MV_SATA_CHANNEL  *pMvSataChannel = pMvSataAdapter->sataChannel[channelIndex];
  458         
  459         if (!pMvSataChannel) return;
  460 
  461         if (plugged)
  462         {
  463                 pVDev = &(pAdapter->VDevices[channelIndex]);
  464                 init_vdev_params(pAdapter, channelIndex);
  465 
  466                 pVDev->VDeviceType = pVDev->u.disk.df_atapi? VD_ATAPI : 
  467                         pVDev->u.disk.df_removable_drive? VD_REMOVABLE : VD_SINGLE_DISK;
  468 
  469                 pVDev->VDeviceCapacity = pVDev->u.disk.dDeRealCapacity-SAVE_FOR_RAID_INFO;
  470                 pVDev->pfnSendCommand = pfnSendCommand[pVDev->VDeviceType];
  471                 pVDev->pfnDeviceFailed = pfnDeviceFailed[pVDev->VDeviceType];
  472                 pVDev->vf_online = 1;
  473 
  474 #ifdef SUPPORT_ARRAY
  475                 if(pVDev->pParent) 
  476                 {
  477                         int iMember;
  478                         for(iMember = 0; iMember <      pVDev->pParent->u.array.bArnMember; iMember++)
  479                                 if((PVDevice)pVDev->pParent->u.array.pMember[iMember] == pVDev)
  480                                         pVDev->pParent->u.array.pMember[iMember] = NULL;
  481                         pVDev->pParent = NULL;
  482                 }
  483 #endif
  484                 fNotifyGUI(ET_DEVICE_PLUGGED,pVDev);
  485                 fCheckBootable(pVDev);
  486                 RegisterVDevice(pVDev);
  487 
  488 #ifndef FOR_DEMO
  489                 if (pAdapter->beeping) {
  490                         pAdapter->beeping = 0;
  491                         BeepOff(pAdapter->mvSataAdapter.adapterIoBaseAddress);
  492                 }
  493 #endif
  494 
  495         }
  496         else
  497         {
  498                 pVDev  = &(pAdapter->VDevices[channelIndex]);
  499                 failDevice(pVDev);
  500         }
  501 }
  502 
  503 static int
  504 start_channel(IAL_ADAPTER_T *pAdapter, MV_U8 channelNum)
  505 {
  506         MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
  507         MV_SATA_CHANNEL *pMvSataChannel = pMvSataAdapter->sataChannel[channelNum];
  508         MV_CHANNEL              *pChannelInfo = &(pAdapter->mvChannel[channelNum]);
  509         MV_U32          udmaMode,pioMode;
  510 
  511         KdPrint(("RR18xx [%d]: start channel (%d)", pMvSataAdapter->adapterId, 
  512                          channelNum));
  513 
  514 
  515         /* Software reset channel */
  516         if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
  517         {
  518                 MV_ERROR("RR18xx [%d,%d]: failed to perform Software reset\n",
  519                                  pMvSataAdapter->adapterId, channelNum);
  520                 return -1;
  521         }
  522 
  523         /* Hardware reset channel */
  524         if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
  525         {
  526                 /* If failed, try again - this is when trying to hardreset a channel */
  527                 /* when drive is just spinning up */
  528                 StallExec(5000000); /* wait 5 sec before trying again */
  529                 if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
  530                 {
  531                         MV_ERROR("RR18xx [%d,%d]: failed to perform Hard reset\n",
  532                                          pMvSataAdapter->adapterId, channelNum);
  533                         return -1;
  534                 }
  535         }
  536 
  537         /* identify device*/
  538         if (mvStorageDevATAIdentifyDevice(pMvSataAdapter, channelNum) == MV_FALSE)
  539         {
  540                 MV_ERROR("RR18xx [%d,%d]: failed to perform ATA Identify command\n"
  541                                  , pMvSataAdapter->adapterId, channelNum);
  542                 return -1;
  543         }
  544         if (hptmv_parse_identify_results(pMvSataChannel))
  545         {
  546                 MV_ERROR("RR18xx [%d,%d]: Error in parsing ATA Identify message\n"
  547                                  , pMvSataAdapter->adapterId, channelNum);
  548                 return -1;
  549         }
  550 
  551         /* mvStorageDevATASetFeatures */
  552         /* Disable 8 bit PIO in case CFA enabled */
  553         if (pMvSataChannel->identifyDevice[86] & 4)
  554         {
  555                 KdPrint(("RR18xx [%d]: Disable 8 bit PIO (CFA enabled) \n",
  556                                   pMvSataAdapter->adapterId));
  557                 if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  558                                                                            MV_ATA_SET_FEATURES_DISABLE_8_BIT_PIO, 0,
  559                                                                            0, 0, 0) == MV_FALSE)
  560                 {
  561                         MV_ERROR("RR18xx [%d]: channel %d: mvStorageDevATASetFeatures"
  562                                          " failed\n", pMvSataAdapter->adapterId, channelNum); 
  563                         return -1;
  564                 }
  565         }
  566         /* Write cache */
  567 #ifdef ENABLE_WRITE_CACHE
  568         if (pMvSataChannel->identifyDevice[82] & 0x20)
  569         {
  570                 if (!(pMvSataChannel->identifyDevice[85] & 0x20)) /* if not enabled by default */
  571                 {
  572                         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  573                                                                                    MV_ATA_SET_FEATURES_ENABLE_WCACHE, 0,
  574                                                                                    0, 0, 0) == MV_FALSE)
  575                         {
  576                                 MV_ERROR("RR18xx [%d]: channel %d: mvStorageDevATASetFeatures failed\n",
  577                                                  pMvSataAdapter->adapterId, channelNum); 
  578                                 return -1;
  579                         }
  580                 }
  581                 KdPrint(("RR18xx [%d]: channel %d, write cache enabled\n",
  582                                   pMvSataAdapter->adapterId, channelNum));
  583         }
  584         else
  585         {
  586                 KdPrint(("RR18xx [%d]: channel %d, write cache not supported\n",
  587                                   pMvSataAdapter->adapterId, channelNum));
  588         }
  589 #else /* disable write cache */
  590         {
  591                 if (pMvSataChannel->identifyDevice[85] & 0x20)
  592                 {
  593                         KdPrint(("RR18xx [%d]: channel =%d, disable write cache\n",
  594                                           pMvSataAdapter->adapterId, channelNum));
  595                         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  596                                                                                    MV_ATA_SET_FEATURES_DISABLE_WCACHE, 0,
  597                                                                                    0, 0, 0) == MV_FALSE)
  598                         {
  599                                 MV_ERROR("RR18xx [%d]: channel %d: mvStorageDevATASetFeatures failed\n",
  600                                                  pMvSataAdapter->adapterId, channelNum); 
  601                                 return -1;
  602                         }
  603                 }
  604                 KdPrint(("RR18xx [%d]: channel=%d, write cache disabled\n",
  605                                   pMvSataAdapter->adapterId, channelNum));
  606         }
  607 #endif
  608 
  609         /* Set transfer mode */
  610         KdPrint(("RR18xx [%d] Set transfer mode XFER_PIO_SLOW\n",
  611                           pMvSataAdapter->adapterId));
  612         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  613                                                                    MV_ATA_SET_FEATURES_TRANSFER,
  614                                                                    MV_ATA_TRANSFER_PIO_SLOW, 0, 0, 0) == 
  615                 MV_FALSE)
  616         {
  617                 MV_ERROR("RR18xx [%d] channel %d: Set Features failed\n",
  618                                  pMvSataAdapter->adapterId, channelNum); 
  619                 return -1;
  620         }
  621 
  622         if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 1)
  623         {
  624                 pioMode = MV_ATA_TRANSFER_PIO_4;
  625         }
  626         else if (pMvSataChannel->identifyDevice[IDEN_PIO_MODE_SPPORTED] & 2)
  627         {
  628                 pioMode = MV_ATA_TRANSFER_PIO_3;
  629         }
  630         else
  631         {
  632                 MV_ERROR("IAL Error in IDENTIFY info: PIO modes 3 and 4 not supported\n");
  633                 pioMode = MV_ATA_TRANSFER_PIO_SLOW;
  634         }
  635 
  636         KdPrint(("RR18xx [%d] Set transfer mode XFER_PIO_4\n",
  637                           pMvSataAdapter->adapterId));
  638         pAdapter->mvChannel[channelNum].maxPioModeSupported = pioMode;
  639         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  640                                                                    MV_ATA_SET_FEATURES_TRANSFER,
  641                                                                    pioMode, 0, 0, 0) == MV_FALSE)
  642         {
  643                 MV_ERROR("RR18xx [%d] channel %d: Set Features failed\n",
  644                                  pMvSataAdapter->adapterId, channelNum); 
  645                 return -1;
  646         }
  647 
  648         udmaMode = MV_ATA_TRANSFER_UDMA_0;
  649         if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x40)
  650         {
  651                 udmaMode =  MV_ATA_TRANSFER_UDMA_6;
  652         }
  653         else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x20)
  654         {
  655                 udmaMode =  MV_ATA_TRANSFER_UDMA_5;
  656         }
  657         else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 0x10)
  658         {
  659                 udmaMode =  MV_ATA_TRANSFER_UDMA_4;
  660         }
  661         else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 8)
  662         {
  663                 udmaMode =  MV_ATA_TRANSFER_UDMA_3;
  664         }
  665         else if (pMvSataChannel->identifyDevice[IDEN_UDMA_MODE] & 4)
  666         {
  667                 udmaMode =  MV_ATA_TRANSFER_UDMA_2;
  668         }
  669 
  670         KdPrint(("RR18xx [%d] Set transfer mode XFER_UDMA_%d\n",
  671                           pMvSataAdapter->adapterId, udmaMode & 0xf));
  672         pChannelInfo->maxUltraDmaModeSupported = udmaMode;
  673 
  674         /*if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  675                                                                    MV_ATA_SET_FEATURES_TRANSFER, udmaMode,
  676                                                                    0, 0, 0) == MV_FALSE)
  677         {
  678                 MV_ERROR("RR18xx [%d] channel %d: Set Features failed\n",
  679                                  pMvSataAdapter->adapterId, channelNum); 
  680                 return -1;
  681         }*/
  682         if (pChannelInfo->maxUltraDmaModeSupported == 0xFF) 
  683                 return TRUE;
  684         else 
  685                 do
  686                 {
  687                         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  688                                                                    MV_ATA_SET_FEATURES_TRANSFER, 
  689                                                                    pChannelInfo->maxUltraDmaModeSupported,
  690                                                                    0, 0, 0) == MV_FALSE)
  691                         {
  692                                 if (pChannelInfo->maxUltraDmaModeSupported > MV_ATA_TRANSFER_UDMA_0)
  693                                 {
  694                                         if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
  695                                         {
  696                                                 MV_REG_WRITE_BYTE(pMvSataAdapter->adapterIoBaseAddress,
  697                                                                                   pMvSataChannel->eDmaRegsOffset +
  698                                                                                   0x11c, /* command reg */
  699                                                                                   MV_ATA_COMMAND_IDLE_IMMEDIATE); 
  700                                                 mvMicroSecondsDelay(10000);
  701                                                 mvSataChannelHardReset(pMvSataAdapter, channelNum);
  702                                                 if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channelNum) == MV_FALSE)
  703                                                         return FALSE;
  704                                         }
  705                                         if (mvSataChannelHardReset(pMvSataAdapter, channelNum) == MV_FALSE)
  706                                                 return FALSE;
  707                                         pChannelInfo->maxUltraDmaModeSupported--;
  708                                         continue;
  709                                 }
  710                                 else   return FALSE;
  711                         }
  712                         break;
  713                 }while (1);
  714 
  715         /* Read look ahead */
  716 #ifdef ENABLE_READ_AHEAD
  717         if (pMvSataChannel->identifyDevice[82] & 0x40)
  718         {
  719                 if (!(pMvSataChannel->identifyDevice[85] & 0x40)) /* if not enabled by default */
  720                 {
  721                         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  722                                                                                    MV_ATA_SET_FEATURES_ENABLE_RLA, 0, 0,
  723                                                                                    0, 0) == MV_FALSE)
  724                         {
  725                                 MV_ERROR("RR18xx [%d] channel %d: Set Features failed\n",
  726                                                  pMvSataAdapter->adapterId, channelNum); 
  727                                 return -1;
  728                         }
  729                 }
  730                 KdPrint(("RR18xx [%d]: channel=%d, read look ahead enabled\n", 
  731                                   pMvSataAdapter->adapterId, channelNum));
  732         }
  733         else
  734         {
  735                 KdPrint(("RR18xx [%d]: channel %d, Read Look Ahead not supported\n",
  736                                   pMvSataAdapter->adapterId, channelNum));
  737         }
  738 #else 
  739         {
  740                 if (pMvSataChannel->identifyDevice[86] & 0x20)
  741                 {
  742                         KdPrint(("RR18xx [%d]:channel %d, disable read look ahead\n",
  743                                           pMvSataAdapter->adapterId, channelNum));
  744                         if (mvStorageDevATASetFeatures(pMvSataAdapter, channelNum,
  745                                                                                    MV_ATA_SET_FEATURES_DISABLE_RLA, 0, 0,
  746                                                                                    0, 0) == MV_FALSE)
  747                         {
  748                                 MV_ERROR("RR18xx [%d]:channel %d:  ATA Set Features failed\n",
  749                                                  pMvSataAdapter->adapterId, channelNum); 
  750                                 return -1;
  751                         }
  752                 }
  753                 KdPrint(("RR18xx [%d]:channel %d, read look ahead disabled\n",
  754                                   pMvSataAdapter->adapterId, channelNum));
  755         }    
  756 #endif
  757 
  758 
  759         {
  760                 KdPrint(("RR18xx [%d]: channel %d config EDMA, Non Queued Mode\n",
  761                                   pMvSataAdapter->adapterId, 
  762                                   channelNum));
  763                 if (mvSataConfigEdmaMode(pMvSataAdapter, channelNum,
  764                                                                  MV_EDMA_MODE_NOT_QUEUED, 0) == MV_FALSE)
  765                 {
  766                         MV_ERROR("RR18xx [%d] channel %d Error: mvSataConfigEdmaMode failed\n",
  767                                          pMvSataAdapter->adapterId, channelNum);
  768                         return -1;
  769                 }
  770         }
  771         /* Enable EDMA */
  772         if (mvSataEnableChannelDma(pMvSataAdapter, channelNum) == MV_FALSE)
  773         {
  774                 MV_ERROR("RR18xx [%d] Failed to enable DMA, channel=%d\n",
  775                                  pMvSataAdapter->adapterId, channelNum);
  776                 return -1;
  777         }
  778         MV_ERROR("RR18xx [%d,%d]: channel started successfully\n",
  779                          pMvSataAdapter->adapterId, channelNum);
  780 
  781 #ifndef FOR_DEMO
  782         set_fail_led(pMvSataAdapter, channelNum, 0);
  783 #endif
  784         return 0;
  785 }
  786 
  787 static void
  788 hptmv_handle_event(void * data, int flag)
  789 {
  790         IAL_ADAPTER_T   *pAdapter = (IAL_ADAPTER_T *)data;
  791         MV_SATA_ADAPTER *pMvSataAdapter = &pAdapter->mvSataAdapter;
  792         MV_U8           channelIndex;
  793  
  794 /*      mvOsSemTake(&pMvSataAdapter->semaphore); */
  795         for (channelIndex = 0; channelIndex < MV_SATA_CHANNELS_NUM; channelIndex++)
  796         {
  797                 switch(pAdapter->sataEvents[channelIndex])
  798                 {
  799                         case SATA_EVENT_CHANNEL_CONNECTED:
  800                                 /* Handle only connects */
  801                                 if (flag == 1)
  802                                         break;
  803                                 KdPrint(("RR18xx [%d,%d]: new device connected\n",
  804                                                  pMvSataAdapter->adapterId, channelIndex));
  805                                 hptmv_init_channel(pAdapter, channelIndex);
  806                                 if (mvSataConfigureChannel( pMvSataAdapter, channelIndex) == MV_FALSE)
  807                                 {
  808                                         MV_ERROR("RR18xx [%d,%d] Failed to configure\n",
  809                                                          pMvSataAdapter->adapterId, channelIndex);
  810                                         hptmv_free_channel(pAdapter, channelIndex);
  811                                 }
  812                                 else
  813                                 {
  814                                         /*mvSataChannelHardReset(pMvSataAdapter, channel);*/
  815                                         if (start_channel( pAdapter, channelIndex))
  816                                         {
  817                                                 MV_ERROR("RR18xx [%d,%d]Failed to start channel\n",
  818                                                                  pMvSataAdapter->adapterId, channelIndex);
  819                                                 hptmv_free_channel(pAdapter, channelIndex);
  820                                         }
  821                                         else 
  822                                         {
  823                                                 device_change(pAdapter, channelIndex, TRUE);
  824                                         }
  825                                 }
  826                                 pAdapter->sataEvents[channelIndex] = SATA_EVENT_NO_CHANGE;
  827                            break;
  828 
  829                         case SATA_EVENT_CHANNEL_DISCONNECTED:
  830                                 /* Handle only disconnects */
  831                                 if (flag == 0)
  832                                         break;
  833                                 KdPrint(("RR18xx [%d,%d]: device disconnected\n",
  834                                                  pMvSataAdapter->adapterId, channelIndex));
  835                                         /* Flush pending commands */
  836                                 if(pMvSataAdapter->sataChannel[channelIndex])
  837                                 {
  838                                         _VBUS_INST(&pAdapter->VBus)
  839                                         mvSataFlushDmaQueue (pMvSataAdapter, channelIndex,
  840                                                                                  MV_FLUSH_TYPE_CALLBACK);
  841                                         CheckPendingCall(_VBUS_P0);
  842                                         mvSataRemoveChannel(pMvSataAdapter,channelIndex);
  843                                         hptmv_free_channel(pAdapter, channelIndex);
  844                                         pMvSataAdapter->sataChannel[channelIndex] = NULL;
  845                                         KdPrint(("RR18xx [%d,%d]: channel removed\n",
  846                                                  pMvSataAdapter->adapterId, channelIndex));
  847                                         if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
  848                                                 Check_Idle_Call(pAdapter);
  849                                 }
  850                                 else
  851                                 {
  852                                         KdPrint(("RR18xx [%d,%d]: channel already removed!!\n",
  853                                                          pMvSataAdapter->adapterId, channelIndex));
  854                                 }
  855                                 pAdapter->sataEvents[channelIndex] = SATA_EVENT_NO_CHANGE;
  856                                 break;
  857                                 
  858                         case SATA_EVENT_NO_CHANGE:
  859                                 break;
  860 
  861                         default:
  862                                 break;
  863                 }
  864         }
  865 /*      mvOsSemRelease(&pMvSataAdapter->semaphore); */
  866 }
  867 
  868 #define EVENT_CONNECT                                   1
  869 #define EVENT_DISCONNECT                                0
  870 
  871 static void
  872 hptmv_handle_event_connect(void *data)
  873 {
  874   hptmv_handle_event (data, 0);
  875 }
  876 
  877 static void
  878 hptmv_handle_event_disconnect(void *data)
  879 {
  880   hptmv_handle_event (data, 1);
  881 }
  882 
  883 static MV_BOOLEAN
  884 hptmv_event_notify(MV_SATA_ADAPTER *pMvSataAdapter, MV_EVENT_TYPE eventType,
  885                                                                    MV_U32 param1, MV_U32 param2)
  886 {
  887         IAL_ADAPTER_T   *pAdapter = pMvSataAdapter->IALData;
  888 
  889         switch (eventType)
  890         {
  891                 case MV_EVENT_TYPE_SATA_CABLE:
  892                         {
  893                                 MV_U8   channel = param2;
  894 
  895                                 if (param1 == EVENT_CONNECT)
  896                                 {
  897                                         pAdapter->sataEvents[channel] = SATA_EVENT_CHANNEL_CONNECTED;
  898                                         KdPrint(("RR18xx [%d,%d]: device connected event received\n",
  899                                                          pMvSataAdapter->adapterId, channel));
  900                                         /* Delete previous timers (if multiple drives connected in the same time */
  901                                         pAdapter->event_timer_connect = timeout(hptmv_handle_event_connect, pAdapter, 10*hz);
  902                                 }
  903                                 else if (param1 == EVENT_DISCONNECT)
  904                                 {
  905                                         pAdapter->sataEvents[channel] = SATA_EVENT_CHANNEL_DISCONNECTED;
  906                                         KdPrint(("RR18xx [%d,%d]: device disconnected event received \n",
  907                                                          pMvSataAdapter->adapterId, channel));
  908                                         device_change(pAdapter, channel, FALSE);
  909                                         /* Delete previous timers (if multiple drives disconnected in the same time */
  910                                         /*pAdapter->event_timer_disconnect = timeout(hptmv_handle_event_disconnect, pAdapter, 10*hz); */
  911                                         /*It is not necessary to wait, handle it directly*/
  912                                         hptmv_handle_event_disconnect(pAdapter);
  913                                 }
  914                                 else
  915                                 {
  916 
  917                                         MV_ERROR("RR18xx: illegal value for param1(%d) at "
  918                                                          "connect/disconnect event, host=%d\n", param1,
  919                                                          pMvSataAdapter->adapterId );
  920 
  921                                 }
  922                         }
  923                         break;
  924                 case MV_EVENT_TYPE_ADAPTER_ERROR:
  925                         KdPrint(("RR18xx: DEVICE error event received, pci cause "
  926                                           "reg=%x,  don't how to handle this\n", param1));
  927                         return MV_TRUE;
  928                 default:
  929                         MV_ERROR("RR18xx[%d]: unknown event type (%d)\n",
  930                                          pMvSataAdapter->adapterId, eventType);
  931                         return MV_FALSE;
  932         }
  933         return MV_TRUE;
  934 }
  935 
  936 static int 
  937 hptmv_allocate_edma_queues(IAL_ADAPTER_T *pAdapter)
  938 {
  939         pAdapter->requestsArrayBaseAddr = (MV_U8 *)contigmalloc(REQUESTS_ARRAY_SIZE, 
  940                         M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
  941         if (pAdapter->requestsArrayBaseAddr == NULL)
  942         {
  943                 MV_ERROR("RR18xx[%d]: Failed to allocate memory for EDMA request"
  944                                  " queues\n", pAdapter->mvSataAdapter.adapterId);
  945                 return -1;
  946         }
  947         pAdapter->requestsArrayBaseDmaAddr = fOsPhysicalAddress(pAdapter->requestsArrayBaseAddr);
  948         pAdapter->requestsArrayBaseAlignedAddr = pAdapter->requestsArrayBaseAddr;
  949         pAdapter->requestsArrayBaseAlignedAddr += MV_EDMA_REQUEST_QUEUE_SIZE;
  950         pAdapter->requestsArrayBaseAlignedAddr  = (MV_U8 *)
  951                 (((ULONG_PTR)pAdapter->requestsArrayBaseAlignedAddr) & ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1));
  952         pAdapter->requestsArrayBaseDmaAlignedAddr = pAdapter->requestsArrayBaseDmaAddr; 
  953         pAdapter->requestsArrayBaseDmaAlignedAddr += MV_EDMA_REQUEST_QUEUE_SIZE;
  954         pAdapter->requestsArrayBaseDmaAlignedAddr &= ~(ULONG_PTR)(MV_EDMA_REQUEST_QUEUE_SIZE - 1);
  955 
  956         if ((pAdapter->requestsArrayBaseDmaAlignedAddr - pAdapter->requestsArrayBaseDmaAddr) != 
  957                 (pAdapter->requestsArrayBaseAlignedAddr - pAdapter->requestsArrayBaseAddr))
  958         {
  959                 MV_ERROR("RR18xx[%d]: Error in Request Quueues Alignment\n",
  960                                  pAdapter->mvSataAdapter.adapterId);
  961                 contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
  962                 return -1;
  963         }
  964         /* response queues */
  965         pAdapter->responsesArrayBaseAddr = (MV_U8 *)contigmalloc(RESPONSES_ARRAY_SIZE, 
  966                         M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
  967         if (pAdapter->responsesArrayBaseAddr == NULL)
  968         {
  969                 MV_ERROR("RR18xx[%d]: Failed to allocate memory for EDMA response"
  970                                  " queues\n", pAdapter->mvSataAdapter.adapterId);
  971                 contigfree(pAdapter->requestsArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
  972                 return -1;
  973         }
  974         pAdapter->responsesArrayBaseDmaAddr = fOsPhysicalAddress(pAdapter->responsesArrayBaseAddr);
  975         pAdapter->responsesArrayBaseAlignedAddr = pAdapter->responsesArrayBaseAddr;
  976         pAdapter->responsesArrayBaseAlignedAddr += MV_EDMA_RESPONSE_QUEUE_SIZE;
  977         pAdapter->responsesArrayBaseAlignedAddr  = (MV_U8 *)
  978                 (((ULONG_PTR)pAdapter->responsesArrayBaseAlignedAddr) & ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1));
  979         pAdapter->responsesArrayBaseDmaAlignedAddr = pAdapter->responsesArrayBaseDmaAddr; 
  980         pAdapter->responsesArrayBaseDmaAlignedAddr += MV_EDMA_RESPONSE_QUEUE_SIZE;
  981         pAdapter->responsesArrayBaseDmaAlignedAddr &= ~(ULONG_PTR)(MV_EDMA_RESPONSE_QUEUE_SIZE - 1);
  982 
  983         if ((pAdapter->responsesArrayBaseDmaAlignedAddr - pAdapter->responsesArrayBaseDmaAddr) != 
  984                 (pAdapter->responsesArrayBaseAlignedAddr - pAdapter->responsesArrayBaseAddr))
  985         {
  986                 MV_ERROR("RR18xx[%d]: Error in Response Queues Alignment\n",
  987                                  pAdapter->mvSataAdapter.adapterId);
  988                 contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
  989                 contigfree(pAdapter->responsesArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
  990                 return -1;
  991         }
  992         return 0;
  993 }
  994 
  995 static void
  996 hptmv_free_edma_queues(IAL_ADAPTER_T *pAdapter)
  997 {
  998         contigfree(pAdapter->requestsArrayBaseAddr, REQUESTS_ARRAY_SIZE, M_DEVBUF);
  999         contigfree(pAdapter->responsesArrayBaseAddr, RESPONSES_ARRAY_SIZE, M_DEVBUF);
 1000 }
 1001 
 1002 static PVOID
 1003 AllocatePRDTable(IAL_ADAPTER_T *pAdapter)
 1004 {
 1005         PVOID ret;
 1006         if (pAdapter->pFreePRDLink) {
 1007                 KdPrint(("pAdapter->pFreePRDLink:%p\n",pAdapter->pFreePRDLink));
 1008                 ret = pAdapter->pFreePRDLink;
 1009                 pAdapter->pFreePRDLink = *(void**)ret;
 1010                 return ret;
 1011         }
 1012         return NULL;
 1013 }
 1014 
 1015 static void
 1016 FreePRDTable(IAL_ADAPTER_T *pAdapter, PVOID PRDTable)
 1017 {
 1018         *(void**)PRDTable = pAdapter->pFreePRDLink;
 1019         pAdapter->pFreePRDLink = PRDTable;
 1020 }
 1021 
 1022 extern PVDevice fGetFirstChild(PVDevice pLogical);
 1023 extern void fResetBootMark(PVDevice pLogical);
 1024 static void
 1025 fRegisterVdevice(IAL_ADAPTER_T *pAdapter)
 1026 {
 1027         PVDevice pPhysical, pLogical;
 1028         PVBus  pVBus;
 1029         int i,j;
 1030 
 1031         for(i=0;i<MV_SATA_CHANNELS_NUM;i++) {
 1032                 pPhysical = &(pAdapter->VDevices[i]);
 1033                 pLogical = pPhysical;
 1034                 while (pLogical->pParent) pLogical = pLogical->pParent;
 1035                 if (pLogical->vf_online==0) {
 1036                         pPhysical->vf_bootmark = pLogical->vf_bootmark = 0;
 1037                         continue;
 1038                 }
 1039                 if (pLogical->VDeviceType==VD_SPARE || pPhysical!=fGetFirstChild(pLogical)) 
 1040                         continue;
 1041 
 1042                 pVBus = &pAdapter->VBus;
 1043                 if(pVBus)
 1044                 {
 1045                         j=0;
 1046                         while(j<MAX_VDEVICE_PER_VBUS && pVBus->pVDevice[j]) j++;
 1047                         if(j<MAX_VDEVICE_PER_VBUS){
 1048                                 pVBus->pVDevice[j] = pLogical; 
 1049                                 pLogical->pVBus = pVBus;
 1050 
 1051                                 if (j>0 && pLogical->vf_bootmark) {
 1052                                         if (pVBus->pVDevice[0]->vf_bootmark) {
 1053                                                 fResetBootMark(pLogical);
 1054                                         }
 1055                                         else {
 1056                                                 do { pVBus->pVDevice[j] = pVBus->pVDevice[j-1]; } while (--j);
 1057                                                 pVBus->pVDevice[0] = pLogical;
 1058                                         }
 1059                                 }
 1060                         }
 1061                 }
 1062         }
 1063 }
 1064 
 1065 PVDevice
 1066 GetSpareDisk(_VBUS_ARG PVDevice pArray)
 1067 {
 1068         IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)pArray->pVBus->OsExt;
 1069         LBA_T capacity = LongDiv(pArray->VDeviceCapacity, pArray->u.array.bArnMember-1);
 1070         LBA_T thiscap, maxcap = MAX_LBA_T;
 1071         PVDevice pVDevice, pFind = NULL;
 1072         int i;
 1073 
 1074         for(i=0;i<MV_SATA_CHANNELS_NUM;i++)
 1075         {
 1076                 pVDevice = &pAdapter->VDevices[i];
 1077                 if(!pVDevice) 
 1078                         continue;
 1079                 thiscap = pArray->vf_format_v2? pVDevice->u.disk.dDeRealCapacity : pVDevice->VDeviceCapacity;
 1080                 /* find the smallest usable spare disk */
 1081                 if (pVDevice->VDeviceType==VD_SPARE &&
 1082                         pVDevice->u.disk.df_on_line &&
 1083                         thiscap < maxcap &&
 1084                         thiscap >= capacity)
 1085                 {                                               
 1086                                 maxcap = pVDevice->VDeviceCapacity;
 1087                                 pFind = pVDevice;                       
 1088                 }
 1089         }
 1090         return pFind;
 1091 }
 1092 
 1093 /******************************************************************
 1094  * IO ATA Command
 1095  *******************************************************************/
 1096 int HPTLIBAPI
 1097 fDeReadWrite(PDevice pDev, ULONG Lba, UCHAR Cmd, void *tmpBuffer)
 1098 {
 1099         return mvReadWrite(pDev->mv, Lba, Cmd, tmpBuffer);
 1100 }
 1101 
 1102 void HPTLIBAPI fDeSelectMode(PDevice pDev, UCHAR NewMode)
 1103 {
 1104         MV_SATA_CHANNEL *pSataChannel = pDev->mv;
 1105         MV_SATA_ADAPTER *pSataAdapter = pSataChannel->mvSataAdapter;    
 1106         MV_U8 channelIndex = pSataChannel->channelNumber;
 1107         UCHAR mvMode;
 1108         /* 508x don't use MW-DMA? */
 1109         if (NewMode>4 && NewMode<8) NewMode = 4;
 1110         pDev->bDeModeSetting = NewMode;
 1111         if (NewMode<=4)
 1112                 mvMode = MV_ATA_TRANSFER_PIO_0 + NewMode;
 1113         else
 1114                 mvMode = MV_ATA_TRANSFER_UDMA_0 + (NewMode-8);
 1115 
 1116         /*To fix 88i8030 bug*/
 1117         if (mvMode > MV_ATA_TRANSFER_UDMA_0 && mvMode < MV_ATA_TRANSFER_UDMA_4)
 1118                 mvMode = MV_ATA_TRANSFER_UDMA_0;
 1119 
 1120         mvSataDisableChannelDma(pSataAdapter, channelIndex);
 1121         /* Flush pending commands */
 1122         mvSataFlushDmaQueue (pSataAdapter, channelIndex, MV_FLUSH_TYPE_NONE);
 1123 
 1124         if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
 1125                                                                    MV_ATA_SET_FEATURES_TRANSFER,
 1126                                                                    mvMode, 0, 0, 0) == MV_FALSE)
 1127         {
 1128                 KdPrint(("channel %d: Set Features failed\n", channelIndex)); 
 1129         }
 1130         /* Enable EDMA */
 1131         if (mvSataEnableChannelDma(pSataAdapter, channelIndex) == MV_FALSE)
 1132                 KdPrint(("Failed to enable DMA, channel=%d", channelIndex));
 1133 }
 1134 
 1135 int HPTLIBAPI fDeSetTCQ(PDevice pDev, int enable, int depth)
 1136 {
 1137         MV_SATA_CHANNEL *pSataChannel = pDev->mv;
 1138         MV_SATA_ADAPTER *pSataAdapter = pSataChannel->mvSataAdapter;
 1139         MV_U8 channelIndex = pSataChannel->channelNumber;
 1140         IAL_ADAPTER_T *pAdapter = pSataAdapter->IALData;
 1141         MV_CHANNEL              *channelInfo = &(pAdapter->mvChannel[channelIndex]);
 1142         int dmaActive = pSataChannel->queueCommandsEnabled;
 1143         int ret = 0;
 1144 
 1145         if (dmaActive) {
 1146                 mvSataDisableChannelDma(pSataAdapter, channelIndex);
 1147                 mvSataFlushDmaQueue(pSataAdapter,channelIndex,MV_FLUSH_TYPE_CALLBACK);
 1148         }
 1149 
 1150         if (enable) {
 1151                 if (pSataChannel->queuedDMA == MV_EDMA_MODE_NOT_QUEUED &&
 1152                         (pSataChannel->identifyDevice[IDEN_SUPPORTED_COMMANDS2] & (0x2))) {
 1153                         UCHAR depth = ((pSataChannel->identifyDevice[IDEN_QUEUE_DEPTH]) & 0x1f) + 1;
 1154                         channelInfo->queueDepth = (depth==32)? 31 : depth;
 1155                         mvSataConfigEdmaMode(pSataAdapter, channelIndex, MV_EDMA_MODE_QUEUED, depth);
 1156                         ret = 1;
 1157                 }
 1158         }
 1159         else
 1160         {
 1161                 if (pSataChannel->queuedDMA != MV_EDMA_MODE_NOT_QUEUED) {
 1162                         channelInfo->queueDepth = 2;
 1163                         mvSataConfigEdmaMode(pSataAdapter, channelIndex, MV_EDMA_MODE_NOT_QUEUED, 0);
 1164                         ret = 1;
 1165                 }
 1166         }
 1167 
 1168         if (dmaActive)
 1169                 mvSataEnableChannelDma(pSataAdapter,channelIndex);
 1170         return ret;
 1171 }
 1172 
 1173 int HPTLIBAPI fDeSetNCQ(PDevice pDev, int enable, int depth)
 1174 {
 1175         return 0;
 1176 }
 1177 
 1178 int HPTLIBAPI fDeSetWriteCache(PDevice pDev, int enable)
 1179 {
 1180         MV_SATA_CHANNEL *pSataChannel = pDev->mv;
 1181         MV_SATA_ADAPTER *pSataAdapter = pSataChannel->mvSataAdapter;
 1182         MV_U8 channelIndex = pSataChannel->channelNumber;
 1183         IAL_ADAPTER_T *pAdapter = pSataAdapter->IALData;
 1184         MV_CHANNEL              *channelInfo = &(pAdapter->mvChannel[channelIndex]);
 1185         int dmaActive = pSataChannel->queueCommandsEnabled;
 1186         int ret = 0;
 1187 
 1188         if (dmaActive) {
 1189                 mvSataDisableChannelDma(pSataAdapter, channelIndex);
 1190                 mvSataFlushDmaQueue(pSataAdapter,channelIndex,MV_FLUSH_TYPE_CALLBACK);
 1191         }
 1192 
 1193         if ((pSataChannel->identifyDevice[82] & (0x20))) {
 1194                 if (enable) {
 1195                         if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
 1196                                 MV_ATA_SET_FEATURES_ENABLE_WCACHE, 0, 0, 0, 0))
 1197                         {
 1198                                 channelInfo->writeCacheEnabled = MV_TRUE;
 1199                                 ret = 1;
 1200                         }
 1201                 }
 1202                 else {
 1203                         if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
 1204                                 MV_ATA_SET_FEATURES_DISABLE_WCACHE, 0, 0, 0, 0))
 1205                         {
 1206                                 channelInfo->writeCacheEnabled = MV_FALSE;
 1207                                 ret = 1;
 1208                         }
 1209                 }
 1210         }
 1211 
 1212         if (dmaActive)
 1213                 mvSataEnableChannelDma(pSataAdapter,channelIndex);
 1214         return ret;
 1215 }
 1216 
 1217 int HPTLIBAPI fDeSetReadAhead(PDevice pDev, int enable)
 1218 {
 1219         MV_SATA_CHANNEL *pSataChannel = pDev->mv;
 1220         MV_SATA_ADAPTER *pSataAdapter = pSataChannel->mvSataAdapter;
 1221         MV_U8 channelIndex = pSataChannel->channelNumber;
 1222         IAL_ADAPTER_T *pAdapter = pSataAdapter->IALData;
 1223         MV_CHANNEL              *channelInfo = &(pAdapter->mvChannel[channelIndex]);
 1224         int dmaActive = pSataChannel->queueCommandsEnabled;
 1225         int ret = 0;
 1226 
 1227         if (dmaActive) {
 1228                 mvSataDisableChannelDma(pSataAdapter, channelIndex);
 1229                 mvSataFlushDmaQueue(pSataAdapter,channelIndex,MV_FLUSH_TYPE_CALLBACK);
 1230         }
 1231 
 1232         if ((pSataChannel->identifyDevice[82] & (0x40))) {
 1233                 if (enable) {
 1234                         if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
 1235                                 MV_ATA_SET_FEATURES_ENABLE_RLA, 0, 0, 0, 0))
 1236                         {
 1237                                 channelInfo->readAheadEnabled = MV_TRUE;
 1238                                 ret = 1;
 1239                         }
 1240                 }
 1241                 else {
 1242                         if (mvStorageDevATASetFeatures(pSataAdapter, channelIndex,
 1243                                 MV_ATA_SET_FEATURES_DISABLE_RLA, 0, 0, 0, 0))
 1244                         {
 1245                                 channelInfo->readAheadEnabled = MV_FALSE;
 1246                                 ret = 1;
 1247                         }
 1248                 }
 1249         }
 1250 
 1251         if (dmaActive)
 1252                 mvSataEnableChannelDma(pSataAdapter,channelIndex);
 1253         return ret;
 1254 }
 1255 
 1256 #ifdef SUPPORT_ARRAY
 1257 #define IdeRegisterVDevice  fCheckArray
 1258 #else 
 1259 void
 1260 IdeRegisterVDevice(PDevice pDev)
 1261 {
 1262         PVDevice pVDev = Map2pVDevice(pDev);
 1263 
 1264         pVDev->VDeviceType = pDev->df_atapi? VD_ATAPI : 
 1265                                                  pDev->df_removable_drive? VD_REMOVABLE : VD_SINGLE_DISK;
 1266         pVDev->vf_online = 1;
 1267         pVDev->VDeviceCapacity = pDev->dDeRealCapacity;
 1268         pVDev->pfnSendCommand = pfnSendCommand[pVDev->VDeviceType];
 1269         pVDev->pfnDeviceFailed = pfnDeviceFailed[pVDev->VDeviceType];
 1270 }
 1271 #endif
 1272 
 1273 static __inline PBUS_DMAMAP
 1274 dmamap_get(struct IALAdapter * pAdapter)
 1275 {
 1276         PBUS_DMAMAP     p = pAdapter->pbus_dmamap_list;
 1277         if (p)
 1278                 pAdapter->pbus_dmamap_list = p-> next;
 1279         return p;
 1280 }
 1281 
 1282 static __inline void
 1283 dmamap_put(PBUS_DMAMAP p)
 1284 {
 1285         p->next = p->pAdapter->pbus_dmamap_list;
 1286         p->pAdapter->pbus_dmamap_list = p;
 1287 }
 1288 
 1289 /*Since mtx not provide the initialize when declare, so we Final init here to initialize the global mtx*/
 1290 #if __FreeBSD_version >= 500000
 1291 #define override_kernel_driver()
 1292 
 1293 static void hpt_init(void *dummy)
 1294 {
 1295         override_kernel_driver();       
 1296         mtx_init(&driver_lock, "hptsleeplock", NULL, MTX_DEF);
 1297 }
 1298 SYSINIT(hptinit, SI_SUB_CONFIGURE, SI_ORDER_FIRST, hpt_init, NULL);
 1299 #endif
 1300 
 1301 static int num_adapters = 0;
 1302 static int
 1303 init_adapter(IAL_ADAPTER_T *pAdapter)
 1304 {
 1305         PVBus _vbus_p = &pAdapter->VBus;
 1306         MV_SATA_ADAPTER *pMvSataAdapter;
 1307         int i, channel, rid;
 1308 
 1309         PVDevice pVDev;
 1310 
 1311         intrmask_t oldspl = lock_driver();
 1312 
 1313         pAdapter->next = 0;
 1314 
 1315         if(gIal_Adapter == 0){
 1316                 gIal_Adapter = pAdapter;
 1317                 pCurAdapter = gIal_Adapter;
 1318         }
 1319         else {
 1320                 pCurAdapter->next = pAdapter;
 1321                 pCurAdapter = pAdapter;
 1322         }
 1323 
 1324         pAdapter->outstandingCommands = 0;
 1325 
 1326         pMvSataAdapter = &(pAdapter->mvSataAdapter);
 1327         _vbus_p->OsExt = (void *)pAdapter; 
 1328         pMvSataAdapter->IALData = pAdapter;
 1329 
 1330         if (bus_dma_tag_create(bus_get_dma_tag(pAdapter->hpt_dev),/* parent */
 1331                         4,      /* alignment */
 1332                         BUS_SPACE_MAXADDR_32BIT+1, /* boundary */
 1333                         BUS_SPACE_MAXADDR,      /* lowaddr */
 1334                         BUS_SPACE_MAXADDR,      /* highaddr */
 1335                         NULL, NULL,             /* filter, filterarg */
 1336                         PAGE_SIZE * (MAX_SG_DESCRIPTORS-1), /* maxsize */
 1337                         MAX_SG_DESCRIPTORS, /* nsegments */
 1338                         0x10000,        /* maxsegsize */
 1339                         BUS_DMA_WAITOK,         /* flags */
 1340 #if __FreeBSD_version>502000
 1341                         busdma_lock_mutex,      /* lockfunc */
 1342                         &driver_lock,           /* lockfuncarg */
 1343 #endif
 1344                         &pAdapter->io_dma_parent /* tag */))
 1345                 {
 1346                         return ENXIO;
 1347         }
 1348 
 1349 
 1350         if (hptmv_allocate_edma_queues(pAdapter))
 1351         {
 1352                 MV_ERROR("RR18xx: Failed to allocate memory for EDMA queues\n");
 1353                 unlock_driver(oldspl);
 1354                 return ENOMEM;
 1355         }
 1356 
 1357         /* also map EPROM address */
 1358         rid = 0x10;
 1359         if (!(pAdapter->mem_res = bus_alloc_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, &rid,
 1360                         0, ~0, MV_SATA_PCI_BAR0_SPACE_SIZE+0x40000, RF_ACTIVE))
 1361                 ||
 1362                 !(pMvSataAdapter->adapterIoBaseAddress = rman_get_virtual(pAdapter->mem_res)))
 1363         {
 1364                 MV_ERROR("RR18xx: Failed to remap memory space\n");
 1365                 hptmv_free_edma_queues(pAdapter);
 1366                 unlock_driver(oldspl);
 1367                 return ENXIO;
 1368         }
 1369         else
 1370         {
 1371                 KdPrint(("RR18xx: io base address 0x%p\n", pMvSataAdapter->adapterIoBaseAddress));
 1372         }
 1373 
 1374         pMvSataAdapter->adapterId = num_adapters++;
 1375         /* get the revision ID */
 1376         pMvSataAdapter->pciConfigRevisionId = pci_read_config(pAdapter->hpt_dev, PCIR_REVID, 1);
 1377         pMvSataAdapter->pciConfigDeviceId = pci_get_device(pAdapter->hpt_dev);
 1378         
 1379         /* init RR18xx */
 1380         pMvSataAdapter->intCoalThre[0]= 1;
 1381         pMvSataAdapter->intCoalThre[1]= 1;
 1382         pMvSataAdapter->intTimeThre[0] = 1;
 1383         pMvSataAdapter->intTimeThre[1] = 1;
 1384         pMvSataAdapter->pciCommand = 0x0107E371;
 1385         pMvSataAdapter->pciSerrMask = 0xd77fe6ul;
 1386         pMvSataAdapter->pciInterruptMask = 0xd77fe6ul;
 1387         pMvSataAdapter->mvSataEventNotify = hptmv_event_notify;
 1388 
 1389         if (mvSataInitAdapter(pMvSataAdapter) == MV_FALSE)
 1390         {
 1391                 MV_ERROR("RR18xx[%d]: core failed to initialize the adapter\n",
 1392                                  pMvSataAdapter->adapterId);
 1393 unregister:
 1394                 bus_release_resource(pAdapter->hpt_dev, SYS_RES_MEMORY, rid, pAdapter->mem_res);
 1395                 hptmv_free_edma_queues(pAdapter);
 1396                 unlock_driver(oldspl);
 1397                 return ENXIO;
 1398         }
 1399         pAdapter->ver_601 = pMvSataAdapter->pcbVersion;
 1400 
 1401 #ifndef FOR_DEMO
 1402         set_fail_leds(pMvSataAdapter, 0);
 1403 #endif
 1404         
 1405         /* setup command blocks */
 1406         KdPrint(("Allocate command blocks\n"));
 1407         _vbus_(pFreeCommands) = 0;
 1408         pAdapter->pCommandBlocks = 
 1409                 malloc(sizeof(struct _Command) * MAX_COMMAND_BLOCKS_FOR_EACH_VBUS, M_DEVBUF, M_NOWAIT);
 1410         KdPrint(("pCommandBlocks:%p\n",pAdapter->pCommandBlocks));
 1411         if (!pAdapter->pCommandBlocks) {
 1412                 MV_ERROR("insufficient memory\n");
 1413                 goto unregister;
 1414         }
 1415 
 1416         for (i=0; i<MAX_COMMAND_BLOCKS_FOR_EACH_VBUS; i++) {
 1417                 FreeCommand(_VBUS_P &(pAdapter->pCommandBlocks[i]));
 1418         }
 1419 
 1420         /*Set up the bus_dmamap*/
 1421         pAdapter->pbus_dmamap = (PBUS_DMAMAP)malloc (sizeof(struct _BUS_DMAMAP) * MAX_QUEUE_COMM, M_DEVBUF, M_NOWAIT);
 1422         if(!pAdapter->pbus_dmamap) {
 1423                 MV_ERROR("insufficient memory\n");
 1424                 free(pAdapter->pCommandBlocks, M_DEVBUF);
 1425                 goto unregister;
 1426         }
 1427 
 1428         memset((void *)pAdapter->pbus_dmamap, 0, sizeof(struct _BUS_DMAMAP) * MAX_QUEUE_COMM);
 1429         pAdapter->pbus_dmamap_list = 0;
 1430         for (i=0; i < MAX_QUEUE_COMM; i++) {
 1431                 PBUS_DMAMAP  pmap = &(pAdapter->pbus_dmamap[i]);
 1432                 pmap->pAdapter = pAdapter;
 1433                 dmamap_put(pmap);
 1434 
 1435                 if(bus_dmamap_create(pAdapter->io_dma_parent, 0, &pmap->dma_map)) {
 1436                         MV_ERROR("Can not allocate dma map\n");
 1437                         free(pAdapter->pCommandBlocks, M_DEVBUF);
 1438                         free(pAdapter->pbus_dmamap, M_DEVBUF);
 1439                         goto unregister;
 1440                 }
 1441         }
 1442         /* setup PRD Tables */
 1443         KdPrint(("Allocate PRD Tables\n"));
 1444         pAdapter->pFreePRDLink = 0;
 1445         
 1446         pAdapter->prdTableAddr = (PUCHAR)contigmalloc(
 1447                 (PRD_ENTRIES_SIZE*PRD_TABLES_FOR_VBUS + 32), M_DEVBUF, M_NOWAIT, 0, 0xffffffff, PAGE_SIZE, 0ul);
 1448                 
 1449         KdPrint(("prdTableAddr:%p\n",pAdapter->prdTableAddr));
 1450         if (!pAdapter->prdTableAddr) {
 1451                 MV_ERROR("insufficient PRD Tables\n");
 1452                 goto unregister;
 1453         }
 1454         pAdapter->prdTableAlignedAddr = (PUCHAR)(((ULONG_PTR)pAdapter->prdTableAddr + 0x1f) & ~(ULONG_PTR)0x1fL);
 1455         {
 1456                 PUCHAR PRDTable = pAdapter->prdTableAlignedAddr;
 1457                 for (i=0; i<PRD_TABLES_FOR_VBUS; i++)
 1458                 {
 1459 /*                      KdPrint(("i=%d,pAdapter->pFreePRDLink=%p\n",i,pAdapter->pFreePRDLink)); */
 1460                         FreePRDTable(pAdapter, PRDTable);
 1461                         PRDTable += PRD_ENTRIES_SIZE;
 1462                 }
 1463         }
 1464 
 1465         /* enable the adapter interrupts */
 1466 
 1467         /* configure and start the connected channels*/
 1468         for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++)
 1469         {
 1470                 pAdapter->mvChannel[channel].online = MV_FALSE;
 1471                 if (mvSataIsStorageDeviceConnected(pMvSataAdapter, channel)
 1472                         == MV_TRUE)
 1473                 {
 1474                         KdPrint(("RR18xx[%d]: channel %d is connected\n",
 1475                                           pMvSataAdapter->adapterId, channel));
 1476 
 1477                         if (hptmv_init_channel(pAdapter, channel) == 0)
 1478                         {
 1479                                 if (mvSataConfigureChannel(pMvSataAdapter, channel) == MV_FALSE)
 1480                                 {
 1481                                         MV_ERROR("RR18xx[%d]: Failed to configure channel"
 1482                                                          " %d\n",pMvSataAdapter->adapterId, channel);
 1483                                         hptmv_free_channel(pAdapter, channel);
 1484                                 }
 1485                                 else
 1486                                 {
 1487                                         if (start_channel(pAdapter, channel))
 1488                                         {
 1489                                                 MV_ERROR("RR18xx[%d]: Failed to start channel,"
 1490                                                                  " channel=%d\n",pMvSataAdapter->adapterId,
 1491                                                                  channel);
 1492                                                 hptmv_free_channel(pAdapter, channel);
 1493                                         }
 1494                                         pAdapter->mvChannel[channel].online = MV_TRUE; 
 1495                                         /*  mvSataChannelSetEdmaLoopBackMode(pMvSataAdapter,
 1496                                                                                                            channel,
 1497                                                                                                            MV_TRUE);*/
 1498                                 }
 1499                         }
 1500                 }
 1501                 KdPrint(("pAdapter->mvChannel[channel].online:%x, channel:%d\n",
 1502                         pAdapter->mvChannel[channel].online, channel));
 1503         }
 1504 
 1505 #ifdef SUPPORT_ARRAY
 1506         for(i = MAX_ARRAY_DEVICE - 1; i >= 0; i--) {
 1507                 pVDev = ArrayTables(i);
 1508                 mArFreeArrayTable(pVDev);
 1509         }
 1510 #endif
 1511 
 1512         KdPrint(("Initialize Devices\n"));
 1513         for (channel = 0; channel < MV_SATA_CHANNELS_NUM; channel++) {
 1514                 MV_SATA_CHANNEL *pMvSataChannel = pMvSataAdapter->sataChannel[channel];
 1515                 if (pMvSataChannel) {
 1516                         init_vdev_params(pAdapter, channel);
 1517                         IdeRegisterVDevice(&pAdapter->VDevices[channel].u.disk);
 1518                 }
 1519         }
 1520 #ifdef SUPPORT_ARRAY
 1521         CheckArrayCritical(_VBUS_P0);
 1522 #endif
 1523         _vbus_p->nInstances = 1;
 1524         fRegisterVdevice(pAdapter);
 1525 
 1526         for (channel=0;channel<MV_SATA_CHANNELS_NUM;channel++) {
 1527                 pVDev = _vbus_p->pVDevice[channel];
 1528                 if (pVDev && pVDev->vf_online)
 1529                         fCheckBootable(pVDev);
 1530         }
 1531 
 1532 #if defined(SUPPORT_ARRAY) && defined(_RAID5N_)
 1533         init_raid5_memory(_VBUS_P0);
 1534         _vbus_(r5).enable_write_back = 1;
 1535         printf("RR18xx: RAID5 write-back %s\n", _vbus_(r5).enable_write_back? "enabled" : "disabled");
 1536 #endif
 1537 
 1538         mvSataUnmaskAdapterInterrupt(pMvSataAdapter);
 1539         unlock_driver(oldspl);
 1540         return 0;
 1541 }
 1542 
 1543 int
 1544 MvSataResetChannel(MV_SATA_ADAPTER *pMvSataAdapter, MV_U8 channel)
 1545 {
 1546         IAL_ADAPTER_T   *pAdapter = (IAL_ADAPTER_T *)pMvSataAdapter->IALData;
 1547 
 1548         mvSataDisableChannelDma(pMvSataAdapter, channel);
 1549         /* Flush pending commands */
 1550         mvSataFlushDmaQueue (pMvSataAdapter, channel, MV_FLUSH_TYPE_CALLBACK);
 1551 
 1552         /* Software reset channel */
 1553         if (mvStorageDevATASoftResetDevice(pMvSataAdapter, channel) == MV_FALSE)
 1554         {
 1555                 MV_ERROR("RR18xx [%d,%d]: failed to perform Software reset\n",
 1556                                  pMvSataAdapter->adapterId, channel);
 1557                 hptmv_free_channel(pAdapter, channel);
 1558                 return -1;
 1559         }
 1560         
 1561         /* Hardware reset channel */
 1562         if (mvSataChannelHardReset(pMvSataAdapter, channel)== MV_FALSE)
 1563         {
 1564                 MV_ERROR("RR18xx [%d,%d] Failed to Hard reser the SATA channel\n",
 1565                                  pMvSataAdapter->adapterId, channel);
 1566                 hptmv_free_channel(pAdapter, channel);
 1567                 return -1;
 1568         }
 1569 
 1570         if (mvSataIsStorageDeviceConnected(pMvSataAdapter, channel) == MV_FALSE)
 1571         {
 1572                  MV_ERROR("RR18xx [%d,%d] Failed to Connect Device\n",
 1573                                  pMvSataAdapter->adapterId, channel);
 1574                 hptmv_free_channel(pAdapter, channel);
 1575                 return -1;
 1576         }else
 1577         {
 1578                 MV_ERROR("channel %d: perform recalibrate command", channel);
 1579                 if (!mvStorageDevATAExecuteNonUDMACommand(pMvSataAdapter, channel,
 1580                                                                 MV_NON_UDMA_PROTOCOL_NON_DATA,
 1581                                                                 MV_FALSE,
 1582                                                                 NULL,    /* pBuffer*/
 1583                                                                 0,               /* count  */
 1584                                                                 0,              /*features*/
 1585                                                                                 /* sectorCount */
 1586                                                                 0,
 1587                                                                 0,      /* lbaLow */
 1588                                                                 0,      /* lbaMid */
 1589                                                                         /* lbaHigh */
 1590                                                                 0,
 1591                                                                 0,              /* device */
 1592                                                                                 /* command */
 1593                                                                 0x10))
 1594                         MV_ERROR("channel %d: recalibrate failed", channel);
 1595                 
 1596                 /* Set transfer mode */
 1597                 if((mvStorageDevATASetFeatures(pMvSataAdapter, channel,
 1598                                                 MV_ATA_SET_FEATURES_TRANSFER,
 1599                                                 MV_ATA_TRANSFER_PIO_SLOW, 0, 0, 0) == MV_FALSE) || 
 1600                         (mvStorageDevATASetFeatures(pMvSataAdapter, channel,
 1601                                                 MV_ATA_SET_FEATURES_TRANSFER,
 1602                                                 pAdapter->mvChannel[channel].maxPioModeSupported, 0, 0, 0) == MV_FALSE) ||
 1603                         (mvStorageDevATASetFeatures(pMvSataAdapter, channel,
 1604                                                 MV_ATA_SET_FEATURES_TRANSFER,
 1605                                                 pAdapter->mvChannel[channel].maxUltraDmaModeSupported, 0, 0, 0) == MV_FALSE) )
 1606                 {
 1607                         MV_ERROR("channel %d: Set Features failed", channel);
 1608                         hptmv_free_channel(pAdapter, channel);
 1609                         return -1;
 1610                 }
 1611                 /* Enable EDMA */
 1612                 if (mvSataEnableChannelDma(pMvSataAdapter, channel) == MV_FALSE)
 1613                 {
 1614                         MV_ERROR("Failed to enable DMA, channel=%d", channel);
 1615                         hptmv_free_channel(pAdapter, channel);
 1616                         return -1;
 1617                 }
 1618         }
 1619         return 0;
 1620 }
 1621 
 1622 static int
 1623 fResetActiveCommands(PVBus _vbus_p)
 1624 {
 1625         MV_SATA_ADAPTER *pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
 1626         MV_U8 channel;
 1627         for (channel=0;channel< MV_SATA_CHANNELS_NUM;channel++) {
 1628                 if (pMvSataAdapter->sataChannel[channel] && pMvSataAdapter->sataChannel[channel]->outstandingCommands) 
 1629                         MvSataResetChannel(pMvSataAdapter,channel);
 1630         }
 1631         return 0;
 1632 }
 1633 
 1634 void fCompleteAllCommandsSynchronously(PVBus _vbus_p)
 1635 {
 1636         UINT cont;
 1637         ULONG ticks = 0;
 1638         MV_U8 channel;
 1639         MV_SATA_ADAPTER *pMvSataAdapter = &((IAL_ADAPTER_T *)_vbus_p->OsExt)->mvSataAdapter;
 1640         MV_SATA_CHANNEL *pMvSataChannel;
 1641 
 1642         do {
 1643 check_cmds:
 1644                 cont = 0;
 1645                 CheckPendingCall(_VBUS_P0);
 1646 #ifdef _RAID5N_
 1647                 dataxfer_poll();
 1648                 xor_poll();
 1649 #endif
 1650                 for (channel=0;channel< MV_SATA_CHANNELS_NUM;channel++) {
 1651                         pMvSataChannel = pMvSataAdapter->sataChannel[channel];
 1652                         if (pMvSataChannel && pMvSataChannel->outstandingCommands) 
 1653                         {
 1654                                 while (pMvSataChannel->outstandingCommands) {
 1655                                         if (!mvSataInterruptServiceRoutine(pMvSataAdapter)) {
 1656                                                 StallExec(1000);
 1657                                                 if (ticks++ > 3000) {
 1658                                                         MvSataResetChannel(pMvSataAdapter,channel);
 1659                                                         goto check_cmds;
 1660                                                 }
 1661                                         }
 1662                                         else 
 1663                                                 ticks = 0;
 1664                                 }
 1665                                 cont = 1;
 1666                         }
 1667                 }
 1668         } while (cont);
 1669 }
 1670 
 1671 void
 1672 fResetVBus(_VBUS_ARG0)
 1673 {
 1674         KdPrint(("fMvResetBus(%p)", _vbus_p));
 1675 
 1676         /* some commands may already finished. */
 1677         CheckPendingCall(_VBUS_P0);
 1678 
 1679         fResetActiveCommands(_vbus_p);
 1680         /* 
 1681          * the other pending commands may still be finished successfully.
 1682          */
 1683         fCompleteAllCommandsSynchronously(_vbus_p);
 1684 
 1685         /* Now there should be no pending commands. No more action needed. */
 1686         CheckIdleCall(_VBUS_P0);
 1687 
 1688         KdPrint(("fMvResetBus() done"));
 1689 }
 1690 
 1691 /*No rescan function*/
 1692 void
 1693 fRescanAllDevice(_VBUS_ARG0)
 1694 {
 1695 }
 1696 
 1697 static MV_BOOLEAN 
 1698 CommandCompletionCB(MV_SATA_ADAPTER *pMvSataAdapter,
 1699                                         MV_U8 channelNum,
 1700                                         MV_COMPLETION_TYPE comp_type,
 1701                                         MV_VOID_PTR commandId,
 1702                                         MV_U16 responseFlags,
 1703                                         MV_U32 timeStamp,
 1704                                         MV_STORAGE_DEVICE_REGISTERS *registerStruct)
 1705 {
 1706         PCommand pCmd = (PCommand) commandId;
 1707         _VBUS_INST(pCmd->pVDevice->pVBus)
 1708 
 1709         if (pCmd->uScratch.sata_param.prdAddr) 
 1710                 FreePRDTable(pMvSataAdapter->IALData,pCmd->uScratch.sata_param.prdAddr);
 1711 
 1712         switch (comp_type)
 1713         {
 1714         case MV_COMPLETION_TYPE_NORMAL:
 1715                 pCmd->Result = RETURN_SUCCESS;
 1716                 break;
 1717         case MV_COMPLETION_TYPE_ABORT:
 1718                 pCmd->Result = RETURN_BUS_RESET;
 1719                 break;
 1720         case MV_COMPLETION_TYPE_ERROR:
 1721                  MV_ERROR("IAL: COMPLETION ERROR, adapter %d, channel %d, flags=%x\n",
 1722                                  pMvSataAdapter->adapterId, channelNum, responseFlags);
 1723 
 1724                 if (responseFlags & 4) {
 1725                         MV_ERROR("ATA regs: error %x, sector count %x, LBA low %x, LBA mid %x,"
 1726                                 " LBA high %x, device %x, status %x\n",
 1727                                 registerStruct->errorRegister,
 1728                                 registerStruct->sectorCountRegister,
 1729                                 registerStruct->lbaLowRegister,
 1730                                 registerStruct->lbaMidRegister,
 1731                                 registerStruct->lbaHighRegister,
 1732                                 registerStruct->deviceRegister,
 1733                                 registerStruct->statusRegister);
 1734                 }
 1735                 /*We can't do handleEdmaError directly here, because CommandCompletionCB is called by 
 1736                  * mv's ISR, if we retry the command, than the internel data structure may be destroyed*/
 1737                 pCmd->uScratch.sata_param.responseFlags = responseFlags;
 1738                 pCmd->uScratch.sata_param.bIdeStatus = registerStruct->statusRegister;
 1739                 pCmd->uScratch.sata_param.errorRegister = registerStruct->errorRegister;
 1740                 pCmd->pVDevice->u.disk.QueueLength--;
 1741                 CallAfterReturn(_VBUS_P (DPC_PROC)handleEdmaError,pCmd);
 1742                 return TRUE;
 1743                 
 1744         default:
 1745                 MV_ERROR(" Unknown completion type (%d)\n", comp_type);
 1746                 return MV_FALSE;
 1747         }
 1748         
 1749         if (pCmd->uCmd.Ide.Command == IDE_COMMAND_VERIFY && pCmd->uScratch.sata_param.cmd_priv > 1) {
 1750                 pCmd->uScratch.sata_param.cmd_priv --;
 1751                 return TRUE;
 1752         }
 1753         pCmd->pVDevice->u.disk.QueueLength--;
 1754         CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1755         return TRUE;
 1756 }
 1757 
 1758 void
 1759 fDeviceSendCommand(_VBUS_ARG PCommand pCmd)
 1760 {
 1761         MV_SATA_EDMA_PRD_ENTRY  *pPRDTable = 0;
 1762         MV_SATA_ADAPTER *pMvSataAdapter;
 1763         MV_SATA_CHANNEL *pMvSataChannel;
 1764         PVDevice pVDevice = pCmd->pVDevice;
 1765         PDevice  pDevice = &pVDevice->u.disk;
 1766         LBA_T    Lba = pCmd->uCmd.Ide.Lba;
 1767         USHORT   nSector = pCmd->uCmd.Ide.nSectors;
 1768 
 1769         MV_QUEUE_COMMAND_RESULT result;
 1770         MV_QUEUE_COMMAND_INFO commandInfo;      
 1771         MV_UDMA_COMMAND_PARAMS  *pUdmaParams = &commandInfo.commandParams.udmaCommand;
 1772         MV_NONE_UDMA_COMMAND_PARAMS *pNoUdmaParams = &commandInfo.commandParams.NoneUdmaCommand;
 1773 
 1774         MV_BOOLEAN is48bit;
 1775         MV_U8      channel;
 1776         int        i=0;
 1777         
 1778         DECLARE_BUFFER(FPSCAT_GATH, tmpSg);
 1779 
 1780         if (!pDevice->df_on_line) {
 1781                 MV_ERROR("Device is offline");
 1782                 pCmd->Result = RETURN_BAD_DEVICE;
 1783                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1784                 return;
 1785         }
 1786 
 1787         pDevice->HeadPosition = pCmd->uCmd.Ide.Lba + pCmd->uCmd.Ide.nSectors;
 1788         pMvSataChannel = pDevice->mv;
 1789         pMvSataAdapter = pMvSataChannel->mvSataAdapter;
 1790         channel = pMvSataChannel->channelNumber;
 1791         
 1792         /* old RAID0 has hidden lba. Remember to clear dDeHiddenLba when delete array! */
 1793         Lba += pDevice->dDeHiddenLba;
 1794         /* check LBA */
 1795         if (Lba+nSector-1 > pDevice->dDeRealCapacity) {
 1796                 pCmd->Result = RETURN_INVALID_REQUEST;
 1797                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1798                 return;
 1799         }
 1800         
 1801         /*
 1802          * always use 48bit LBA if drive supports it.
 1803          * Some Seagate drives report error if you use a 28-bit command
 1804          * to access sector 0xfffffff.
 1805          */
 1806         is48bit = pMvSataChannel->lba48Address;
 1807 
 1808         switch (pCmd->uCmd.Ide.Command)
 1809         {
 1810         case IDE_COMMAND_READ:
 1811         case IDE_COMMAND_WRITE:
 1812                 if (pDevice->bDeModeSetting<8) goto pio;
 1813                 
 1814                 commandInfo.type = MV_QUEUED_COMMAND_TYPE_UDMA;
 1815                 pUdmaParams->isEXT = is48bit;
 1816                 pUdmaParams->numOfSectors = nSector;
 1817                 pUdmaParams->lowLBAAddress = Lba;
 1818                 pUdmaParams->highLBAAddress = 0;
 1819                 pUdmaParams->prdHighAddr = 0;
 1820                 pUdmaParams->callBack = CommandCompletionCB;
 1821                 pUdmaParams->commandId = (MV_VOID_PTR )pCmd;
 1822                 if(pCmd->uCmd.Ide.Command == IDE_COMMAND_READ)
 1823                         pUdmaParams->readWrite = MV_UDMA_TYPE_READ;
 1824                 else 
 1825                         pUdmaParams->readWrite = MV_UDMA_TYPE_WRITE;
 1826                 
 1827                 if (pCmd->pSgTable && pCmd->cf_physical_sg) {
 1828                         FPSCAT_GATH sg1=tmpSg, sg2=pCmd->pSgTable;
 1829                         do { *sg1++=*sg2; } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
 1830                 }
 1831                 else {
 1832                         if (!pCmd->pfnBuildSgl || !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 0)) {
 1833 pio:                            
 1834                                 mvSataDisableChannelDma(pMvSataAdapter, channel);
 1835                                 mvSataFlushDmaQueue(pMvSataAdapter, channel, MV_FLUSH_TYPE_CALLBACK);
 1836         
 1837                                 if (pCmd->pSgTable && pCmd->cf_physical_sg==0) {
 1838                                         FPSCAT_GATH sg1=tmpSg, sg2=pCmd->pSgTable;
 1839                                         do { *sg1++=*sg2; } while ((sg2++->wSgFlag & SG_FLAG_EOT)==0);
 1840                                 }
 1841                                 else {
 1842                                         if (!pCmd->pfnBuildSgl || !pCmd->pfnBuildSgl(_VBUS_P pCmd, tmpSg, 1)) {
 1843                                                 pCmd->Result = RETURN_NEED_LOGICAL_SG;
 1844                                                 goto finish_cmd;
 1845                                         }
 1846                                 }
 1847                                                                                 
 1848                                 do {
 1849                                         ULONG size = tmpSg->wSgSize? tmpSg->wSgSize : 0x10000;
 1850                                         ULONG_PTR addr = tmpSg->dSgAddress;
 1851                                         if (size & 0x1ff) {
 1852                                                 pCmd->Result = RETURN_INVALID_REQUEST;
 1853                                                 goto finish_cmd;
 1854                                         }
 1855                                         if (mvStorageDevATAExecuteNonUDMACommand(pMvSataAdapter, channel,
 1856                                                 (pCmd->cf_data_out)?MV_NON_UDMA_PROTOCOL_PIO_DATA_OUT:MV_NON_UDMA_PROTOCOL_PIO_DATA_IN,
 1857                                                 is48bit,
 1858                                                 (MV_U16_PTR)addr, 
 1859                                                 size >> 1,      /* count       */
 1860                                                 0,              /* features  N/A  */
 1861                                                 (MV_U16)(size>>9),      /*sector count*/
 1862                                                 (MV_U16)(  (is48bit? (MV_U16)((Lba >> 16) & 0xFF00) : 0 )  | (UCHAR)(Lba & 0xFF) ), /*lbalow*/
 1863                                                 (MV_U16)((Lba >> 8) & 0xFF), /* lbaMid      */
 1864                                                 (MV_U16)((Lba >> 16) & 0xFF),/* lbaHigh     */
 1865                                                 (MV_U8)(0x40 | (is48bit ? 0 : (UCHAR)(Lba >> 24) & 0xFF )),/* device      */
 1866                                                 (MV_U8)(is48bit ? (pCmd->cf_data_in?IDE_COMMAND_READ_EXT:IDE_COMMAND_WRITE_EXT):pCmd->uCmd.Ide.Command)
 1867                                         )==MV_FALSE)
 1868                                         {
 1869                                                 pCmd->Result = RETURN_IDE_ERROR;
 1870                                                 goto finish_cmd;
 1871                                         }
 1872                                         Lba += size>>9;
 1873                                         if(Lba & 0xF0000000) is48bit = MV_TRUE;
 1874                                 }
 1875                                 while ((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
 1876                                 pCmd->Result = RETURN_SUCCESS;
 1877 finish_cmd:
 1878                                 mvSataEnableChannelDma(pMvSataAdapter,channel);
 1879                                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1880                                 return;
 1881                         }
 1882                 }
 1883                 
 1884                 pPRDTable = (MV_SATA_EDMA_PRD_ENTRY *) AllocatePRDTable(pMvSataAdapter->IALData);
 1885                 KdPrint(("pPRDTable:%p\n",pPRDTable));
 1886                 if (!pPRDTable) {
 1887                         pCmd->Result = RETURN_DEVICE_BUSY;
 1888                         CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1889                         HPT_ASSERT(0);
 1890                         return;
 1891                 }
 1892 
 1893                 do{
 1894                         pPRDTable[i].highBaseAddr = (sizeof(tmpSg->dSgAddress)>4 ? (MV_U32)(tmpSg->dSgAddress>>32) : 0);
 1895                         pPRDTable[i].flags = (MV_U16)tmpSg->wSgFlag;
 1896                         pPRDTable[i].byteCount = (MV_U16)tmpSg->wSgSize;
 1897                         pPRDTable[i].lowBaseAddr = (MV_U32)tmpSg->dSgAddress;
 1898                         pPRDTable[i].reserved = 0;
 1899                         i++;
 1900                 }while((tmpSg++->wSgFlag & SG_FLAG_EOT)==0);
 1901                 
 1902                 pUdmaParams->prdLowAddr = (ULONG)fOsPhysicalAddress(pPRDTable);
 1903                 if ((pUdmaParams->numOfSectors == 256) && (pMvSataChannel->lba48Address == MV_FALSE)) {
 1904                         pUdmaParams->numOfSectors = 0;
 1905                 }
 1906                 
 1907                 pCmd->uScratch.sata_param.prdAddr = (PVOID)pPRDTable;
 1908 
 1909                 result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
 1910 
 1911                 if (result != MV_QUEUE_COMMAND_RESULT_OK)
 1912                 {
 1913 queue_failed:
 1914                         switch (result)
 1915                         {
 1916                         case MV_QUEUE_COMMAND_RESULT_BAD_LBA_ADDRESS:
 1917                                 MV_ERROR("IAL Error: Edma Queue command failed. Bad LBA "
 1918                                                  "LBA[31:0](0x%08x)\n", pUdmaParams->lowLBAAddress);
 1919                                 pCmd->Result = RETURN_IDE_ERROR;
 1920                                 break;
 1921                         case MV_QUEUE_COMMAND_RESULT_QUEUED_MODE_DISABLED:
 1922                                 MV_ERROR("IAL Error: Edma Queue command failed. EDMA"
 1923                                                  " disabled adapter %d channel %d\n",
 1924                                                  pMvSataAdapter->adapterId, channel);
 1925                                 mvSataEnableChannelDma(pMvSataAdapter,channel);
 1926                                 pCmd->Result = RETURN_IDE_ERROR;
 1927                                 break;
 1928                         case MV_QUEUE_COMMAND_RESULT_FULL:
 1929                                 MV_ERROR("IAL Error: Edma Queue command failed. Queue is"
 1930                                                  " Full adapter %d channel %d\n",
 1931                                                  pMvSataAdapter->adapterId, channel);
 1932                                 pCmd->Result = RETURN_DEVICE_BUSY;
 1933                                 break;
 1934                         case MV_QUEUE_COMMAND_RESULT_BAD_PARAMS:
 1935                                 MV_ERROR("IAL Error: Edma Queue command failed. (Bad "
 1936                                                  "Params), pMvSataAdapter: %p,  pSataChannel: %p.\n",
 1937                                                  pMvSataAdapter, pMvSataAdapter->sataChannel[channel]);
 1938                                 pCmd->Result = RETURN_IDE_ERROR;
 1939                                 break;
 1940                         default:
 1941                                 MV_ERROR("IAL Error: Bad result value (%d) from queue"
 1942                                                  " command\n", result);
 1943                                 pCmd->Result = RETURN_IDE_ERROR;
 1944                         }
 1945                         if(pPRDTable) 
 1946                                 FreePRDTable(pMvSataAdapter->IALData,pPRDTable);
 1947                         CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1948                 }
 1949                 pDevice->QueueLength++;
 1950                 return;
 1951                 
 1952         case IDE_COMMAND_VERIFY:
 1953                 commandInfo.type = MV_QUEUED_COMMAND_TYPE_NONE_UDMA;
 1954                 pNoUdmaParams->bufPtr = NULL;
 1955                 pNoUdmaParams->callBack = CommandCompletionCB;
 1956                 pNoUdmaParams->commandId = (MV_VOID_PTR)pCmd;
 1957                 pNoUdmaParams->count = 0;
 1958                 pNoUdmaParams->features = 0;
 1959                 pNoUdmaParams->protocolType = MV_NON_UDMA_PROTOCOL_NON_DATA;
 1960                 
 1961                 pCmd->uScratch.sata_param.cmd_priv = 1;
 1962                 if (pMvSataChannel->lba48Address == MV_TRUE){
 1963                         pNoUdmaParams->command = MV_ATA_COMMAND_READ_VERIFY_SECTORS_EXT;
 1964                         pNoUdmaParams->isEXT = MV_TRUE;
 1965                         pNoUdmaParams->lbaHigh = (MV_U16)((Lba & 0xff0000) >> 16);
 1966                         pNoUdmaParams->lbaMid = (MV_U16)((Lba & 0xff00) >> 8);   
 1967                         pNoUdmaParams->lbaLow = 
 1968                                 (MV_U16)(((Lba & 0xff000000) >> 16)| (Lba & 0xff));
 1969                         pNoUdmaParams->sectorCount = nSector;
 1970                         pNoUdmaParams->device = 0x40;
 1971                         result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
 1972                         if (result != MV_QUEUE_COMMAND_RESULT_OK){
 1973                                 goto queue_failed;
 1974                         }
 1975                         return;
 1976                 }
 1977                 else{
 1978                         pNoUdmaParams->command = MV_ATA_COMMAND_READ_VERIFY_SECTORS;
 1979                         pNoUdmaParams->isEXT = MV_FALSE;
 1980                         pNoUdmaParams->lbaHigh = (MV_U16)((Lba & 0xff0000) >> 16);
 1981                         pNoUdmaParams->lbaMid = (MV_U16)((Lba & 0xff00) >> 8);   
 1982                         pNoUdmaParams->lbaLow = (MV_U16)(Lba & 0xff);
 1983                         pNoUdmaParams->sectorCount = 0xff & nSector;
 1984                         pNoUdmaParams->device = (MV_U8)(0x40 |
 1985                                 ((Lba & 0xf000000) >> 24));
 1986                         pNoUdmaParams->callBack = CommandCompletionCB;
 1987                         result = mvSataQueueCommand(pMvSataAdapter, channel, &commandInfo);
 1988                         /*FIXME: how about the commands already queued? but marvel also forgets to consider this*/
 1989                         if (result != MV_QUEUE_COMMAND_RESULT_OK){
 1990                                 goto queue_failed;
 1991                         }
 1992                 }
 1993                 break;
 1994         default:
 1995                 pCmd->Result = RETURN_INVALID_REQUEST;
 1996                 CallAfterReturn(_VBUS_P (DPC_PROC)pCmd->pfnCompletion, pCmd);
 1997                 break;
 1998         }
 1999 }
 2000 
 2001 /**********************************************************
 2002  *
 2003  *      Probe the hostadapter.
 2004  *
 2005  **********************************************************/
 2006 static int
 2007 hpt_probe(device_t dev)
 2008 {
 2009         if ((pci_get_vendor(dev) == MV_SATA_VENDOR_ID) &&
 2010                 (pci_get_device(dev) == MV_SATA_DEVICE_ID_5081
 2011 #ifdef FOR_DEMO
 2012                 || pci_get_device(dev) == MV_SATA_DEVICE_ID_5080
 2013 #endif
 2014                 ))
 2015         {
 2016                 KdPrintI((CONTROLLER_NAME " found\n"));
 2017                 device_set_desc(dev, CONTROLLER_NAME);
 2018                 return (BUS_PROBE_DEFAULT);
 2019         }
 2020         else
 2021                 return(ENXIO);
 2022 }
 2023 
 2024 /***********************************************************
 2025  *
 2026  *      Auto configuration:  attach and init a host adapter.
 2027  *
 2028  ***********************************************************/
 2029 static int
 2030 hpt_attach(device_t dev)
 2031 {
 2032         IAL_ADAPTER_T * pAdapter = device_get_softc(dev);
 2033         int rid;
 2034         union ccb *ccb;
 2035         struct cam_devq *devq;
 2036         struct cam_sim *hpt_vsim;
 2037 
 2038         printf("%s Version %s \n", DRIVER_NAME, DRIVER_VERSION);
 2039 
 2040         if (!pAdapter)
 2041         {
 2042                 pAdapter = (IAL_ADAPTER_T *)malloc(sizeof (IAL_ADAPTER_T), M_DEVBUF, M_NOWAIT);
 2043 #if __FreeBSD_version > 410000
 2044                 device_set_softc(dev, (void *)pAdapter);
 2045 #else 
 2046                 device_set_driver(dev, (driver_t *)pAdapter);
 2047 #endif
 2048         }
 2049 
 2050         if (!pAdapter) return (ENOMEM);
 2051         bzero(pAdapter, sizeof(IAL_ADAPTER_T));
 2052 
 2053         pAdapter->hpt_dev = dev;
 2054         
 2055         rid = init_adapter(pAdapter);
 2056         if (rid)
 2057                 return rid;
 2058 
 2059         rid = 0;
 2060         if ((pAdapter->hpt_irq = bus_alloc_resource(pAdapter->hpt_dev, SYS_RES_IRQ, &rid, 0, ~0ul, 1, RF_SHAREABLE | RF_ACTIVE)) == NULL)
 2061         {
 2062                 hpt_printk(("can't allocate interrupt\n"));
 2063                 return(ENXIO);
 2064         }
 2065 
 2066 #if __FreeBSD_version <700000
 2067         if (bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM,
 2068                                 hpt_intr, pAdapter, &pAdapter->hpt_intr))
 2069 #else 
 2070         if (bus_setup_intr(pAdapter->hpt_dev, pAdapter->hpt_irq, INTR_TYPE_CAM,
 2071                                 NULL, hpt_intr, pAdapter, &pAdapter->hpt_intr))
 2072 #endif
 2073         {
 2074                 hpt_printk(("can't set up interrupt\n"));
 2075                 free(pAdapter, M_DEVBUF);
 2076                 return(ENXIO);
 2077         }
 2078 
 2079 
 2080         if((ccb = (union ccb *)malloc(sizeof(*ccb), M_DEVBUF, M_WAITOK)) != (union ccb*)NULL)
 2081         {
 2082                 bzero(ccb, sizeof(*ccb));
 2083                 ccb->ccb_h.pinfo.priority = 1;
 2084                 ccb->ccb_h.pinfo.index = CAM_UNQUEUED_INDEX;
 2085         }
 2086         else
 2087         {
 2088                 return ENOMEM;
 2089         }
 2090         /*
 2091          * Create the device queue for our SIM(s).
 2092          */
 2093         if((devq = cam_simq_alloc(8/*MAX_QUEUE_COMM*/)) == NULL)
 2094         {
 2095                 KdPrint(("ENXIO\n"));
 2096                 return ENOMEM;
 2097         }
 2098 
 2099         /*
 2100          * Construct our SIM entry
 2101          */
 2102 #if __FreeBSD_version <700000
 2103         hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll, __str(PROC_DIR_NAME),
 2104                         pAdapter, device_get_unit(pAdapter->hpt_dev), 1, 8, devq);
 2105 #else 
 2106         hpt_vsim = cam_sim_alloc(hpt_action, hpt_poll, __str(PROC_DIR_NAME),
 2107                         pAdapter, device_get_unit(pAdapter->hpt_dev), &Giant, 1, 8, devq);
 2108 #endif
 2109         if (hpt_vsim == NULL) {
 2110                 cam_simq_free(devq);
 2111                 return ENOMEM;
 2112         }
 2113 
 2114 #if __FreeBSD_version <700000
 2115         if (xpt_bus_register(hpt_vsim, 0) != CAM_SUCCESS)
 2116 #else 
 2117         if (xpt_bus_register(hpt_vsim, dev, 0) != CAM_SUCCESS)
 2118 #endif
 2119         {
 2120                 cam_sim_free(hpt_vsim, /*free devq*/ TRUE);
 2121                 hpt_vsim = NULL;
 2122                 return ENXIO;
 2123         }
 2124 
 2125         if(xpt_create_path(&pAdapter->path, /*periph */ NULL,
 2126                         cam_sim_path(hpt_vsim), CAM_TARGET_WILDCARD,
 2127                         CAM_LUN_WILDCARD) != CAM_REQ_CMP)
 2128         {
 2129                 xpt_bus_deregister(cam_sim_path(hpt_vsim));
 2130                 cam_sim_free(hpt_vsim, /*free_devq*/TRUE);
 2131                 hpt_vsim = NULL;
 2132                 return ENXIO;
 2133         }
 2134 
 2135         xpt_setup_ccb(&(ccb->ccb_h), pAdapter->path, /*priority*/5);
 2136         ccb->ccb_h.func_code = XPT_SASYNC_CB;
 2137         ccb->csa.event_enable = AC_LOST_DEVICE;
 2138         ccb->csa.callback = hpt_async;
 2139         ccb->csa.callback_arg = hpt_vsim;
 2140         xpt_action((union ccb *)ccb);
 2141         free(ccb, M_DEVBUF);
 2142 
 2143         if (device_get_unit(dev) == 0) {
 2144                 /* Start the work thread.  XXX */
 2145                 launch_worker_thread();
 2146         }
 2147 
 2148         return 0;
 2149 }
 2150 
 2151 static int
 2152 hpt_detach(device_t dev)
 2153 {       
 2154         return (EBUSY);
 2155 }
 2156 
 2157 
 2158 /***************************************************************
 2159  * The poll function is used to simulate the interrupt when
 2160  * the interrupt subsystem is not functioning.
 2161  *
 2162  ***************************************************************/
 2163 static void
 2164 hpt_poll(struct cam_sim *sim)
 2165 {
 2166         hpt_intr((void *)cam_sim_softc(sim));
 2167 }
 2168 
 2169 /****************************************************************
 2170  *      Name:   hpt_intr
 2171  *      Description:    Interrupt handler.
 2172  ****************************************************************/
 2173 static void
 2174 hpt_intr(void *arg)
 2175 {
 2176         IAL_ADAPTER_T *pAdapter = (IAL_ADAPTER_T *)arg;
 2177         intrmask_t oldspl = lock_driver();
 2178         
 2179         /* KdPrintI(("----- Entering Isr() -----\n")); */
 2180         if (mvSataInterruptServiceRoutine(&pAdapter->mvSataAdapter) == MV_TRUE)
 2181         {
 2182                 _VBUS_INST(&pAdapter->VBus)
 2183                 CheckPendingCall(_VBUS_P0);
 2184         }
 2185 
 2186         /* KdPrintI(("----- Leaving Isr() -----\n")); */
 2187         unlock_driver(oldspl);
 2188 }
 2189 
 2190 /**********************************************************
 2191  *                      Asynchronous Events
 2192  *********************************************************/
 2193 #if (!defined(UNREFERENCED_PARAMETER))
 2194 #define UNREFERENCED_PARAMETER(x) (void)(x)
 2195 #endif
 2196 
 2197 static void
 2198 hpt_async(void * callback_arg, u_int32_t code, struct cam_path * path,
 2199     void * arg)
 2200 {
 2201         /* debug XXXX */
 2202         panic("Here");
 2203         UNREFERENCED_PARAMETER(callback_arg);
 2204         UNREFERENCED_PARAMETER(code);
 2205         UNREFERENCED_PARAMETER(path);
 2206         UNREFERENCED_PARAMETER(arg);
 2207 
 2208 }
 2209 
 2210 static void
 2211 FlushAdapter(IAL_ADAPTER_T *pAdapter)
 2212 {
 2213         int i;
 2214 
 2215         hpt_printk(("flush all devices\n"));
 2216         
 2217         /* flush all devices */
 2218         for (i=0; i<MAX_VDEVICE_PER_VBUS; i++) {
 2219                 PVDevice pVDev = pAdapter->VBus.pVDevice[i];
 2220                 if(pVDev) fFlushVDev(pVDev);
 2221         }
 2222 }
 2223 
 2224 static int
 2225 hpt_shutdown(device_t dev)
 2226 {
 2227                 IAL_ADAPTER_T *pAdapter;
 2228         
 2229                 pAdapter = device_get_softc(dev);
 2230                 if (pAdapter == NULL)
 2231                         return (EINVAL);
 2232 
 2233                 EVENTHANDLER_DEREGISTER(shutdown_final, pAdapter->eh);
 2234                 FlushAdapter(pAdapter);
 2235                   /* give the flush some time to happen, 
 2236                     *otherwise "shutdown -p now" will make file system corrupted */
 2237                 DELAY(1000 * 1000 * 5);
 2238                 return 0;
 2239 }
 2240 
 2241 void
 2242 Check_Idle_Call(IAL_ADAPTER_T *pAdapter)
 2243 {
 2244         _VBUS_INST(&pAdapter->VBus)
 2245 
 2246         if (mWaitingForIdle(_VBUS_P0)) {
 2247                 CheckIdleCall(_VBUS_P0);
 2248 #ifdef SUPPORT_ARRAY
 2249                 {
 2250                         int i;
 2251                         PVDevice pArray;
 2252                         for(i = 0; i < MAX_ARRAY_PER_VBUS; i++){
 2253                                 if ((pArray=ArrayTables(i))->u.array.dArStamp==0) 
 2254                                         continue; 
 2255                                 else if (pArray->u.array.rf_auto_rebuild) {
 2256                                                 KdPrint(("auto rebuild.\n"));
 2257                                                 pArray->u.array.rf_auto_rebuild = 0;
 2258                                                 hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapter, pArray, DUPLICATE);
 2259                                 }
 2260                         }
 2261                 }
 2262 #endif
 2263         }
 2264         /* launch the awaiting commands blocked by mWaitingForIdle */
 2265         while(pAdapter->pending_Q!= NULL)
 2266         {
 2267                 _VBUS_INST(&pAdapter->VBus)
 2268                 union ccb *ccb = (union ccb *)pAdapter->pending_Q->ccb_h.ccb_ccb_ptr;
 2269                 hpt_free_ccb(&pAdapter->pending_Q, ccb);
 2270                 CallAfterReturn(_VBUS_P (DPC_PROC)OsSendCommand, ccb);
 2271         }
 2272 }
 2273 
 2274 static void
 2275 ccb_done(union ccb *ccb)
 2276 {
 2277         PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter;
 2278         IAL_ADAPTER_T * pAdapter = pmap->pAdapter;
 2279         KdPrintI(("ccb_done: ccb %p status %x\n", ccb, ccb->ccb_h.status));
 2280 
 2281         dmamap_put(pmap);
 2282         xpt_done(ccb);
 2283 
 2284         pAdapter->outstandingCommands--;
 2285 
 2286         if (pAdapter->outstandingCommands == 0)
 2287         {
 2288                 if(DPC_Request_Nums == 0)
 2289                         Check_Idle_Call(pAdapter);
 2290         }
 2291 }
 2292 
 2293 /****************************************************************
 2294  *      Name:   hpt_action
 2295  *      Description:    Process a queued command from the CAM layer.
 2296  *      Parameters:             sim - Pointer to SIM object
 2297  *                                      ccb - Pointer to SCSI command structure.
 2298  ****************************************************************/
 2299 
 2300 void
 2301 hpt_action(struct cam_sim *sim, union ccb *ccb)
 2302 {
 2303         intrmask_t oldspl;
 2304         IAL_ADAPTER_T * pAdapter = (IAL_ADAPTER_T *) cam_sim_softc(sim);
 2305         PBUS_DMAMAP  pmap;
 2306         _VBUS_INST(&pAdapter->VBus)
 2307 
 2308         CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("hpt_action\n"));
 2309         KdPrint(("hpt_action(%lx,%lx{%x})\n", (u_long)sim, (u_long)ccb, ccb->ccb_h.func_code));
 2310 
 2311         switch (ccb->ccb_h.func_code)
 2312         {
 2313                 case XPT_SCSI_IO:       /* Execute the requested I/O operation */
 2314                 {
 2315                         /* ccb->ccb_h.path_id is not our bus id - don't check it */
 2316 
 2317                         if (ccb->ccb_h.target_lun)      {
 2318                                 ccb->ccb_h.status = CAM_LUN_INVALID;
 2319                                 xpt_done(ccb);
 2320                                 return;
 2321                         }
 2322                         if (ccb->ccb_h.target_id >= MAX_VDEVICE_PER_VBUS ||
 2323                                 pAdapter->VBus.pVDevice[ccb->ccb_h.target_id]==0) {
 2324                                 ccb->ccb_h.status = CAM_TID_INVALID;
 2325                                 xpt_done(ccb);
 2326                                 return;
 2327                         }
 2328 
 2329                         oldspl = lock_driver();
 2330                         if (pAdapter->outstandingCommands==0 && DPC_Request_Nums==0)
 2331                                 Check_Idle_Call(pAdapter);
 2332 
 2333                         pmap = dmamap_get(pAdapter);
 2334                         HPT_ASSERT(pmap);
 2335                         ccb->ccb_adapter = pmap;
 2336                         memset((void *)pmap->psg, 0,  sizeof(pmap->psg));
 2337 
 2338                         if (mWaitingForIdle(_VBUS_P0))
 2339                                 hpt_queue_ccb(&pAdapter->pending_Q, ccb);
 2340                         else
 2341                                 OsSendCommand(_VBUS_P ccb);
 2342                         unlock_driver(oldspl);
 2343 
 2344                         /* KdPrint(("leave scsiio\n")); */
 2345                         break;
 2346                 }
 2347 
 2348                 case XPT_RESET_BUS:
 2349                         KdPrint(("reset bus\n"));
 2350                         oldspl = lock_driver();
 2351                         fResetVBus(_VBUS_P0);
 2352                         unlock_driver(oldspl);
 2353                         xpt_done(ccb);
 2354                         break;
 2355 
 2356                 case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
 2357                 case XPT_EN_LUN:                /* Enable LUN as a target */
 2358                 case XPT_TARGET_IO:             /* Execute target I/O request */
 2359                 case XPT_ACCEPT_TARGET_IO:      /* Accept Host Target Mode CDB */
 2360                 case XPT_CONT_TARGET_IO:        /* Continue Host Target I/O Connection*/
 2361                 case XPT_ABORT:                 /* Abort the specified CCB */
 2362                 case XPT_TERM_IO:               /* Terminate the I/O process */
 2363                         /* XXX Implement */
 2364                         ccb->ccb_h.status = CAM_REQ_INVALID;
 2365                         xpt_done(ccb);
 2366                         break;
 2367 
 2368                 case XPT_GET_TRAN_SETTINGS:
 2369                 case XPT_SET_TRAN_SETTINGS:
 2370                         /* XXX Implement */
 2371                         ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 2372                         xpt_done(ccb);
 2373                         break;
 2374 
 2375                 case XPT_CALC_GEOMETRY:
 2376 #if __FreeBSD_version >= 500000
 2377                         cam_calc_geometry(&ccb->ccg, 1);
 2378 #else
 2379                         {
 2380                         struct    ccb_calc_geometry *ccg;
 2381                         u_int32_t size_mb;
 2382                         u_int32_t secs_per_cylinder;
 2383 
 2384                         ccg = &ccb->ccg;
 2385                         size_mb = ccg->volume_size / ((1024L * 1024L) / ccg->block_size);
 2386 
 2387                         if (size_mb > 1024 ) {
 2388                                 ccg->heads = 255;
 2389                                 ccg->secs_per_track = 63;
 2390                         } else {
 2391                                 ccg->heads = 64;
 2392                                 ccg->secs_per_track = 32;
 2393                         }
 2394                         secs_per_cylinder = ccg->heads * ccg->secs_per_track;
 2395                         ccg->cylinders = ccg->volume_size / secs_per_cylinder;
 2396                         ccb->ccb_h.status = CAM_REQ_CMP;
 2397                         }
 2398 #endif
 2399                         xpt_done(ccb);
 2400                         break;
 2401 
 2402                 case XPT_PATH_INQ:              /* Path routing inquiry */
 2403                 {
 2404                         struct ccb_pathinq *cpi = &ccb->cpi;
 2405 
 2406                         cpi->version_num = 1; /* XXX??? */
 2407                         cpi->hba_inquiry = PI_SDTR_ABLE;
 2408                         cpi->target_sprt = 0;
 2409                         /* Not necessary to reset bus */
 2410                         cpi->hba_misc = PIM_NOBUSRESET;
 2411                         cpi->hba_eng_cnt = 0;
 2412 
 2413                         cpi->max_target = MAX_VDEVICE_PER_VBUS;
 2414                         cpi->max_lun = 0;
 2415                         cpi->initiator_id = MAX_VDEVICE_PER_VBUS;
 2416 
 2417                         cpi->bus_id = cam_sim_bus(sim);
 2418                         cpi->base_transfer_speed = 3300;
 2419                         strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 2420                         strncpy(cpi->hba_vid, "HPT   ", HBA_IDLEN);
 2421                         strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
 2422                         cpi->unit_number = cam_sim_unit(sim);
 2423                         cpi->transport = XPORT_SPI;
 2424                         cpi->transport_version = 2;
 2425                         cpi->protocol = PROTO_SCSI;
 2426                         cpi->protocol_version = SCSI_REV_2;
 2427                         cpi->ccb_h.status = CAM_REQ_CMP;
 2428                         xpt_done(ccb);
 2429                         break;
 2430                 }
 2431 
 2432                 default:
 2433                         KdPrint(("invalid cmd\n"));
 2434                         ccb->ccb_h.status = CAM_REQ_INVALID;
 2435                         xpt_done(ccb);
 2436                         break;
 2437         }
 2438         /* KdPrint(("leave hpt_action..............\n")); */
 2439 }
 2440 
 2441 /* shall be called at lock_driver() */
 2442 static void
 2443 hpt_queue_ccb(union ccb **ccb_Q, union ccb *ccb)
 2444 {
 2445         if(*ccb_Q == NULL)
 2446                 ccb->ccb_h.ccb_ccb_ptr = ccb;
 2447         else {
 2448                 ccb->ccb_h.ccb_ccb_ptr = (*ccb_Q)->ccb_h.ccb_ccb_ptr;
 2449                 (*ccb_Q)->ccb_h.ccb_ccb_ptr = (char *)ccb;
 2450         }
 2451 
 2452         *ccb_Q = ccb;
 2453 }
 2454 
 2455 /* shall be called at lock_driver() */
 2456 static void
 2457 hpt_free_ccb(union ccb **ccb_Q, union ccb *ccb)
 2458 {
 2459         union ccb *TempCCB;
 2460 
 2461         TempCCB = *ccb_Q;
 2462 
 2463         if(ccb->ccb_h.ccb_ccb_ptr == ccb) /*it means SCpnt is the last one in CURRCMDs*/
 2464                 *ccb_Q = NULL;
 2465         else {
 2466                 while(TempCCB->ccb_h.ccb_ccb_ptr != (char *)ccb)
 2467                         TempCCB = (union ccb *)TempCCB->ccb_h.ccb_ccb_ptr;
 2468 
 2469                 TempCCB->ccb_h.ccb_ccb_ptr = ccb->ccb_h.ccb_ccb_ptr;
 2470 
 2471                 if(*ccb_Q == ccb)
 2472                         *ccb_Q = TempCCB;
 2473         }
 2474 }
 2475 
 2476 #ifdef SUPPORT_ARRAY
 2477 /***************************************************************************
 2478  * Function:     hpt_worker_thread
 2479  * Description:  Do background rebuilding. Execute in kernel thread context.
 2480  * Returns:      None
 2481  ***************************************************************************/
 2482 static void hpt_worker_thread(void)
 2483 {
 2484         intrmask_t oldspl;
 2485 
 2486         for(;;) {
 2487                 while (DpcQueue_First!=DpcQueue_Last) {
 2488                         ST_HPT_DPC p;
 2489                         oldspl = lock_driver();
 2490                         p = DpcQueue[DpcQueue_First];
 2491                         DpcQueue_First++;
 2492                         DpcQueue_First %= MAX_DPC;
 2493                         DPC_Request_Nums++;
 2494                         unlock_driver(oldspl);
 2495                         p.dpc(p.pAdapter, p.arg, p.flags);
 2496 
 2497                         oldspl = lock_driver();
 2498                         DPC_Request_Nums--;
 2499                         /* since we may have prevented Check_Idle_Call, do it here */
 2500                         if (DPC_Request_Nums==0) {
 2501                                 if (p.pAdapter->outstandingCommands == 0) {
 2502                                         _VBUS_INST(&p.pAdapter->VBus);
 2503                                         Check_Idle_Call(p.pAdapter);
 2504                                         CheckPendingCall(_VBUS_P0);
 2505                                 }
 2506                         }
 2507                         unlock_driver(oldspl);
 2508 
 2509                         /*Schedule out*/
 2510 #if (__FreeBSD_version < 500000)
 2511                         YIELD_THREAD;
 2512 #else 
 2513 #if (__FreeBSD_version > 700033)
 2514                         pause("sched", 1);
 2515 #else
 2516                         tsleep((caddr_t)hpt_worker_thread, PPAUSE, "sched", 1); 
 2517 #endif
 2518 #endif
 2519                         if (SIGISMEMBER(curproc->p_siglist, SIGSTOP)) {
 2520                                 /* abort rebuilding process. */
 2521                                 IAL_ADAPTER_T *pAdapter;
 2522                                 PVDevice      pArray;
 2523                                 PVBus         _vbus_p;
 2524                                 int i;
 2525                                 pAdapter = gIal_Adapter;
 2526 
 2527                                 while(pAdapter != 0){
 2528 
 2529                                         _vbus_p = &pAdapter->VBus;
 2530 
 2531                                         for (i=0;i<MAX_ARRAY_PER_VBUS;i++) 
 2532                                         {
 2533                                                 if ((pArray=ArrayTables(i))->u.array.dArStamp==0) 
 2534                                                         continue; 
 2535                                                 else if (pArray->u.array.rf_rebuilding ||
 2536                                                                 pArray->u.array.rf_verifying ||
 2537                                                                 pArray->u.array.rf_initializing)
 2538                                                         {
 2539                                                                 pArray->u.array.rf_abort_rebuild = 1;
 2540                                                         }
 2541                                         }
 2542                                         pAdapter = pAdapter->next;
 2543                                 }
 2544                         }
 2545                 }
 2546 
 2547 /*Remove this debug option*/
 2548 /*
 2549 #ifdef DEBUG
 2550                 if (SIGISMEMBER(curproc->p_siglist, SIGSTOP))
 2551 #if (__FreeBSD_version > 700033)
 2552                         pause("hptrdy", 2*hz);
 2553 #else
 2554                         tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz);
 2555 #endif
 2556 #endif
 2557 */
 2558         #if (__FreeBSD_version >= 800002)
 2559                 kproc_suspend_check(curproc);
 2560         #elif (__FreeBSD_version >= 500043)
 2561                 kthread_suspend_check(curproc);
 2562         #else 
 2563                 kproc_suspend_loop(curproc);
 2564         #endif
 2565 #if (__FreeBSD_version > 700033)
 2566                 pause("hptrdy", 2*hz);  /* wait for something to do */
 2567 #else
 2568                 tsleep((caddr_t)hpt_worker_thread, PPAUSE, "hptrdy", 2*hz);  /* wait for something to do */
 2569 #endif
 2570         }
 2571 }
 2572 
 2573 static struct proc *hptdaemonproc;
 2574 static struct kproc_desc hpt_kp = {
 2575         "hpt_wt",
 2576         hpt_worker_thread,
 2577         &hptdaemonproc
 2578 };
 2579 
 2580 /*Start this thread in the hpt_attach, to prevent kernel from loading it without our controller.*/
 2581 static void
 2582 launch_worker_thread(void)
 2583 {
 2584         IAL_ADAPTER_T *pAdapTemp;
 2585         
 2586         kproc_start(&hpt_kp);
 2587 
 2588         for (pAdapTemp = gIal_Adapter; pAdapTemp; pAdapTemp = pAdapTemp->next) {
 2589 
 2590                 _VBUS_INST(&pAdapTemp->VBus)
 2591                 int i;
 2592                 PVDevice pVDev;
 2593 
 2594                 for(i = 0; i < MAX_ARRAY_PER_VBUS; i++) 
 2595                         if ((pVDev=ArrayTables(i))->u.array.dArStamp==0) 
 2596                                 continue; 
 2597                         else{
 2598                                 if (pVDev->u.array.rf_need_rebuild && !pVDev->u.array.rf_rebuilding)
 2599                                         hpt_queue_dpc((HPT_DPC)hpt_rebuild_data_block, pAdapTemp, pVDev,
 2600                                         (UCHAR)((pVDev->u.array.CriticalMembers || pVDev->VDeviceType == VD_RAID_1)? DUPLICATE : REBUILD_PARITY));
 2601                         }
 2602         }
 2603 
 2604         /*
 2605          * hpt_worker_thread needs to be suspended after shutdown sync, when fs sync finished.
 2606          */
 2607 #if (__FreeBSD_version < 500043)
 2608         EVENTHANDLER_REGISTER(shutdown_post_sync, shutdown_kproc, hptdaemonproc,
 2609             SHUTDOWN_PRI_LAST);
 2610 #else 
 2611         EVENTHANDLER_REGISTER(shutdown_post_sync, kproc_shutdown, hptdaemonproc,
 2612             SHUTDOWN_PRI_LAST);
 2613 #endif
 2614 }
 2615 /*
 2616  *SYSINIT(hptwt, SI_SUB_KTHREAD_IDLE, SI_ORDER_FIRST, launch_worker_thread, NULL);
 2617 */
 2618 
 2619 #endif
 2620 
 2621 /********************************************************************************/
 2622 
 2623 int HPTLIBAPI fOsBuildSgl(_VBUS_ARG PCommand pCmd, FPSCAT_GATH pSg, int logical)
 2624 {
 2625         union ccb *ccb = (union ccb *)pCmd->pOrgCommand;
 2626  
 2627         if (logical) {
 2628                 pSg->dSgAddress = (ULONG_PTR)(UCHAR *)ccb->csio.data_ptr;
 2629                 pSg->wSgSize = ccb->csio.dxfer_len;
 2630                 pSg->wSgFlag = SG_FLAG_EOT;
 2631                 return TRUE;
 2632         }
 2633         /* since we have provided physical sg, nobody will ask us to build physical sg */
 2634         HPT_ASSERT(0);
 2635         return FALSE;
 2636 }
 2637 
 2638 /*******************************************************************************/
 2639 ULONG HPTLIBAPI
 2640 GetStamp(void)
 2641 {
 2642         /* 
 2643          * the system variable, ticks, can't be used since it hasn't yet been active 
 2644          * when our driver starts (ticks==0, it's a invalid stamp value)
 2645          */
 2646         ULONG stamp;
 2647         do { stamp = random(); } while (stamp==0);
 2648         return stamp;
 2649 }
 2650 
 2651 
 2652 static void
 2653 SetInquiryData(PINQUIRYDATA inquiryData, PVDevice pVDev)
 2654 {
 2655         int i;
 2656         IDENTIFY_DATA2 *pIdentify = (IDENTIFY_DATA2*)pVDev->u.disk.mv->identifyDevice;
 2657 
 2658         inquiryData->DeviceType = T_DIRECT; /*DIRECT_ACCESS_DEVICE*/
 2659         inquiryData->AdditionalLength = (UCHAR)(sizeof(INQUIRYDATA) - 5);
 2660 #ifndef SERIAL_CMDS
 2661         inquiryData->CommandQueue = 1;
 2662 #endif
 2663 
 2664         switch(pVDev->VDeviceType) {
 2665         case VD_SINGLE_DISK:
 2666         case VD_ATAPI:
 2667         case VD_REMOVABLE:
 2668                 /* Set the removable bit, if applicable. */
 2669                 if ((pVDev->u.disk.df_removable_drive) || (pIdentify->GeneralConfiguration & 0x80))
 2670                         inquiryData->RemovableMedia = 1;
 2671 
 2672                 /* Fill in vendor identification fields. */
 2673                 for (i = 0; i < 20; i += 2) {                           
 2674                         inquiryData->VendorId[i]        = ((PUCHAR)pIdentify->ModelNumber)[i + 1];
 2675                         inquiryData->VendorId[i+1]      = ((PUCHAR)pIdentify->ModelNumber)[i];
 2676 
 2677                 }
 2678 
 2679                 /* Initialize unused portion of product id. */
 2680                 for (i = 0; i < 4; i++) inquiryData->ProductId[12+i] = ' ';
 2681 
 2682                 /* firmware revision */
 2683                 for (i = 0; i < 4; i += 2)
 2684                 {                               
 2685                         inquiryData->ProductRevisionLevel[i]    = ((PUCHAR)pIdentify->FirmwareRevision)[i+1];
 2686                         inquiryData->ProductRevisionLevel[i+1]  = ((PUCHAR)pIdentify->FirmwareRevision)[i];
 2687                 }
 2688                 break;
 2689         default:
 2690                 memcpy(&inquiryData->VendorId, "RR18xx  ", 8);
 2691 #ifdef SUPPORT_ARRAY
 2692                 switch(pVDev->VDeviceType){
 2693                 case VD_RAID_0:
 2694                         if ((pVDev->u.array.pMember[0] && mIsArray(pVDev->u.array.pMember[0])) ||
 2695                                 (pVDev->u.array.pMember[1] && mIsArray(pVDev->u.array.pMember[1])))
 2696                                 memcpy(&inquiryData->ProductId, "RAID 1/0 Array  ", 16);
 2697                         else
 2698                                 memcpy(&inquiryData->ProductId, "RAID 0 Array    ", 16);
 2699                         break;
 2700                 case VD_RAID_1:
 2701                         if ((pVDev->u.array.pMember[0] && mIsArray(pVDev->u.array.pMember[0])) ||
 2702                                 (pVDev->u.array.pMember[1] && mIsArray(pVDev->u.array.pMember[1])))
 2703                                 memcpy(&inquiryData->ProductId, "RAID 0/1 Array  ", 16);
 2704                         else
 2705                                 memcpy(&inquiryData->ProductId, "RAID 1 Array    ", 16);
 2706                         break;
 2707                 case VD_RAID_5:
 2708                         memcpy(&inquiryData->ProductId, "RAID 5 Array    ", 16);
 2709                         break;
 2710                 case VD_JBOD:
 2711                         memcpy(&inquiryData->ProductId, "JBOD Array      ", 16);
 2712                         break;
 2713                 }
 2714 #endif
 2715                 memcpy(&inquiryData->ProductRevisionLevel, "3.00", 4);
 2716                 break;
 2717         }
 2718 }
 2719 
 2720 static void
 2721 hpt_timeout(void *arg)
 2722 {
 2723         _VBUS_INST(&((PBUS_DMAMAP)((union ccb *)arg)->ccb_adapter)->pAdapter->VBus)
 2724         intrmask_t oldspl = lock_driver();
 2725         fResetVBus(_VBUS_P0);
 2726         unlock_driver(oldspl);
 2727 }
 2728 
 2729 static void 
 2730 hpt_io_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 2731 {
 2732         PCommand pCmd = (PCommand)arg;
 2733         union ccb *ccb = pCmd->pOrgCommand;
 2734         struct ccb_hdr *ccb_h = &ccb->ccb_h;
 2735         PBUS_DMAMAP pmap = (PBUS_DMAMAP) ccb->ccb_adapter;
 2736         IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
 2737         PVDevice        pVDev = pAdapter->VBus.pVDevice[ccb_h->target_id];
 2738         FPSCAT_GATH psg = pCmd->pSgTable;
 2739         int idx;
 2740         _VBUS_INST(pVDev->pVBus)
 2741 
 2742         HPT_ASSERT(pCmd->cf_physical_sg);
 2743                 
 2744         if (error)
 2745                 panic("busdma error");
 2746                 
 2747         HPT_ASSERT(nsegs<= MAX_SG_DESCRIPTORS);
 2748 
 2749         if (nsegs != 0) {
 2750                 for (idx = 0; idx < nsegs; idx++, psg++) {
 2751                         psg->dSgAddress = (ULONG_PTR)(UCHAR *)segs[idx].ds_addr;
 2752                         psg->wSgSize = segs[idx].ds_len;
 2753                         psg->wSgFlag = (idx == nsegs-1)? SG_FLAG_EOT: 0;
 2754         /*              KdPrint(("psg[%d]:add=%p,size=%x,flag=%x\n", idx, psg->dSgAddress,psg->wSgSize,psg->wSgFlag)); */
 2755                 }
 2756                 /*      psg[-1].wSgFlag = SG_FLAG_EOT; */
 2757                 
 2758                 if (pCmd->cf_data_in) {
 2759                         bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map,
 2760                             BUS_DMASYNC_PREREAD);
 2761                 }
 2762                 else if (pCmd->cf_data_out) {
 2763                         bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map,
 2764                             BUS_DMASYNC_PREWRITE);
 2765                 }
 2766         }
 2767 
 2768         ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz);
 2769         pVDev->pfnSendCommand(_VBUS_P pCmd);
 2770         CheckPendingCall(_VBUS_P0);
 2771 }
 2772 
 2773 
 2774 
 2775 static void HPTLIBAPI
 2776 OsSendCommand(_VBUS_ARG union ccb *ccb)
 2777 {
 2778         PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter;
 2779         IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
 2780         struct ccb_hdr *ccb_h = &ccb->ccb_h;
 2781         struct ccb_scsiio *csio = &ccb->csio;
 2782         PVDevice        pVDev = pAdapter->VBus.pVDevice[ccb_h->target_id];
 2783 
 2784         KdPrintI(("OsSendCommand: ccb %p  cdb %x-%x-%x\n",
 2785                 ccb,
 2786                 *(ULONG *)&ccb->csio.cdb_io.cdb_bytes[0],
 2787                 *(ULONG *)&ccb->csio.cdb_io.cdb_bytes[4],
 2788                 *(ULONG *)&ccb->csio.cdb_io.cdb_bytes[8]
 2789         ));
 2790 
 2791         pAdapter->outstandingCommands++;
 2792 
 2793         if (pVDev == NULL || pVDev->vf_online == 0) {
 2794                 ccb->ccb_h.status = CAM_REQ_INVALID;
 2795                 ccb_done(ccb);
 2796                 goto Command_Complished;
 2797         }
 2798 
 2799         switch(ccb->csio.cdb_io.cdb_bytes[0])
 2800         {
 2801                 case TEST_UNIT_READY:
 2802                 case START_STOP_UNIT:
 2803                 case SYNCHRONIZE_CACHE:
 2804                         /* FALLTHROUGH */
 2805                         ccb->ccb_h.status = CAM_REQ_CMP;
 2806                         break;
 2807 
 2808                 case INQUIRY:
 2809                         ZeroMemory(ccb->csio.data_ptr, ccb->csio.dxfer_len);
 2810                         SetInquiryData((PINQUIRYDATA)ccb->csio.data_ptr, pVDev);
 2811                         ccb_h->status = CAM_REQ_CMP;
 2812                         break;
 2813 
 2814                 case READ_CAPACITY:
 2815                 {               
 2816                         UCHAR *rbuf=csio->data_ptr;
 2817                         unsigned int cap;
 2818 
 2819                         if (pVDev->VDeviceCapacity > 0xfffffffful) {
 2820                                 cap = 0xfffffffful;
 2821                         } else {
 2822                                 cap = pVDev->VDeviceCapacity - 1;
 2823                         }
 2824 
 2825                         rbuf[0] = (UCHAR)(cap>>24);
 2826                         rbuf[1] = (UCHAR)(cap>>16);
 2827                         rbuf[2] = (UCHAR)(cap>>8);
 2828                         rbuf[3] = (UCHAR)cap;
 2829                         /* Claim 512 byte blocks (big-endian). */
 2830                         rbuf[4] = 0;
 2831                         rbuf[5] = 0;
 2832                         rbuf[6] = 2;
 2833                         rbuf[7] = 0;
 2834                         
 2835                         ccb_h->status = CAM_REQ_CMP;
 2836                         break;
 2837                 }
 2838 
 2839                 case 0x9e: /*SERVICE_ACTION_IN*/ 
 2840                 {
 2841                         UCHAR *rbuf = csio->data_ptr;
 2842                         LBA_T cap = pVDev->VDeviceCapacity - 1;
 2843                         
 2844                         rbuf[0] = (UCHAR)(cap>>56);
 2845                         rbuf[1] = (UCHAR)(cap>>48);
 2846                         rbuf[2] = (UCHAR)(cap>>40);
 2847                         rbuf[3] = (UCHAR)(cap>>32);
 2848                         rbuf[4] = (UCHAR)(cap>>24);
 2849                         rbuf[5] = (UCHAR)(cap>>16);
 2850                         rbuf[6] = (UCHAR)(cap>>8);
 2851                         rbuf[7] = (UCHAR)cap;
 2852                         rbuf[8] = 0;
 2853                         rbuf[9] = 0;
 2854                         rbuf[10] = 2;
 2855                         rbuf[11] = 0;
 2856                         
 2857                         ccb_h->status = CAM_REQ_CMP;
 2858                         break;  
 2859                 }
 2860 
 2861                 case READ_6:
 2862                 case WRITE_6:
 2863                 case READ_10:
 2864                 case WRITE_10:
 2865                 case 0x88: /* READ_16 */
 2866                 case 0x8a: /* WRITE_16 */
 2867                 case 0x13:
 2868                 case 0x2f:
 2869                 {
 2870                         UCHAR Cdb[16];
 2871                         UCHAR CdbLength;
 2872                         _VBUS_INST(pVDev->pVBus)
 2873                         PCommand pCmd = AllocateCommand(_VBUS_P0);
 2874                         int error;
 2875                         HPT_ASSERT(pCmd);
 2876 
 2877                         CdbLength = csio->cdb_len;
 2878                         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0)
 2879                         {
 2880                                 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0)
 2881                                 {
 2882                                         bcopy(csio->cdb_io.cdb_ptr, Cdb, CdbLength);
 2883                                 }
 2884                                 else
 2885                                 {
 2886                                         KdPrintE(("ERROR!!!\n"));
 2887                                         ccb->ccb_h.status = CAM_REQ_INVALID;
 2888                                         break;
 2889                                 }
 2890                         }
 2891                         else
 2892                         {
 2893                                 bcopy(csio->cdb_io.cdb_bytes, Cdb, CdbLength);
 2894                         }
 2895 
 2896                         pCmd->pOrgCommand = ccb;
 2897                         pCmd->pVDevice = pVDev;
 2898                         pCmd->pfnCompletion = fOsCommandDone;
 2899                         pCmd->pfnBuildSgl = fOsBuildSgl;
 2900                         pCmd->pSgTable = pmap->psg;
 2901 
 2902                         switch (Cdb[0])
 2903                         {
 2904                                 case READ_6:
 2905                                 case WRITE_6:
 2906                                 case 0x13:
 2907                                         pCmd->uCmd.Ide.Lba =  ((ULONG)Cdb[1] << 16) | ((ULONG)Cdb[2] << 8) | (ULONG)Cdb[3];
 2908                                         pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[4];
 2909                                         break;
 2910 
 2911                                 case 0x88: /* READ_16 */
 2912                                 case 0x8a: /* WRITE_16 */
 2913                                         pCmd->uCmd.Ide.Lba = 
 2914                                                 (HPT_U64)Cdb[2] << 56 |
 2915                                                 (HPT_U64)Cdb[3] << 48 |
 2916                                                 (HPT_U64)Cdb[4] << 40 |
 2917                                                 (HPT_U64)Cdb[5] << 32 |
 2918                                                 (HPT_U64)Cdb[6] << 24 |
 2919                                                 (HPT_U64)Cdb[7] << 16 |
 2920                                                 (HPT_U64)Cdb[8] << 8 |
 2921                                                 (HPT_U64)Cdb[9];
 2922                                         pCmd->uCmd.Ide.nSectors = (USHORT)Cdb[12] << 8 | (USHORT)Cdb[13];
 2923                                         break;
 2924                                         
 2925                                 default:
 2926                                         pCmd->uCmd.Ide.Lba = (ULONG)Cdb[5] | ((ULONG)Cdb[4] << 8) | ((ULONG)Cdb[3] << 16) | ((ULONG)Cdb[2] << 24);
 2927                                         pCmd->uCmd.Ide.nSectors = (USHORT) Cdb[8] | ((USHORT)Cdb[7]<<8);
 2928                                         break;
 2929                         }
 2930 
 2931                         switch (Cdb[0])
 2932                         {
 2933                                 case READ_6:
 2934                                 case READ_10:
 2935                                 case 0x88: /* READ_16 */
 2936                                         pCmd->uCmd.Ide.Command = IDE_COMMAND_READ;
 2937                                         pCmd->cf_data_in = 1;
 2938                                         break;
 2939 
 2940                                 case WRITE_6:
 2941                                 case WRITE_10:
 2942                                 case 0x8a: /* WRITE_16 */
 2943                                         pCmd->uCmd.Ide.Command = IDE_COMMAND_WRITE;
 2944                                         pCmd->cf_data_out = 1;
 2945                                         break;
 2946                                 case 0x13:
 2947                                 case 0x2f:
 2948                                         pCmd->uCmd.Ide.Command = IDE_COMMAND_VERIFY;
 2949                                         break;
 2950                         }
 2951 /*///////////////////////// */
 2952                         pCmd->cf_physical_sg = 1;
 2953                         error = bus_dmamap_load_ccb(pAdapter->io_dma_parent, 
 2954                                                     pmap->dma_map, 
 2955                                                     ccb,
 2956                                                     hpt_io_dmamap_callback,
 2957                                                     pCmd, BUS_DMA_WAITOK
 2958                                                     );
 2959                         KdPrint(("bus_dmamap_load return %d\n", error));
 2960                         if (error && error!=EINPROGRESS) {
 2961                                 hpt_printk(("bus_dmamap_load error %d\n", error));
 2962                                 FreeCommand(_VBUS_P pCmd);
 2963                                 ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 2964                                 dmamap_put(pmap);
 2965                                 pAdapter->outstandingCommands--;
 2966                                 xpt_done(ccb);
 2967                         }
 2968                         goto Command_Complished;
 2969                 }
 2970 
 2971                 default:
 2972                         ccb->ccb_h.status = CAM_REQ_INVALID;
 2973                         break;
 2974         }
 2975         ccb_done(ccb);
 2976 Command_Complished:
 2977         CheckPendingCall(_VBUS_P0);
 2978         return;
 2979 }
 2980 
 2981 static void HPTLIBAPI 
 2982 fOsCommandDone(_VBUS_ARG PCommand pCmd)
 2983 {
 2984         union ccb *ccb = pCmd->pOrgCommand;
 2985         PBUS_DMAMAP pmap = (PBUS_DMAMAP)ccb->ccb_adapter; 
 2986         IAL_ADAPTER_T *pAdapter = pmap->pAdapter;
 2987 
 2988         KdPrint(("fOsCommandDone(pcmd=%p, result=%d)\n", pCmd, pCmd->Result));
 2989         
 2990         untimeout(hpt_timeout, (caddr_t)ccb, ccb->ccb_h.timeout_ch);
 2991         
 2992         switch(pCmd->Result) {
 2993         case RETURN_SUCCESS:
 2994                 ccb->ccb_h.status = CAM_REQ_CMP;
 2995                 break;
 2996         case RETURN_BAD_DEVICE:
 2997                 ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 2998                 break;
 2999         case RETURN_DEVICE_BUSY:
 3000                 ccb->ccb_h.status = CAM_BUSY;
 3001                 break;
 3002         case RETURN_INVALID_REQUEST:
 3003                 ccb->ccb_h.status = CAM_REQ_INVALID;
 3004                 break;
 3005         case RETURN_SELECTION_TIMEOUT:
 3006                 ccb->ccb_h.status = CAM_SEL_TIMEOUT;
 3007                 break;
 3008         case RETURN_RETRY:
 3009                 ccb->ccb_h.status = CAM_BUSY;
 3010                 break;
 3011         default:
 3012                 ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR;
 3013                 break;
 3014         }
 3015 
 3016         if (pCmd->cf_data_in) {
 3017                 bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_POSTREAD);
 3018         }
 3019         else if (pCmd->cf_data_out) {
 3020                 bus_dmamap_sync(pAdapter->io_dma_parent, pmap->dma_map, BUS_DMASYNC_POSTWRITE);
 3021         }
 3022         
 3023         bus_dmamap_unload(pAdapter->io_dma_parent, pmap->dma_map);
 3024 
 3025         FreeCommand(_VBUS_P pCmd);
 3026         ccb_done(ccb);
 3027 }
 3028 
 3029 int
 3030 hpt_queue_dpc(HPT_DPC dpc, IAL_ADAPTER_T * pAdapter, void *arg, UCHAR flags)
 3031 {
 3032         int p;
 3033 
 3034         p = (DpcQueue_Last + 1) % MAX_DPC;
 3035         if (p==DpcQueue_First) {
 3036                 KdPrint(("DPC Queue full!\n"));
 3037                 return -1;
 3038         }
 3039 
 3040         DpcQueue[DpcQueue_Last].dpc = dpc;
 3041         DpcQueue[DpcQueue_Last].pAdapter = pAdapter;
 3042         DpcQueue[DpcQueue_Last].arg = arg;
 3043         DpcQueue[DpcQueue_Last].flags = flags;
 3044         DpcQueue_Last = p;
 3045 
 3046         return 0;
 3047 }
 3048 
 3049 #ifdef _RAID5N_
 3050 /* 
 3051  * Allocate memory above 16M, otherwise we may eat all low memory for ISA devices.
 3052  * How about the memory for 5081 request/response array and PRD table?
 3053  */
 3054 void
 3055 *os_alloc_page(_VBUS_ARG0)
 3056 { 
 3057         return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000, 0xffffffff, PAGE_SIZE, 0ul);
 3058 }
 3059 
 3060 void
 3061 *os_alloc_dma_page(_VBUS_ARG0)
 3062 {
 3063         return (void *)contigmalloc(0x1000, M_DEVBUF, M_NOWAIT, 0x1000000, 0xffffffff, PAGE_SIZE, 0ul);
 3064 }
 3065 
 3066 void
 3067 os_free_page(_VBUS_ARG void *p) 
 3068 { 
 3069         contigfree(p, 0x1000, M_DEVBUF); 
 3070 }
 3071 
 3072 void
 3073 os_free_dma_page(_VBUS_ARG void *p) 
 3074 { 
 3075         contigfree(p, 0x1000, M_DEVBUF); 
 3076 }
 3077 
 3078 void
 3079 DoXor1(ULONG *p0, ULONG *p1, ULONG *p2, UINT nBytes)
 3080 {
 3081         UINT i;
 3082         for (i = 0; i < nBytes / 4; i++) *p0++ = *p1++ ^ *p2++;
 3083 }
 3084 
 3085 void
 3086 DoXor2(ULONG *p0, ULONG *p2, UINT nBytes)
 3087 {
 3088         UINT i;
 3089         for (i = 0; i < nBytes / 4; i++) *p0++ ^= *p2++;
 3090 }
 3091 #endif

Cache object: 98fc3c112dd3c86b13d59ec670fd25d0


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.