// called with global interrupts enabled status_t AHCIPort::Init2() { TRACE("AHCIPort::Init2 port %d\n", fIndex); // start DMA engine fRegs->cmd |= PORT_CMD_ST; // enable interrupts fRegs->ie = PORT_INT_MASK; FlushPostedWrites(); ResetPort(true); TRACE("ie 0x%08" B_PRIx32 "\n", fRegs->ie); TRACE("is 0x%08" B_PRIx32 "\n", fRegs->is); TRACE("cmd 0x%08" B_PRIx32 "\n", fRegs->cmd); TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts); TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl); TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr); TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact); TRACE("tfd 0x%08" B_PRIx32 "\n", fRegs->tfd); fDevicePresent = (fRegs->ssts & 0xf) == 0x3; return B_OK; }
USHORT _loadds PASCAL FAR PortManagement( USHORT PortID, USHORT ReqHandle, USHORT Param1, ULONG Param2, USHORT FunctionCode, USHORT MACDS ) { switch( FunctionCode ) { case ANDIS_FC_REG_PCM: return RegisterPCM( ReqHandle, Param1, (PENTRYTBL)Param2, MACDS ); case ANDIS_FC_REL_PCM: return ReleasePCM( ReqHandle, Param1, MACDS ); case ANDIS_FC_ACT_MODE: return ActivateMode( ReqHandle, Param1, MACDS ); case ANDIS_FC_RET_PPI_STAT: return RetrievePPIStatus( ReqHandle, (PULONG)Param2, MACDS ); case ANDIS_FC_GET_PPAT_PARMS: return GetPPATParms( ReqHandle, Param1, (PXVPPAT)Param2, MACDS ); case ANDIS_FC_SET_PPAT_PARMS: return SetPPATParms( ReqHandle, (PXVPPAT)Param2, MACDS ); case ANDIS_FC_RESET_PORT: return ResetPort( ReqHandle, Param1, MACDS ); case ANDIS_FC_ACT_PHYS_CONN: return ActivatePhysConn( ReqHandle, Param1, Param2, MACDS ); case ANDIS_FC_DEACT_PHYS_CONN: return DeactivatePhysConn( ReqHandle, Param2, MACDS ); case ANDIS_FC_REG_NULL_DLC: return RegisterNullDLC( ReqHandle,Param1,(PENTRYTBL)Param2,MACDS ); case ANDIS_FC_REL_NULL_DLC: return ReleaseNullDLC( ReqHandle, Param1, MACDS ); case ANDIS_FC_ACT_DTR: return ActivateDTR( ReqHandle, MACDS ); case ANDIS_FC_ACT_RTS: return ActivateRTS( ReqHandle, MACDS ); default: return ANDIS_RC_INVALID_FUNC; } }
CIRDriver::~CIRDriver() { DEBUG("~CIRDriver\n"); ResetPort(); KillThread(&IRThreadHandle,&IRThreadEvent); KillThread(&DaemonThreadHandle,&DaemonThreadEvent); if(hDataReadyEvent) CloseHandle(hDataReadyEvent); }
void AHCIPort::ExecuteSataRequest(sata_request *request, bool isWrite) { FLOW("ExecuteAtaRequest port %d\n", fIndex); StartTransfer(); int prdEntrys; if (request->ccb() && request->ccb()->data_length) { FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT, request->ccb()->sg_list, request->ccb()->sg_count, request->ccb()->data_length); } else if (request->data() && request->size()) { FillPrdTable(fPRDTable, &prdEntrys, PRD_TABLE_ENTRY_COUNT, request->data(), request->size()); } else prdEntrys = 0; FLOW("prdEntrys %d\n", prdEntrys); fCommandList->prdtl_flags_cfl = 0; fCommandList->cfl = 5; // 20 bytes, length in DWORDS memcpy((char *)fCommandTable->cfis, request->fis(), 20); fTestUnitReadyActive = request->is_test_unit_ready(); if (request->is_atapi()) { // ATAPI PACKET is a 12 or 16 byte SCSI command memset((char *)fCommandTable->acmd, 0, 32); memcpy((char *)fCommandTable->acmd, request->ccb()->cdb, request->ccb()->cdb_length); fCommandList->a = 1; } if (isWrite) fCommandList->w = 1; fCommandList->prdtl = prdEntrys; fCommandList->prdbc = 0; if (wait_until_clear(&fRegs->tfd, ATA_BSY | ATA_DRQ, 1000000) < B_OK) { TRACE("ExecuteAtaRequest port %d: device is busy\n", fIndex); ResetPort(); FinishTransfer(); request->abort(); return; } cpu_status cpu = disable_interrupts(); acquire_spinlock(&fSpinlock); fCommandsActive |= 1; fRegs->ci = 1; FlushPostedWrites(); release_spinlock(&fSpinlock); restore_interrupts(cpu); int tfd; status_t status = WaitForTransfer(&tfd, 20000000); FLOW("tfd %#x\n", tfd); FLOW("prdbc %ld\n", fCommandList->prdbc); FLOW("ci 0x%08" B_PRIx32 "\n", fRegs->ci); FLOW("is 0x%08" B_PRIx32 "\n", fRegs->is); FLOW("serr 0x%08" B_PRIx32 "\n", fRegs->serr); /* TRACE("ci 0x%08" B_PRIx32 "\n", fRegs->ci); TRACE("ie 0x%08" B_PRIx32 "\n", fRegs->ie); TRACE("is 0x%08" B_PRIx32 "\n", fRegs->is); TRACE("cmd 0x%08" B_PRIx32 "\n", fRegs->cmd); TRACE("ssts 0x%08" B_PRIx32 "\n", fRegs->ssts); TRACE("sctl 0x%08" B_PRIx32 "\n", fRegs->sctl); TRACE("serr 0x%08" B_PRIx32 "\n", fRegs->serr); TRACE("sact 0x%08" B_PRIx32 "\n", fRegs->sact); TRACE("tfd 0x%08" B_PRIx32 "\n", fRegs->tfd); */ if (fResetPort || status == B_TIMED_OUT) { fResetPort = false; ResetPort(); } size_t bytesTransfered = fCommandList->prdbc; FinishTransfer(); if (status == B_TIMED_OUT) { TRACE("ExecuteAtaRequest port %d: device timeout\n", fIndex); request->abort(); } else { request->finish(tfd, bytesTransfered); } }
void Hub::Explore(change_item **changeList) { for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { status_t result = UpdatePortStatus(i); if (result < B_OK) continue; #ifdef TRACE_USB if (fPortStatus[i].change) { TRACE("port %" B_PRId32 ": status: 0x%04x; change: 0x%04x\n", i, fPortStatus[i].status, fPortStatus[i].change); TRACE("device at port %" B_PRId32 ": %p (%" B_PRId32 ")\n", i, fChildren[i], fChildren[i] != NULL ? fChildren[i]->USBID() : 0); } #endif if (fPortStatus[i].change & PORT_STATUS_CONNECTION) { // clear status change DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_CONNECTION, i + 1, 0, NULL, 0, NULL); if (fPortStatus[i].status & PORT_STATUS_CONNECTION) { // new device attached! TRACE_ALWAYS("port %" B_PRId32 ": new device connected\n", i); int32 retry = 2; while (retry--) { // wait for stable device power result = _DebouncePort(i); if (result != B_OK) { TRACE_ERROR("debouncing port %" B_PRId32 " failed: %s\n", i, strerror(result)); break; } // reset the port, this will also enable it result = ResetPort(i); if (result < B_OK) { TRACE_ERROR("resetting port %" B_PRId32 " failed\n", i); break; } result = UpdatePortStatus(i); if (result < B_OK) break; if ((fPortStatus[i].status & PORT_STATUS_CONNECTION) == 0) { // device has vanished after reset, ignore TRACE("device disappeared on reset\n"); break; } if (fChildren[i] != NULL) { TRACE_ERROR("new device on a port that is already in " "use\n"); fChildren[i]->Changed(changeList, false); fChildren[i] = NULL; } usb_speed speed = USB_SPEED_FULLSPEED; if (fDeviceDescriptor.usb_version == 0x300) speed = USB_SPEED_SUPER; else if (fPortStatus[i].status & PORT_STATUS_LOW_SPEED) speed = USB_SPEED_LOWSPEED; else if (fPortStatus[i].status & PORT_STATUS_HIGH_SPEED) speed = USB_SPEED_HIGHSPEED; // either let the device inherit our addresses (if we are // already potentially using a transaction translator) or // set ourselfs as the hub when we might become the // transaction translator for the device. int8 hubAddress = HubAddress(); uint8 hubPort = HubPort(); if (Speed() == USB_SPEED_HIGHSPEED || fDeviceDescriptor.usb_version == 0x300) { hubAddress = DeviceAddress(); hubPort = i + 1; } Device *newDevice = GetBusManager()->AllocateDevice(this, hubAddress, hubPort, speed); if (newDevice) { newDevice->Changed(changeList, true); fChildren[i] = newDevice; break; } else { // the device failed to setup correctly, disable the // port so that the device doesn't get in the way of // future addressing. DisablePort(i); } } } else { // Device removed... TRACE_ALWAYS("port %" B_PRId32 ": device removed\n", i); if (fChildren[i] != NULL) { TRACE("removing device %p\n", fChildren[i]); fChildren[i]->Changed(changeList, false); fChildren[i] = NULL; } } } // other port changes we do not really handle, report and clear them if (fPortStatus[i].change & PORT_STATUS_ENABLE) { TRACE_ALWAYS("port %" B_PRId32 " %sabled\n", i, (fPortStatus[i].status & PORT_STATUS_ENABLE) ? "en" : "dis"); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_ENABLE, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_SUSPEND) { TRACE_ALWAYS("port %" B_PRId32 " is %ssuspended\n", i, (fPortStatus[i].status & PORT_STATUS_SUSPEND) ? "" : "not "); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_SUSPEND, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_OVER_CURRENT) { TRACE_ALWAYS("port %" B_PRId32 " is %sin an over current state\n", i, (fPortStatus[i].status & PORT_STATUS_OVER_CURRENT) ? "" : "not "); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_OVER_CURRENT, i + 1, 0, NULL, 0, NULL); } if (fPortStatus[i].change & PORT_STATUS_RESET) { TRACE_ALWAYS("port %" B_PRId32 "was reset\n", i); DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1, 0, NULL, 0, NULL); } } // explore down the tree if we have hubs connected for (int32 i = 0; i < fHubDescriptor.num_ports; i++) { if (!fChildren[i] || (fChildren[i]->Type() & USB_OBJECT_HUB) == 0) continue; ((Hub *)fChildren[i])->Explore(changeList); } }