forked from KolibriOS/kolibrios
1) create skeleton queues
2) install irq handlers & enable uhci interrupts git-svn-id: svn://kolibrios.org@1605 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
875283e594
commit
abc581c09f
@ -41,6 +41,9 @@ bool FindUSBControllers()
|
|||||||
hc->pciId = PciRead32(bus,devfn, 0);
|
hc->pciId = PciRead32(bus,devfn, 0);
|
||||||
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
|
||||||
|
|
||||||
|
hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF;
|
||||||
|
dbgprintf("Host IRQ %d\n", hc->irq_line);
|
||||||
|
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
u32_t base;
|
u32_t base;
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
|
||||||
#define UHCI_USBLEGSUP 0x00c0 /* legacy support */
|
#define UHCI_USBLEGSUP 0x00c0 /* legacy support */
|
||||||
#define UHCI_USBCMD 0 /* command register */
|
#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */
|
||||||
#define UHCI_USBINTR 4 /* interrupt register */
|
|
||||||
#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
|
#define UHCI_USBLEGSUP_RWC 0x8f00 /* the R/WC bits */
|
||||||
#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
|
#define UHCI_USBLEGSUP_RO 0x5040 /* R/O and reserved bits */
|
||||||
|
|
||||||
|
|
||||||
|
#define UHCI_USBCMD 0 /* command register */
|
||||||
|
#define UHCI_USBINTR 4 /* interrupt register */
|
||||||
#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */
|
#define UHCI_USBCMD_RUN 0x0001 /* RUN/STOP bit */
|
||||||
#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */
|
#define UHCI_USBCMD_HCRESET 0x0002 /* Host Controller reset */
|
||||||
#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */
|
#define UHCI_USBCMD_EGSM 0x0008 /* Global Suspend Mode */
|
||||||
@ -117,12 +120,38 @@ reset_needed:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hc_interrupt()
|
||||||
|
{
|
||||||
|
hc_t *hc;
|
||||||
|
|
||||||
|
printf("USB interrupt\n");
|
||||||
|
|
||||||
|
hc = (hc_t*)hc_list.next;
|
||||||
|
|
||||||
|
while( &hc->list != &hc_list)
|
||||||
|
{
|
||||||
|
hc_t *tmp;
|
||||||
|
u16_t status;
|
||||||
|
|
||||||
|
tmp = hc;
|
||||||
|
hc = (hc_t*)hc->list.next;
|
||||||
|
|
||||||
|
status = in16(tmp->iobase + USBSTS);
|
||||||
|
if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
|
||||||
|
continue;
|
||||||
|
out16(tmp->iobase + USBSTS, status); /* Clear it */
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool init_hc(hc_t *hc)
|
bool init_hc(hc_t *hc)
|
||||||
{
|
{
|
||||||
int port;
|
int port;
|
||||||
u32_t ifl;
|
u32_t ifl;
|
||||||
u16_t dev_status;
|
u16_t dev_status;
|
||||||
|
td_t *td;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dbgprintf("\n\ninit uhci %x\n\n", hc->pciId);
|
dbgprintf("\n\ninit uhci %x\n\n", hc->pciId);
|
||||||
@ -166,18 +195,42 @@ bool init_hc(hc_t *hc)
|
|||||||
hc->frame_dma = GetPgAddr(hc->frame_base);
|
hc->frame_dma = GetPgAddr(hc->frame_base);
|
||||||
hc->frame_number = 0;
|
hc->frame_number = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < UHCI_NUM_SKELQH; i++)
|
||||||
|
{
|
||||||
qh_t *qh = alloc_qh();
|
qh_t *qh = alloc_qh();
|
||||||
|
|
||||||
qh->qlink = 1;
|
qh->qlink = 1;
|
||||||
qh->qelem = 1;
|
qh->qelem = 1;
|
||||||
|
|
||||||
hc->qh1 = qh;
|
hc->qh[i] = qh;
|
||||||
|
}
|
||||||
|
for (i = SKEL_ISO + 1; i < SKEL_ASYNC; ++i)
|
||||||
|
hc->qh[i]->qlink = hc->qh[SKEL_ASYNC]->dma | 2;
|
||||||
|
|
||||||
// dbgprintf("alloc qh %x dma %x\n", qh, qh->dma);
|
/*
|
||||||
|
td = alloc_td();
|
||||||
|
|
||||||
for(i=0; i<1024; i++)
|
td->link = 1;
|
||||||
hc->frame_base[i] = qh->dma | 2;
|
td->status = (1<<24) | (1<<23) ;
|
||||||
|
td->token = TOKEN( 0x7FF, DATA0, 0, 0, 0xE1);
|
||||||
|
td->buffer = 0;
|
||||||
|
td->bk = NULL;
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < 1024; i++)
|
||||||
|
{
|
||||||
|
int qnum;
|
||||||
|
|
||||||
|
qnum = 8 - (int) __bsf( i | 1024);
|
||||||
|
|
||||||
|
if (qnum <= 1)
|
||||||
|
qnum = 9;
|
||||||
|
|
||||||
|
hc->frame_base[i] = hc->qh[qnum]->dma | 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
mb();
|
||||||
|
|
||||||
/* Set the frame length to the default: 1 ms exactly */
|
/* Set the frame length to the default: 1 ms exactly */
|
||||||
out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
|
out8(hc->iobase + USBSOF, USBSOF_DEFAULT);
|
||||||
@ -189,6 +242,13 @@ bool init_hc(hc_t *hc)
|
|||||||
out16(hc->iobase + USBFRNUM, 0);
|
out16(hc->iobase + USBFRNUM, 0);
|
||||||
|
|
||||||
out16(hc->iobase + USBSTS, 0x3F);
|
out16(hc->iobase + USBSTS, 0x3F);
|
||||||
|
|
||||||
|
out16(hc->iobase + UHCI_USBINTR, 4);
|
||||||
|
|
||||||
|
AttachIntHandler(hc->irq_line, hc_interrupt, 0);
|
||||||
|
|
||||||
|
pciWriteWord(hc->PciTag, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT);
|
||||||
|
|
||||||
out16(hc->iobase + USBCMD, USBCMD_RS | USBCMD_CF |
|
out16(hc->iobase + USBCMD, USBCMD_RS | USBCMD_CF |
|
||||||
USBCMD_MAXP);
|
USBCMD_MAXP);
|
||||||
|
|
||||||
@ -347,7 +407,7 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir,
|
|||||||
|
|
||||||
if( td_prev )
|
if( td_prev )
|
||||||
td_prev->link = td->dma | 4;
|
td_prev->link = td->dma | 4;
|
||||||
td->status = 0x00800000 | dev->speed;
|
td->status = TD_CTRL_ACTIVE | dev->speed;
|
||||||
td->token = TOKEN(packet_size,enp->toggle,enp->address,
|
td->token = TOKEN(packet_size,enp->toggle,enp->address,
|
||||||
dev->addr,dir);
|
dev->addr,dir);
|
||||||
td->buffer = data_dma;
|
td->buffer = data_dma;
|
||||||
@ -358,17 +418,10 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir,
|
|||||||
data_dma+= packet_size;
|
data_dma+= packet_size;
|
||||||
size-= packet_size;
|
size-= packet_size;
|
||||||
enp->toggle ^= DATA1;
|
enp->toggle ^= DATA1;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
td->status |= TD_CTRL_IOC;
|
||||||
rq->td_tail = td;
|
rq->td_tail = td;
|
||||||
/*
|
|
||||||
dbgprintf("create request %x\n"
|
|
||||||
"head %x\n"
|
|
||||||
"tail %x\n"
|
|
||||||
"data %x\n"
|
|
||||||
"size %x\n",
|
|
||||||
rq, rq->td_head, rq->td_tail,
|
|
||||||
rq->data, rq->size);
|
|
||||||
*/
|
|
||||||
return rq;
|
return rq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +458,7 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
|
|||||||
|
|
||||||
td = alloc_td();
|
td = alloc_td();
|
||||||
td_prev->link = td->dma | 4;
|
td_prev->link = td->dma | 4;
|
||||||
td->status = 0x00800000 | dev->speed;
|
td->status = TD_CTRL_ACTIVE | dev->speed;
|
||||||
td->token = TOKEN(packet_size, toggle, 0,dev->addr, pid);
|
td->token = TOKEN(packet_size, toggle, 0,dev->addr, pid);
|
||||||
td->buffer = data_dma;
|
td->buffer = data_dma;
|
||||||
td->bk = td_prev;
|
td->bk = td_prev;
|
||||||
@ -423,15 +476,17 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
|
|||||||
pid = (pid == DIN) ? DOUT : DIN;
|
pid = (pid == DIN) ? DOUT : DIN;
|
||||||
|
|
||||||
td->link = 1;
|
td->link = 1;
|
||||||
td->status = 0x00800000 | dev->speed;
|
td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed ;
|
||||||
td->token = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
|
td->token = (0x7FF<<21)|DATA1|(dev->addr<<8)|pid;
|
||||||
td->buffer = 0;
|
td->buffer = 0;
|
||||||
td->bk = td_prev;
|
td->bk = td_prev;
|
||||||
|
|
||||||
qh = dev->host->qh1;
|
qh = dev->host->qh[SKEL_ASYNC];
|
||||||
|
|
||||||
qh->qelem = td0->dma;
|
qh->qelem = td0->dma;
|
||||||
__asm__ __volatile__ ("":::"memory");
|
|
||||||
|
mb();
|
||||||
|
// __asm__ __volatile__ ("":::"memory");
|
||||||
|
|
||||||
count_t timeout = 25;
|
count_t timeout = 25;
|
||||||
while(timeout--){
|
while(timeout--){
|
||||||
|
@ -112,7 +112,7 @@ bool mouse_handler(udev_t *dev, struct tag_request *rq)
|
|||||||
pkt = (struct boot_packet *)rq->data;
|
pkt = (struct boot_packet *)rq->data;
|
||||||
SetMouseData(pkt->buttons, pkt->x, -pkt->y, -pkt->z, 0);
|
SetMouseData(pkt->buttons, pkt->x, -pkt->y, -pkt->z, 0);
|
||||||
};
|
};
|
||||||
td->status = 0x00800000 | dev->speed;
|
td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed;
|
||||||
td->token ^= DATA1;
|
td->token ^= DATA1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -145,6 +145,7 @@ void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d)
|
|||||||
packet = kzalloc(enp.size, 0);
|
packet = kzalloc(enp.size, 0);
|
||||||
|
|
||||||
rq = create_request(dev, &enp, DIN, packet, enp.size);
|
rq = create_request(dev, &enp, DIN, packet, enp.size);
|
||||||
|
rq->qnum = 6;
|
||||||
rq->handler = &mouse_handler;
|
rq->handler = &mouse_handler;
|
||||||
|
|
||||||
list_add_tail(&rq->list, &rq_list);
|
list_add_tail(&rq->list, &rq_list);
|
||||||
|
@ -113,11 +113,12 @@ u32_t drvEntry(int action, char *cmdline)
|
|||||||
|
|
||||||
td = rq->td_head;
|
td = rq->td_head;
|
||||||
dev = rq->dev;
|
dev = rq->dev;
|
||||||
qh = dev->host->qh1;
|
|
||||||
|
|
||||||
|
qh = dev->host->qh[rq->qnum];
|
||||||
qh->qelem = td->dma;
|
qh->qelem = td->dma;
|
||||||
|
|
||||||
__asm__ __volatile__ ("":::"memory");
|
mb();
|
||||||
|
|
||||||
rq = (request_t*)rq->list.next;
|
rq = (request_t*)rq->list.next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,6 +38,23 @@ typedef struct
|
|||||||
|
|
||||||
}qh_t __attribute__((aligned(16)));
|
}qh_t __attribute__((aligned(16)));
|
||||||
|
|
||||||
|
|
||||||
|
#define UHCI_NUM_SKELQH 11
|
||||||
|
|
||||||
|
#define SKEL_ISO 1
|
||||||
|
#define SKEL_ASYNC 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define QH_1 0
|
||||||
|
#define QH_2 1
|
||||||
|
#define QH_4 2
|
||||||
|
#define QH_8 3
|
||||||
|
#define QH_16 4
|
||||||
|
#define QH_32 5
|
||||||
|
#define QH_64 6
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
list_t list;
|
list_t list;
|
||||||
@ -48,7 +65,7 @@ typedef struct
|
|||||||
count_t frame_number;
|
count_t frame_number;
|
||||||
addr_t frame_dma;
|
addr_t frame_dma;
|
||||||
|
|
||||||
qh_t *qh1;
|
qh_t *qh[UHCI_NUM_SKELQH];
|
||||||
|
|
||||||
u32_t *data;
|
u32_t *data;
|
||||||
addr_t data_dma;
|
addr_t data_dma;
|
||||||
@ -63,6 +80,7 @@ typedef struct
|
|||||||
addr_t memBase[6];
|
addr_t memBase[6];
|
||||||
size_t memSize[6];
|
size_t memSize[6];
|
||||||
u32_t memType[6];
|
u32_t memType[6];
|
||||||
|
u32_t irq_line;
|
||||||
}hc_t;
|
}hc_t;
|
||||||
|
|
||||||
typedef struct tag_td
|
typedef struct tag_td
|
||||||
@ -214,6 +232,7 @@ typedef struct tag_request
|
|||||||
size_t size;
|
size_t size;
|
||||||
udev_t *dev;
|
udev_t *dev;
|
||||||
u32_t type;
|
u32_t type;
|
||||||
|
int qnum;
|
||||||
bool (*handler)(udev_t *dev, struct tag_request *rq);
|
bool (*handler)(udev_t *dev, struct tag_request *rq);
|
||||||
}request_t;
|
}request_t;
|
||||||
|
|
||||||
@ -248,3 +267,13 @@ struct boot_packet
|
|||||||
#define DATA0 (0<<19)
|
#define DATA0 (0<<19)
|
||||||
#define DATA1 (1<<19)
|
#define DATA1 (1<<19)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32_t __bsf(u32_t val)
|
||||||
|
{
|
||||||
|
asm("bsf %1,%0"
|
||||||
|
:"=r" (val)
|
||||||
|
:"rm" (val));
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user