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

Cache object: 504761969034cc43f833ab56ac6b9c17


[ 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.