Implemented endpoint creation for Pipes.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18986 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Niels Sascha Reedijk
2006-10-02 10:59:15 +00:00
parent be2bd5ef4b
commit 0439428356
4 changed files with 193 additions and 54 deletions
+148 -2
View File
@@ -363,6 +363,9 @@ OHCI::~OHCI()
status_t
OHCI::Start()
{
if (InitCheck())
return B_ERROR;
if (!(ReadReg(OHCI_CONTROL) & OHCI_HCFS_OPERATIONAL)) {
TRACE(("USB OHCI::Start(): Controller not started. TODO: find out what happens.\n"));
return B_ERROR;
@@ -397,6 +400,25 @@ status_t OHCI::SubmitTransfer( Transfer *t )
return B_ERROR;
}
status_t
OHCI::NotifyPipeChange(Pipe *pipe, usb_change change)
{
if (InitCheck())
return B_ERROR;
switch (change) {
case USB_CHANGE_CREATED:
return InsertEndpointForPipe(pipe);
case USB_CHANGE_DESTROYED:
// Do something
return B_ERROR;
case USB_CHANGE_PIPE_POLICY_CHANGED:
default:
break;
}
return B_ERROR; //We should never go here
}
status_t
OHCI::GetPortStatus(uint8 index, usb_port_status *status)
{
@@ -481,7 +503,8 @@ OHCI::ClearPortFeature(uint8 index, uint16 feature)
Endpoint *
OHCI::AllocateEndpoint()
{
Endpoint *endpoint = new Endpoint;
//Allocate memory chunk
Endpoint *endpoint = new(std::nothrow) Endpoint;
void *phy;
if (fStack->AllocateChunk((void **)&endpoint->ed, &phy, sizeof(ohci_endpoint_descriptor)) != B_OK) {
TRACE(("OHCI::AllocateEndpoint(): Error Allocating Endpoint\n"));
@@ -489,8 +512,15 @@ OHCI::AllocateEndpoint()
}
endpoint->physicaladdress = (addr_t)phy;
//Initialize the physical part
memset((void *)endpoint->ed, 0, sizeof(ohci_endpoint_descriptor));
endpoint->ed->ed_flags = OHCI_ED_SKIP;
endpoint->ed->flags = OHCI_ENDPOINT_SKIP;
//Add a NULL list by creating one TransferDescriptor
TransferDescriptor *trans = new(std::nothrow) TransferDescriptor;
endpoint->head = endpoint->tail = trans;
endpoint->ed->headp = endpoint->ed->tailp = trans->physicaladdress;
return endpoint;
}
@@ -501,6 +531,122 @@ OHCI::FreeEndpoint(Endpoint *end)
delete end;
}
TransferDescriptor *
OHCI::AllocateTransfer()
{
TransferDescriptor *transfer = new TransferDescriptor;
void *phy;
if (fStack->AllocateChunk((void **)&transfer->td, &phy, sizeof(ohci_transfer_descriptor)) != B_OK) {
TRACE(("OHCI::AllocateTransfer(): Error Allocating Transfer\n"));
return 0;
}
transfer->physicaladdress = (addr_t)phy;
memset((void *)transfer->td, 0, sizeof(ohci_transfer_descriptor));
return transfer;
}
void
OHCI::FreeTransfer(TransferDescriptor *trans)
{
fStack->FreeChunk((void *)trans->td, (void *) trans->physicaladdress, sizeof(ohci_transfer_descriptor));
delete trans;
}
status_t
OHCI::InsertEndpointForPipe(Pipe *p)
{
TRACE(("OHCI: Inserting Endpoint for device %u function %u\n", p->DeviceAddress(), p->EndpointAddress()));
if (InitCheck())
return B_ERROR;
Endpoint *endpoint = AllocateEndpoint();
if (!endpoint)
return B_NO_MEMORY;
//Set up properties of the endpoint
//TODO: does this need its own utility function?
{
uint32 properties = 0;
//Set the device address
properties |= OHCI_ENDPOINT_SET_FA(p->DeviceAddress());
//Set the endpoint number
properties |= OHCI_ENDPOINT_SET_EN(p->EndpointAddress());
//Set the direction
switch (p->Direction()) {
case Pipe::In:
properties |= OHCI_ENDPOINT_DIR_IN;
break;
case Pipe::Out:
properties |= OHCI_ENDPOINT_DIR_OUT;
break;
case Pipe::Default:
properties |= OHCI_ENDPOINT_DIR_TD;
break;
default:
//TODO: error
break;
}
//Set the speed
switch (p->Speed()) {
case USB_SPEED_LOWSPEED:
//the bit is 0
break;
case USB_SPEED_FULLSPEED:
properties |= OHCI_ENDPOINT_SPEED;
break;
case USB_SPEED_HIGHSPEED:
default:
//TODO: error
break;
}
//Assign the format. Isochronous endpoints require this switch
if (p->Type() & USB_OBJECT_ISO_PIPE)
properties |= OHCI_ENDPOINT_FORMAT_ISO;
//Set the maximum packet size
properties |= OHCI_ENDPOINT_SET_MAXP(p->MaxPacketSize());
endpoint->ed->flags = properties;
}
//Check which list we need to add the endpoint in
Endpoint *listhead;
switch (p->Type()) {
case USB_OBJECT_CONTROL_PIPE:
listhead = fDummyControl;
break;
case USB_OBJECT_BULK_PIPE:
listhead = fDummyBulk;
break;
case USB_OBJECT_ISO_PIPE:
listhead = fDummyIsochronous;
break;
default:
FreeEndpoint(endpoint);
return B_ERROR;
}
//Add the endpoint to the queues
if (p->Type() != USB_OBJECT_ISO_PIPE) {
//Link the endpoint into the head of the list
endpoint->SetNext(listhead->next);
listhead->SetNext(endpoint);
} else {
//Link the endpoint into the tail of the list
Endpoint *tail = listhead;
while (tail->next != 0)
tail = tail->next;
tail->SetNext(endpoint);
}
return B_OK;
}
pci_module_info *OHCI::pci_module = 0;
+24 -3
View File
@@ -34,7 +34,8 @@
struct pci_info;
struct pci_module_info;
class OHCIRootHub;
class Endpoint;
struct Endpoint;
struct TransferDescriptor;
// --------------------------------
// OHCI: The OHCI class derived
@@ -50,6 +51,9 @@ public:
~OHCI();
status_t Start();
status_t SubmitTransfer(Transfer *t); //Override from BusManager.
status_t NotifyPipeChange(Pipe *pipe, //Override from BusManager.
usb_change change);
static pci_module_info *pci_module; // Global data for the module.
status_t GetPortStatus(uint8 index, usb_port_status *status);
@@ -81,7 +85,11 @@ private:
uint8 fNumPorts; // the number of ports
// functions
Endpoint *AllocateEndpoint(); // allocate memory for an endpoint
void FreeEndpoint(Endpoint *end); //Free endpoint
void FreeEndpoint(Endpoint *end); // Free endpoint
TransferDescriptor *AllocateTransfer(); // create a NULL transfer
void FreeTransfer(TransferDescriptor *trans); // Free transfer
status_t InsertEndpointForPipe(Pipe *p);
};
// --------------------------------
@@ -106,12 +114,25 @@ struct Endpoint
addr_t physicaladdress;//Point to the physical address
ohci_endpoint_descriptor *ed; //Logical 'endpoint'
Endpoint *next; //Pointer to the 'next' endpoint
TransferDescriptor *head, *tail; //Pointers to the 'head' and 'tail' transfer descriptors
//Utility functions
void SetNext(Endpoint *end) {
next = end;
ed->next_endpoint = end->physicaladdress;
if (end == 0)
ed->next_endpoint = 0;
else
ed->next_endpoint = end->physicaladdress;
};
//Constructor (or better: initialiser)
Endpoint() : physicaladdress(0), ed(0), next(0), head(0), tail(0) {};
};
struct TransferDescriptor
{
addr_t physicaladdress;
ohci_transfer_descriptor *td;
};
#endif // OHCI_H
+21 -22
View File
@@ -296,42 +296,41 @@ struct ohci_hcca
typedef struct ohci_endpoint_descriptor
{
uint32 ed_flags;
addr_t ed_qtailp; // Queue tail pointer
addr_t ed_qheadp; // Queue head pointer
uint32 flags;
addr_t tailp; // Queue tail pointer
addr_t headp; // Queue head pointer
addr_t next_endpoint; // Next endpoint in the list
};
#define OHCI_ED_GET_FA(s) ((s) & 0x7f)
#define OHCI_ED_ADDRMASK 0x0000007f
#define OHCI_ED_SET_FA(s) (s)
#define OHCI_ED_GET_EN(s) (((s) >> 7) & 0xf)
#define OHCI_ED_SET_EN(s) ((s) << 7)
#define OHCI_ED_DIR_MASK 0x00001800
#define OHCI_ED_DIR_TD 0x00000000
#define OHCI_ED_DIR_OUT 0x00000800
#define OHCI_ED_DIR_IN 0x00001000
#define OHCI_ED_SPEED 0x00002000
#define OHCI_ED_SKIP 0x00004000
#define OHCI_ED_FORMAT_GEN 0x00000000
#define OHCI_ED_FORMAT_ISO 0x00008000
#define OHCI_ED_GET_MAXP(s) (((s) >> 16) & 0x07ff)
#define OHCI_ED_SET_MAXP(s) ((s) << 16)
#define OHCI_ED_MAXPMASK (0x7ff << 16)
#define OHCI_ENDPOINT_GET_FA(s) ((s) & 0x7f)
#define OHCI_ENDPOINT_ADDRMASK 0x0000007f
#define OHCI_ENDPOINT_SET_FA(s) (s)
#define OHCI_ENDPOINT_GET_EN(s) (((s) >> 7) & 0xf)
#define OHCI_ENDPOINT_SET_EN(s) ((s) << 7)
#define OHCI_ENDPOINT_DIR_MASK 0x00001800
#define OHCI_ENDPOINT_DIR_TD 0x00000000
#define OHCI_ENDPOINT_DIR_OUT 0x00000800
#define OHCI_ENDPOINT_DIR_IN 0x00001000
#define OHCI_ENDPOINT_SPEED 0x00002000
#define OHCI_ENDPOINT_SKIP 0x00004000
#define OHCI_ENDPOINT_FORMAT_GEN 0x00000000
#define OHCI_ENDPOINT_FORMAT_ISO 0x00008000
#define OHCI_ENDPOINT_GET_MAXP(s) (((s) >> 16) & 0x07ff)
#define OHCI_ENDPOINT_SET_MAXP(s) ((s) << 16)
#define OHCI_ENDPOINT_MAXPMASK (0x7ff << 16)
#define OHCI_HALTED 0x00000001
#define OHCI_TOGGLECARRY 0x00000002
#define OHCI_HEADMASK 0xfffffffc
#define OHCI_ED_ALIGN 16
// --------------------------------
// General transfer descriptor structure (section 4.3.1)
// --------------------------------
typedef struct hc_transfer_descriptor
typedef struct ohci_transfer_descriptor
{
uint32 td_flags;
uint32 flags;
addr_t td_cbp; // Current Buffer Pointer
addr_t td_nexttd; // Next Transfer Descriptor
addr_t td_be; // Buffer End
@@ -32,28 +32,6 @@
#include "ohci_hardware.h"
// ------------------------------------
// OHCI:: Software general
// transfer descriptor
// ------------------------------------
typedef struct hcd_soft_transfer
{
hc_transfer_descriptor td;
struct hcd_soft_transfer *nexttd; // mirrors nexttd in TD
struct hcd_soft_trasfer *dnext; // next in done list
addr_t physaddr; // physical address to the host controller transfer
//LIST_ENTRY(hcd_soft_transfer) hnext;
uint16 len; // the lenght
uint16 flags; // flags
}hcd_soft_transfer;
#define OHCI_CALL_DONE 0x0001
#define OHCI_ADD_LEN 0x0002
#define OHCI_STD_SIZE ((sizeof (struct hcd_soft_transfer) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
#define OHCI_STD_CHUNK 128
// --------------------------------------
// OHCI:: Software isonchronous
// transfer descriptor
@@ -80,10 +58,5 @@ typedef struct hcd_soft_itransfer
#define OHCI_NO_EDS (2*OHCI_NO_INTRS-1)
// --------------------------
// OHCI:: Hash size for the
// --------------------------
#define OHCI_HASH_SIZE 128
#endif // OHCI_SOFT