]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/uartpci.c
kernel: cleanup makefile for $CONF.$O target
[plan9front.git] / sys / src / 9 / pc / uartpci.c
index d86acf50f02c8f95be386edd9374ffaf2eb373ad..aed64a1b1e33d7c44e45bd4083d36e4720e3fe44 100644 (file)
@@ -21,17 +21,24 @@ uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name,
        char buf[64];
        Uart *head, *uart;
 
+       head = malloc(sizeof(Uart)*n);
+       if(head == nil){
+               print("uartpci: no memory for Uarts\n");
+               return nil;
+       }
+
        io = p->mem[barno].bar & ~0x01;
        snprint(buf, sizeof(buf), "%s%d", pciphysuart.name, ctlrno);
        if(ioalloc(io, p->mem[barno].size, 0, buf) < 0){
                print("uartpci: I/O 0x%uX in use\n", io);
+               free(head);
                return nil;
        }
 
-       head = uart = malloc(sizeof(Uart)*n);
+       pcienable(p);
+       uart = head;
        for(i = 0; i < n; i++){
-               ctlr = i8250alloc(io, p->intl, p->tbdf);
-               io += iosize;
+               ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);
                if(ctlr == nil)
                        continue;
 
@@ -44,16 +51,20 @@ uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name,
                        (uart-1)->next = uart;
                uart++;
        }
-
-       if (head) {
-               if(perlehead != nil)
-                       perletail->next = head;
-               else
-                       perlehead = head;
-               for(perletail = head; perletail->next != nil;
-                   perletail = perletail->next)
-                       ;
+       if(head == uart){
+               iofree(io);
+               free(head);
+               return nil;
        }
+
+       if(perlehead != nil)
+               perletail->next = head;
+       else
+               perlehead = head;
+       for(perletail = head; perletail->next != nil;
+           perletail = perletail->next)
+               ;
+
        return head;
 }
 
@@ -99,8 +110,9 @@ uartpcipnp(void)
        perlehead = perletail = nil;
        ctlrno = 0;
        for(p = pcimatch(nil, 0, 0); p != nil; p = pcimatch(p, 0, 0)){
-               if(p->ccrb != Pcibccomm || p->ccru > 2)
-                       continue;
+               /* StarTech PCI8S9503V has ccru == 0x80 (other) */
+               if(p->ccrb != Pcibccomm || p->ccru > 2 && p->ccru != 0x80)
+                       continue;
 
                switch(p->did<<16 | p->vid){
                default:
@@ -165,7 +177,14 @@ uartpcipnp(void)
                        freq = 7372800;
                        switch(subid){
                        default:
+                               print("uartpci: unknown perle subid %#ux\n", subid);
                                continue;
+                       case (0x1588<<16)|0x10B5:       /* StarTech PCI8S9503V (P588UG) */
+                               name = "P588UG";
+                               /* max. baud rate is 921,600 */
+                               freq = 1843200;
+                               uart = uartpci(ctlrno, p, 2, 8, freq, name, 8);
+                               break;
                        case (0x0011<<16)|0x12E0:       /* Perle PCI-Fast16 */
                                name = "PCI-Fast16";
                                uart = uartpci(ctlrno, p, 2, 16, freq, name, 8);