Ejemplo n.º 1
0
// 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;
}
Ejemplo n.º 2
0
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;
      }
}
Ejemplo n.º 3
0
CIRDriver::~CIRDriver()
{
	DEBUG("~CIRDriver\n");
	ResetPort();
	KillThread(&IRThreadHandle,&IRThreadEvent);
	KillThread(&DaemonThreadHandle,&DaemonThreadEvent);
	if(hDataReadyEvent) CloseHandle(hDataReadyEvent);
}
Ejemplo n.º 4
0
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);
    }
}
Ejemplo n.º 5
0
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);
	}
}