Lines 46-53
Link Here
|
46 |
#include <sys/mbuf.h> |
46 |
#include <sys/mbuf.h> |
47 |
#include <sys/malloc.h> |
47 |
#include <sys/malloc.h> |
48 |
#include <sys/module.h> |
48 |
#include <sys/module.h> |
49 |
#include <sys/tty.h> |
49 |
#include <sys/sysctl.h> |
50 |
#include <sys/syslog.h> |
50 |
#include <sys/syslog.h> |
|
|
51 |
#include <sys/tty.h> |
51 |
#include <sys/fcntl.h> |
52 |
#include <sys/fcntl.h> |
52 |
#include <sys/serial.h> |
53 |
#include <sys/serial.h> |
53 |
#include <sys/bus.h> |
54 |
#include <sys/bus.h> |
Lines 75-81
Link Here
|
75 |
static void digistart(struct tty *tp); |
76 |
static void digistart(struct tty *tp); |
76 |
static int digiparam(struct tty *tp, struct termios *t); |
77 |
static int digiparam(struct tty *tp, struct termios *t); |
77 |
static void digiclose(struct tty *tp); |
78 |
static void digiclose(struct tty *tp); |
78 |
static void digi_intr(void *); |
|
|
79 |
static int digi_init(struct digi_softc *_sc); |
79 |
static int digi_init(struct digi_softc *_sc); |
80 |
static int digi_loadmoduledata(struct digi_softc *); |
80 |
static int digi_loadmoduledata(struct digi_softc *); |
81 |
static int digi_inuse(struct digi_softc *); |
81 |
static int digi_inuse(struct digi_softc *); |
Lines 94-100
Link Here
|
94 |
static struct con_bios *con_bios_list; |
94 |
static struct con_bios *con_bios_list; |
95 |
devclass_t digi_devclass; |
95 |
devclass_t digi_devclass; |
96 |
static char driver_name[] = "digi"; |
96 |
static char driver_name[] = "digi"; |
97 |
unsigned digi_debug = 0; |
97 |
|
|
|
98 |
#ifdef DEBUG |
99 |
unsigned long digi_debug = 0; |
100 |
|
101 |
SYSCTL_ULONG(_debug, OID_AUTO, digi_debug, CTLFLAG_RW, &digi_debug, 0, |
102 |
"digi(4) debug flags"); |
103 |
TUNABLE_ULONG("debug.digi_debug", &digi_debug); |
104 |
#endif |
98 |
|
105 |
|
99 |
static struct speedtab digispeedtab[] = { |
106 |
static struct speedtab digispeedtab[] = { |
100 |
{ 0, 0}, /* old (sysV-like) Bx codes */ |
107 |
{ 0, 0}, /* old (sysV-like) Bx codes */ |
Lines 159-165
Link Here
|
159 |
/* interrupt OK! */ |
166 |
/* interrupt OK! */ |
160 |
return; |
167 |
return; |
161 |
} |
168 |
} |
162 |
log(LOG_ERR, "digi%d: Interrupt didn't work, use polled mode\n", unit); |
169 |
log(LOG_ERR, "digi%d: Interrupt didn't work, use polled mode\n", sc->res.unit); |
163 |
#endif |
170 |
#endif |
164 |
sc->callout = timeout(digi_poll, sc, (hz >= 200) ? hz / 100 : 1); |
171 |
sc->callout = timeout(digi_poll, sc, (hz >= 200) ? hz / 100 : 1); |
165 |
} |
172 |
} |
Lines 182-188
Link Here
|
182 |
} |
189 |
} |
183 |
|
190 |
|
184 |
static int |
191 |
static int |
185 |
digi_bcopy(const void *vfrom, void *vto, size_t sz) |
192 |
digi_bcopy(const void *vfrom, void volatile *vto, size_t sz) |
186 |
{ |
193 |
{ |
187 |
volatile const char *from = (volatile const char *)vfrom; |
194 |
volatile const char *from = (volatile const char *)vfrom; |
188 |
volatile char *to = (volatile char *)vto; |
195 |
volatile char *to = (volatile char *)vto; |
Lines 212-218
Link Here
|
212 |
digi_init(struct digi_softc *sc) |
219 |
digi_init(struct digi_softc *sc) |
213 |
{ |
220 |
{ |
214 |
int i, cnt, resp; |
221 |
int i, cnt, resp; |
215 |
u_char *ptr; |
222 |
u_char volatile *ptr; |
|
|
223 |
u_char *cptr; |
216 |
int lowwater; |
224 |
int lowwater; |
217 |
struct digi_p *port; |
225 |
struct digi_p *port; |
218 |
volatile struct board_chan *bc; |
226 |
volatile struct board_chan *bc; |
Lines 302-307
Link Here
|
302 |
} |
310 |
} |
303 |
DLOG(DIGIDB_INIT, (sc->dev, "Got init reset after %d us\n", i)); |
311 |
DLOG(DIGIDB_INIT, (sc->dev, "Got init reset after %d us\n", i)); |
304 |
|
312 |
|
|
|
313 |
/* Clear POST area */ |
314 |
ptr = sc->setwin(sc, MISCGLOBAL); |
315 |
for (i = 0; i < 16; i++) |
316 |
*(uint8_t volatile *)(ptr + i) = 0; |
317 |
|
305 |
/* Now upload the BIOS */ |
318 |
/* Now upload the BIOS */ |
306 |
cnt = (sc->bios.size < sc->win_size - BIOSOFFSET) ? |
319 |
cnt = (sc->bios.size < sc->win_size - BIOSOFFSET) ? |
307 |
sc->bios.size : sc->win_size - BIOSOFFSET; |
320 |
sc->bios.size : sc->win_size - BIOSOFFSET; |
Lines 323-332
Link Here
|
323 |
} |
336 |
} |
324 |
|
337 |
|
325 |
ptr = sc->setwin(sc, 0); |
338 |
ptr = sc->setwin(sc, 0); |
326 |
vW(ptr + 0) = 0x0401; |
339 |
vD(ptr + 0) = 0x0bf00401; |
327 |
vW(ptr + 2) = 0x0bf0; |
340 |
vD(ptr + 4) = 0x00000000; |
328 |
vW(ptr + 4) = 0x0000; |
|
|
329 |
vW(ptr + 6) = 0x0000; |
330 |
|
341 |
|
331 |
break; |
342 |
break; |
332 |
} |
343 |
} |
Lines 334-340
Link Here
|
334 |
DLOG(DIGIDB_INIT, (sc->dev, "BIOS uploaded\n")); |
345 |
DLOG(DIGIDB_INIT, (sc->dev, "BIOS uploaded\n")); |
335 |
|
346 |
|
336 |
ptr = sc->setwin(sc, MISCGLOBAL); |
347 |
ptr = sc->setwin(sc, MISCGLOBAL); |
337 |
W(ptr) = 0; |
348 |
vW(ptr) = 0; |
338 |
|
349 |
|
339 |
if (sc->pcibus) { |
350 |
if (sc->pcibus) { |
340 |
PCIPORT = FEPCLR; |
351 |
PCIPORT = FEPCLR; |
Lines 399-405
Link Here
|
399 |
outb(sc->port, FEPREQ | FEPMEM); |
410 |
outb(sc->port, FEPREQ | FEPMEM); |
400 |
outb(sc->port, FEPCLR | FEPMEM); |
411 |
outb(sc->port, FEPCLR | FEPMEM); |
401 |
|
412 |
|
402 |
for (i = 0; W(ptr); i++) { |
413 |
for (i = 0; vW(ptr); i++) { |
403 |
if (i > hz) { |
414 |
if (i > hz) { |
404 |
log(LOG_ERR, "digi%d: FEP/OS move failed\n", |
415 |
log(LOG_ERR, "digi%d: FEP/OS move failed\n", |
405 |
sc->res.unit); |
416 |
sc->res.unit); |
Lines 449-462
Link Here
|
449 |
DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS loaded\n")); |
460 |
DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS loaded\n")); |
450 |
|
461 |
|
451 |
ptr = sc->setwin(sc, 0xc30); |
462 |
ptr = sc->setwin(sc, 0xc30); |
452 |
W(ptr + 4) = 0x1004; |
463 |
vD(ptr + 4) = 0xbfc01004; |
453 |
W(ptr + 6) = 0xbfc0; |
464 |
vD(ptr + 0) = 0x00000003; |
454 |
W(ptr + 0) = 0x03; |
|
|
455 |
W(ptr + 2) = 0x00; |
456 |
|
465 |
|
457 |
/* Clear the confirm word */ |
466 |
/* Clear the confirm word */ |
458 |
ptr = sc->setwin(sc, FEPSTAT); |
467 |
ptr = sc->setwin(sc, FEPSTAT); |
459 |
W(ptr + 0) = 0; |
468 |
vW(ptr + 0) = 0; |
460 |
|
469 |
|
461 |
if (sc->port) |
470 |
if (sc->port) |
462 |
outb(sc->port, 0); /* XXX necessary ? */ |
471 |
outb(sc->port, 0); /* XXX necessary ? */ |
Lines 469-481
Link Here
|
469 |
|
478 |
|
470 |
/* A BIOS request to execute the FEP/OS */ |
479 |
/* A BIOS request to execute the FEP/OS */ |
471 |
ptr = sc->setwin(sc, 0xc40); |
480 |
ptr = sc->setwin(sc, 0xc40); |
472 |
W(ptr + 0) = 1; |
481 |
vW(ptr + 0) = 1; |
473 |
W(ptr + 2) = FEPCODE >> 4; |
482 |
vW(ptr + 2) = FEPCODE >> 4; |
474 |
W(ptr + 4) = 4; |
483 |
vW(ptr + 4) = 4; |
475 |
|
484 |
|
476 |
/* Clear the confirm word */ |
485 |
/* Clear the confirm word */ |
477 |
ptr = sc->setwin(sc, FEPSTAT); |
486 |
ptr = sc->setwin(sc, FEPSTAT); |
478 |
W(ptr + 0) = 0; |
487 |
vW(ptr + 0) = 0; |
479 |
|
488 |
|
480 |
/* Run the BIOS request */ |
489 |
/* Run the BIOS request */ |
481 |
outb(sc->port, FEPREQ | FEPMEM); /* send interrupt to BIOS */ |
490 |
outb(sc->port, FEPREQ | FEPMEM); /* send interrupt to BIOS */ |
Lines 498-505
Link Here
|
498 |
DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS started after %d iterations\n", i)); |
507 |
DLOG(DIGIDB_INIT, (sc->dev, "FEP/OS started after %d iterations\n", i)); |
499 |
|
508 |
|
500 |
if (sc->model >= PCXEM) { |
509 |
if (sc->model >= PCXEM) { |
|
|
510 |
#if 0 |
511 |
/* Interrupt configuration */ |
501 |
ptr = sc->setwin(sc, 0xe04); |
512 |
ptr = sc->setwin(sc, 0xe04); |
502 |
vW(ptr) = 2; |
513 |
vW(ptr) = 2; |
|
|
514 |
#endif |
515 |
/* Read number of ports */ |
503 |
ptr = sc->setwin(sc, 0xc02); |
516 |
ptr = sc->setwin(sc, 0xc02); |
504 |
sc->numports = vW(ptr); |
517 |
sc->numports = vW(ptr); |
505 |
} else { |
518 |
} else { |
Lines 551-572
Link Here
|
551 |
tp->t_open = digiopen; |
564 |
tp->t_open = digiopen; |
552 |
tp->t_close = digiclose; |
565 |
tp->t_close = digiclose; |
553 |
tp->t_sc = port; |
566 |
tp->t_sc = port; |
|
|
567 |
cptr = (u_char *)(intptr_t)ptr; |
554 |
|
568 |
|
555 |
if (sc->model == PCXEVE) { |
569 |
if (sc->model == PCXEVE) { |
556 |
port->txbuf = ptr + |
570 |
port->txbuf = cptr + |
557 |
(((bc->tseg - sc->mem_seg) << 4) & 0x1fff); |
571 |
(((bc->tseg - sc->mem_seg) << 4) & 0x1fff); |
558 |
port->rxbuf = ptr + |
572 |
port->rxbuf = cptr + |
559 |
(((bc->rseg - sc->mem_seg) << 4) & 0x1fff); |
573 |
(((bc->rseg - sc->mem_seg) << 4) & 0x1fff); |
560 |
port->txwin = FEPWIN | ((bc->tseg - sc->mem_seg) >> 9); |
574 |
port->txwin = FEPWIN | ((bc->tseg - sc->mem_seg) >> 9); |
561 |
port->rxwin = FEPWIN | ((bc->rseg - sc->mem_seg) >> 9); |
575 |
port->rxwin = FEPWIN | ((bc->rseg - sc->mem_seg) >> 9); |
562 |
} else if (sc->model == PCXI || sc->model == PCXE) { |
576 |
} else if (sc->model == PCXI || sc->model == PCXE) { |
563 |
port->txbuf = ptr + ((bc->tseg - sc->mem_seg) << 4); |
577 |
port->txbuf = cptr + ((bc->tseg - sc->mem_seg) << 4); |
564 |
port->rxbuf = ptr + ((bc->rseg - sc->mem_seg) << 4); |
578 |
port->rxbuf = cptr + ((bc->rseg - sc->mem_seg) << 4); |
565 |
port->txwin = port->rxwin = 0; |
579 |
port->txwin = port->rxwin = 0; |
566 |
} else { |
580 |
} else { |
567 |
port->txbuf = ptr + |
581 |
port->txbuf = cptr + |
568 |
(((bc->tseg - sc->mem_seg) << 4) % sc->win_size); |
582 |
(((bc->tseg - sc->mem_seg) << 4) % sc->win_size); |
569 |
port->rxbuf = ptr + |
583 |
port->rxbuf = cptr + |
570 |
(((bc->rseg - sc->mem_seg) << 4) % sc->win_size); |
584 |
(((bc->rseg - sc->mem_seg) << 4) % sc->win_size); |
571 |
port->txwin = FEPWIN | |
585 |
port->txwin = FEPWIN | |
572 |
(((bc->tseg - sc->mem_seg) << 4) / sc->win_size); |
586 |
(((bc->tseg - sc->mem_seg) << 4) / sc->win_size); |
Lines 585-590
Link Here
|
585 |
fepcmd_w(port, SRXHWATER, (3 * port->rxbufsize) >> 2, 10); |
599 |
fepcmd_w(port, SRXHWATER, (3 * port->rxbufsize) >> 2, 10); |
586 |
|
600 |
|
587 |
bc->edelay = 100; |
601 |
bc->edelay = 100; |
|
|
602 |
bc->idata = 1; /*XXXXXX*/ |
588 |
|
603 |
|
589 |
ttyinitmode(tp, 0, 0); |
604 |
ttyinitmode(tp, 0, 0); |
590 |
port->send_ring = 1; /* Default action on signal RI */ |
605 |
port->send_ring = 1; /* Default action on signal RI */ |
Lines 1080-1086
Link Here
|
1080 |
return (0); |
1095 |
return (0); |
1081 |
} |
1096 |
} |
1082 |
|
1097 |
|
1083 |
static void |
1098 |
void |
1084 |
digi_intr(void *vp) |
1099 |
digi_intr(void *vp) |
1085 |
{ |
1100 |
{ |
1086 |
struct digi_p *port; |
1101 |
struct digi_p *port; |
Lines 1113-1158
Link Here
|
1113 |
window = sc->window; |
1128 |
window = sc->window; |
1114 |
sc->setwin(sc, 0); |
1129 |
sc->setwin(sc, 0); |
1115 |
|
1130 |
|
1116 |
if (sc->model >= PCXEM && W(sc->vmem + 0xd00)) { |
1131 |
if (sc->model >= PCXEM && vW(sc->vmem + 0xd00)) { |
1117 |
struct con_bios *con = con_bios_list; |
1132 |
struct con_bios *con = con_bios_list; |
1118 |
register u_char *ptr; |
1133 |
register u_char volatile *ptr; |
1119 |
|
1134 |
|
1120 |
ptr = sc->vmem + W(sc->vmem + 0xd00); |
1135 |
ptr = sc->vmem + vW(sc->vmem + 0xd00); |
1121 |
while (con) { |
1136 |
while (con) { |
1122 |
if (ptr[1] && W(ptr + 2) == W(con->bios + 2)) |
1137 |
if (ptr[1] && vW(ptr + 2) == vW(con->bios + 2)) |
1123 |
/* Not first block -- exact match */ |
1138 |
/* Not first block -- exact match */ |
1124 |
break; |
1139 |
break; |
1125 |
|
1140 |
|
1126 |
if (W(ptr + 4) >= W(con->bios + 4) && |
1141 |
if (vW(ptr + 4) >= W(con->bios + 4) && |
1127 |
W(ptr + 4) <= W(con->bios + 6)) |
1142 |
vW(ptr + 4) <= W(con->bios + 6)) |
1128 |
/* Initial search concetrator BIOS */ |
1143 |
/* Initial search concetrator BIOS */ |
1129 |
break; |
1144 |
break; |
1130 |
} |
1145 |
} |
1131 |
|
1146 |
|
1132 |
if (con == NULL) { |
1147 |
if (con == NULL) { |
1133 |
log(LOG_ERR, "digi%d: wanted bios LREV = 0x%04x" |
1148 |
log(LOG_ERR, "digi%d: wanted bios LREV = 0x%04x" |
1134 |
" not found!\n", sc->res.unit, W(ptr + 4)); |
1149 |
" not found!\n", sc->res.unit, vW(ptr + 4)); |
1135 |
W(ptr + 10) = 0; |
1150 |
vW(ptr + 10) = 0; |
1136 |
W(sc->vmem + 0xd00) = 0; |
1151 |
vW(sc->vmem + 0xd00) = 0; |
1137 |
goto eoi; |
1152 |
goto eoi; |
1138 |
} |
1153 |
} |
1139 |
cxcon = con->bios; |
1154 |
cxcon = con->bios; |
1140 |
W(ptr + 4) = W(cxcon + 4); |
1155 |
vW(ptr + 4) = W(cxcon + 4); |
1141 |
W(ptr + 6) = W(cxcon + 6); |
1156 |
vW(ptr + 6) = W(cxcon + 6); |
1142 |
if (ptr[1] == 0) |
1157 |
if (ptr[1] == 0) |
1143 |
W(ptr + 2) = W(cxcon + 2); |
1158 |
vW(ptr + 2) = W(cxcon + 2); |
1144 |
W(ptr + 8) = (ptr[1] << 6) + W(cxcon + 8); |
1159 |
vW(ptr + 8) = (ptr[1] << 6) + W(cxcon + 8); |
1145 |
size = W(cxcon + 10) - (ptr[1] << 10); |
1160 |
size = W(cxcon + 10) - (ptr[1] << 10); |
1146 |
if (size <= 0) { |
1161 |
if (size <= 0) { |
1147 |
W(ptr + 8) = W(cxcon + 8); |
1162 |
vW(ptr + 8) = W(cxcon + 8); |
1148 |
W(ptr + 10) = 0; |
1163 |
vW(ptr + 10) = 0; |
1149 |
} else { |
1164 |
} else { |
1150 |
if (size > 1024) |
1165 |
if (size > 1024) |
1151 |
size = 1024; |
1166 |
size = 1024; |
1152 |
W(ptr + 10) = size; |
1167 |
vW(ptr + 10) = size; |
1153 |
bcopy(cxcon + (ptr[1] << 10), ptr + 12, size); |
1168 |
bcopy(cxcon + (ptr[1] << 10), (void *)((intptr_t)ptr + 12), size); |
1154 |
} |
1169 |
} |
1155 |
W(sc->vmem + 0xd00) = 0; |
1170 |
vW(sc->vmem + 0xd00) = 0; |
1156 |
goto eoi; |
1171 |
goto eoi; |
1157 |
} |
1172 |
} |
1158 |
|
1173 |
|
Lines 1299-1304
Link Here
|
1299 |
} |
1314 |
} |
1300 |
sc->gdata->eout = etail; |
1315 |
sc->gdata->eout = etail; |
1301 |
eoi: |
1316 |
eoi: |
|
|
1317 |
/* Ack any interrupt */ |
1318 |
if (sc->pcibus) |
1319 |
(void)sc->vmem[0x200002]; |
1320 |
|
1302 |
if (sc->window != 0) |
1321 |
if (sc->window != 0) |
1303 |
sc->towin(sc, 0); |
1322 |
sc->towin(sc, 0); |
1304 |
if (window != 0) |
1323 |
if (window != 0) |
Lines 1403-1409
Link Here
|
1403 |
static void |
1422 |
static void |
1404 |
fepcmd(struct digi_p *port, int cmd, int op1, int ncmds) |
1423 |
fepcmd(struct digi_p *port, int cmd, int op1, int ncmds) |
1405 |
{ |
1424 |
{ |
1406 |
u_char *mem; |
1425 |
u_char volatile *mem; |
1407 |
unsigned tail, head; |
1426 |
unsigned tail, head; |
1408 |
int count, n; |
1427 |
int count, n; |
1409 |
|
1428 |
|
Lines 1414-1420
Link Here
|
1414 |
head = port->sc->gdata->cin; |
1433 |
head = port->sc->gdata->cin; |
1415 |
mem[head + 0] = cmd; |
1434 |
mem[head + 0] = cmd; |
1416 |
mem[head + 1] = port->pnum; |
1435 |
mem[head + 1] = port->pnum; |
1417 |
*(u_short *)(mem + head + 2) = op1; |
1436 |
*(u_short volatile *)(mem + head + 2) = op1; |
1418 |
|
1437 |
|
1419 |
head = (head + 4) & port->sc->gdata->cmax; |
1438 |
head = (head + 4) & port->sc->gdata->cmax; |
1420 |
port->sc->gdata->cin = head; |
1439 |
port->sc->gdata->cin = head; |
Lines 1503-1509
Link Here
|
1503 |
bus_teardown_intr(sc->dev, sc->res.irq, sc->res.irqHandler); |
1522 |
bus_teardown_intr(sc->dev, sc->res.irq, sc->res.irqHandler); |
1504 |
#ifdef DIGI_INTERRUPT |
1523 |
#ifdef DIGI_INTERRUPT |
1505 |
if (sc->res.irq != NULL) { |
1524 |
if (sc->res.irq != NULL) { |
1506 |
bus_release_resource(dev, SYS_RES_IRQ, sc->res.irqrid, |
1525 |
bus_release_resource(sc->dev, SYS_RES_IRQ, sc->res.irqrid, |
1507 |
sc->res.irq); |
1526 |
sc->res.irq); |
1508 |
sc->res.irq = NULL; |
1527 |
sc->res.irq = NULL; |
1509 |
} |
1528 |
} |