|
Lines 288-304
Link Here
|
| 288 |
u_char obuf2[256]; |
288 |
u_char obuf2[256]; |
| 289 |
}; |
289 |
}; |
| 290 |
|
290 |
|
|
|
291 |
#define MAXCHAN 8 /* up to 8 channels per multiport */ |
| 292 |
|
| 293 |
struct multicom { |
| 294 |
int nchan; /* channels per adapter */ |
| 295 |
struct resource *res; |
| 296 |
struct resource *irq; |
| 297 |
void *intrhand; |
| 298 |
struct com_s com [MAXCHAN]; |
| 299 |
}; |
| 300 |
|
| 291 |
#ifdef COM_ESP |
301 |
#ifdef COM_ESP |
| 292 |
static int espattach __P((struct com_s *com, Port_t esp_port)); |
302 |
static int espattach __P((struct com_s *com, Port_t esp_port)); |
| 293 |
#endif |
303 |
#endif |
| 294 |
static int sioattach __P((device_t dev, int rid)); |
304 |
static int sioattach __P((device_t dev, int rid)); |
| 295 |
static int sio_isa_attach __P((device_t dev)); |
305 |
static int sio_isa_attach __P((device_t dev)); |
|
|
306 |
static int sio_attach_unit __P((struct com_s *com, int unit, Port_t iobase, |
| 307 |
u_int flags, bool_t no_irq, |
| 308 |
bus_space_tag_t t, bus_space_handle_t h)); |
| 296 |
|
309 |
|
| 297 |
static timeout_t siobusycheck; |
310 |
static timeout_t siobusycheck; |
| 298 |
static timeout_t siodtrwakeup; |
311 |
static timeout_t siodtrwakeup; |
| 299 |
static void comhardclose __P((struct com_s *com)); |
312 |
static void comhardclose __P((struct com_s *com)); |
| 300 |
static void sioinput __P((struct com_s *com)); |
313 |
static void sioinput __P((struct com_s *com)); |
| 301 |
static void siointr1 __P((struct com_s *com)); |
314 |
static void siointr1 __P((struct com_s *com)); |
|
|
315 |
static void sio_pci_intr __P((void *arg)); |
| 302 |
static void siointr __P((void *arg)); |
316 |
static void siointr __P((void *arg)); |
| 303 |
static int commctl __P((struct com_s *com, int bits, int how)); |
317 |
static int commctl __P((struct com_s *com, int bits, int how)); |
| 304 |
static int comparam __P((struct tty *tp, struct termios *t)); |
318 |
static int comparam __P((struct tty *tp, struct termios *t)); |
|
Lines 321-327
Link Here
|
| 321 |
|
335 |
|
| 322 |
#if NPCI > 0 |
336 |
#if NPCI > 0 |
| 323 |
static int sio_pci_attach __P((device_t dev)); |
337 |
static int sio_pci_attach __P((device_t dev)); |
| 324 |
static void sio_pci_kludge_unit __P((device_t dev)); |
|
|
| 325 |
static int sio_pci_probe __P((device_t dev)); |
338 |
static int sio_pci_probe __P((device_t dev)); |
| 326 |
#endif /* NPCI > 0 */ |
339 |
#endif /* NPCI > 0 */ |
| 327 |
|
340 |
|
|
Lines 329-336
Link Here
|
| 329 |
|
342 |
|
| 330 |
/* table and macro for fast conversion from a unit number to its com struct */ |
343 |
/* table and macro for fast conversion from a unit number to its com struct */ |
| 331 |
static devclass_t sio_devclass; |
344 |
static devclass_t sio_devclass; |
| 332 |
#define com_addr(unit) ((struct com_s *) \ |
345 |
#define SIO_MAXUNITS 64 /* up to 64 ports */ |
| 333 |
devclass_get_softc(sio_devclass, unit)) |
346 |
#define com_addr(unit) (p_com_addr[unit]) |
|
|
347 |
static struct com_s *p_com_addr[SIO_MAXUNITS]; |
| 334 |
|
348 |
|
| 335 |
static device_method_t sio_isa_methods[] = { |
349 |
static device_method_t sio_isa_methods[] = { |
| 336 |
/* Device interface */ |
350 |
/* Device interface */ |
|
Lines 373-381
Link Here
|
| 373 |
}; |
387 |
}; |
| 374 |
|
388 |
|
| 375 |
static driver_t sio_pci_driver = { |
389 |
static driver_t sio_pci_driver = { |
| 376 |
driver_name, |
390 |
"siopci", |
| 377 |
sio_pci_methods, |
391 |
sio_pci_methods, |
| 378 |
sizeof(struct com_s), |
392 |
sizeof(struct multicom), |
| 379 |
}; |
393 |
}; |
| 380 |
#endif /* NPCI > 0 */ |
394 |
#endif /* NPCI > 0 */ |
| 381 |
|
395 |
|
|
Lines 419-424
Link Here
|
| 419 |
static struct callout_handle sio_timeout_handle |
433 |
static struct callout_handle sio_timeout_handle |
| 420 |
= CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); |
434 |
= CALLOUT_HANDLE_INITIALIZER(&sio_timeout_handle); |
| 421 |
static int sio_numunits; |
435 |
static int sio_numunits; |
|
|
436 |
static int sio_pci_numunits = NSIO; |
| 422 |
|
437 |
|
| 423 |
static struct speedtab comspeedtab[] = { |
438 |
static struct speedtab comspeedtab[] = { |
| 424 |
{ 0, 0 }, |
439 |
{ 0, 0 }, |
|
Lines 576-587
Link Here
|
| 576 |
struct pci_ids { |
591 |
struct pci_ids { |
| 577 |
u_int32_t type; |
592 |
u_int32_t type; |
| 578 |
const char *desc; |
593 |
const char *desc; |
| 579 |
int rid; |
594 |
int rid; /* pci base address register */ |
|
|
595 |
int nchan; /* channels per adapter */ |
| 596 |
int iostep; /* addresses per channel */ |
| 597 |
int fifo_size; /* fifo size in bytes */ |
| 598 |
int hw_rts_cts; /* hardware rts/cts support */ |
| 580 |
}; |
599 |
}; |
| 581 |
|
600 |
|
| 582 |
static struct pci_ids pci_ids[] = { |
601 |
static struct pci_ids pci_ids[] = { |
| 583 |
{ 0x100812b9, "3COM PCI FaxModem", 0x10 }, |
602 |
{ 0x100812b9, "3COM PCI FaxModem", 0x10 }, |
| 584 |
{ 0x048011c1, "ActionTec 56k FAX PCI Modem", 0x14 }, |
603 |
{ 0x048011c1, "ActionTec 56k FAX PCI Modem", 0x14 }, |
|
|
604 |
{ 0xc00110b5, "Cronyx Omega-PCI Serial Adapter", 0x18, 8, 8, 64, 1 }, |
| 585 |
{ 0x00000000, NULL, 0 } |
605 |
{ 0x00000000, NULL, 0 } |
| 586 |
}; |
606 |
}; |
| 587 |
|
607 |
|
|
Lines 591-596
Link Here
|
| 591 |
{ |
611 |
{ |
| 592 |
u_int32_t type; |
612 |
u_int32_t type; |
| 593 |
struct pci_ids *id; |
613 |
struct pci_ids *id; |
|
|
614 |
struct multicom *d = device_get_softc(dev); |
| 615 |
struct com_s *com; |
| 616 |
Port_t iobase; |
| 617 |
bus_space_tag_t bst; |
| 618 |
bus_space_handle_t bsh, bsh_port; |
| 619 |
int rid, offset, s, err = 0; |
| 594 |
|
620 |
|
| 595 |
type = pci_get_devid(dev); |
621 |
type = pci_get_devid(dev); |
| 596 |
id = pci_ids; |
622 |
id = pci_ids; |
|
Lines 598-634
Link Here
|
| 598 |
id++; |
624 |
id++; |
| 599 |
if (id->desc == NULL) |
625 |
if (id->desc == NULL) |
| 600 |
return (ENXIO); |
626 |
return (ENXIO); |
| 601 |
sio_pci_kludge_unit(dev); |
|
|
| 602 |
return (sioattach(dev, id->rid)); |
| 603 |
} |
| 604 |
|
627 |
|
| 605 |
/* |
628 |
bzero((char*)d, sizeof(*d)); |
| 606 |
* Don't cut and paste this to other drivers. It is a horrible kludge |
629 |
s = splimp(); |
| 607 |
* which will fail to work and also be unnecessary in future versions. |
630 |
d->nchan = id->nchan > 1 ? id->nchan : 1; |
| 608 |
*/ |
631 |
|
| 609 |
static void |
632 |
/* Allocate i/o region. */ |
| 610 |
sio_pci_kludge_unit(dev) |
633 |
rid = id->rid; |
| 611 |
device_t dev; |
634 |
d->res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, |
| 612 |
{ |
635 |
RF_ACTIVE); |
| 613 |
devclass_t dc; |
636 |
if (! d->res) { |
| 614 |
int err; |
637 |
printf("sio%d: couldn't map ports/memory\n", sio_pci_numunits); |
| 615 |
int start; |
638 |
err = ENXIO; |
| 616 |
int unit; |
639 |
goto fail; |
|
|
640 |
} |
| 617 |
|
641 |
|
| 618 |
unit = 0; |
642 |
/* Allocate interrupt. */ |
| 619 |
start = 0; |
643 |
rid = 0; |
| 620 |
while (resource_int_value("sio", unit, "port", &start) == 0 && |
644 |
d->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, |
| 621 |
start > 0) |
645 |
RF_SHAREABLE | RF_ACTIVE); |
| 622 |
unit++; |
646 |
if (! d->irq) { |
| 623 |
if (device_get_unit(dev) < unit) { |
647 |
printf("sio%d: couldn't map interrupt\n", sio_pci_numunits); |
| 624 |
dc = device_get_devclass(dev); |
648 |
err = ENXIO; |
| 625 |
while (devclass_get_device(dc, unit)) |
649 |
goto fail; |
| 626 |
unit++; |
650 |
} |
| 627 |
device_printf(dev, "moving to sio%d\n", unit); |
651 |
|
| 628 |
err = device_set_unit(dev, unit); /* EVIL DO NOT COPY */ |
652 |
/* Register the interrupt handler. */ |
| 629 |
if (err) |
653 |
err = bus_setup_intr(dev, d->irq, INTR_TYPE_TTY | INTR_TYPE_FAST, |
| 630 |
device_printf(dev, "error moving device %d\n", err); |
654 |
sio_pci_intr, d, &d->intrhand); |
|
|
655 |
if (err) { |
| 656 |
printf("sio%d: couldn't set up irq\n", sio_pci_numunits); |
| 657 |
fail: if (d->res) |
| 658 |
bus_release_resource(dev, SYS_RES_IOPORT, |
| 659 |
id->rid, d->res); |
| 660 |
if (d->irq) |
| 661 |
bus_release_resource(dev, SYS_RES_IRQ, 0, d->irq); |
| 662 |
goto done; |
| 663 |
} |
| 664 |
|
| 665 |
/* Attach sio ports. */ |
| 666 |
bst = rman_get_bustag(d->res); |
| 667 |
bsh = rman_get_bushandle(d->res); |
| 668 |
iobase = rman_get_start(d->res); |
| 669 |
offset = 0; |
| 670 |
for (com=d->com; com<d->com+d->nchan; ++com, offset+=id->iostep) { |
| 671 |
/* Get a handle for a subregion of an already-mapped |
| 672 |
* area of bus space. */ |
| 673 |
#if waiting_for_somebody_to_implement_bus_space_subregion |
| 674 |
if (bus_space_subregion (bst, bsh, offset, 8, &bsh_port) != 0) { |
| 675 |
printf("sio%d: cannot get bus subregion\n", |
| 676 |
sio_pci_numunits); |
| 677 |
continue; |
| 631 |
} |
678 |
} |
|
|
679 |
#else |
| 680 |
bsh_port = bsh + offset; |
| 681 |
#endif |
| 682 |
/* Interrupt enable, do it _before_ sio_attach_unit. */ |
| 683 |
outb (iobase + offset + com_mcr, |
| 684 |
d->nchan > 1 ? MCR_IENABLE : 0); |
| 685 |
|
| 686 |
if (sio_attach_unit(com, sio_pci_numunits++, iobase + offset, |
| 687 |
id->fifo_size << 24, 0, bst, bsh_port) != 0) |
| 688 |
printf("sio%d: cannot attach\n", sio_pci_numunits); |
| 689 |
|
| 690 |
/* Must do this _after_ sio_attach_unit. */ |
| 691 |
com->st16650a = id->hw_rts_cts; |
| 692 |
} |
| 693 |
done: |
| 694 |
splx (s); |
| 695 |
return err; |
| 632 |
} |
696 |
} |
| 633 |
|
697 |
|
| 634 |
static int |
698 |
static int |
|
Lines 645-651
Link Here
|
| 645 |
if (id->desc == NULL) |
709 |
if (id->desc == NULL) |
| 646 |
return (ENXIO); |
710 |
return (ENXIO); |
| 647 |
device_set_desc(dev, id->desc); |
711 |
device_set_desc(dev, id->desc); |
| 648 |
return (sioprobe(dev, id->rid)); |
712 |
return (0); |
| 649 |
} |
713 |
} |
| 650 |
#endif /* NPCI > 0 */ |
714 |
#endif /* NPCI > 0 */ |
| 651 |
|
715 |
|
|
Lines 1096-1110
Link Here
|
| 1096 |
int xrid; |
1160 |
int xrid; |
| 1097 |
{ |
1161 |
{ |
| 1098 |
struct com_s *com; |
1162 |
struct com_s *com; |
| 1099 |
#ifdef COM_ESP |
|
|
| 1100 |
Port_t *espp; |
| 1101 |
#endif |
| 1102 |
Port_t iobase; |
1163 |
Port_t iobase; |
| 1103 |
int unit; |
1164 |
int unit; |
| 1104 |
u_int flags; |
1165 |
u_int flags; |
| 1105 |
int rid; |
1166 |
int rid; |
| 1106 |
struct resource *port; |
1167 |
struct resource *port; |
| 1107 |
int ret; |
1168 |
int ret; |
|
|
1169 |
int no_irq; |
| 1108 |
|
1170 |
|
| 1109 |
rid = xrid; |
1171 |
rid = xrid; |
| 1110 |
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, |
1172 |
port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, |
|
Lines 1117-1122
Link Here
|
| 1117 |
com = device_get_softc(dev); |
1179 |
com = device_get_softc(dev); |
| 1118 |
flags = device_get_flags(dev); |
1180 |
flags = device_get_flags(dev); |
| 1119 |
|
1181 |
|
|
|
1182 |
#ifdef COM_MULTIPORT |
| 1183 |
if (COM_ISMULTIPORT(flags)) { |
| 1184 |
device_t masterdev; |
| 1185 |
|
| 1186 |
masterdev = devclass_get_device(sio_devclass, |
| 1187 |
COM_MPMASTER(flags)); |
| 1188 |
no_irq = (masterdev == NULL || bus_get_resource(masterdev, |
| 1189 |
SYS_RES_IRQ, 0, NULL, NULL) != 0); |
| 1190 |
} else |
| 1191 |
#endif /* COM_MULTIPORT */ |
| 1192 |
no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; |
| 1193 |
|
| 1194 |
ret = sio_attach_unit(com, unit, iobase, flags, no_irq, |
| 1195 |
rman_get_bustag(port), rman_get_bushandle(port)); |
| 1196 |
|
| 1197 |
if (ret != 0) { |
| 1198 |
/* Leave i/o resources allocated if this is a `cn'-level |
| 1199 |
* console, so that other devices can't snarf them. */ |
| 1200 |
if (iobase != siocniobase) |
| 1201 |
bus_release_resource(dev, SYS_RES_IOPORT, rid, port); |
| 1202 |
return ret; |
| 1203 |
} |
| 1204 |
|
| 1205 |
rid = 0; |
| 1206 |
com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, |
| 1207 |
RF_ACTIVE); |
| 1208 |
if (com->irqres) { |
| 1209 |
ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, |
| 1210 |
INTR_TYPE_TTY | INTR_TYPE_FAST, |
| 1211 |
siointr, com, &com->cookie); |
| 1212 |
if (ret) { |
| 1213 |
ret = BUS_SETUP_INTR(device_get_parent(dev), dev, |
| 1214 |
com->irqres, INTR_TYPE_TTY, |
| 1215 |
siointr, com, &com->cookie); |
| 1216 |
if (ret == 0) |
| 1217 |
device_printf(dev, "unable to activate interrupt in fast mode - using normal mode"); |
| 1218 |
} |
| 1219 |
if (ret) |
| 1220 |
device_printf(dev, "could not activate interrupt\n"); |
| 1221 |
} |
| 1222 |
com->ioportres = port; |
| 1223 |
return 0; |
| 1224 |
} |
| 1225 |
|
| 1226 |
int |
| 1227 |
sio_attach_unit(com, unit, iobase, flags, no_irq, bst, bsh) |
| 1228 |
struct com_s *com; |
| 1229 |
int unit; |
| 1230 |
Port_t iobase; |
| 1231 |
u_int flags; |
| 1232 |
bool_t no_irq; |
| 1233 |
bus_space_tag_t bst; |
| 1234 |
bus_space_handle_t bsh; |
| 1235 |
{ |
| 1236 |
#ifdef COM_ESP |
| 1237 |
Port_t *espp; |
| 1238 |
#endif |
| 1239 |
|
| 1240 |
if (unit >= SIO_MAXUNITS) |
| 1241 |
return ENXIO; |
| 1120 |
if (unit >= sio_numunits) |
1242 |
if (unit >= sio_numunits) |
| 1121 |
sio_numunits = unit + 1; |
1243 |
sio_numunits = unit + 1; |
| 1122 |
/* |
1244 |
/* |
|
Lines 1133-1145
Link Here
|
| 1133 |
*/ |
1255 |
*/ |
| 1134 |
bzero(com, sizeof *com); |
1256 |
bzero(com, sizeof *com); |
| 1135 |
com->unit = unit; |
1257 |
com->unit = unit; |
| 1136 |
com->ioportres = port; |
1258 |
com->bst = bst; |
| 1137 |
com->bst = rman_get_bustag(port); |
1259 |
com->bsh = bsh; |
| 1138 |
com->bsh = rman_get_bushandle(port); |
|
|
| 1139 |
com->cfcr_image = CFCR_8BITS; |
1260 |
com->cfcr_image = CFCR_8BITS; |
| 1140 |
com->dtr_wait = 3 * hz; |
1261 |
com->dtr_wait = 3 * hz; |
| 1141 |
com->loses_outints = COM_LOSESOUTINTS(flags) != 0; |
1262 |
com->loses_outints = COM_LOSESOUTINTS(flags) != 0; |
| 1142 |
com->no_irq = bus_get_resource(dev, SYS_RES_IRQ, 0, NULL, NULL) != 0; |
1263 |
com->no_irq = no_irq; |
| 1143 |
com->tx_fifo_size = 1; |
1264 |
com->tx_fifo_size = 1; |
| 1144 |
com->obufs[0].l_head = com->obuf1; |
1265 |
com->obufs[0].l_head = com->obuf1; |
| 1145 |
com->obufs[1].l_head = com->obuf2; |
1266 |
com->obufs[1].l_head = com->obuf2; |
|
Lines 1175-1186
Link Here
|
| 1175 |
com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; |
1296 |
com->it_in.c_ispeed = com->it_in.c_ospeed = TTYDEF_SPEED; |
| 1176 |
if (siosetwater(com, com->it_in.c_ispeed) != 0) { |
1297 |
if (siosetwater(com, com->it_in.c_ispeed) != 0) { |
| 1177 |
enable_intr(); |
1298 |
enable_intr(); |
| 1178 |
/* |
|
|
| 1179 |
* Leave i/o resources allocated if this is a `cn'-level |
| 1180 |
* console, so that other devices can't snarf them. |
| 1181 |
*/ |
| 1182 |
if (iobase != siocniobase) |
| 1183 |
bus_release_resource(dev, SYS_RES_IOPORT, rid, port); |
| 1184 |
return (ENOMEM); |
1299 |
return (ENOMEM); |
| 1185 |
} |
1300 |
} |
| 1186 |
enable_intr(); |
1301 |
enable_intr(); |
|
Lines 1287-1303
Link Here
|
| 1287 |
|
1402 |
|
| 1288 |
#ifdef COM_MULTIPORT |
1403 |
#ifdef COM_MULTIPORT |
| 1289 |
if (COM_ISMULTIPORT(flags)) { |
1404 |
if (COM_ISMULTIPORT(flags)) { |
| 1290 |
device_t masterdev; |
|
|
| 1291 |
|
| 1292 |
com->multiport = TRUE; |
1405 |
com->multiport = TRUE; |
| 1293 |
printf(" (multiport"); |
1406 |
printf(" (multiport"); |
| 1294 |
if (unit == COM_MPMASTER(flags)) |
1407 |
if (unit == COM_MPMASTER(flags)) |
| 1295 |
printf(" master"); |
1408 |
printf(" master"); |
| 1296 |
printf(")"); |
1409 |
printf(")"); |
| 1297 |
masterdev = devclass_get_device(sio_devclass, |
|
|
| 1298 |
COM_MPMASTER(flags)); |
| 1299 |
com->no_irq = (masterdev == NULL || bus_get_resource(masterdev, |
| 1300 |
SYS_RES_IRQ, 0, NULL, NULL) != 0); |
| 1301 |
} |
1410 |
} |
| 1302 |
#endif /* COM_MULTIPORT */ |
1411 |
#endif /* COM_MULTIPORT */ |
| 1303 |
if (unit == comconsole) |
1412 |
if (unit == comconsole) |
|
Lines 1306-1311
Link Here
|
| 1306 |
printf(" with a bogus IIR_TXRDY register"); |
1415 |
printf(" with a bogus IIR_TXRDY register"); |
| 1307 |
printf("\n"); |
1416 |
printf("\n"); |
| 1308 |
|
1417 |
|
|
|
1418 |
com_addr(unit) = com; |
| 1419 |
|
| 1309 |
if (!sio_registered) { |
1420 |
if (!sio_registered) { |
| 1310 |
register_swi(SWI_TTY, siopoll); |
1421 |
register_swi(SWI_TTY, siopoll); |
| 1311 |
sio_registered = TRUE; |
1422 |
sio_registered = TRUE; |
|
Lines 1326-1349
Link Here
|
| 1326 |
com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; |
1437 |
com->pps.ppscap = PPS_CAPTUREASSERT | PPS_CAPTURECLEAR; |
| 1327 |
pps_init(&com->pps); |
1438 |
pps_init(&com->pps); |
| 1328 |
|
1439 |
|
| 1329 |
rid = 0; |
|
|
| 1330 |
com->irqres = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0ul, ~0ul, 1, |
| 1331 |
RF_ACTIVE); |
| 1332 |
if (com->irqres) { |
| 1333 |
ret = BUS_SETUP_INTR(device_get_parent(dev), dev, com->irqres, |
| 1334 |
INTR_TYPE_TTY | INTR_TYPE_FAST, |
| 1335 |
siointr, com, &com->cookie); |
| 1336 |
if (ret) { |
| 1337 |
ret = BUS_SETUP_INTR(device_get_parent(dev), dev, |
| 1338 |
com->irqres, INTR_TYPE_TTY, |
| 1339 |
siointr, com, &com->cookie); |
| 1340 |
if (ret == 0) |
| 1341 |
device_printf(dev, "unable to activate interrupt in fast mode - using normal mode"); |
| 1342 |
} |
| 1343 |
if (ret) |
| 1344 |
device_printf(dev, "could not activate interrupt\n"); |
| 1345 |
} |
| 1346 |
|
| 1347 |
return (0); |
1440 |
return (0); |
| 1348 |
} |
1441 |
} |
| 1349 |
|
1442 |
|
|
Lines 1830-1835
Link Here
|
| 1830 |
} while (possibly_more_intrs); |
1923 |
} while (possibly_more_intrs); |
| 1831 |
COM_UNLOCK(); |
1924 |
COM_UNLOCK(); |
| 1832 |
#endif /* COM_MULTIPORT */ |
1925 |
#endif /* COM_MULTIPORT */ |
|
|
1926 |
} |
| 1927 |
|
| 1928 |
static void |
| 1929 |
sio_pci_intr(arg) |
| 1930 |
void *arg; |
| 1931 |
{ |
| 1932 |
struct multicom *d = arg; |
| 1933 |
struct com_s *com; |
| 1934 |
bool_t possibly_more_intrs; |
| 1935 |
|
| 1936 |
disable_intr(); |
| 1937 |
do { |
| 1938 |
possibly_more_intrs = FALSE; |
| 1939 |
for (com=d->com; com<d->com+d->nchan; ++com) { |
| 1940 |
if ((inb(com->int_id_port) & IIR_IMASK) != IIR_NOPEND) { |
| 1941 |
siointr1(com); |
| 1942 |
possibly_more_intrs = TRUE; |
| 1943 |
} |
| 1944 |
} |
| 1945 |
} while (possibly_more_intrs); |
| 1946 |
enable_intr(); |
| 1833 |
} |
1947 |
} |
| 1834 |
|
1948 |
|
| 1835 |
static void |
1949 |
static void |