sdvirtio: ioalloc, cleanup

front
cinap_lenrek 2012-04-24 07:48:59 +02:00
parent 8562240e8c
commit 43fb53943e
1 changed files with 23 additions and 17 deletions

View File

@ -15,13 +15,15 @@ typedef struct Vused Vused;
typedef struct Vqueue Vqueue; typedef struct Vqueue Vqueue;
typedef struct Vdev Vdev; typedef struct Vdev Vdev;
/* status flags */
enum { enum {
Acknowledge = 1, Acknowledge = 1,
Driver = 2, Driver = 2,
DriverOk = 4, DriverOk = 4,
Failed = 128, Failed = 0x80,
}; };
/* virtio ports */
enum { enum {
Devfeat = 0, Devfeat = 0,
Drvfeat = 4, Drvfeat = 4,
@ -35,6 +37,7 @@ enum {
Devspec = 20, Devspec = 20,
}; };
/* descriptor flags */
enum { enum {
Next = 1, Next = 1,
Write = 2, Write = 2,
@ -151,12 +154,11 @@ mkvqueue(int size)
static Vdev* static Vdev*
viopnpdevs(int typ) viopnpdevs(int typ)
{ {
Vdev *vd, *head, *tail; Vdev *vd, *h, *t;
Pcidev *p; Pcidev *p;
u32int a;
int n, i; int n, i;
head = tail = nil; h = t = nil;
for(p = nil; p = pcimatch(p, 0, 0);){ for(p = nil; p = pcimatch(p, 0, 0);){
if(p->vid != 0x1AF4) if(p->vid != 0x1AF4)
continue; continue;
@ -171,6 +173,11 @@ viopnpdevs(int typ)
break; break;
} }
vd->port = p->mem[0].bar & ~0x1; vd->port = p->mem[0].bar & ~0x1;
if(ioalloc(vd->port, p->mem[0].size, 0, "virtio") < 0){
print("viopnpdevs: port %lux in use\n", vd->port);
free(vd);
continue;
}
vd->typ = typ; vd->typ = typ;
vd->pci = p; vd->pci = p;
@ -186,18 +193,18 @@ viopnpdevs(int typ)
if((vd->queue[i] = mkvqueue(n)) == nil) if((vd->queue[i] = mkvqueue(n)) == nil)
break; break;
coherence(); coherence();
a = PADDR(vd->queue[i]->desc)/BY2PG; outl(vd->port+Qaddr, PADDR(vd->queue[i]->desc)/BY2PG);
outl(vd->port+Qaddr, a);
} }
vd->nqueue = i; vd->nqueue = i;
if(head == nil) if(h == nil)
head = vd; h = vd;
else else
tail->next = vd; t->next = vd;
tail = vd; t = vd;
} }
return head;
return h;
} }
struct Rock { struct Rock {
@ -404,11 +411,10 @@ viopnp(void)
if(vd->nqueue != 1) if(vd->nqueue != 1)
continue; continue;
intrenable(vd->pci->intl, viointerrupt, vd, vd->pci->tbdf, "sdvirtio"); intrenable(vd->pci->intl, viointerrupt, vd, vd->pci->tbdf, "virtio");
outb(vd->port+Status, inb(vd->port+Status) | DriverOk); outb(vd->port+Status, inb(vd->port+Status) | DriverOk);
s = malloc(sizeof(*s)); if((s = malloc(sizeof(*s))) == nil)
if(s == nil)
break; break;
s->ctlr = vd; s->ctlr = vd;
s->idno = id++; s->idno = id++;