Device Driver "struct PCIDevice *pcidev;" pcidev's...

This forum is for general developer support questions.

Device Driver "struct PCIDevice *pcidev;" pcidev's...

Postby Belxjander » Wed Jun 13, 2018 1:41 am

I'm currently trying to write a device driver for a PCI bridged PCI-Express USB3 XHCI controller

and running into the following situation...

during ramlib execution of the device "DevInit" and eventually passing through "InitUnit()"

I can use the expansion.library "IPCI" Interface and get a valid pcidev=IPCI->FindDeviceTags(...) result...

However when using the IPCI interface from within the Unit specific Task created... I keep getting a NULL pcidev from exact search parameters (including an index of which unit it is).

This is what runs during DevInit...
Code: Select all
   if((Base = IExec->OpenLibrary("expansion.library",0L)))
   {
      Self->IExpansion = (APTR)IExec->GetInterface(Base,"main",1L,NULL);
      Self->IPCI = (APTR)IExec->GetInterface(Base,"pci",1L,NULL);
      for(hwcnt=0UL;hwcnt<DEVICE_UNIT_COUNT;hwcnt++)
      {
         pcidev=Self->IPCI->FindDeviceTags(
               FDT_Class,      0x000C0330,
               FDT_ClassMask,   0x00FFFFFF,
               FDT_Index,      hwcnt,
               TAG_DONE,      TAG_DONE
            );
         if(pcidev)
            InitUnit(Self,pcidev,hwcnt);
         IExec->DropInterface((APTR)pcidev);
      }
   }


And this is from within the UnitTask itself...

Code: Select all
   if(Unit->IPCI)
   {
      Unit->uCard=Unit->IPCI->FindDeviceTags(
               FDT_Class,      0x000C0330,
               FDT_ClassMask,   0x00FFFFFF,
               FDT_Index,      Unit->unitn,
               TAG_DONE,      TAG_DONE
            );
      KDEBUG("XHCI /UnitTask/ unit->uCard[%lx,%lx]\n",unitn,Unit->uCard);
   }


and the full code for the InitUnit() function is ...
Code: Select all
VOID InitUnit(struct DEVICE_CLASS *Base, struct PCIDevice *card, uint32 unitn)
{
   struct DEVICE_UNIT_CLASS *unit=NULL;

   if(card)
      unit=Base->IExec->AllocVecTags(DEVICE_UNIT_SIZE,AVT_Type,MEMF_SHARED,AVT_ClearWithValue,0L,TAG_DONE,TAG_DONE);
   if(unit)
   {
      Base->IExec->InitSemaphore((APTR)unit);
      unit->unitn=unitn;
      Base->IExec->ObtainSemaphore((APTR)unit);
      unit->InterruptService.is_Node.ln_Name=(APTR)xHCIdevInterruptName;
      unit->InterruptService.is_Data=unit;
      unit->InterruptService.is_Code=(APTR)&HwInterruptService;
      Base->IExec->NewList(&unit->uQueue);
      HwCardReset(card);
      unit->uTask=Base->IExec->CreateTaskTags("XHCI Controller Task", UNIT_TASK_PRIORITY, &ExecUnitTask, UNIT_STACK_SIZE,
         AT_Param1, (uint32)Base->IExec, AT_Param2, (uint32)unit, AT_Param3, (uint32)Base, CT_LockStack, TRUE, TAG_DONE );
      if(unit->uTask)
         Base->IExec->AddIntServer(card->MapInterrupt(),&unit->InterruptService);
      Base->Library.lib_OpenCnt++;
      Base->IExec->ReleaseSemaphore((APTR)unit);
   }
   return;
};
'


I'm mostly wondering about where I may have screwed up the controller specific access, as during the exec DevInit routine the card needs to be reset, and the UnitTask will switch the controller itself into a running state along with obtaining and locking system resources for the controller specific scratch memory and other unit specific details.

I am also still to work on expanding the HwInterruptService() function to handle controller specific Interrupts ( I'm also specifically allocating it this way since I will be possibly handling multiple XHCI controllers and they all apparently talk with the OS the same way (just different locations for pre-defined register blocks.
or that is at least what the XHCI specification documentation appears to read like so far.

(I still think I have missed something after reading all the documentation through 3-4 times too)
Belxjander
 
Posts: 276
Joined: Mon May 14, 2012 11:26 pm
Location: 日本千葉県松戸市 / Matsudo City, Chiba, Japan

Return to General Developer Support

Who is online

Users browsing this forum: tbreeden and 2 guests