示例#1
0
static int32
scsi_int_dispatch(void *data)
{
    BusLogic *bl = (BusLogic *) data;
    BL_CCB32 *bl_ccb;
    uchar intstat = inb(BL_INT_REG);

#if BOOT
#else
    if(!(intstat & BL_INT_INTV)) return B_UNHANDLED_INTERRUPT;
#endif
    if(intstat & BL_INT_CMDC) {
        bl->done = 1;
#ifdef VERBOSE_IRQ
        kprintf("buslogic_irq: Command Complete\n");
#endif
    }

    if(intstat & BL_INT_RSTS) {
        kprintf("buslogic_irq: BUS RESET\n");
    }

    /* have we got mail? */
    if(intstat & BL_INT_IMBL) {
        while(bl->in_boxes[bl->in_nextbox].completion_code) {
            bl_ccb = (BL_CCB32 *)
                     PhysToVirt(unLE(bl->in_boxes[bl->in_nextbox].ccb_phys));

#ifdef VERBOSE_IRQ
            kprintf("buslogic_irq: CCB %08x (%08x) done, cc=0x%02x\n",
                    unLE(bl->in_boxes[bl->in_nextbox].ccb_phys), (uint32) bl_ccb,
                    bl->in_boxes[bl->in_nextbox].completion_code);
#endif
            release_sem_etc(bl_ccb->done, 1, B_DO_NOT_RESCHEDULE);

            bl->in_boxes[bl->in_nextbox].completion_code = 0;
            bl->in_nextbox++;
            if(bl->in_nextbox == bl->box_count) bl->in_nextbox = 0;
        }
    }

    /* acknowledge the irq */
    outb(BL_CONTROL_REG, BL_CONTROL_RINT);

    return B_HANDLED_INTERRUPT;
}
示例#2
0
/* specified by XferOffset. */
USHORT CopyToSGList (void FAR *Buffer, ULONG Count, PSCATGATENTRY pSGList,
                     USHORT cSGList, ULONG XferOffset)
{
 ULONG	ppXferBuf;
 ULONG	XferBufLen;
 USHORT	XferLength;
 void	far* VirtAddr;

 while ((cSGList)&&(pSGList->XferBufLen<=XferOffset)) 
 {					/* Seek into the scatgat list */
  XferOffset-=(pSGList++)->XferBufLen;
  cSGList--;
 }
 XferBufLen= 0;
 while (Count)
 {
  if (!XferBufLen)			/* Need to use next SG entry */
  {
   if (!(cSGList--))			/* We run out of SG list elements */
    return IOERR_CMD_SGLIST_BAD;
   ppXferBuf= pSGList->ppXferBuf+ XferOffset;
   XferBufLen= pSGList->XferBufLen- XferOffset;
   pSGList++;
   XferOffset= 0;
  }

  XferLength= 32768;	/* To fit in USHORT */
  if (Count<XferLength) XferLength= Count;
  if (XferBufLen<XferLength) XferLength= XferBufLen;

  if (!(VirtAddr= PhysToVirt(ppXferBuf,XferLength)))
  {
   ENABLE
   return IOERR_CMD_SGLIST_BAD;
  }
  memcpy (VirtAddr,Buffer,XferLength);
  ENABLE
  ppXferBuf+= XferLength;
  ((char far *)Buffer)+= XferLength;
  Count-= XferLength;
  XferBufLen-= XferLength;
 }
//--------------------------------------------------------------------------
static bool is_kernpage_used(ea_t ea, uint *size)
{
  // via pagetable at 0xfffd0000
  //  fedcba9876543210fedcba9876543210
  //  sssssssbbbbbbbbbpppp............
  int ixPage = (ea >> 20) & 0xFFF;
  // first level page table (uncached) (2nd half is r/o)
  int dwEntry = ((DWORD*)0xFFFD0000)[ixPage];
  *size = (1 << 20);
  if ( (dwEntry & 3) == 2 )
  {
    // section descriptor
    return true;
  }
  else if ( (dwEntry & 0xfffff) == 0 )
  {
    return false;
  }
  else if ( (dwEntry & 3) == 1 )
  {
    *size = (1 << 12);
    // coarse page table entry
    int phys_2nd_tlb = ea & ~0x3f;
    int virt_2nd_tlb = PhysToVirt(phys_2nd_tlb);
    if ( virt_2nd_tlb == 0 )
      return false;

    int ix2ndPage = (ea>>12) & 0xff;
    int dw2ndEntry = ((DWORD*)virt_2nd_tlb)[ix2ndPage];
    if ( (dw2ndEntry & 3) ==1 )
    {
      // large page
      return true;
    }
    else if ( (dw2ndEntry & 3) == 2 )
    {
      // small page
      return true;
    }
    return false;
  }