c64xx_pci.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:22k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
  9. /*
  10.  *  ======== c64xx_pci.c ========
  11.  * 
  12.  *  DSP/BIOS PCI IOM mini-driver for the c64xx DSPs
  13.  *  Uses the  BIOS PCI Chip Support Library(CSL).
  14.  */
  15. #include <std.h>
  16. #include <csl_pci.h>
  17. #include <hwi.h>
  18. #include <mem.h>
  19. #include <que.h>
  20. #include <iom.h>
  21. #include <c64xx_pci.h>
  22. /* PCI Interrupt mapped to HWI Vector 4 */
  23. #define ISR_VECTOR_ID   4
  24. #define GET_BYTE_COUNT(count) 
  25.         (((count)<< 16) & C64XX_PCI_MASK_PCIMC_CNT)
  26. #define CALLBACK(chan, packet, result) { (packet)->status = (result);
  27.             ((chan)->callback)((Ptr)(chan)->callbackArg, (packet));}
  28. /* Channel variables */
  29. typedef struct ChanObj {
  30.     QUE_Handle          queue; /* priority queue */
  31.     Uns                 writeCount; /* count for number of IOM_WRITE IOPs */ 
  32.     IOM_Packet          *flushAbortIop; /* hold IOM_FLUSH/IOM_ABORT IOP */ 
  33.     /* callback used to notify client when I/O complete */ 
  34.     IOM_TiomCallback    callback;
  35.     Ptr                 callbackArg;
  36. } ChanObj, *ChanHandle;
  37. /* Device object */
  38. typedef struct PCIDeviceObj 
  39. {
  40.     IOM_Packet                  *curPacket; /* current packet in process */
  41.     QUE_Obj                     highPrioQue;
  42.     QUE_Obj                     lowPrioQue; 
  43.     C64XX_PCI_TerrCallback      errCallback; /* async error callback */
  44.     Uns                         evtMask; /* registered events ored together */ 
  45.     C64XX_PCI_ErrInfo           *errInfo; /* detailed info for async error */ 
  46.     Int                         openCount; /* count number of open channels */
  47. } PCIDeviceObj, PCIDeviceHandle;
  48. /* static device object */
  49. static PCIDeviceObj device;
  50. static Void doTransfer(C64XX_PCI_Request *request);
  51. static Void isr();
  52. #ifdef PCI_ERROR_ISR_IMPL
  53. static Void pciErrorIsr();
  54. #endif
  55. static Void processQueue();
  56. static Void removePackets(Ptr chanp, Int cmd);
  57. static Void resetChannel(Ptr chanp);
  58. static Void resetDevice();
  59. /*
  60.  * Forward declaration of mini driver interface functions. They are only 
  61.  * exposed via the IOM_Fxns function table to avoid namespace pollution.
  62.  */
  63. static Int      mdBindDev(Ptr *devp, Int devid, Ptr devParams);
  64. static Int      mdControlChan(Ptr chanp, Uns command, Ptr arg);
  65. static Int      mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  66.         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg);
  67. static Int      mdDeleteChan(Ptr chanp);
  68. static Int      mdSubmitChan(Ptr chanp, IOM_Packet* pPacket);
  69. static Int      mdUnBindDev(Ptr devp);
  70. /*
  71.  * Public mini driver interface table.
  72.  */
  73. IOM_Fxns C64XX_PCI_FXNS = {
  74.     &mdBindDev,
  75.     &mdUnBindDev,
  76.     &mdControlChan,
  77.     &mdCreateChan,
  78.     &mdDeleteChan,
  79.     &mdSubmitChan
  80. };
  81. /*
  82.  *  ======== mdBindDev ========
  83.  *  This function will init the queues, set up interrupt.
  84.  *  it does not allocate memory, so return NULL.  
  85.  */
  86. static Int mdBindDev(Ptr *devp, Int devid, Ptr devParams)
  87. {
  88.     Int intrId;
  89.     C64XX_PCI_DevParams *pciDevParams = (C64XX_PCI_DevParams *)devParams;
  90.     HWI_Attrs hwiAttrs;
  91.     QUE_new(&device.highPrioQue);
  92.     QUE_new(&device.lowPrioQue); 
  93.     
  94.     device.curPacket = NULL;
  95.     device.openCount = 0;
  96.     
  97.     if (pciDevParams != NULL) {
  98.         /* Check the version number */
  99.         if (pciDevParams->versionId != C64XX_PCI_VERSION_1){
  100.            /* Unsupported version */
  101.            return(IOM_EBADARGS);
  102.         }
  103.         if (pciDevParams->pciIntrId > 0) {
  104.            intrId = pciDevParams->pciIntrId;
  105.         }
  106.         else {
  107.            intrId = ISR_VECTOR_ID;
  108.         }
  109.         
  110.         hwiAttrs.intrMask = pciDevParams->intrMask;
  111.         if (pciDevParams->errCallback != NULL) {
  112.             device.errCallback = pciDevParams->errCallback->errFxn;
  113.             device.evtMask = pciDevParams->errCallback->evtMask;
  114.             device.errInfo = pciDevParams->errCallback->errInfo;
  115.         }
  116.         else {
  117.             device.errCallback = NULL;
  118.         }
  119. #ifdef PCI_ERROR_ISR_IMPL
  120.         /* 
  121.          *  pciErrIntrId plug in depend on board hardware design.
  122.          *  ERR_ISR_VECTOR_ID: TBD. 
  123.          */
  124.         
  125.         Int pciErrIntrId;
  126.         if (pciDevParams->pciErrIntrId > 0) {
  127.             pciErrIntrId = pciDevParams->pciErrIntrId;
  128.         }
  129.         else {
  130.             pciErrIntrId = ERR_ISR_VECTOR_ID; 
  131.         }
  132. #endif
  133.     }
  134.     else {
  135.         intrId = ISR_VECTOR_ID;
  136.         hwiAttrs.intrMask = C64XX_PCI_INTR_MASK_DEFAULT;
  137.         device.errCallback = NULL;
  138.     }
  139.     
  140.     hwiAttrs.ccMask = IRQ_CCMASK_NONE; /* the default value */
  141.     hwiAttrs.arg = NULL;
  142.     /* plug in normal pci isr routine */
  143.     IRQ_map(IRQ_EVT_DSPINT, intrId); 
  144.     /* dmachan parameter set to -1 since 6416 has EDMA instead of DMA */  
  145.     HWI_dispatchPlug(intrId, (Fxn)isr, -1, &hwiAttrs);
  146. #ifdef PCI_ERROR_ISR_IMPL
  147.     /* plug in error pci isr routine if registered. IRQ_EVT_XXX: TBD.  
  148.      * need to enable two bits in PCI Command Register: TBD 
  149.      *          bit6 - parity error reporting enable bit
  150.      *          bit8 - system error reporting ebable bit
  151.      */
  152.     IRQ_map(IRQ_EVT_XXX, pciErrIntrId); 
  153.     HWI_dispatchPlug(pciErrIntrId, (Fxn)pciErrIsr, -1, NULL);
  154.     IRQ_enable(IRQ_EVT_XXX);
  155. #endif
  156.     return (IOM_COMPLETED);
  157.     
  158. }
  159. /*
  160.  *  ======== mdControlChan ========
  161.  *  This function could be implemented by using function table, avoid complier
  162.  *  link each function and also avoid using "switch" call. 
  163.  *  return status  
  164.  */
  165. static Int mdControlChan(Ptr chanp, Uns command, Ptr arg)
  166. {
  167.     C64XX_PCI_EEPROMData *promData = (C64XX_PCI_EEPROMData *)arg;
  168.     Uns                   result; 
  169.     Uns                   imask;
  170.     
  171. #ifdef TEST_ERROR_HANDLER
  172.     Bool report;
  173.     C64XX_PCI_Request *req;
  174.     IOM_Packet *packet;
  175.     Uns error;
  176.     Uns event;
  177. #endif
  178.     
  179.     switch (command) {
  180.         /* EEPROM call. */
  181.         case C64XX_PCI_EEPROM_ERASE: 
  182.             promData->eeData = PCI_eepromErase((Uns)promData->eeAddr);
  183.             return (IOM_COMPLETED); 
  184.         case C64XX_PCI_EEPROM_ERASE_ALL:
  185.             promData->eeData = PCI_eepromEraseAll();
  186.             return (IOM_COMPLETED); 
  187.         case C64XX_PCI_EEPROM_IS_AUTO_CFG:
  188.             promData->eeData = PCI_eepromIsAutoCfg();
  189.             return (IOM_COMPLETED); 
  190.         case C64XX_PCI_EEPROM_READ:
  191.             promData->eeData = PCI_eepromRead((Uns)promData->eeAddr);
  192.             return (IOM_COMPLETED); 
  193.         case C64XX_PCI_EEPROM_SIZE:
  194.             promData->eeData = PCI_eepromSize();
  195.             return (IOM_COMPLETED); 
  196.         case C64XX_PCI_EEPROM_TEST:
  197.             promData->eeData = PCI_eepromTest();
  198.             return (IOM_COMPLETED); 
  199.         case C64XX_PCI_EEPROM_WRITE:
  200.             result = PCI_eepromWrite((Uns)promData->eeAddr, promData->eeData);
  201.             promData->eeData = result;
  202.             return (IOM_COMPLETED); 
  203.         case C64XX_PCI_EEPROM_WRITE_ALL:
  204.             result = PCI_eepromWriteAll(promData->eeData);
  205.             promData->eeData = result;
  206.             return (IOM_COMPLETED); 
  207.         /* Host interrupt call */
  208.         case C64XX_PCI_DSP_INT_REQ_SET:
  209.             PCI_dspIntReqSet();
  210.             return (IOM_COMPLETED);
  211.         case C64XX_PCI_DSP_INT_REQ_CLEAR:
  212.             PCI_dspIntReqClear();
  213.             return (IOM_COMPLETED);
  214.         /* reset calls */
  215.         case C64XX_PCI_RESET_CHANNEL:
  216.             resetChannel(chanp);
  217.             return (IOM_COMPLETED);      
  218.         case C64XX_PCI_RESET_ALL_CHANNELS:
  219.             resetDevice();
  220.             return (IOM_COMPLETED);            
  221. #ifdef TEST_ERROR_HANDLER
  222.         case C64XX_PCI_TEST_ERROR_HANDLER:
  223.     error = 0;
  224.     report = FALSE;
  225.     event = *((Uns *)arg);
  226.     imask = HWI_disable();
  227.     if (device.errCallback == NULL) {
  228.         HWI_restore(imask);
  229.         return (IOM_COMPLETED);        
  230.     }
  231.     if ((event == C64XX_PCI_EVT_PARITY_ERR) && 
  232.             (device.evtMask & C64XX_PCI_EVT_PARITY_ERR)) {
  233.         error = error | C64XX_PCI_EVT_PARITY_ERR;
  234.         report = TRUE;
  235.     } 
  236.     else if ((event == C64XX_PCI_EVT_SYSTEM_ERR) && 
  237.             (device.evtMask & C64XX_PCI_EVT_SYSTEM_ERR)) {
  238.         error = error | C64XX_PCI_EVT_SYSTEM_ERR;
  239.         report = TRUE;
  240.     } 
  241.     if (!report) {
  242.         HWI_restore(imask);
  243.         return (IOM_COMPLETED);
  244.     }
  245.     if (device.curPacket != NULL) {
  246.         packet = device.curPacket;
  247.         req = (C64XX_PCI_Request *)packet->addr;
  248.         device.errInfo->inprogressDstAddr = req->dstAddr;
  249.         device.errInfo->inprogressSrcAddr = req->srcAddr;
  250.         /* device.errInfo->statusReg = PCI_STATUS_REGISTER; */
  251.     } 
  252.     else {
  253.         device.errInfo->inprogressDstAddr = NULL;
  254.         device.errInfo->inprogressSrcAddr = NULL;
  255.         /* device.errInfo->statusReg = PCI_STATUS_REGISTER; */
  256.     }
  257.     (device.errCallback)(error, (Ptr)device.errInfo);
  258.     HWI_restore(imask);
  259.     return (IOM_COMPLETED);
  260. #endif 
  261.         default:
  262.             break;
  263.     }
  264.     
  265.     return (IOM_ENOTIMPL);      
  266. }
  267. /*
  268.  *  ======== mdCreateChan ========
  269.  *  This function allocates memory for channel object and initializes it.
  270.  *  return IOM_COMPLETED if success return IOM_EALLOC if fails
  271.  */
  272. static Int mdCreateChan(Ptr *chanp, Ptr devp, String name, Int mode,
  273.         Ptr chanParams, IOM_TiomCallback cbFxn, Ptr cbArg)
  274. {
  275.     ChanHandle          chan;   
  276.     C64XX_PCI_Attrs     *pciAttrs = (C64XX_PCI_Attrs *)chanParams;
  277.     Uns                 imask;
  278.     
  279.     chan = MEM_alloc(0, sizeof(ChanObj), 0);
  280.     if ( chan == MEM_ILLEGAL ) { 
  281.         return (IOM_EALLOC);
  282.     }
  283.   
  284.     if (mode != IOM_INOUT) {
  285.         return (IOM_EBADMODE);
  286.     }
  287.     /* Initialize the channel structure */
  288.     if ( pciAttrs != NULL && 
  289.             pciAttrs->queuePriority == C64XX_PCI_QUEUE_PRIORITY_HIGH) {
  290.         chan->queue = &device.highPrioQue;
  291.     }
  292.     else {
  293.         chan->queue = &device.lowPrioQue;    
  294.     }
  295.     
  296.     chan->writeCount = 0;
  297.     chan->flushAbortIop = NULL;
  298.     chan->callback = cbFxn;
  299.     chan->callbackArg = cbArg; 
  300.          
  301.     imask = HWI_disable();
  302.     if (device.openCount == 0) {
  303.         /* enable PCI events */
  304.         PCI_intEnable(PCI_EVT_PCIMASTER);
  305.         PCI_intEnable(PCI_EVT_PCITARGET);
  306.         PCI_intEnable(PCI_EVT_MASTEROK);
  307.         IRQ_enable(IRQ_EVT_DSPINT);
  308.     }
  309.     device.openCount++;
  310.     HWI_restore(imask);
  311.     *chanp = chan;
  312.     return (IOM_COMPLETED);
  313. }
  314. /*
  315.  *  ======== mdDeleteChan ========
  316.  *  frees memory
  317.  *  return status
  318.  */
  319. static Int mdDeleteChan(Ptr chanp)
  320. {
  321.     ChanHandle  chan = (ChanHandle)chanp;
  322.     Uns                 imask;
  323.     MEM_free(0, chan, sizeof(ChanObj));
  324.     imask = HWI_disable();
  325.     device.openCount--;
  326.     if (device.openCount == 0) {
  327.         /* disable PCI events */
  328.         PCI_intDisable(PCI_EVT_PCIMASTER);
  329.         PCI_intDisable(PCI_EVT_PCITARGET);
  330.         PCI_intDisable(PCI_EVT_MASTEROK);
  331.         IRQ_disable(IRQ_EVT_DSPINT);
  332.     }
  333.     HWI_restore(imask);
  334.     return (IOM_COMPLETED); 
  335. }
  336. /*
  337.  *  ======== mdSubmitChan ========
  338.  *  return submit status
  339.  */
  340. static Int mdSubmitChan(Ptr chanp, IOM_Packet *pPacket)
  341. {
  342.     ChanHandle          chan = (ChanHandle)chanp;
  343.     IOM_Packet*         packet = pPacket;
  344.     Uns                 imask;
  345.     C64XX_PCI_Request  *req;    
  346.     C64XX_PCI_Request  *curReq; 
  347.     req = (C64XX_PCI_Request *)packet->addr;
  348.     req->reserved = chan;
  349.     
  350.     /* IOM_READ or IOM_WRITE command handle in the same way */ 
  351.     if (packet->cmd == IOM_READ || packet->cmd == IOM_WRITE) {
  352.         imask = HWI_disable();
  353.         QUE_enqueue(chan->queue, packet);
  354.         if (device.curPacket == NULL) {
  355. #ifndef TEST_RESET
  356.             processQueue();
  357. #endif
  358.         }
  359.         HWI_restore(imask);
  360.         return (IOM_PENDING);
  361.     } 
  362.     if (packet->cmd == IOM_FLUSH || packet->cmd == IOM_ABORT) { 
  363.         
  364.         imask = HWI_disable();
  365.         chan->flushAbortIop = packet;
  366.         /* check the channel of pending packet */ 
  367.         if (device.curPacket != NULL) {
  368.                 curReq = (C64XX_PCI_Request *)device.curPacket->addr;
  369.             /* The pending packet is this channel. Let isr handles it */
  370.             if ((ChanHandle)curReq->reserved == chan) {
  371.                 HWI_restore(imask);         
  372.                 return (IOM_PENDING);
  373.             } 
  374.         }         
  375.         
  376.         /* the pending packet is not FLUSH/ABORT channel */
  377.         removePackets(chan, packet->cmd);
  378.         /* FLUSH/ABORT done */
  379.         if (chan->writeCount == 0) {
  380.             chan->flushAbortIop = NULL;
  381.             HWI_restore(imask); 
  382.             return (IOM_COMPLETED);
  383.         }                   
  384.         HWI_restore(imask);         
  385.         return (IOM_PENDING);
  386.     }   
  387.     return (IOM_EBADIO); 
  388. }
  389. /*
  390.  *  ======== mdUnBindDev ========
  391.  *  return status
  392.  */
  393. static Int mdUnBindDev(Ptr devp)
  394. {
  395.     /* empty for now */
  396.     return (IOM_COMPLETED);
  397. }
  398. /*
  399.  *  ======== C64XX_PCI_init ========
  400.  */
  401. Void C64XX_PCI_init(Void)
  402. {
  403.     /* empty for now */
  404. }
  405. /*
  406.  *  ======== isr ========
  407.  *  interrupt service routine is runtime pluged in
  408.  */
  409. static Void isr(Void)
  410. {
  411.     ChanHandle          chan;
  412.     IOM_Packet          *oldPacket;
  413.     C64XX_PCI_Request   *oldReq;         
  414.     Int                 status = IOM_EBADIO;
  415.     
  416.     if (PCI_FGET(PCIIS, MASTEROK)) {
  417.         /* pci master transfer complete */       
  418.         PCI_FSET(PCIIS, MASTEROK, 1);
  419.         status = IOM_COMPLETED;
  420.         
  421.     } 
  422.     else if (PCI_FGET(PCIIS, PCIMASTER)) { 
  423.         /* pci master abort */
  424.         PCI_FSET(PCIIS, PCIMASTER, 1);
  425.         
  426.     } 
  427.     else if (PCI_FGET(PCIIS, PCITARGET)) {
  428.         /* pci target abort */
  429.         PCI_FSET(PCIIS, PCITARGET, 1);
  430.         
  431.     } 
  432.     else {
  433.         /* not registered interrupt, clear intr here */
  434.         PCI_RSET(PCIIS, 0x00000FFF);
  435.         /* error handling TBD */
  436.         return;
  437.     }
  438.     if (device.curPacket != NULL) {
  439.         oldPacket = device.curPacket;
  440.         oldReq = (C64XX_PCI_Request *)oldPacket->addr; 
  441.         chan = (ChanHandle)oldReq->reserved;
  442.          
  443.         device.curPacket = NULL;
  444.         if (chan->flushAbortIop == NULL) {
  445.             /* normal. process next request in the queues */
  446.             processQueue();
  447.             
  448.             /* callback */
  449.             CALLBACK(chan,oldPacket,status);   
  450.             return;
  451.         } 
  452.         
  453.         /* flush or abort cmd */
  454.         /* first do callback */
  455.         CALLBACK(chan,oldPacket,status); 
  456.                      
  457.         if (chan->writeCount) { 
  458.            chan->writeCount--;              
  459.         } 
  460.         else {
  461.            removePackets(chan, chan->flushAbortIop->cmd);
  462.         }
  463.             
  464.         /* process next request in the queues */
  465.         processQueue();    
  466.         /* if all write IOPs are done, call the callback for the FLUSH IOP */
  467.         if (chan->writeCount == 0) {
  468.            CALLBACK(chan,chan->flushAbortIop,IOM_COMPLETED);
  469.            chan->flushAbortIop = NULL;   
  470.         } 
  471.         return; 
  472.     } 
  473.     /* process next request in the queues */
  474.     processQueue(); 
  475. }
  476. /*
  477.  *  ======== pciErrorIsr ========
  478.  *  interrupt service routine is runtime pluged in for asynchronous error TBD
  479.  */
  480. #ifdef PCI_ERROR_ISR_IMPL
  481. static Void pciErrorIsr(Void)
  482. {
  483.     /* How to check PCI status register to identify the error source --
  484.     parity/system: TBD (on C6416, not accessable) use 'event' here to 
  485.     represent the status register related content */ 
  486.     
  487.     Bool report = FALSE;
  488.     Uns error = 0;
  489.     C64XX_PCI_Request *req;
  490.     IOM_Packet *packet;
  491.     if (device.errCallback == NULL) {
  492.         return;
  493.     }
  494.     if ((event == C64XX_PCI_EVT_PARITY_ERR) && 
  495.             (device.evtMask & C64XX_PCI_EVT_PARITY_ERR)) {
  496.         error = error | C64XX_PCI_EVT_PARITY_ERR;
  497.         report = TRUE;
  498.     } 
  499.     else if ((event == C64XX_PCI_EVT_SYSTEM_ERR) && 
  500.             (device.evtMask & C64XX_PCI_EVT_SYSTEM_ERR)) {
  501.         error = error | C64XX_PCI_EVT_SYSTEM_ERR;
  502.         report = TRUE;
  503.     } 
  504.     if (!report) {
  505.         return;
  506.     }
  507.     if (device.curPacket != NULL) {
  508.         packet = device.curPacket;
  509.         req = (C64XX_PCI_Request *)packet->addr;
  510.         device.errInfo->inprogressDstAddr = req->dstAddr;
  511.         device.errInfo->inprogressSrcAddr = req->srcAddr;
  512.         device.errInfo->statusReg = PCI_STATUS_REGISTER;
  513.     } 
  514.     else {
  515.         device.errInfo->inprogressDstAddr = NULL;
  516.         device.errInfo->inprogressSrcAddr = NULL;
  517.         device.errInfo->statusReg = PCI_STATUS_REGISTER;
  518.     }
  519.     (device.errCallback)(error, (Ptr)device.errorInfo);
  520.      
  521. }
  522. #endif
  523. /*
  524.  *  ======== doTransfer ========
  525.  */
  526. static Void doTransfer(C64XX_PCI_Request *request)
  527. {
  528.     C64XX_PCI_Request   *req = request;
  529.     PCI_ConfigXfr       config;
  530.     Uns                 xfrMode;
  531.          
  532.     xfrMode = C64XX_PCI_GETXFERMODE(request->options);
  533.         
  534.     if (xfrMode == PCI_WRITE) {
  535.         config.dspma = (Uns)req->srcAddr;
  536.         config.pcima = (Uns)req->dstAddr; 
  537.         config.pcimc = GET_BYTE_COUNT(req->byteCnt);
  538.                                   
  539.     } 
  540.     else if (xfrMode ==  PCI_READ_PREF || xfrMode ==  PCI_READ_NOPREF) {
  541.         config.dspma = (Uns)req->dstAddr;
  542.         config.pcima = (Uns)req->srcAddr; 
  543.         config.pcimc = GET_BYTE_COUNT(req->byteCnt);                    
  544.     }
  545.         
  546.     PCI_xfrConfig(&config);
  547.     PCI_xfrStart(xfrMode);      
  548. }
  549. /*
  550.  *  ======== processQueue ========
  551.  */
  552. static Void processQueue()
  553. {
  554.     QUE_Handle          que;
  555.     C64XX_PCI_Request   *req;
  556.     que = &device.highPrioQue;
  557.     /* process next packet in queue */  
  558.     if (QUE_empty(que)) {
  559.         que = &device.lowPrioQue;
  560.         if (QUE_empty(que)) {
  561.             return;
  562.         }
  563.     } 
  564.     device.curPacket = QUE_dequeue(que);
  565.     req = (C64XX_PCI_Request *)device.curPacket->addr;
  566.     doTransfer(req);                     
  567. }
  568. /*
  569.  *  ======== removePackets ========
  570.  */
  571. static Void removePackets(Ptr chanp, Int cmd) 
  572. {           
  573.     ChanHandle          chan = (ChanHandle)chanp;
  574.     QUE_Elem            *next;
  575.     QUE_Elem            *current;
  576.     C64XX_PCI_Request  *curReq;  
  577.     Int                 status;
  578.     if (cmd != IOM_FLUSH && cmd != IOM_ABORT) {
  579.         return;
  580.     } 
  581.     
  582.     current = QUE_head(chan->queue);
  583.     curReq = (C64XX_PCI_Request *)((IOM_Packet *)current)->addr;
  584.    
  585.     while (chan->queue != current) {
  586.         next = QUE_next(current);
  587.           
  588.         /* check the channel of the each IOM_Packet in the queue */
  589.         /* find the match. The packet and remove channels are identical */ 
  590.         if ((ChanHandle)curReq->reserved == chan) {
  591.             /* for write flush wait for complete */
  592.             if ( cmd == IOM_FLUSH && 
  593.                     ((IOM_Packet *)current)->cmd == IOM_WRITE ) {
  594.                 chan->writeCount++;
  595.             } else {
  596.                 /* for read flush or abort, do flush */
  597.                 if (cmd == IOM_FLUSH) {
  598.                     status = IOM_FLUSHED;
  599.                 }
  600.                 else {
  601.                     status = IOM_ABORTED;
  602.                 }
  603.                 QUE_remove(current);
  604.                 CALLBACK(chan, (IOM_Packet *)current, status); 
  605.             }
  606.         } 
  607.           
  608.         current = next;
  609.         curReq = (C64XX_PCI_Request*)((IOM_Packet *)current)->addr;      
  610.     } /* end while */
  611. }
  612. /*
  613.  *  ======== resetChannel ========
  614.  */
  615. static Void resetChannel(Ptr chanp)
  616. {
  617.     ChanHandle          chan = (ChanHandle)chanp;
  618.     C64XX_PCI_Request  *curReq;
  619.     Uns                 imask;
  620.     
  621.     imask = HWI_disable();
  622.     /* assume reset async ? */
  623.     if (device.curPacket != NULL) {       
  624.         curReq = (C64XX_PCI_Request *)((IOM_Packet *)device.curPacket)->addr; 
  625.         if ((ChanHandle)curReq->reserved == chan) {
  626.             CALLBACK((ChanHandle)curReq->reserved, 
  627.                     (IOM_Packet *)device.curPacket, IOM_ABORTED); 
  628.             device.curPacket = NULL; 
  629.         }     
  630.     }
  631.     
  632.     removePackets(chanp, IOM_ABORT);
  633.     HWI_restore(imask); 
  634. }
  635. /*
  636.  *  ======== resetDevice ========
  637.  */
  638. static Void resetDevice()
  639. {
  640.     QUE_Elem            *next;
  641.     QUE_Elem            *current;
  642.     QUE_Handle          queue;
  643.     C64XX_PCI_Request  *curReq;
  644.     Int                 i;  
  645.     Uns                 imask;
  646.     
  647.     imask = HWI_disable();
  648.     /* assume reset async ? */
  649.     if (device.curPacket != NULL) {       
  650.         curReq = (C64XX_PCI_Request *)((IOM_Packet *)device.curPacket)->addr; 
  651.          CALLBACK((ChanHandle)curReq->reserved, 
  652.                     (IOM_Packet *)device.curPacket, IOM_ABORTED); 
  653.         device.curPacket = NULL;      
  654.     }
  655.     
  656.     for (i = 0; i < 2; i++) {
  657.         if (i == 0 ) {
  658.             queue = &device.highPrioQue;      
  659.         } 
  660.         else {
  661.             queue = &device.lowPrioQue; 
  662.         }
  663.         /* remove all the elements in the high/low priority queue */
  664.         current = QUE_head(queue);
  665.         curReq = (C64XX_PCI_Request *)((IOM_Packet *)current)->addr;
  666.     
  667.         while (queue != current) {
  668.             next = QUE_next(current);
  669.           
  670.             QUE_remove(current);
  671.             CALLBACK((ChanHandle)curReq->reserved, 
  672.                     (IOM_Packet *)current, IOM_ABORTED);
  673.                  
  674.             current = next;
  675.             curReq = (C64XX_PCI_Request*)((IOM_Packet *)current)->addr; 
  676.         } /* end while */        
  677.     } /* end for */
  678.     
  679.     HWI_restore(imask); 
  680. }