Changes to add support for the PCI version of the Cyclades Cyclom-Y
serial adapter, and support for multiple Cyclom controllers.
This commit is contained in:
parent
d2322fc6ac
commit
3010cd6550
@ -305,6 +305,7 @@ pccard/pccard.c optional crd
|
|||||||
pccard/pcic.c optional pcic device-driver
|
pccard/pcic.c optional pcic device-driver
|
||||||
pci/aic7870.c optional ahc device-driver
|
pci/aic7870.c optional ahc device-driver
|
||||||
pci/bt9xx.c optional bt device-driver
|
pci/bt9xx.c optional bt device-driver
|
||||||
|
pci/cy_pci.c optional cy device-driver
|
||||||
pci/if_de.c optional de device-driver
|
pci/if_de.c optional de device-driver
|
||||||
pci/if_ed_p.c optional ed device-driver
|
pci/if_ed_p.c optional ed device-driver
|
||||||
pci/if_fxp.c optional fxp device-driver
|
pci/if_fxp.c optional fxp device-driver
|
||||||
|
295
sys/dev/cy/cy.c
295
sys/dev/cy/cy.c
@ -27,7 +27,7 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cy.c,v 1.36 1996/10/04 10:33:08 davidg Exp $
|
* $Id: cy.c,v 1.37 1996/10/04 14:17:32 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cy.h"
|
#include "cy.h"
|
||||||
@ -141,7 +141,7 @@
|
|||||||
|
|
||||||
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
||||||
#define CD1400_xIVR_CHAN_SHIFT 3
|
#define CD1400_xIVR_CHAN_SHIFT 3
|
||||||
#define CD1400_xIVR_CHAN 0x0F /* XXX reduce to pack Cyclom-8Ys */
|
#define CD1400_xIVR_CHAN 0x1F /* XXX reduce to pack Cyclom-8Ys */
|
||||||
|
|
||||||
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
||||||
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
||||||
@ -153,7 +153,8 @@
|
|||||||
#define CONTROL_LOCK_STATE 0x40
|
#define CONTROL_LOCK_STATE 0x40
|
||||||
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
||||||
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
||||||
#define MINOR_TO_UNIT(mynor) ((mynor) & ~MINOR_MAGIC_MASK)
|
#define MINOR_TO_UNIT(mynor) (((mynor) >> 16) * CY_MAX_PORTS + \
|
||||||
|
(((mynor) & 0xff) & ~MINOR_MAGIC_MASK))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input buffer watermarks.
|
* Input buffer watermarks.
|
||||||
@ -262,6 +263,7 @@ struct com_s {
|
|||||||
|
|
||||||
cy_addr cy_iobase; /* base address of this port's cyclom */
|
cy_addr cy_iobase; /* base address of this port's cyclom */
|
||||||
cy_addr iobase; /* base address of this port's cd1400 */
|
cy_addr iobase; /* base address of this port's cd1400 */
|
||||||
|
int cy_align; /* index for register alignment */
|
||||||
|
|
||||||
struct tty *tp; /* cross reference */
|
struct tty *tp; /* cross reference */
|
||||||
|
|
||||||
@ -330,8 +332,10 @@ void siopoll __P((void));
|
|||||||
#define siommap nommap
|
#define siommap nommap
|
||||||
#define siostrategy nostrategy
|
#define siostrategy nostrategy
|
||||||
|
|
||||||
|
int cyattach_common __P((cy_addr cy_iobase, int cy_align));
|
||||||
|
static int cy_units __P((cy_addr cy_iobase, int cy_align));
|
||||||
static int sioattach __P((struct isa_device *dev));
|
static int sioattach __P((struct isa_device *dev));
|
||||||
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd));
|
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd, int cy_align));
|
||||||
static timeout_t siodtrwakeup;
|
static timeout_t siodtrwakeup;
|
||||||
static void comhardclose __P((struct com_s *com));
|
static void comhardclose __P((struct com_s *com));
|
||||||
#if 0
|
#if 0
|
||||||
@ -399,6 +403,7 @@ static u_int cy_timeouts;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cy_nr_cd1400s[NCY];
|
static int cy_nr_cd1400s[NCY];
|
||||||
|
static int cy_total_devices;
|
||||||
#undef RxFifoThreshold
|
#undef RxFifoThreshold
|
||||||
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
||||||
static int cy_chip_offset[] = {
|
static int cy_chip_offset[] = {
|
||||||
@ -416,16 +421,9 @@ static int
|
|||||||
sioprobe(dev)
|
sioprobe(dev)
|
||||||
struct isa_device *dev;
|
struct isa_device *dev;
|
||||||
{
|
{
|
||||||
int cyu;
|
|
||||||
u_char firmware_version;
|
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int unit;
|
|
||||||
|
|
||||||
iobase = (cy_addr)dev->id_maddr;
|
iobase = (cy_addr)dev->id_maddr;
|
||||||
unit = dev->id_unit;
|
|
||||||
if ((u_int)unit >= NCY)
|
|
||||||
return (0);
|
|
||||||
cy_nr_cd1400s[unit] = 0;
|
|
||||||
|
|
||||||
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
||||||
cy_inb(iobase, CY16_RESET); /* XXX? */
|
cy_inb(iobase, CY16_RESET); /* XXX? */
|
||||||
@ -435,22 +433,34 @@ sioprobe(dev)
|
|||||||
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
||||||
DELAY(500);
|
DELAY(500);
|
||||||
|
|
||||||
|
return (cy_units(iobase, 0) == 0 ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cy_units(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
cy_addr iobase;
|
||||||
|
int cyu;
|
||||||
|
|
||||||
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
||||||
int i;
|
int i;
|
||||||
|
u_char firmware_version;
|
||||||
|
|
||||||
iobase = (cy_addr) (dev->id_maddr + cy_chip_offset[cyu]);
|
iobase = cy_iobase + (cy_chip_offset[cyu] << cy_align);
|
||||||
/* wait for chip to become ready for new command */
|
/* wait for chip to become ready for new command */
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
DELAY(50);
|
DELAY(50);
|
||||||
if (!cd_inb(iobase, CD1400_CCR))
|
if (!cd_inb(iobase, CD1400_CCR, cy_align))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the GFRCR register */
|
/* clear the GFRCR register */
|
||||||
cd_outb(iobase, CD1400_GFRCR, 0);
|
cd_outb(iobase, CD1400_GFRCR, cy_align, 0);
|
||||||
|
|
||||||
/* issue a reset command */
|
/* issue a reset command */
|
||||||
cd_outb(iobase, CD1400_CCR,
|
cd_outb(iobase, CD1400_CCR, cy_align,
|
||||||
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
||||||
|
|
||||||
/* wait for the CD1400 to initialize itself */
|
/* wait for the CD1400 to initialize itself */
|
||||||
@ -458,7 +468,7 @@ sioprobe(dev)
|
|||||||
DELAY(50);
|
DELAY(50);
|
||||||
|
|
||||||
/* retrieve firmware version */
|
/* retrieve firmware version */
|
||||||
firmware_version = cd_inb(iobase, CD1400_GFRCR);
|
firmware_version = cd_inb(iobase, CD1400_GFRCR, cy_align);
|
||||||
if ((firmware_version & 0xf0) == 0x40)
|
if ((firmware_version & 0xf0) == 0x40)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -470,38 +480,60 @@ sioprobe(dev)
|
|||||||
*/
|
*/
|
||||||
if ((firmware_version & 0xf0) != 0x40)
|
if ((firmware_version & 0xf0) != 0x40)
|
||||||
break;
|
break;
|
||||||
++cy_nr_cd1400s[unit];
|
|
||||||
}
|
}
|
||||||
return (cy_nr_cd1400s[unit] == 0 ? 0 : -1);
|
return (cyu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sioattach(isdp)
|
sioattach(isdp)
|
||||||
struct isa_device *isdp;
|
struct isa_device *isdp;
|
||||||
{
|
{
|
||||||
int cyu;
|
int adapter;
|
||||||
cy_addr cy_iobase;
|
|
||||||
dev_t dev;
|
|
||||||
cy_addr iobase;
|
|
||||||
int ncyu;
|
|
||||||
int unit;
|
|
||||||
|
|
||||||
unit = isdp->id_unit;
|
adapter = cyattach_common((cy_addr) isdp->id_maddr, 0);
|
||||||
if ((u_int)unit >= NCY)
|
if (adapter < 0)
|
||||||
return (0);
|
|
||||||
ncyu = cy_nr_cd1400s[unit];
|
|
||||||
if (ncyu == 0)
|
|
||||||
return (0);
|
return (0);
|
||||||
|
/*
|
||||||
|
* XXX
|
||||||
|
* This kludge is to allow ISA/PCI device specifications in the
|
||||||
|
* kernel config file to be in any order.
|
||||||
|
*/
|
||||||
|
if (isdp->id_unit != adapter) {
|
||||||
|
printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
|
||||||
|
isdp->id_unit = adapter; /* XXX */
|
||||||
|
}
|
||||||
isdp->id_ri_flags |= RI_FAST;
|
isdp->id_ri_flags |= RI_FAST;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
cy_iobase = (cy_addr)isdp->id_maddr;
|
int
|
||||||
unit *= CY_MAX_PORTS;
|
cyattach_common(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
int cyu, ncyu, unit, adapter;
|
||||||
|
dev_t dev;
|
||||||
|
cy_addr iobase;
|
||||||
|
|
||||||
|
adapter = cy_total_devices;
|
||||||
|
if ((u_int)adapter >= NCY) {
|
||||||
|
printf("cy%d: can't attach adapter: insufficient cy devices configured\n",
|
||||||
|
adapter);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
ncyu = cy_units(cy_iobase, cy_align);
|
||||||
|
if (ncyu == 0)
|
||||||
|
return (-1);
|
||||||
|
cy_nr_cd1400s[adapter] = ncyu;
|
||||||
|
cy_total_devices++;
|
||||||
|
|
||||||
|
unit = adapter * CY_MAX_PORTS;
|
||||||
for (cyu = 0; cyu < ncyu; ++cyu) {
|
for (cyu = 0; cyu < ncyu; ++cyu) {
|
||||||
int cdu;
|
int cdu;
|
||||||
|
|
||||||
iobase = (cy_addr) (isdp->id_maddr + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* Set up a receive timeout period of than 1+ ms. */
|
/* Set up a receive timeout period of than 1+ ms. */
|
||||||
cd_outb(iobase, CD1400_PPR,
|
cd_outb(iobase, CD1400_PPR, cy_align,
|
||||||
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
||||||
|
|
||||||
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
||||||
@ -522,6 +554,7 @@ sioattach(isdp)
|
|||||||
|
|
||||||
com->cy_iobase = cy_iobase;
|
com->cy_iobase = cy_iobase;
|
||||||
com->iobase = iobase;
|
com->iobase = iobase;
|
||||||
|
com->cy_align = cy_align;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't use all the flags from <sys/ttydefaults.h> since they
|
* We don't use all the flags from <sys/ttydefaults.h> since they
|
||||||
@ -574,9 +607,9 @@ sioattach(isdp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
return (1);
|
return (adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -664,8 +697,8 @@ open_top:
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
|
|
||||||
/* reset this channel */
|
/* reset this channel */
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resetting disables the transmitter and receiver as well as
|
* Resetting disables the transmitter and receiver as well as
|
||||||
@ -677,7 +710,7 @@ open_top:
|
|||||||
com->channel_control = 0;
|
com->channel_control = 0;
|
||||||
|
|
||||||
/* Encode per-board unit in LIVR for access in intr routines. */
|
/* Encode per-board unit in LIVR for access in intr routines. */
|
||||||
cd_outb(iobase, CD1400_LIVR,
|
cd_outb(iobase, CD1400_LIVR, com->cy_align,
|
||||||
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -732,8 +765,8 @@ open_top:
|
|||||||
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
||||||
disable_intr();
|
disable_intr();
|
||||||
com->prev_modem_status = com->last_modem_status
|
com->prev_modem_status = com->last_modem_status
|
||||||
= cd_inb(iobase, CD1400_MSVR2);
|
= cd_inb(iobase, CD1400_MSVR2, com->cy_align);
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -827,7 +860,7 @@ comhardclose(com)
|
|||||||
com->poll_output = FALSE;
|
com->poll_output = FALSE;
|
||||||
#endif
|
#endif
|
||||||
com->do_timestamp = 0;
|
com->do_timestamp = 0;
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
#if 0
|
#if 0
|
||||||
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
||||||
#endif
|
#endif
|
||||||
@ -837,7 +870,7 @@ comhardclose(com)
|
|||||||
outb(iobase + com_ier, 0);
|
outb(iobase + com_ier, 0);
|
||||||
#else
|
#else
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_SRER, com->intr_enable = 0);
|
cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
#endif
|
#endif
|
||||||
tp = com->tp;
|
tp = com->tp;
|
||||||
@ -859,7 +892,7 @@ comhardclose(com)
|
|||||||
com->channel_control = CD1400_CCR_CMDCHANCTL
|
com->channel_control = CD1400_CCR_CMDCHANCTL
|
||||||
| CD1400_CCR_XMTEN
|
| CD1400_CCR_XMTEN
|
||||||
| CD1400_CCR_RCVDIS;
|
| CD1400_CCR_RCVDIS;
|
||||||
cd1400_channel_cmd(iobase, com->channel_control);
|
cd1400_channel_cmd(iobase, com->channel_control, com->cy_align);
|
||||||
|
|
||||||
if (com->dtr_wait != 0) {
|
if (com->dtr_wait != 0) {
|
||||||
timeout(siodtrwakeup, com, com->dtr_wait);
|
timeout(siodtrwakeup, com, com->dtr_wait);
|
||||||
@ -948,20 +981,19 @@ void
|
|||||||
siointr(unit)
|
siointr(unit)
|
||||||
int unit;
|
int unit;
|
||||||
{
|
{
|
||||||
int baseu;
|
cy_addr cy_iobase, iobase;
|
||||||
cy_addr cy_iobase;
|
int baseu, cyu, cy_align;
|
||||||
int cyu;
|
u_char status;
|
||||||
cy_addr iobase;
|
|
||||||
u_char status;
|
|
||||||
|
|
||||||
baseu = unit * CY_MAX_PORTS;
|
baseu = unit * CY_MAX_PORTS;
|
||||||
cy_iobase = com_addr(baseu)->cy_iobase;
|
cy_iobase = com_addr(baseu)->cy_iobase;
|
||||||
|
cy_align = com_addr(baseu)->cy_align;
|
||||||
|
|
||||||
/* check each CD1400 in turn */
|
/* check each CD1400 in turn */
|
||||||
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
||||||
iobase = (cy_addr) (cy_iobase + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* poll to see if it has any work */
|
/* poll to see if it has any work */
|
||||||
status = cd_inb(iobase, CD1400_SVRR);
|
status = cd_inb(iobase, CD1400_SVRR, cy_align);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -981,13 +1013,13 @@ siointr(unit)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_rir = cd_inb(iobase, CD1400_RIR);
|
save_rir = cd_inb(iobase, CD1400_RIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter rx service */
|
/* enter rx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_rir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_rir);
|
||||||
|
|
||||||
serv_type = cd_inb(iobase, CD1400_RIVR);
|
serv_type = cd_inb(iobase, CD1400_RIVR, cy_align);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
@ -1002,9 +1034,9 @@ siointr(unit)
|
|||||||
|
|
||||||
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
||||||
++com->recv_exception;
|
++com->recv_exception;
|
||||||
line_status = cd_inb(iobase, CD1400_RDSR);
|
line_status = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
/* break/unnattached error bits or real input? */
|
/* break/unnattached error bits or real input? */
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
if (line_status & CD1400_RDSR_SPECIAL
|
if (line_status & CD1400_RDSR_SPECIAL
|
||||||
&& com->hotchar != 0)
|
&& com->hotchar != 0)
|
||||||
@ -1053,7 +1085,7 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
if (line_status & LSR_OE)
|
if (line_status & LSR_OE)
|
||||||
@ -1063,7 +1095,7 @@ siointr(unit)
|
|||||||
} else {
|
} else {
|
||||||
int ifree;
|
int ifree;
|
||||||
|
|
||||||
count = cd_inb(iobase, CD1400_RDCR);
|
count = cd_inb(iobase, CD1400_RDCR, cy_align);
|
||||||
com->bytes_in += count;
|
com->bytes_in += count;
|
||||||
ioptr = com->iptr;
|
ioptr = com->iptr;
|
||||||
ifree = com->ibufend - ioptr;
|
ifree = com->ibufend - ioptr;
|
||||||
@ -1075,7 +1107,7 @@ siointr(unit)
|
|||||||
microtime(&com->timestamp);
|
microtime(&com->timestamp);
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase,
|
recv_data = cd_inb(iobase,
|
||||||
CD1400_RDSR);
|
CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data
|
&& recv_data
|
||||||
@ -1090,7 +1122,7 @@ siointr(unit)
|
|||||||
com->delta_error_counts
|
com->delta_error_counts
|
||||||
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1107,12 +1139,12 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
com_events += count;
|
com_events += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1129,12 +1161,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_RIR,
|
cd_outb(iobase, CD1400_RIR, cy_align,
|
||||||
save_rir
|
save_rir
|
||||||
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_MDMCH) {
|
if (status & CD1400_SVRR_MDMCH) {
|
||||||
@ -1148,11 +1180,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_mir = cd_inb(iobase, CD1400_MIR);
|
save_mir = cd_inb(iobase, CD1400_MIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter modem service */
|
/* enter modem service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_mir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_mir);
|
||||||
|
|
||||||
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_mir & CD1400_MIR_CHAN));
|
+ (save_mir & CD1400_MIR_CHAN));
|
||||||
@ -1165,7 +1197,7 @@ cont:
|
|||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
#endif
|
#endif
|
||||||
++com->mdm;
|
++com->mdm;
|
||||||
modem_status = cd_inb(iobase, CD1400_MSVR2);
|
modem_status = cd_inb(iobase, CD1400_MSVR2, cy_align);
|
||||||
if (modem_status != com->last_modem_status) {
|
if (modem_status != com->last_modem_status) {
|
||||||
if (com->do_dcd_timestamp
|
if (com->do_dcd_timestamp
|
||||||
&& !(com->last_modem_status & MSR_DCD)
|
&& !(com->last_modem_status & MSR_DCD)
|
||||||
@ -1194,13 +1226,13 @@ cont:
|
|||||||
| CS_ODEVREADY)
|
| CS_ODEVREADY)
|
||||||
&& !(com->intr_enable
|
&& !(com->intr_enable
|
||||||
& CD1400_SRER_TXRDY))
|
& CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state &= ~CS_ODEVREADY;
|
com->state &= ~CS_ODEVREADY;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1210,12 +1242,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_MIR,
|
cd_outb(iobase, CD1400_MIR, cy_align,
|
||||||
save_mir
|
save_mir
|
||||||
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_TXRDY) {
|
if (status & CD1400_SVRR_TXRDY) {
|
||||||
@ -1228,11 +1260,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_tir = cd_inb(iobase, CD1400_TIR);
|
save_tir = cd_inb(iobase, CD1400_TIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter tx service */
|
/* enter tx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_tir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_tir);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ cyu * CD1400_NO_OF_CHANNELS
|
+ cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_tir & CD1400_TIR_CHAN));
|
+ (save_tir & CD1400_TIR_CHAN));
|
||||||
@ -1255,7 +1287,7 @@ cont:
|
|||||||
ocount = CD1400_TX_FIFO_SIZE;
|
ocount = CD1400_TX_FIFO_SIZE;
|
||||||
com->bytes_out += ocount;
|
com->bytes_out += ocount;
|
||||||
do
|
do
|
||||||
cd_outb(iobase, CD1400_TDR, *ioptr++);
|
cd_outb(iobase, CD1400_TDR, cy_align, *ioptr++);
|
||||||
while (--ocount != 0);
|
while (--ocount != 0);
|
||||||
com->obufq.l_head = ioptr;
|
com->obufq.l_head = ioptr;
|
||||||
if (ioptr >= com->obufq.l_tail) {
|
if (ioptr >= com->obufq.l_tail) {
|
||||||
@ -1271,7 +1303,7 @@ cont:
|
|||||||
} else {
|
} else {
|
||||||
/* output just completed */
|
/* output just completed */
|
||||||
com->state &= ~CS_BUSY;
|
com->state &= ~CS_BUSY;
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1285,18 +1317,18 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_TIR,
|
cd_outb(iobase, CD1400_TIR, cy_align,
|
||||||
save_tir
|
save_tir
|
||||||
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
schedsofttty();
|
schedsofttty();
|
||||||
}
|
}
|
||||||
@ -1406,7 +1438,7 @@ sioioctl(dev, cmd, data, flag, p)
|
|||||||
splx(s);
|
splx(s);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
cd_outb(iobase, CD1400_CAR, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
#if 0
|
#if 0
|
||||||
case TIOCSBRK:
|
case TIOCSBRK:
|
||||||
@ -1544,9 +1576,9 @@ repeat:
|
|||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
iobase = com->iobase,
|
iobase = com->iobase,
|
||||||
cd_outb(iobase, CD1400_CAR,
|
cd_outb(iobase, CD1400_CAR, com->cy_align,
|
||||||
unit & CD1400_CAR_CHAN),
|
unit & CD1400_CAR_CHAN),
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -1669,19 +1701,19 @@ comparam(tp, t)
|
|||||||
com = com_addr(unit);
|
com = com_addr(unit);
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
s = spltty();
|
s = spltty();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (odivisor == 0)
|
if (odivisor == 0)
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
||||||
else
|
else
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIS);
|
(void)commctl(com, TIOCM_DTR, DMBIS);
|
||||||
|
|
||||||
if (idivisor != 0) {
|
if (idivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_RBPR, idivisor);
|
cd_outb(iobase, CD1400_RBPR, com->cy_align, idivisor);
|
||||||
cd_outb(iobase, CD1400_RCOR, iprescaler);
|
cd_outb(iobase, CD1400_RCOR, com->cy_align, iprescaler);
|
||||||
}
|
}
|
||||||
if (odivisor != 0) {
|
if (odivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_TBPR, odivisor);
|
cd_outb(iobase, CD1400_TBPR, com->cy_align, odivisor);
|
||||||
cd_outb(iobase, CD1400_TCOR, oprescaler);
|
cd_outb(iobase, CD1400_TCOR, com->cy_align, oprescaler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1694,20 +1726,20 @@ comparam(tp, t)
|
|||||||
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
||||||
if (opt != com->channel_control) {
|
if (opt != com->channel_control) {
|
||||||
com->channel_control = opt;
|
com->channel_control = opt;
|
||||||
cd1400_channel_cmd(iobase, opt);
|
cd1400_channel_cmd(iobase, opt, com->cy_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Smarts
|
#ifdef Smarts
|
||||||
/* set special chars */
|
/* set special chars */
|
||||||
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
||||||
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR1, t->c_cc[VSTOP]);
|
cd_outb(iobase, CD1400_SCHR1, com->cy_align, t->c_cc[VSTOP]);
|
||||||
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR2, t->c_cc[VSTART]);
|
cd_outb(iobase, CD1400_SCHR2, com->cy_align, t->c_cc[VSTART]);
|
||||||
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR3, t->c_cc[VINTR]);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, t->c_cc[VINTR]);
|
||||||
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR4, t->c_cc[VSUSP]);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, t->c_cc[VSUSP]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1754,14 +1786,14 @@ comparam(tp, t)
|
|||||||
cor_change = 0;
|
cor_change = 0;
|
||||||
if (opt != com->cor[0]) {
|
if (opt != com->cor[0]) {
|
||||||
cor_change |= CD1400_CCR_COR1;
|
cor_change |= CD1400_CCR_COR1;
|
||||||
cd_outb(iobase, CD1400_COR1, com->cor[0] = opt);
|
cd_outb(iobase, CD1400_COR1, com->cy_align, com->cor[0] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set receive time-out period, normally to max(one char time, 5 ms).
|
* Set receive time-out period, normally to max(one char time, 5 ms).
|
||||||
*/
|
*/
|
||||||
if (t->c_ispeed == 0)
|
if (t->c_ispeed == 0)
|
||||||
itimeout = cd_inb(iobase, CD1400_RTPR);
|
itimeout = cd_inb(iobase, CD1400_RTPR, com->cy_align);
|
||||||
else {
|
else {
|
||||||
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
@ -1777,7 +1809,7 @@ comparam(tp, t)
|
|||||||
itimeout = t->c_cc[VTIME] * 10;
|
itimeout = t->c_cc[VTIME] * 10;
|
||||||
if (itimeout > 255)
|
if (itimeout > 255)
|
||||||
itimeout = 255;
|
itimeout = 255;
|
||||||
cd_outb(iobase, CD1400_RTPR, itimeout);
|
cd_outb(iobase, CD1400_RTPR, com->cy_align, itimeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 2 -
|
* set channel option register 2 -
|
||||||
@ -1796,7 +1828,7 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[1]) {
|
if (opt != com->cor[1]) {
|
||||||
cor_change |= CD1400_CCR_COR2;
|
cor_change |= CD1400_CCR_COR2;
|
||||||
cd_outb(iobase, CD1400_COR2, com->cor[1] = opt);
|
cd_outb(iobase, CD1400_COR2, com->cy_align, com->cor[1] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1814,12 +1846,12 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cor_change |= CD1400_CCR_COR3;
|
cor_change |= CD1400_CCR_COR3;
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify the CD1400 if COR1-3 have changed */
|
/* notify the CD1400 if COR1-3 have changed */
|
||||||
if (cor_change)
|
if (cor_change)
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 4 -
|
* set channel option register 4 -
|
||||||
@ -1858,7 +1890,7 @@ comparam(tp, t)
|
|||||||
#else
|
#else
|
||||||
opt |= CD1400_COR4_PFO_EXCEPTION;
|
opt |= CD1400_COR4_PFO_EXCEPTION;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR4, opt);
|
cd_outb(iobase, CD1400_COR4, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 5 -
|
* set channel option register 5 -
|
||||||
@ -1875,7 +1907,7 @@ comparam(tp, t)
|
|||||||
if (t->c_oflag & OCRNL)
|
if (t->c_oflag & OCRNL)
|
||||||
opt |= CD1400_COR5_OCRNL;
|
opt |= CD1400_COR5_OCRNL;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR5, opt);
|
cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX we probably alway want to track carrier changes, so that
|
* XXX we probably alway want to track carrier changes, so that
|
||||||
@ -1892,7 +1924,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR1_CTSzd;
|
opt |= CD1400_MCOR1_CTSzd;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR1, opt);
|
cd_outb(iobase, CD1400_MCOR1, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set modem change option register 2
|
* set modem change option register 2
|
||||||
@ -1903,7 +1935,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR2_CTSod;
|
opt |= CD1400_MCOR2_CTSod;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR2, opt);
|
cd_outb(iobase, CD1400_MCOR2, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX should have done this long ago, but there is too much state
|
* XXX should have done this long ago, but there is too much state
|
||||||
@ -1946,11 +1978,11 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
||||||
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,17 +2014,17 @@ comstart(tp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (tp->t_state & TS_TTSTOP) {
|
if (tp->t_state & TS_TTSTOP) {
|
||||||
com->state &= ~CS_TTGO;
|
com->state &= ~CS_TTGO;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state |= CS_TTGO;
|
com->state |= CS_TTGO;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
||||||
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
if (tp->t_state & TS_TBLOCK) {
|
if (tp->t_state & TS_TBLOCK) {
|
||||||
@ -2000,7 +2032,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -2013,7 +2045,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2048,7 +2080,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2076,7 +2108,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2182,18 +2214,18 @@ commctl(com, bits, how)
|
|||||||
switch (how) {
|
switch (how) {
|
||||||
case DMSET:
|
case DMSET:
|
||||||
com->mcr_image = mcr;
|
com->mcr_image = mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIS:
|
case DMBIS:
|
||||||
com->mcr_image = mcr = com->mcr_image | mcr;
|
com->mcr_image = mcr = com->mcr_image | mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIC:
|
case DMBIC:
|
||||||
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -2331,17 +2363,17 @@ disc_optim(tp, t, com)
|
|||||||
com->hotchar = 0;
|
com->hotchar = 0;
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
cd_outb(iobase, CD1400_CAR, com->unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, com->unit & CD1400_CAR_CHAN);
|
||||||
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
||||||
if (com->hotchar != 0) {
|
if (com->hotchar != 0) {
|
||||||
cd_outb(iobase, CD1400_SCHR3, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, com->hotchar);
|
||||||
cd_outb(iobase, CD1400_SCHR4, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, com->hotchar);
|
||||||
opt |= CD1400_COR3_SCD34;
|
opt |= CD1400_COR3_SCD34;
|
||||||
}
|
}
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
cd1400_channel_cmd(com->iobase,
|
cd1400_channel_cmd(com->iobase,
|
||||||
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3);
|
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3, com->cy_align);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2405,9 +2437,10 @@ comspeed(speed, prescaler_io)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cd1400_channel_cmd(iobase, cmd)
|
cd1400_channel_cmd(iobase, cmd, cy_align)
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int cmd;
|
int cmd;
|
||||||
|
int cy_align;
|
||||||
{
|
{
|
||||||
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
||||||
as the card is probed every round? Replaced delaycount with 8k.
|
as the card is probed every round? Replaced delaycount with 8k.
|
||||||
@ -2417,14 +2450,14 @@ cd1400_channel_cmd(iobase, cmd)
|
|||||||
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
||||||
|
|
||||||
/* wait for processing of previous command to complete */
|
/* wait for processing of previous command to complete */
|
||||||
while (cd_inb(iobase, CD1400_CCR) && maxwait--)
|
while (cd_inb(iobase, CD1400_CCR, cy_align) && maxwait--)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!maxwait)
|
if (!maxwait)
|
||||||
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
||||||
5 * 8 * 1024);
|
5 * 8 * 1024);
|
||||||
|
|
||||||
cd_outb(iobase, CD1400_CCR, cmd);
|
cd_outb(iobase, CD1400_CCR, cy_align, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -2448,7 +2481,7 @@ cystatus(unit)
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("cd1400 base address:\\tt%p\n", iobase);
|
printf("cd1400 base address:\\tt%p\n", iobase);
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
||||||
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
||||||
com->cor[0], com->cor[1], com->cor[2]);
|
com->cor[0], com->cor[1], com->cor[2]);
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cy.c,v 1.36 1996/10/04 10:33:08 davidg Exp $
|
* $Id: cy.c,v 1.37 1996/10/04 14:17:32 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cy.h"
|
#include "cy.h"
|
||||||
@ -141,7 +141,7 @@
|
|||||||
|
|
||||||
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
||||||
#define CD1400_xIVR_CHAN_SHIFT 3
|
#define CD1400_xIVR_CHAN_SHIFT 3
|
||||||
#define CD1400_xIVR_CHAN 0x0F /* XXX reduce to pack Cyclom-8Ys */
|
#define CD1400_xIVR_CHAN 0x1F /* XXX reduce to pack Cyclom-8Ys */
|
||||||
|
|
||||||
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
||||||
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
||||||
@ -153,7 +153,8 @@
|
|||||||
#define CONTROL_LOCK_STATE 0x40
|
#define CONTROL_LOCK_STATE 0x40
|
||||||
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
||||||
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
||||||
#define MINOR_TO_UNIT(mynor) ((mynor) & ~MINOR_MAGIC_MASK)
|
#define MINOR_TO_UNIT(mynor) (((mynor) >> 16) * CY_MAX_PORTS + \
|
||||||
|
(((mynor) & 0xff) & ~MINOR_MAGIC_MASK))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input buffer watermarks.
|
* Input buffer watermarks.
|
||||||
@ -262,6 +263,7 @@ struct com_s {
|
|||||||
|
|
||||||
cy_addr cy_iobase; /* base address of this port's cyclom */
|
cy_addr cy_iobase; /* base address of this port's cyclom */
|
||||||
cy_addr iobase; /* base address of this port's cd1400 */
|
cy_addr iobase; /* base address of this port's cd1400 */
|
||||||
|
int cy_align; /* index for register alignment */
|
||||||
|
|
||||||
struct tty *tp; /* cross reference */
|
struct tty *tp; /* cross reference */
|
||||||
|
|
||||||
@ -330,8 +332,10 @@ void siopoll __P((void));
|
|||||||
#define siommap nommap
|
#define siommap nommap
|
||||||
#define siostrategy nostrategy
|
#define siostrategy nostrategy
|
||||||
|
|
||||||
|
int cyattach_common __P((cy_addr cy_iobase, int cy_align));
|
||||||
|
static int cy_units __P((cy_addr cy_iobase, int cy_align));
|
||||||
static int sioattach __P((struct isa_device *dev));
|
static int sioattach __P((struct isa_device *dev));
|
||||||
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd));
|
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd, int cy_align));
|
||||||
static timeout_t siodtrwakeup;
|
static timeout_t siodtrwakeup;
|
||||||
static void comhardclose __P((struct com_s *com));
|
static void comhardclose __P((struct com_s *com));
|
||||||
#if 0
|
#if 0
|
||||||
@ -399,6 +403,7 @@ static u_int cy_timeouts;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cy_nr_cd1400s[NCY];
|
static int cy_nr_cd1400s[NCY];
|
||||||
|
static int cy_total_devices;
|
||||||
#undef RxFifoThreshold
|
#undef RxFifoThreshold
|
||||||
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
||||||
static int cy_chip_offset[] = {
|
static int cy_chip_offset[] = {
|
||||||
@ -416,16 +421,9 @@ static int
|
|||||||
sioprobe(dev)
|
sioprobe(dev)
|
||||||
struct isa_device *dev;
|
struct isa_device *dev;
|
||||||
{
|
{
|
||||||
int cyu;
|
|
||||||
u_char firmware_version;
|
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int unit;
|
|
||||||
|
|
||||||
iobase = (cy_addr)dev->id_maddr;
|
iobase = (cy_addr)dev->id_maddr;
|
||||||
unit = dev->id_unit;
|
|
||||||
if ((u_int)unit >= NCY)
|
|
||||||
return (0);
|
|
||||||
cy_nr_cd1400s[unit] = 0;
|
|
||||||
|
|
||||||
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
||||||
cy_inb(iobase, CY16_RESET); /* XXX? */
|
cy_inb(iobase, CY16_RESET); /* XXX? */
|
||||||
@ -435,22 +433,34 @@ sioprobe(dev)
|
|||||||
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
||||||
DELAY(500);
|
DELAY(500);
|
||||||
|
|
||||||
|
return (cy_units(iobase, 0) == 0 ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cy_units(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
cy_addr iobase;
|
||||||
|
int cyu;
|
||||||
|
|
||||||
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
||||||
int i;
|
int i;
|
||||||
|
u_char firmware_version;
|
||||||
|
|
||||||
iobase = (cy_addr) (dev->id_maddr + cy_chip_offset[cyu]);
|
iobase = cy_iobase + (cy_chip_offset[cyu] << cy_align);
|
||||||
/* wait for chip to become ready for new command */
|
/* wait for chip to become ready for new command */
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
DELAY(50);
|
DELAY(50);
|
||||||
if (!cd_inb(iobase, CD1400_CCR))
|
if (!cd_inb(iobase, CD1400_CCR, cy_align))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the GFRCR register */
|
/* clear the GFRCR register */
|
||||||
cd_outb(iobase, CD1400_GFRCR, 0);
|
cd_outb(iobase, CD1400_GFRCR, cy_align, 0);
|
||||||
|
|
||||||
/* issue a reset command */
|
/* issue a reset command */
|
||||||
cd_outb(iobase, CD1400_CCR,
|
cd_outb(iobase, CD1400_CCR, cy_align,
|
||||||
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
||||||
|
|
||||||
/* wait for the CD1400 to initialize itself */
|
/* wait for the CD1400 to initialize itself */
|
||||||
@ -458,7 +468,7 @@ sioprobe(dev)
|
|||||||
DELAY(50);
|
DELAY(50);
|
||||||
|
|
||||||
/* retrieve firmware version */
|
/* retrieve firmware version */
|
||||||
firmware_version = cd_inb(iobase, CD1400_GFRCR);
|
firmware_version = cd_inb(iobase, CD1400_GFRCR, cy_align);
|
||||||
if ((firmware_version & 0xf0) == 0x40)
|
if ((firmware_version & 0xf0) == 0x40)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -470,38 +480,60 @@ sioprobe(dev)
|
|||||||
*/
|
*/
|
||||||
if ((firmware_version & 0xf0) != 0x40)
|
if ((firmware_version & 0xf0) != 0x40)
|
||||||
break;
|
break;
|
||||||
++cy_nr_cd1400s[unit];
|
|
||||||
}
|
}
|
||||||
return (cy_nr_cd1400s[unit] == 0 ? 0 : -1);
|
return (cyu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sioattach(isdp)
|
sioattach(isdp)
|
||||||
struct isa_device *isdp;
|
struct isa_device *isdp;
|
||||||
{
|
{
|
||||||
int cyu;
|
int adapter;
|
||||||
cy_addr cy_iobase;
|
|
||||||
dev_t dev;
|
|
||||||
cy_addr iobase;
|
|
||||||
int ncyu;
|
|
||||||
int unit;
|
|
||||||
|
|
||||||
unit = isdp->id_unit;
|
adapter = cyattach_common((cy_addr) isdp->id_maddr, 0);
|
||||||
if ((u_int)unit >= NCY)
|
if (adapter < 0)
|
||||||
return (0);
|
|
||||||
ncyu = cy_nr_cd1400s[unit];
|
|
||||||
if (ncyu == 0)
|
|
||||||
return (0);
|
return (0);
|
||||||
|
/*
|
||||||
|
* XXX
|
||||||
|
* This kludge is to allow ISA/PCI device specifications in the
|
||||||
|
* kernel config file to be in any order.
|
||||||
|
*/
|
||||||
|
if (isdp->id_unit != adapter) {
|
||||||
|
printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
|
||||||
|
isdp->id_unit = adapter; /* XXX */
|
||||||
|
}
|
||||||
isdp->id_ri_flags |= RI_FAST;
|
isdp->id_ri_flags |= RI_FAST;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
cy_iobase = (cy_addr)isdp->id_maddr;
|
int
|
||||||
unit *= CY_MAX_PORTS;
|
cyattach_common(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
int cyu, ncyu, unit, adapter;
|
||||||
|
dev_t dev;
|
||||||
|
cy_addr iobase;
|
||||||
|
|
||||||
|
adapter = cy_total_devices;
|
||||||
|
if ((u_int)adapter >= NCY) {
|
||||||
|
printf("cy%d: can't attach adapter: insufficient cy devices configured\n",
|
||||||
|
adapter);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
ncyu = cy_units(cy_iobase, cy_align);
|
||||||
|
if (ncyu == 0)
|
||||||
|
return (-1);
|
||||||
|
cy_nr_cd1400s[adapter] = ncyu;
|
||||||
|
cy_total_devices++;
|
||||||
|
|
||||||
|
unit = adapter * CY_MAX_PORTS;
|
||||||
for (cyu = 0; cyu < ncyu; ++cyu) {
|
for (cyu = 0; cyu < ncyu; ++cyu) {
|
||||||
int cdu;
|
int cdu;
|
||||||
|
|
||||||
iobase = (cy_addr) (isdp->id_maddr + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* Set up a receive timeout period of than 1+ ms. */
|
/* Set up a receive timeout period of than 1+ ms. */
|
||||||
cd_outb(iobase, CD1400_PPR,
|
cd_outb(iobase, CD1400_PPR, cy_align,
|
||||||
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
||||||
|
|
||||||
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
||||||
@ -522,6 +554,7 @@ sioattach(isdp)
|
|||||||
|
|
||||||
com->cy_iobase = cy_iobase;
|
com->cy_iobase = cy_iobase;
|
||||||
com->iobase = iobase;
|
com->iobase = iobase;
|
||||||
|
com->cy_align = cy_align;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't use all the flags from <sys/ttydefaults.h> since they
|
* We don't use all the flags from <sys/ttydefaults.h> since they
|
||||||
@ -574,9 +607,9 @@ sioattach(isdp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
return (1);
|
return (adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -664,8 +697,8 @@ open_top:
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
|
|
||||||
/* reset this channel */
|
/* reset this channel */
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resetting disables the transmitter and receiver as well as
|
* Resetting disables the transmitter and receiver as well as
|
||||||
@ -677,7 +710,7 @@ open_top:
|
|||||||
com->channel_control = 0;
|
com->channel_control = 0;
|
||||||
|
|
||||||
/* Encode per-board unit in LIVR for access in intr routines. */
|
/* Encode per-board unit in LIVR for access in intr routines. */
|
||||||
cd_outb(iobase, CD1400_LIVR,
|
cd_outb(iobase, CD1400_LIVR, com->cy_align,
|
||||||
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -732,8 +765,8 @@ open_top:
|
|||||||
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
||||||
disable_intr();
|
disable_intr();
|
||||||
com->prev_modem_status = com->last_modem_status
|
com->prev_modem_status = com->last_modem_status
|
||||||
= cd_inb(iobase, CD1400_MSVR2);
|
= cd_inb(iobase, CD1400_MSVR2, com->cy_align);
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -827,7 +860,7 @@ comhardclose(com)
|
|||||||
com->poll_output = FALSE;
|
com->poll_output = FALSE;
|
||||||
#endif
|
#endif
|
||||||
com->do_timestamp = 0;
|
com->do_timestamp = 0;
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
#if 0
|
#if 0
|
||||||
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
||||||
#endif
|
#endif
|
||||||
@ -837,7 +870,7 @@ comhardclose(com)
|
|||||||
outb(iobase + com_ier, 0);
|
outb(iobase + com_ier, 0);
|
||||||
#else
|
#else
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_SRER, com->intr_enable = 0);
|
cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
#endif
|
#endif
|
||||||
tp = com->tp;
|
tp = com->tp;
|
||||||
@ -859,7 +892,7 @@ comhardclose(com)
|
|||||||
com->channel_control = CD1400_CCR_CMDCHANCTL
|
com->channel_control = CD1400_CCR_CMDCHANCTL
|
||||||
| CD1400_CCR_XMTEN
|
| CD1400_CCR_XMTEN
|
||||||
| CD1400_CCR_RCVDIS;
|
| CD1400_CCR_RCVDIS;
|
||||||
cd1400_channel_cmd(iobase, com->channel_control);
|
cd1400_channel_cmd(iobase, com->channel_control, com->cy_align);
|
||||||
|
|
||||||
if (com->dtr_wait != 0) {
|
if (com->dtr_wait != 0) {
|
||||||
timeout(siodtrwakeup, com, com->dtr_wait);
|
timeout(siodtrwakeup, com, com->dtr_wait);
|
||||||
@ -948,20 +981,19 @@ void
|
|||||||
siointr(unit)
|
siointr(unit)
|
||||||
int unit;
|
int unit;
|
||||||
{
|
{
|
||||||
int baseu;
|
cy_addr cy_iobase, iobase;
|
||||||
cy_addr cy_iobase;
|
int baseu, cyu, cy_align;
|
||||||
int cyu;
|
u_char status;
|
||||||
cy_addr iobase;
|
|
||||||
u_char status;
|
|
||||||
|
|
||||||
baseu = unit * CY_MAX_PORTS;
|
baseu = unit * CY_MAX_PORTS;
|
||||||
cy_iobase = com_addr(baseu)->cy_iobase;
|
cy_iobase = com_addr(baseu)->cy_iobase;
|
||||||
|
cy_align = com_addr(baseu)->cy_align;
|
||||||
|
|
||||||
/* check each CD1400 in turn */
|
/* check each CD1400 in turn */
|
||||||
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
||||||
iobase = (cy_addr) (cy_iobase + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* poll to see if it has any work */
|
/* poll to see if it has any work */
|
||||||
status = cd_inb(iobase, CD1400_SVRR);
|
status = cd_inb(iobase, CD1400_SVRR, cy_align);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -981,13 +1013,13 @@ siointr(unit)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_rir = cd_inb(iobase, CD1400_RIR);
|
save_rir = cd_inb(iobase, CD1400_RIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter rx service */
|
/* enter rx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_rir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_rir);
|
||||||
|
|
||||||
serv_type = cd_inb(iobase, CD1400_RIVR);
|
serv_type = cd_inb(iobase, CD1400_RIVR, cy_align);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
@ -1002,9 +1034,9 @@ siointr(unit)
|
|||||||
|
|
||||||
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
||||||
++com->recv_exception;
|
++com->recv_exception;
|
||||||
line_status = cd_inb(iobase, CD1400_RDSR);
|
line_status = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
/* break/unnattached error bits or real input? */
|
/* break/unnattached error bits or real input? */
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
if (line_status & CD1400_RDSR_SPECIAL
|
if (line_status & CD1400_RDSR_SPECIAL
|
||||||
&& com->hotchar != 0)
|
&& com->hotchar != 0)
|
||||||
@ -1053,7 +1085,7 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
if (line_status & LSR_OE)
|
if (line_status & LSR_OE)
|
||||||
@ -1063,7 +1095,7 @@ siointr(unit)
|
|||||||
} else {
|
} else {
|
||||||
int ifree;
|
int ifree;
|
||||||
|
|
||||||
count = cd_inb(iobase, CD1400_RDCR);
|
count = cd_inb(iobase, CD1400_RDCR, cy_align);
|
||||||
com->bytes_in += count;
|
com->bytes_in += count;
|
||||||
ioptr = com->iptr;
|
ioptr = com->iptr;
|
||||||
ifree = com->ibufend - ioptr;
|
ifree = com->ibufend - ioptr;
|
||||||
@ -1075,7 +1107,7 @@ siointr(unit)
|
|||||||
microtime(&com->timestamp);
|
microtime(&com->timestamp);
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase,
|
recv_data = cd_inb(iobase,
|
||||||
CD1400_RDSR);
|
CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data
|
&& recv_data
|
||||||
@ -1090,7 +1122,7 @@ siointr(unit)
|
|||||||
com->delta_error_counts
|
com->delta_error_counts
|
||||||
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1107,12 +1139,12 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
com_events += count;
|
com_events += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1129,12 +1161,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_RIR,
|
cd_outb(iobase, CD1400_RIR, cy_align,
|
||||||
save_rir
|
save_rir
|
||||||
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_MDMCH) {
|
if (status & CD1400_SVRR_MDMCH) {
|
||||||
@ -1148,11 +1180,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_mir = cd_inb(iobase, CD1400_MIR);
|
save_mir = cd_inb(iobase, CD1400_MIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter modem service */
|
/* enter modem service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_mir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_mir);
|
||||||
|
|
||||||
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_mir & CD1400_MIR_CHAN));
|
+ (save_mir & CD1400_MIR_CHAN));
|
||||||
@ -1165,7 +1197,7 @@ cont:
|
|||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
#endif
|
#endif
|
||||||
++com->mdm;
|
++com->mdm;
|
||||||
modem_status = cd_inb(iobase, CD1400_MSVR2);
|
modem_status = cd_inb(iobase, CD1400_MSVR2, cy_align);
|
||||||
if (modem_status != com->last_modem_status) {
|
if (modem_status != com->last_modem_status) {
|
||||||
if (com->do_dcd_timestamp
|
if (com->do_dcd_timestamp
|
||||||
&& !(com->last_modem_status & MSR_DCD)
|
&& !(com->last_modem_status & MSR_DCD)
|
||||||
@ -1194,13 +1226,13 @@ cont:
|
|||||||
| CS_ODEVREADY)
|
| CS_ODEVREADY)
|
||||||
&& !(com->intr_enable
|
&& !(com->intr_enable
|
||||||
& CD1400_SRER_TXRDY))
|
& CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state &= ~CS_ODEVREADY;
|
com->state &= ~CS_ODEVREADY;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1210,12 +1242,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_MIR,
|
cd_outb(iobase, CD1400_MIR, cy_align,
|
||||||
save_mir
|
save_mir
|
||||||
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_TXRDY) {
|
if (status & CD1400_SVRR_TXRDY) {
|
||||||
@ -1228,11 +1260,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_tir = cd_inb(iobase, CD1400_TIR);
|
save_tir = cd_inb(iobase, CD1400_TIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter tx service */
|
/* enter tx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_tir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_tir);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ cyu * CD1400_NO_OF_CHANNELS
|
+ cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_tir & CD1400_TIR_CHAN));
|
+ (save_tir & CD1400_TIR_CHAN));
|
||||||
@ -1255,7 +1287,7 @@ cont:
|
|||||||
ocount = CD1400_TX_FIFO_SIZE;
|
ocount = CD1400_TX_FIFO_SIZE;
|
||||||
com->bytes_out += ocount;
|
com->bytes_out += ocount;
|
||||||
do
|
do
|
||||||
cd_outb(iobase, CD1400_TDR, *ioptr++);
|
cd_outb(iobase, CD1400_TDR, cy_align, *ioptr++);
|
||||||
while (--ocount != 0);
|
while (--ocount != 0);
|
||||||
com->obufq.l_head = ioptr;
|
com->obufq.l_head = ioptr;
|
||||||
if (ioptr >= com->obufq.l_tail) {
|
if (ioptr >= com->obufq.l_tail) {
|
||||||
@ -1271,7 +1303,7 @@ cont:
|
|||||||
} else {
|
} else {
|
||||||
/* output just completed */
|
/* output just completed */
|
||||||
com->state &= ~CS_BUSY;
|
com->state &= ~CS_BUSY;
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1285,18 +1317,18 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_TIR,
|
cd_outb(iobase, CD1400_TIR, cy_align,
|
||||||
save_tir
|
save_tir
|
||||||
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
schedsofttty();
|
schedsofttty();
|
||||||
}
|
}
|
||||||
@ -1406,7 +1438,7 @@ sioioctl(dev, cmd, data, flag, p)
|
|||||||
splx(s);
|
splx(s);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
cd_outb(iobase, CD1400_CAR, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
#if 0
|
#if 0
|
||||||
case TIOCSBRK:
|
case TIOCSBRK:
|
||||||
@ -1544,9 +1576,9 @@ repeat:
|
|||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
iobase = com->iobase,
|
iobase = com->iobase,
|
||||||
cd_outb(iobase, CD1400_CAR,
|
cd_outb(iobase, CD1400_CAR, com->cy_align,
|
||||||
unit & CD1400_CAR_CHAN),
|
unit & CD1400_CAR_CHAN),
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -1669,19 +1701,19 @@ comparam(tp, t)
|
|||||||
com = com_addr(unit);
|
com = com_addr(unit);
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
s = spltty();
|
s = spltty();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (odivisor == 0)
|
if (odivisor == 0)
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
||||||
else
|
else
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIS);
|
(void)commctl(com, TIOCM_DTR, DMBIS);
|
||||||
|
|
||||||
if (idivisor != 0) {
|
if (idivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_RBPR, idivisor);
|
cd_outb(iobase, CD1400_RBPR, com->cy_align, idivisor);
|
||||||
cd_outb(iobase, CD1400_RCOR, iprescaler);
|
cd_outb(iobase, CD1400_RCOR, com->cy_align, iprescaler);
|
||||||
}
|
}
|
||||||
if (odivisor != 0) {
|
if (odivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_TBPR, odivisor);
|
cd_outb(iobase, CD1400_TBPR, com->cy_align, odivisor);
|
||||||
cd_outb(iobase, CD1400_TCOR, oprescaler);
|
cd_outb(iobase, CD1400_TCOR, com->cy_align, oprescaler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1694,20 +1726,20 @@ comparam(tp, t)
|
|||||||
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
||||||
if (opt != com->channel_control) {
|
if (opt != com->channel_control) {
|
||||||
com->channel_control = opt;
|
com->channel_control = opt;
|
||||||
cd1400_channel_cmd(iobase, opt);
|
cd1400_channel_cmd(iobase, opt, com->cy_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Smarts
|
#ifdef Smarts
|
||||||
/* set special chars */
|
/* set special chars */
|
||||||
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
||||||
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR1, t->c_cc[VSTOP]);
|
cd_outb(iobase, CD1400_SCHR1, com->cy_align, t->c_cc[VSTOP]);
|
||||||
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR2, t->c_cc[VSTART]);
|
cd_outb(iobase, CD1400_SCHR2, com->cy_align, t->c_cc[VSTART]);
|
||||||
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR3, t->c_cc[VINTR]);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, t->c_cc[VINTR]);
|
||||||
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR4, t->c_cc[VSUSP]);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, t->c_cc[VSUSP]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1754,14 +1786,14 @@ comparam(tp, t)
|
|||||||
cor_change = 0;
|
cor_change = 0;
|
||||||
if (opt != com->cor[0]) {
|
if (opt != com->cor[0]) {
|
||||||
cor_change |= CD1400_CCR_COR1;
|
cor_change |= CD1400_CCR_COR1;
|
||||||
cd_outb(iobase, CD1400_COR1, com->cor[0] = opt);
|
cd_outb(iobase, CD1400_COR1, com->cy_align, com->cor[0] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set receive time-out period, normally to max(one char time, 5 ms).
|
* Set receive time-out period, normally to max(one char time, 5 ms).
|
||||||
*/
|
*/
|
||||||
if (t->c_ispeed == 0)
|
if (t->c_ispeed == 0)
|
||||||
itimeout = cd_inb(iobase, CD1400_RTPR);
|
itimeout = cd_inb(iobase, CD1400_RTPR, com->cy_align);
|
||||||
else {
|
else {
|
||||||
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
@ -1777,7 +1809,7 @@ comparam(tp, t)
|
|||||||
itimeout = t->c_cc[VTIME] * 10;
|
itimeout = t->c_cc[VTIME] * 10;
|
||||||
if (itimeout > 255)
|
if (itimeout > 255)
|
||||||
itimeout = 255;
|
itimeout = 255;
|
||||||
cd_outb(iobase, CD1400_RTPR, itimeout);
|
cd_outb(iobase, CD1400_RTPR, com->cy_align, itimeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 2 -
|
* set channel option register 2 -
|
||||||
@ -1796,7 +1828,7 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[1]) {
|
if (opt != com->cor[1]) {
|
||||||
cor_change |= CD1400_CCR_COR2;
|
cor_change |= CD1400_CCR_COR2;
|
||||||
cd_outb(iobase, CD1400_COR2, com->cor[1] = opt);
|
cd_outb(iobase, CD1400_COR2, com->cy_align, com->cor[1] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1814,12 +1846,12 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cor_change |= CD1400_CCR_COR3;
|
cor_change |= CD1400_CCR_COR3;
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify the CD1400 if COR1-3 have changed */
|
/* notify the CD1400 if COR1-3 have changed */
|
||||||
if (cor_change)
|
if (cor_change)
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 4 -
|
* set channel option register 4 -
|
||||||
@ -1858,7 +1890,7 @@ comparam(tp, t)
|
|||||||
#else
|
#else
|
||||||
opt |= CD1400_COR4_PFO_EXCEPTION;
|
opt |= CD1400_COR4_PFO_EXCEPTION;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR4, opt);
|
cd_outb(iobase, CD1400_COR4, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 5 -
|
* set channel option register 5 -
|
||||||
@ -1875,7 +1907,7 @@ comparam(tp, t)
|
|||||||
if (t->c_oflag & OCRNL)
|
if (t->c_oflag & OCRNL)
|
||||||
opt |= CD1400_COR5_OCRNL;
|
opt |= CD1400_COR5_OCRNL;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR5, opt);
|
cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX we probably alway want to track carrier changes, so that
|
* XXX we probably alway want to track carrier changes, so that
|
||||||
@ -1892,7 +1924,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR1_CTSzd;
|
opt |= CD1400_MCOR1_CTSzd;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR1, opt);
|
cd_outb(iobase, CD1400_MCOR1, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set modem change option register 2
|
* set modem change option register 2
|
||||||
@ -1903,7 +1935,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR2_CTSod;
|
opt |= CD1400_MCOR2_CTSod;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR2, opt);
|
cd_outb(iobase, CD1400_MCOR2, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX should have done this long ago, but there is too much state
|
* XXX should have done this long ago, but there is too much state
|
||||||
@ -1946,11 +1978,11 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
||||||
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,17 +2014,17 @@ comstart(tp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (tp->t_state & TS_TTSTOP) {
|
if (tp->t_state & TS_TTSTOP) {
|
||||||
com->state &= ~CS_TTGO;
|
com->state &= ~CS_TTGO;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state |= CS_TTGO;
|
com->state |= CS_TTGO;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
||||||
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
if (tp->t_state & TS_TBLOCK) {
|
if (tp->t_state & TS_TBLOCK) {
|
||||||
@ -2000,7 +2032,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -2013,7 +2045,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2048,7 +2080,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2076,7 +2108,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2182,18 +2214,18 @@ commctl(com, bits, how)
|
|||||||
switch (how) {
|
switch (how) {
|
||||||
case DMSET:
|
case DMSET:
|
||||||
com->mcr_image = mcr;
|
com->mcr_image = mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIS:
|
case DMBIS:
|
||||||
com->mcr_image = mcr = com->mcr_image | mcr;
|
com->mcr_image = mcr = com->mcr_image | mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIC:
|
case DMBIC:
|
||||||
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -2331,17 +2363,17 @@ disc_optim(tp, t, com)
|
|||||||
com->hotchar = 0;
|
com->hotchar = 0;
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
cd_outb(iobase, CD1400_CAR, com->unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, com->unit & CD1400_CAR_CHAN);
|
||||||
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
||||||
if (com->hotchar != 0) {
|
if (com->hotchar != 0) {
|
||||||
cd_outb(iobase, CD1400_SCHR3, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, com->hotchar);
|
||||||
cd_outb(iobase, CD1400_SCHR4, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, com->hotchar);
|
||||||
opt |= CD1400_COR3_SCD34;
|
opt |= CD1400_COR3_SCD34;
|
||||||
}
|
}
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
cd1400_channel_cmd(com->iobase,
|
cd1400_channel_cmd(com->iobase,
|
||||||
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3);
|
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3, com->cy_align);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2405,9 +2437,10 @@ comspeed(speed, prescaler_io)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cd1400_channel_cmd(iobase, cmd)
|
cd1400_channel_cmd(iobase, cmd, cy_align)
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int cmd;
|
int cmd;
|
||||||
|
int cy_align;
|
||||||
{
|
{
|
||||||
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
||||||
as the card is probed every round? Replaced delaycount with 8k.
|
as the card is probed every round? Replaced delaycount with 8k.
|
||||||
@ -2417,14 +2450,14 @@ cd1400_channel_cmd(iobase, cmd)
|
|||||||
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
||||||
|
|
||||||
/* wait for processing of previous command to complete */
|
/* wait for processing of previous command to complete */
|
||||||
while (cd_inb(iobase, CD1400_CCR) && maxwait--)
|
while (cd_inb(iobase, CD1400_CCR, cy_align) && maxwait--)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!maxwait)
|
if (!maxwait)
|
||||||
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
||||||
5 * 8 * 1024);
|
5 * 8 * 1024);
|
||||||
|
|
||||||
cd_outb(iobase, CD1400_CCR, cmd);
|
cd_outb(iobase, CD1400_CCR, cy_align, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -2448,7 +2481,7 @@ cystatus(unit)
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("cd1400 base address:\\tt%p\n", iobase);
|
printf("cd1400 base address:\\tt%p\n", iobase);
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
||||||
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
||||||
com->cor[0], com->cor[1], com->cor[2]);
|
com->cor[0], com->cor[1], com->cor[2]);
|
||||||
|
132
sys/dev/cy/cy_pci.c
Normal file
132
sys/dev/cy/cy_pci.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, David Greenman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice unmodified, this list of conditions, and the following
|
||||||
|
* disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cyclades Y PCI serial interface driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pci.h>
|
||||||
|
#if NPCI > 0
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <vm/vm.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
|
#include <pci/pcivar.h>
|
||||||
|
|
||||||
|
#include <pci/cy_pcireg.h>
|
||||||
|
|
||||||
|
static char *cy_probe __P((pcici_t, pcidi_t));
|
||||||
|
static void cy_attach __P((pcici_t, int));
|
||||||
|
|
||||||
|
extern int cyattach_common(void *, int); /* Not exactly correct */
|
||||||
|
extern void cyintr(int);
|
||||||
|
|
||||||
|
static u_long cy_count;
|
||||||
|
|
||||||
|
static struct pci_device cy_device = {
|
||||||
|
"cy",
|
||||||
|
cy_probe,
|
||||||
|
cy_attach,
|
||||||
|
&cy_count,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
DATA_SET(pcidevice_set, cy_device);
|
||||||
|
|
||||||
|
static char *
|
||||||
|
cy_probe(config_id, device_id)
|
||||||
|
pcici_t config_id;
|
||||||
|
pcidi_t device_id;
|
||||||
|
{
|
||||||
|
if ((device_id & 0xffff) == CY_VENDORID_CYCLADES &&
|
||||||
|
((device_id >> 16) == CY_DEVICEID_CYCLOM_Y_1 ||
|
||||||
|
(device_id >> 16) == CY_DEVICEID_CYCLOM_Y_2))
|
||||||
|
return ("Cyclades Cyclom-Y Serial Adapter");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cy_attach(config_id, unit)
|
||||||
|
pcici_t config_id;
|
||||||
|
int unit;
|
||||||
|
{
|
||||||
|
vm_offset_t paddr;
|
||||||
|
void *vaddr;
|
||||||
|
u_int32_t ioport;
|
||||||
|
int adapter;
|
||||||
|
|
||||||
|
ioport = (u_int32_t) pci_conf_read(config_id, CY_PCI_BASE_ADDR1) & ~0x3;
|
||||||
|
paddr = pci_conf_read(config_id, CY_PCI_BASE_ADDR2) & ~0xf;
|
||||||
|
#if 0
|
||||||
|
if (!pci_map_mem(config_id, CY_PCI_BASE_ADDR2, &vaddr, &paddr)) {
|
||||||
|
printf("cy%d: couldn't map shared memory\n", unit);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
vaddr = pmap_mapdev(paddr, 0x4000);
|
||||||
|
|
||||||
|
adapter = cyattach_common(vaddr, 1);
|
||||||
|
if (adapter < 0) {
|
||||||
|
/*
|
||||||
|
* No ports found. Release resources and punt.
|
||||||
|
*/
|
||||||
|
printf("cy%d: no ports found!", unit);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate our interrupt.
|
||||||
|
* XXX Using the ISA interrupt handler directly is a bit of a violation
|
||||||
|
* since it doesn't actually take the same argument. For PCI, the
|
||||||
|
* argument is a void * token, but for ISA it is a unit. Since
|
||||||
|
* there is no overlap in PCI/ISA unit numbers for this driver, and
|
||||||
|
* since the ISA driver must handle the interrupt anyway, we use
|
||||||
|
* the unit number as the token even for PCI.
|
||||||
|
*/
|
||||||
|
if (!pci_map_int(config_id, (pci_inthand_t *)cyintr, (void *)adapter, &tty_imask)) {
|
||||||
|
printf("cy%d: couldn't map interrupt\n", unit);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Enable the "local" interrupt input to generate a
|
||||||
|
* PCI interrupt.
|
||||||
|
*/
|
||||||
|
outw(ioport + CY_PLX_ICS, inw(CY_PLX_ICS) |
|
||||||
|
CY_PLX_ICS_IENABLE | CY_PLX_ICS_LOCAL_IENABLE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* XXX should release any allocated virtual memory */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NPCI > 0 */
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cyreg.h,v 1.1 1995/07/05 12:15:51 bde Exp $
|
* $Id: cyreg.h,v 1.2 1996/10/04 10:33:13 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,22 +36,21 @@
|
|||||||
#define CY8_SVCACKR 0x100
|
#define CY8_SVCACKR 0x100
|
||||||
#define CY8_SVCACKT 0x200
|
#define CY8_SVCACKT 0x200
|
||||||
#define CY8_SVCACKM 0x300
|
#define CY8_SVCACKM 0x300
|
||||||
#define CY_CD1400_MEMSIZE 0x400
|
#define CY16_RESET 0x0a00
|
||||||
#define CY16_RESET 0x1400
|
#define CY_CLEAR_INTR 0x0c00 /* intr ack address */
|
||||||
#define CY_CLEAR_INTR 0x1800 /* intr ack address */
|
|
||||||
|
|
||||||
#define CY_MAX_CD1400s 8 /* for Cyclom-32Y */
|
#define CY_MAX_CD1400s 8 /* for Cyclom-32Y */
|
||||||
|
|
||||||
#define CY_CLOCK 25000000 /* baud rate clock */
|
#define CY_CLOCK 25000000 /* baud rate clock */
|
||||||
|
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
#define cd_inb(iobase, reg) (++cd_inbs, *((iobase) + 2 * (reg)))
|
#define cd_inb(iobase, reg, cy_align) (++cd_inbs, *((iobase) + ((reg)*2 << (cy_align))))
|
||||||
#define cy_inb(iobase, reg) (++cy_inbs, *((iobase) + (reg)))
|
#define cy_inb(iobase, reg) (++cy_inbs, *((iobase) + (reg)))
|
||||||
#define cd_outb(iobase, reg, val) (++cd_outbs, (void)(*((iobase) + 2 * (reg)) = (val)))
|
#define cd_outb(iobase, reg, cy_align, val) (++cd_outbs, (void)(*((iobase) + ((reg)*2 << (cy_align))) = (val)))
|
||||||
#define cy_outb(iobase, reg, val) (++cy_outbs, (void)(*((iobase) + (reg)) = (val)))
|
#define cy_outb(iobase, reg, val) (++cy_outbs, (void)(*((iobase) + (reg)) = (val)))
|
||||||
#else
|
#else
|
||||||
#define cd_inb(iobase, reg) (*((iobase) + 2 * (reg)))
|
#define cd_inb(iobase, reg, cy_align) (*((iobase) + ((reg)*2 << (cy_align))))
|
||||||
#define cy_inb(iobase, reg) (*((iobase) + (reg)))
|
#define cy_inb(iobase, reg) (*((iobase) + (reg)))
|
||||||
#define cd_outb(iobase, reg, val) ((void)(*((iobase) + 2 * (reg)) = (val)))
|
#define cd_outb(iobase, reg, cy_align, val) ((void)(*((iobase) + ((reg)*2 << (cy_align))) = (val)))
|
||||||
#define cy_outb(iobase, reg, val) ((void)(*((iobase) + (reg)) = (val)))
|
#define cy_outb(iobase, reg, val) ((void)(*((iobase) + (reg)) = (val)))
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cy.c,v 1.36 1996/10/04 10:33:08 davidg Exp $
|
* $Id: cy.c,v 1.37 1996/10/04 14:17:32 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cy.h"
|
#include "cy.h"
|
||||||
@ -141,7 +141,7 @@
|
|||||||
|
|
||||||
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
/* We encode the cyclom unit number (cyu) in spare bits in the IVR's. */
|
||||||
#define CD1400_xIVR_CHAN_SHIFT 3
|
#define CD1400_xIVR_CHAN_SHIFT 3
|
||||||
#define CD1400_xIVR_CHAN 0x0F /* XXX reduce to pack Cyclom-8Ys */
|
#define CD1400_xIVR_CHAN 0x1F /* XXX reduce to pack Cyclom-8Ys */
|
||||||
|
|
||||||
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
#define LOTS_OF_EVENTS 64 /* helps separate urgent events from input */
|
||||||
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
#define RB_I_HIGH_WATER (TTYHOG - 2 * RS_IBUFSIZE)
|
||||||
@ -153,7 +153,8 @@
|
|||||||
#define CONTROL_LOCK_STATE 0x40
|
#define CONTROL_LOCK_STATE 0x40
|
||||||
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
#define DEV_TO_UNIT(dev) (MINOR_TO_UNIT(minor(dev)))
|
||||||
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
#define MINOR_MAGIC_MASK (CALLOUT_MASK | CONTROL_MASK)
|
||||||
#define MINOR_TO_UNIT(mynor) ((mynor) & ~MINOR_MAGIC_MASK)
|
#define MINOR_TO_UNIT(mynor) (((mynor) >> 16) * CY_MAX_PORTS + \
|
||||||
|
(((mynor) & 0xff) & ~MINOR_MAGIC_MASK))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Input buffer watermarks.
|
* Input buffer watermarks.
|
||||||
@ -262,6 +263,7 @@ struct com_s {
|
|||||||
|
|
||||||
cy_addr cy_iobase; /* base address of this port's cyclom */
|
cy_addr cy_iobase; /* base address of this port's cyclom */
|
||||||
cy_addr iobase; /* base address of this port's cd1400 */
|
cy_addr iobase; /* base address of this port's cd1400 */
|
||||||
|
int cy_align; /* index for register alignment */
|
||||||
|
|
||||||
struct tty *tp; /* cross reference */
|
struct tty *tp; /* cross reference */
|
||||||
|
|
||||||
@ -330,8 +332,10 @@ void siopoll __P((void));
|
|||||||
#define siommap nommap
|
#define siommap nommap
|
||||||
#define siostrategy nostrategy
|
#define siostrategy nostrategy
|
||||||
|
|
||||||
|
int cyattach_common __P((cy_addr cy_iobase, int cy_align));
|
||||||
|
static int cy_units __P((cy_addr cy_iobase, int cy_align));
|
||||||
static int sioattach __P((struct isa_device *dev));
|
static int sioattach __P((struct isa_device *dev));
|
||||||
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd));
|
static void cd1400_channel_cmd __P((cy_addr iobase, int cmd, int cy_align));
|
||||||
static timeout_t siodtrwakeup;
|
static timeout_t siodtrwakeup;
|
||||||
static void comhardclose __P((struct com_s *com));
|
static void comhardclose __P((struct com_s *com));
|
||||||
#if 0
|
#if 0
|
||||||
@ -399,6 +403,7 @@ static u_int cy_timeouts;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cy_nr_cd1400s[NCY];
|
static int cy_nr_cd1400s[NCY];
|
||||||
|
static int cy_total_devices;
|
||||||
#undef RxFifoThreshold
|
#undef RxFifoThreshold
|
||||||
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
static int volatile RxFifoThreshold = (CD1400_RX_FIFO_SIZE / 2);
|
||||||
static int cy_chip_offset[] = {
|
static int cy_chip_offset[] = {
|
||||||
@ -416,16 +421,9 @@ static int
|
|||||||
sioprobe(dev)
|
sioprobe(dev)
|
||||||
struct isa_device *dev;
|
struct isa_device *dev;
|
||||||
{
|
{
|
||||||
int cyu;
|
|
||||||
u_char firmware_version;
|
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int unit;
|
|
||||||
|
|
||||||
iobase = (cy_addr)dev->id_maddr;
|
iobase = (cy_addr)dev->id_maddr;
|
||||||
unit = dev->id_unit;
|
|
||||||
if ((u_int)unit >= NCY)
|
|
||||||
return (0);
|
|
||||||
cy_nr_cd1400s[unit] = 0;
|
|
||||||
|
|
||||||
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
/* Cyclom-16Y hardware reset (Cyclom-8Ys don't care) */
|
||||||
cy_inb(iobase, CY16_RESET); /* XXX? */
|
cy_inb(iobase, CY16_RESET); /* XXX? */
|
||||||
@ -435,22 +433,34 @@ sioprobe(dev)
|
|||||||
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
cy_outb(iobase, CY_CLEAR_INTR, 0);
|
||||||
DELAY(500);
|
DELAY(500);
|
||||||
|
|
||||||
|
return (cy_units(iobase, 0) == 0 ? 0 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cy_units(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
cy_addr iobase;
|
||||||
|
int cyu;
|
||||||
|
|
||||||
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
for (cyu = 0; cyu < CY_MAX_CD1400s; ++cyu) {
|
||||||
int i;
|
int i;
|
||||||
|
u_char firmware_version;
|
||||||
|
|
||||||
iobase = (cy_addr) (dev->id_maddr + cy_chip_offset[cyu]);
|
iobase = cy_iobase + (cy_chip_offset[cyu] << cy_align);
|
||||||
/* wait for chip to become ready for new command */
|
/* wait for chip to become ready for new command */
|
||||||
for (i = 0; i < 10; i++) {
|
for (i = 0; i < 10; i++) {
|
||||||
DELAY(50);
|
DELAY(50);
|
||||||
if (!cd_inb(iobase, CD1400_CCR))
|
if (!cd_inb(iobase, CD1400_CCR, cy_align))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear the GFRCR register */
|
/* clear the GFRCR register */
|
||||||
cd_outb(iobase, CD1400_GFRCR, 0);
|
cd_outb(iobase, CD1400_GFRCR, cy_align, 0);
|
||||||
|
|
||||||
/* issue a reset command */
|
/* issue a reset command */
|
||||||
cd_outb(iobase, CD1400_CCR,
|
cd_outb(iobase, CD1400_CCR, cy_align,
|
||||||
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET);
|
||||||
|
|
||||||
/* wait for the CD1400 to initialize itself */
|
/* wait for the CD1400 to initialize itself */
|
||||||
@ -458,7 +468,7 @@ sioprobe(dev)
|
|||||||
DELAY(50);
|
DELAY(50);
|
||||||
|
|
||||||
/* retrieve firmware version */
|
/* retrieve firmware version */
|
||||||
firmware_version = cd_inb(iobase, CD1400_GFRCR);
|
firmware_version = cd_inb(iobase, CD1400_GFRCR, cy_align);
|
||||||
if ((firmware_version & 0xf0) == 0x40)
|
if ((firmware_version & 0xf0) == 0x40)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -470,38 +480,60 @@ sioprobe(dev)
|
|||||||
*/
|
*/
|
||||||
if ((firmware_version & 0xf0) != 0x40)
|
if ((firmware_version & 0xf0) != 0x40)
|
||||||
break;
|
break;
|
||||||
++cy_nr_cd1400s[unit];
|
|
||||||
}
|
}
|
||||||
return (cy_nr_cd1400s[unit] == 0 ? 0 : -1);
|
return (cyu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sioattach(isdp)
|
sioattach(isdp)
|
||||||
struct isa_device *isdp;
|
struct isa_device *isdp;
|
||||||
{
|
{
|
||||||
int cyu;
|
int adapter;
|
||||||
cy_addr cy_iobase;
|
|
||||||
dev_t dev;
|
|
||||||
cy_addr iobase;
|
|
||||||
int ncyu;
|
|
||||||
int unit;
|
|
||||||
|
|
||||||
unit = isdp->id_unit;
|
adapter = cyattach_common((cy_addr) isdp->id_maddr, 0);
|
||||||
if ((u_int)unit >= NCY)
|
if (adapter < 0)
|
||||||
return (0);
|
|
||||||
ncyu = cy_nr_cd1400s[unit];
|
|
||||||
if (ncyu == 0)
|
|
||||||
return (0);
|
return (0);
|
||||||
|
/*
|
||||||
|
* XXX
|
||||||
|
* This kludge is to allow ISA/PCI device specifications in the
|
||||||
|
* kernel config file to be in any order.
|
||||||
|
*/
|
||||||
|
if (isdp->id_unit != adapter) {
|
||||||
|
printf("cy%d: attached as cy%d\n", isdp->id_unit, adapter);
|
||||||
|
isdp->id_unit = adapter; /* XXX */
|
||||||
|
}
|
||||||
isdp->id_ri_flags |= RI_FAST;
|
isdp->id_ri_flags |= RI_FAST;
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
cy_iobase = (cy_addr)isdp->id_maddr;
|
int
|
||||||
unit *= CY_MAX_PORTS;
|
cyattach_common(cy_iobase, cy_align)
|
||||||
|
cy_addr cy_iobase;
|
||||||
|
int cy_align;
|
||||||
|
{
|
||||||
|
int cyu, ncyu, unit, adapter;
|
||||||
|
dev_t dev;
|
||||||
|
cy_addr iobase;
|
||||||
|
|
||||||
|
adapter = cy_total_devices;
|
||||||
|
if ((u_int)adapter >= NCY) {
|
||||||
|
printf("cy%d: can't attach adapter: insufficient cy devices configured\n",
|
||||||
|
adapter);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
ncyu = cy_units(cy_iobase, cy_align);
|
||||||
|
if (ncyu == 0)
|
||||||
|
return (-1);
|
||||||
|
cy_nr_cd1400s[adapter] = ncyu;
|
||||||
|
cy_total_devices++;
|
||||||
|
|
||||||
|
unit = adapter * CY_MAX_PORTS;
|
||||||
for (cyu = 0; cyu < ncyu; ++cyu) {
|
for (cyu = 0; cyu < ncyu; ++cyu) {
|
||||||
int cdu;
|
int cdu;
|
||||||
|
|
||||||
iobase = (cy_addr) (isdp->id_maddr + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* Set up a receive timeout period of than 1+ ms. */
|
/* Set up a receive timeout period of than 1+ ms. */
|
||||||
cd_outb(iobase, CD1400_PPR,
|
cd_outb(iobase, CD1400_PPR, cy_align,
|
||||||
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
howmany(CY_CLOCK / CD1400_PPR_PRESCALER, 1000));
|
||||||
|
|
||||||
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
for (cdu = 0; cdu < CD1400_NO_OF_CHANNELS; ++cdu, ++unit) {
|
||||||
@ -522,6 +554,7 @@ sioattach(isdp)
|
|||||||
|
|
||||||
com->cy_iobase = cy_iobase;
|
com->cy_iobase = cy_iobase;
|
||||||
com->iobase = iobase;
|
com->iobase = iobase;
|
||||||
|
com->cy_align = cy_align;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't use all the flags from <sys/ttydefaults.h> since they
|
* We don't use all the flags from <sys/ttydefaults.h> since they
|
||||||
@ -574,9 +607,9 @@ sioattach(isdp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
return (1);
|
return (adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -664,8 +697,8 @@ open_top:
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
|
|
||||||
/* reset this channel */
|
/* reset this channel */
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDRESET, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resetting disables the transmitter and receiver as well as
|
* Resetting disables the transmitter and receiver as well as
|
||||||
@ -677,7 +710,7 @@ open_top:
|
|||||||
com->channel_control = 0;
|
com->channel_control = 0;
|
||||||
|
|
||||||
/* Encode per-board unit in LIVR for access in intr routines. */
|
/* Encode per-board unit in LIVR for access in intr routines. */
|
||||||
cd_outb(iobase, CD1400_LIVR,
|
cd_outb(iobase, CD1400_LIVR, com->cy_align,
|
||||||
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
(unit & CD1400_xIVR_CHAN) << CD1400_xIVR_CHAN_SHIFT);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -732,8 +765,8 @@ open_top:
|
|||||||
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
(void)commctl(com, TIOCM_DTR | TIOCM_RTS, DMSET);
|
||||||
disable_intr();
|
disable_intr();
|
||||||
com->prev_modem_status = com->last_modem_status
|
com->prev_modem_status = com->last_modem_status
|
||||||
= cd_inb(iobase, CD1400_MSVR2);
|
= cd_inb(iobase, CD1400_MSVR2, com->cy_align);
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
= CD1400_SRER_MDMCH | CD1400_SRER_RXDATA);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -827,7 +860,7 @@ comhardclose(com)
|
|||||||
com->poll_output = FALSE;
|
com->poll_output = FALSE;
|
||||||
#endif
|
#endif
|
||||||
com->do_timestamp = 0;
|
com->do_timestamp = 0;
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
#if 0
|
#if 0
|
||||||
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
outb(iobase + com_cfcr, com->cfcr_image &= ~CFCR_SBREAK);
|
||||||
#endif
|
#endif
|
||||||
@ -837,7 +870,7 @@ comhardclose(com)
|
|||||||
outb(iobase + com_ier, 0);
|
outb(iobase + com_ier, 0);
|
||||||
#else
|
#else
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_SRER, com->intr_enable = 0);
|
cd_outb(iobase, CD1400_SRER, com->cy_align, com->intr_enable = 0);
|
||||||
enable_intr();
|
enable_intr();
|
||||||
#endif
|
#endif
|
||||||
tp = com->tp;
|
tp = com->tp;
|
||||||
@ -859,7 +892,7 @@ comhardclose(com)
|
|||||||
com->channel_control = CD1400_CCR_CMDCHANCTL
|
com->channel_control = CD1400_CCR_CMDCHANCTL
|
||||||
| CD1400_CCR_XMTEN
|
| CD1400_CCR_XMTEN
|
||||||
| CD1400_CCR_RCVDIS;
|
| CD1400_CCR_RCVDIS;
|
||||||
cd1400_channel_cmd(iobase, com->channel_control);
|
cd1400_channel_cmd(iobase, com->channel_control, com->cy_align);
|
||||||
|
|
||||||
if (com->dtr_wait != 0) {
|
if (com->dtr_wait != 0) {
|
||||||
timeout(siodtrwakeup, com, com->dtr_wait);
|
timeout(siodtrwakeup, com, com->dtr_wait);
|
||||||
@ -948,20 +981,19 @@ void
|
|||||||
siointr(unit)
|
siointr(unit)
|
||||||
int unit;
|
int unit;
|
||||||
{
|
{
|
||||||
int baseu;
|
cy_addr cy_iobase, iobase;
|
||||||
cy_addr cy_iobase;
|
int baseu, cyu, cy_align;
|
||||||
int cyu;
|
u_char status;
|
||||||
cy_addr iobase;
|
|
||||||
u_char status;
|
|
||||||
|
|
||||||
baseu = unit * CY_MAX_PORTS;
|
baseu = unit * CY_MAX_PORTS;
|
||||||
cy_iobase = com_addr(baseu)->cy_iobase;
|
cy_iobase = com_addr(baseu)->cy_iobase;
|
||||||
|
cy_align = com_addr(baseu)->cy_align;
|
||||||
|
|
||||||
/* check each CD1400 in turn */
|
/* check each CD1400 in turn */
|
||||||
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
for (cyu = 0; cyu < cy_nr_cd1400s[unit]; ++cyu) {
|
||||||
iobase = (cy_addr) (cy_iobase + cy_chip_offset[cyu]);
|
iobase = (cy_addr) (cy_iobase + (cy_chip_offset[cyu] << cy_align));
|
||||||
/* poll to see if it has any work */
|
/* poll to see if it has any work */
|
||||||
status = cd_inb(iobase, CD1400_SVRR);
|
status = cd_inb(iobase, CD1400_SVRR, cy_align);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
continue;
|
continue;
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -981,13 +1013,13 @@ siointr(unit)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_rir = cd_inb(iobase, CD1400_RIR);
|
save_rir = cd_inb(iobase, CD1400_RIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter rx service */
|
/* enter rx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_rir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_rir);
|
||||||
|
|
||||||
serv_type = cd_inb(iobase, CD1400_RIVR);
|
serv_type = cd_inb(iobase, CD1400_RIVR, cy_align);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
+ ((serv_type >> CD1400_xIVR_CHAN_SHIFT)
|
||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
@ -1002,9 +1034,9 @@ siointr(unit)
|
|||||||
|
|
||||||
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
if (serv_type & CD1400_RIVR_EXCEPTION) {
|
||||||
++com->recv_exception;
|
++com->recv_exception;
|
||||||
line_status = cd_inb(iobase, CD1400_RDSR);
|
line_status = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
/* break/unnattached error bits or real input? */
|
/* break/unnattached error bits or real input? */
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
if (line_status & CD1400_RDSR_SPECIAL
|
if (line_status & CD1400_RDSR_SPECIAL
|
||||||
&& com->hotchar != 0)
|
&& com->hotchar != 0)
|
||||||
@ -1053,7 +1085,7 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
if (line_status & LSR_OE)
|
if (line_status & LSR_OE)
|
||||||
@ -1063,7 +1095,7 @@ siointr(unit)
|
|||||||
} else {
|
} else {
|
||||||
int ifree;
|
int ifree;
|
||||||
|
|
||||||
count = cd_inb(iobase, CD1400_RDCR);
|
count = cd_inb(iobase, CD1400_RDCR, cy_align);
|
||||||
com->bytes_in += count;
|
com->bytes_in += count;
|
||||||
ioptr = com->iptr;
|
ioptr = com->iptr;
|
||||||
ifree = com->ibufend - ioptr;
|
ifree = com->ibufend - ioptr;
|
||||||
@ -1075,7 +1107,7 @@ siointr(unit)
|
|||||||
microtime(&com->timestamp);
|
microtime(&com->timestamp);
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase,
|
recv_data = cd_inb(iobase,
|
||||||
CD1400_RDSR);
|
CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data
|
&& recv_data
|
||||||
@ -1090,7 +1122,7 @@ siointr(unit)
|
|||||||
com->delta_error_counts
|
com->delta_error_counts
|
||||||
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
[CE_INTERRUPT_BUF_OVERFLOW] += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1107,12 +1139,12 @@ siointr(unit)
|
|||||||
outb(com->modem_ctl_port,
|
outb(com->modem_ctl_port,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
com_events += count;
|
com_events += count;
|
||||||
do {
|
do {
|
||||||
recv_data = cd_inb(iobase, CD1400_RDSR);
|
recv_data = cd_inb(iobase, CD1400_RDSR, cy_align);
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
if (com->hotchar != 0
|
if (com->hotchar != 0
|
||||||
&& recv_data == com->hotchar)
|
&& recv_data == com->hotchar)
|
||||||
@ -1129,12 +1161,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_RIR,
|
cd_outb(iobase, CD1400_RIR, cy_align,
|
||||||
save_rir
|
save_rir
|
||||||
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
& ~(CD1400_RIR_RDIREQ | CD1400_RIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_MDMCH) {
|
if (status & CD1400_SVRR_MDMCH) {
|
||||||
@ -1148,11 +1180,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_mir = cd_inb(iobase, CD1400_MIR);
|
save_mir = cd_inb(iobase, CD1400_MIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter modem service */
|
/* enter modem service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_mir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_mir);
|
||||||
|
|
||||||
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
com = com_addr(baseu + cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_mir & CD1400_MIR_CHAN));
|
+ (save_mir & CD1400_MIR_CHAN));
|
||||||
@ -1165,7 +1197,7 @@ cont:
|
|||||||
& CD1400_xIVR_CHAN));
|
& CD1400_xIVR_CHAN));
|
||||||
#endif
|
#endif
|
||||||
++com->mdm;
|
++com->mdm;
|
||||||
modem_status = cd_inb(iobase, CD1400_MSVR2);
|
modem_status = cd_inb(iobase, CD1400_MSVR2, cy_align);
|
||||||
if (modem_status != com->last_modem_status) {
|
if (modem_status != com->last_modem_status) {
|
||||||
if (com->do_dcd_timestamp
|
if (com->do_dcd_timestamp
|
||||||
&& !(com->last_modem_status & MSR_DCD)
|
&& !(com->last_modem_status & MSR_DCD)
|
||||||
@ -1194,13 +1226,13 @@ cont:
|
|||||||
| CS_ODEVREADY)
|
| CS_ODEVREADY)
|
||||||
&& !(com->intr_enable
|
&& !(com->intr_enable
|
||||||
& CD1400_SRER_TXRDY))
|
& CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state &= ~CS_ODEVREADY;
|
com->state &= ~CS_ODEVREADY;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1210,12 +1242,12 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_MIR,
|
cd_outb(iobase, CD1400_MIR, cy_align,
|
||||||
save_mir
|
save_mir
|
||||||
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
& ~(CD1400_MIR_RDIREQ | CD1400_MIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (status & CD1400_SVRR_TXRDY) {
|
if (status & CD1400_SVRR_TXRDY) {
|
||||||
@ -1228,11 +1260,11 @@ cont:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
save_tir = cd_inb(iobase, CD1400_TIR);
|
save_tir = cd_inb(iobase, CD1400_TIR, cy_align);
|
||||||
save_car = cd_inb(iobase, CD1400_CAR);
|
save_car = cd_inb(iobase, CD1400_CAR, cy_align);
|
||||||
|
|
||||||
/* enter tx service */
|
/* enter tx service */
|
||||||
cd_outb(iobase, CD1400_CAR, save_tir);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_tir);
|
||||||
com = com_addr(baseu
|
com = com_addr(baseu
|
||||||
+ cyu * CD1400_NO_OF_CHANNELS
|
+ cyu * CD1400_NO_OF_CHANNELS
|
||||||
+ (save_tir & CD1400_TIR_CHAN));
|
+ (save_tir & CD1400_TIR_CHAN));
|
||||||
@ -1255,7 +1287,7 @@ cont:
|
|||||||
ocount = CD1400_TX_FIFO_SIZE;
|
ocount = CD1400_TX_FIFO_SIZE;
|
||||||
com->bytes_out += ocount;
|
com->bytes_out += ocount;
|
||||||
do
|
do
|
||||||
cd_outb(iobase, CD1400_TDR, *ioptr++);
|
cd_outb(iobase, CD1400_TDR, cy_align, *ioptr++);
|
||||||
while (--ocount != 0);
|
while (--ocount != 0);
|
||||||
com->obufq.l_head = ioptr;
|
com->obufq.l_head = ioptr;
|
||||||
if (ioptr >= com->obufq.l_tail) {
|
if (ioptr >= com->obufq.l_tail) {
|
||||||
@ -1271,7 +1303,7 @@ cont:
|
|||||||
} else {
|
} else {
|
||||||
/* output just completed */
|
/* output just completed */
|
||||||
com->state &= ~CS_BUSY;
|
com->state &= ~CS_BUSY;
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
&= ~CD1400_SRER_TXRDY);
|
&= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -1285,18 +1317,18 @@ cont:
|
|||||||
|
|
||||||
/* terminate service context */
|
/* terminate service context */
|
||||||
#ifdef PollMode
|
#ifdef PollMode
|
||||||
cd_outb(iobase, CD1400_TIR,
|
cd_outb(iobase, CD1400_TIR, cy_align,
|
||||||
save_tir
|
save_tir
|
||||||
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
& ~(CD1400_TIR_RDIREQ | CD1400_TIR_RBUSY));
|
||||||
cd_outb(iobase, CD1400_CAR, save_car);
|
cd_outb(iobase, CD1400_CAR, cy_align, save_car);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_EOSRR, 0);
|
cd_outb(iobase, CD1400_EOSRR, cy_align, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure an edge for the next interrupt */
|
/* ensure an edge for the next interrupt */
|
||||||
cy_outb(cy_iobase, CY_CLEAR_INTR, 0);
|
cd_outb(cy_iobase, CY_CLEAR_INTR, cy_align, 0);
|
||||||
|
|
||||||
schedsofttty();
|
schedsofttty();
|
||||||
}
|
}
|
||||||
@ -1406,7 +1438,7 @@ sioioctl(dev, cmd, data, flag, p)
|
|||||||
splx(s);
|
splx(s);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
cd_outb(iobase, CD1400_CAR, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, MINOR_TO_UNIT(mynor) & CD1400_CAR_CHAN);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
#if 0
|
#if 0
|
||||||
case TIOCSBRK:
|
case TIOCSBRK:
|
||||||
@ -1544,9 +1576,9 @@ repeat:
|
|||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
iobase = com->iobase,
|
iobase = com->iobase,
|
||||||
cd_outb(iobase, CD1400_CAR,
|
cd_outb(iobase, CD1400_CAR, com->cy_align,
|
||||||
unit & CD1400_CAR_CHAN),
|
unit & CD1400_CAR_CHAN),
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -1669,19 +1701,19 @@ comparam(tp, t)
|
|||||||
com = com_addr(unit);
|
com = com_addr(unit);
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
s = spltty();
|
s = spltty();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (odivisor == 0)
|
if (odivisor == 0)
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
(void)commctl(com, TIOCM_DTR, DMBIC); /* hang up line */
|
||||||
else
|
else
|
||||||
(void)commctl(com, TIOCM_DTR, DMBIS);
|
(void)commctl(com, TIOCM_DTR, DMBIS);
|
||||||
|
|
||||||
if (idivisor != 0) {
|
if (idivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_RBPR, idivisor);
|
cd_outb(iobase, CD1400_RBPR, com->cy_align, idivisor);
|
||||||
cd_outb(iobase, CD1400_RCOR, iprescaler);
|
cd_outb(iobase, CD1400_RCOR, com->cy_align, iprescaler);
|
||||||
}
|
}
|
||||||
if (odivisor != 0) {
|
if (odivisor != 0) {
|
||||||
cd_outb(iobase, CD1400_TBPR, odivisor);
|
cd_outb(iobase, CD1400_TBPR, com->cy_align, odivisor);
|
||||||
cd_outb(iobase, CD1400_TCOR, oprescaler);
|
cd_outb(iobase, CD1400_TCOR, com->cy_align, oprescaler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1694,20 +1726,20 @@ comparam(tp, t)
|
|||||||
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
| (cflag & CREAD ? CD1400_CCR_RCVEN : CD1400_CCR_RCVDIS);
|
||||||
if (opt != com->channel_control) {
|
if (opt != com->channel_control) {
|
||||||
com->channel_control = opt;
|
com->channel_control = opt;
|
||||||
cd1400_channel_cmd(iobase, opt);
|
cd1400_channel_cmd(iobase, opt, com->cy_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Smarts
|
#ifdef Smarts
|
||||||
/* set special chars */
|
/* set special chars */
|
||||||
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
/* XXX if one is _POSIX_VDISABLE, can't use some others */
|
||||||
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTOP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR1, t->c_cc[VSTOP]);
|
cd_outb(iobase, CD1400_SCHR1, com->cy_align, t->c_cc[VSTOP]);
|
||||||
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
if (t->c_cc[VSTART] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR2, t->c_cc[VSTART]);
|
cd_outb(iobase, CD1400_SCHR2, com->cy_align, t->c_cc[VSTART]);
|
||||||
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
if (t->c_cc[VINTR] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR3, t->c_cc[VINTR]);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, t->c_cc[VINTR]);
|
||||||
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
if (t->c_cc[VSUSP] != _POSIX_VDISABLE)
|
||||||
cd_outb(iobase, CD1400_SCHR4, t->c_cc[VSUSP]);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, t->c_cc[VSUSP]);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1754,14 +1786,14 @@ comparam(tp, t)
|
|||||||
cor_change = 0;
|
cor_change = 0;
|
||||||
if (opt != com->cor[0]) {
|
if (opt != com->cor[0]) {
|
||||||
cor_change |= CD1400_CCR_COR1;
|
cor_change |= CD1400_CCR_COR1;
|
||||||
cd_outb(iobase, CD1400_COR1, com->cor[0] = opt);
|
cd_outb(iobase, CD1400_COR1, com->cy_align, com->cor[0] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set receive time-out period, normally to max(one char time, 5 ms).
|
* Set receive time-out period, normally to max(one char time, 5 ms).
|
||||||
*/
|
*/
|
||||||
if (t->c_ispeed == 0)
|
if (t->c_ispeed == 0)
|
||||||
itimeout = cd_inb(iobase, CD1400_RTPR);
|
itimeout = cd_inb(iobase, CD1400_RTPR, com->cy_align);
|
||||||
else {
|
else {
|
||||||
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
itimeout = (1000 * bits + t->c_ispeed - 1) / t->c_ispeed;
|
||||||
#ifdef SOFT_HOTCHAR
|
#ifdef SOFT_HOTCHAR
|
||||||
@ -1777,7 +1809,7 @@ comparam(tp, t)
|
|||||||
itimeout = t->c_cc[VTIME] * 10;
|
itimeout = t->c_cc[VTIME] * 10;
|
||||||
if (itimeout > 255)
|
if (itimeout > 255)
|
||||||
itimeout = 255;
|
itimeout = 255;
|
||||||
cd_outb(iobase, CD1400_RTPR, itimeout);
|
cd_outb(iobase, CD1400_RTPR, com->cy_align, itimeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 2 -
|
* set channel option register 2 -
|
||||||
@ -1796,7 +1828,7 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[1]) {
|
if (opt != com->cor[1]) {
|
||||||
cor_change |= CD1400_CCR_COR2;
|
cor_change |= CD1400_CCR_COR2;
|
||||||
cd_outb(iobase, CD1400_COR2, com->cor[1] = opt);
|
cd_outb(iobase, CD1400_COR2, com->cy_align, com->cor[1] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1814,12 +1846,12 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cor_change |= CD1400_CCR_COR3;
|
cor_change |= CD1400_CCR_COR3;
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* notify the CD1400 if COR1-3 have changed */
|
/* notify the CD1400 if COR1-3 have changed */
|
||||||
if (cor_change)
|
if (cor_change)
|
||||||
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change);
|
cd1400_channel_cmd(iobase, CD1400_CCR_CMDCORCHG | cor_change, com->cy_align);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 4 -
|
* set channel option register 4 -
|
||||||
@ -1858,7 +1890,7 @@ comparam(tp, t)
|
|||||||
#else
|
#else
|
||||||
opt |= CD1400_COR4_PFO_EXCEPTION;
|
opt |= CD1400_COR4_PFO_EXCEPTION;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR4, opt);
|
cd_outb(iobase, CD1400_COR4, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set channel option register 5 -
|
* set channel option register 5 -
|
||||||
@ -1875,7 +1907,7 @@ comparam(tp, t)
|
|||||||
if (t->c_oflag & OCRNL)
|
if (t->c_oflag & OCRNL)
|
||||||
opt |= CD1400_COR5_OCRNL;
|
opt |= CD1400_COR5_OCRNL;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_COR5, opt);
|
cd_outb(iobase, CD1400_COR5, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX we probably alway want to track carrier changes, so that
|
* XXX we probably alway want to track carrier changes, so that
|
||||||
@ -1892,7 +1924,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR1_CTSzd;
|
opt |= CD1400_MCOR1_CTSzd;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR1, opt);
|
cd_outb(iobase, CD1400_MCOR1, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set modem change option register 2
|
* set modem change option register 2
|
||||||
@ -1903,7 +1935,7 @@ comparam(tp, t)
|
|||||||
if (cflag & CCTS_OFLOW)
|
if (cflag & CCTS_OFLOW)
|
||||||
opt |= CD1400_MCOR2_CTSod;
|
opt |= CD1400_MCOR2_CTSod;
|
||||||
#endif
|
#endif
|
||||||
cd_outb(iobase, CD1400_MCOR2, opt);
|
cd_outb(iobase, CD1400_MCOR2, com->cy_align, opt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX should have done this long ago, but there is too much state
|
* XXX should have done this long ago, but there is too much state
|
||||||
@ -1946,11 +1978,11 @@ comparam(tp, t)
|
|||||||
#endif
|
#endif
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)) {
|
||||||
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
if (!(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1982,17 +2014,17 @@ comstart(tp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
disable_intr();
|
disable_intr();
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
if (tp->t_state & TS_TTSTOP) {
|
if (tp->t_state & TS_TTSTOP) {
|
||||||
com->state &= ~CS_TTGO;
|
com->state &= ~CS_TTGO;
|
||||||
if (com->intr_enable & CD1400_SRER_TXRDY)
|
if (com->intr_enable & CD1400_SRER_TXRDY)
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
com->intr_enable &= ~CD1400_SRER_TXRDY);
|
||||||
} else {
|
} else {
|
||||||
com->state |= CS_TTGO;
|
com->state |= CS_TTGO;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
if (com->state >= (CS_BUSY | CS_TTGO | CS_ODEVREADY)
|
||||||
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
&& !(com->intr_enable & CD1400_SRER_TXRDY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable |= CD1400_SRER_TXRDY);
|
com->intr_enable |= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
if (tp->t_state & TS_TBLOCK) {
|
if (tp->t_state & TS_TBLOCK) {
|
||||||
@ -2000,7 +2032,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image &= ~MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image &= ~MCR_RTS);
|
com->mcr_image &= ~MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -2013,7 +2045,7 @@ comstart(tp)
|
|||||||
#if 0
|
#if 0
|
||||||
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
outb(com->modem_ctl_port, com->mcr_image |= MCR_RTS);
|
||||||
#else
|
#else
|
||||||
cd_outb(iobase, CD1400_MSVR1,
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align,
|
||||||
com->mcr_image |= MCR_RTS);
|
com->mcr_image |= MCR_RTS);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2048,7 +2080,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2076,7 +2108,7 @@ comstart(tp)
|
|||||||
com->state |= CS_BUSY;
|
com->state |= CS_BUSY;
|
||||||
if (com->state >= (CS_BUSY | CS_TTGO
|
if (com->state >= (CS_BUSY | CS_TTGO
|
||||||
| CS_ODEVREADY))
|
| CS_ODEVREADY))
|
||||||
cd_outb(iobase, CD1400_SRER,
|
cd_outb(iobase, CD1400_SRER, com->cy_align,
|
||||||
com->intr_enable
|
com->intr_enable
|
||||||
|= CD1400_SRER_TXRDY);
|
|= CD1400_SRER_TXRDY);
|
||||||
}
|
}
|
||||||
@ -2182,18 +2214,18 @@ commctl(com, bits, how)
|
|||||||
switch (how) {
|
switch (how) {
|
||||||
case DMSET:
|
case DMSET:
|
||||||
com->mcr_image = mcr;
|
com->mcr_image = mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIS:
|
case DMBIS:
|
||||||
com->mcr_image = mcr = com->mcr_image | mcr;
|
com->mcr_image = mcr = com->mcr_image | mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
case DMBIC:
|
case DMBIC:
|
||||||
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
com->mcr_image = mcr = com->mcr_image & ~mcr;
|
||||||
cd_outb(iobase, CD1400_MSVR1, mcr);
|
cd_outb(iobase, CD1400_MSVR1, com->cy_align, mcr);
|
||||||
cd_outb(iobase, CD1400_MSVR2, mcr);
|
cd_outb(iobase, CD1400_MSVR2, com->cy_align, mcr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
enable_intr();
|
enable_intr();
|
||||||
@ -2331,17 +2363,17 @@ disc_optim(tp, t, com)
|
|||||||
com->hotchar = 0;
|
com->hotchar = 0;
|
||||||
#ifndef SOFT_HOTCHAR
|
#ifndef SOFT_HOTCHAR
|
||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
cd_outb(iobase, CD1400_CAR, com->unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, com->unit & CD1400_CAR_CHAN);
|
||||||
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
opt = com->cor[2] & ~CD1400_COR3_SCD34;
|
||||||
if (com->hotchar != 0) {
|
if (com->hotchar != 0) {
|
||||||
cd_outb(iobase, CD1400_SCHR3, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR3, com->cy_align, com->hotchar);
|
||||||
cd_outb(iobase, CD1400_SCHR4, com->hotchar);
|
cd_outb(iobase, CD1400_SCHR4, com->cy_align, com->hotchar);
|
||||||
opt |= CD1400_COR3_SCD34;
|
opt |= CD1400_COR3_SCD34;
|
||||||
}
|
}
|
||||||
if (opt != com->cor[2]) {
|
if (opt != com->cor[2]) {
|
||||||
cd_outb(iobase, CD1400_COR3, com->cor[2] = opt);
|
cd_outb(iobase, CD1400_COR3, com->cy_align, com->cor[2] = opt);
|
||||||
cd1400_channel_cmd(com->iobase,
|
cd1400_channel_cmd(com->iobase,
|
||||||
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3);
|
CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3, com->cy_align);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -2405,9 +2437,10 @@ comspeed(speed, prescaler_io)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cd1400_channel_cmd(iobase, cmd)
|
cd1400_channel_cmd(iobase, cmd, cy_align)
|
||||||
cy_addr iobase;
|
cy_addr iobase;
|
||||||
int cmd;
|
int cmd;
|
||||||
|
int cy_align;
|
||||||
{
|
{
|
||||||
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
/* XXX hsu@clinet.fi: This is always more dependent on ISA bus speed,
|
||||||
as the card is probed every round? Replaced delaycount with 8k.
|
as the card is probed every round? Replaced delaycount with 8k.
|
||||||
@ -2417,14 +2450,14 @@ cd1400_channel_cmd(iobase, cmd)
|
|||||||
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
u_int maxwait = 5 * 8 * 1024; /* approx. 5 ms */
|
||||||
|
|
||||||
/* wait for processing of previous command to complete */
|
/* wait for processing of previous command to complete */
|
||||||
while (cd_inb(iobase, CD1400_CCR) && maxwait--)
|
while (cd_inb(iobase, CD1400_CCR, cy_align) && maxwait--)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (!maxwait)
|
if (!maxwait)
|
||||||
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
log(LOG_ERR, "cy: channel command timeout (%d loops) - arrgh\n",
|
||||||
5 * 8 * 1024);
|
5 * 8 * 1024);
|
||||||
|
|
||||||
cd_outb(iobase, CD1400_CCR, cmd);
|
cd_outb(iobase, CD1400_CCR, cy_align, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
@ -2448,7 +2481,7 @@ cystatus(unit)
|
|||||||
iobase = com->iobase;
|
iobase = com->iobase;
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("cd1400 base address:\\tt%p\n", iobase);
|
printf("cd1400 base address:\\tt%p\n", iobase);
|
||||||
cd_outb(iobase, CD1400_CAR, unit & CD1400_CAR_CHAN);
|
cd_outb(iobase, CD1400_CAR, com->cy_align, unit & CD1400_CAR_CHAN);
|
||||||
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
printf("saved channel_control:\t\t0x%02x\n", com->channel_control);
|
||||||
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
printf("saved cor1-3:\t\t\t0x%02x 0x%02x 0x%02x\n",
|
||||||
com->cor[0], com->cor[1], com->cor[2]);
|
com->cor[0], com->cor[1], com->cor[2]);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cyreg.h,v 1.1 1995/07/05 12:15:51 bde Exp $
|
* $Id: cyreg.h,v 1.2 1996/10/04 10:33:13 davidg Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,22 +36,21 @@
|
|||||||
#define CY8_SVCACKR 0x100
|
#define CY8_SVCACKR 0x100
|
||||||
#define CY8_SVCACKT 0x200
|
#define CY8_SVCACKT 0x200
|
||||||
#define CY8_SVCACKM 0x300
|
#define CY8_SVCACKM 0x300
|
||||||
#define CY_CD1400_MEMSIZE 0x400
|
#define CY16_RESET 0x0a00
|
||||||
#define CY16_RESET 0x1400
|
#define CY_CLEAR_INTR 0x0c00 /* intr ack address */
|
||||||
#define CY_CLEAR_INTR 0x1800 /* intr ack address */
|
|
||||||
|
|
||||||
#define CY_MAX_CD1400s 8 /* for Cyclom-32Y */
|
#define CY_MAX_CD1400s 8 /* for Cyclom-32Y */
|
||||||
|
|
||||||
#define CY_CLOCK 25000000 /* baud rate clock */
|
#define CY_CLOCK 25000000 /* baud rate clock */
|
||||||
|
|
||||||
#ifdef CyDebug
|
#ifdef CyDebug
|
||||||
#define cd_inb(iobase, reg) (++cd_inbs, *((iobase) + 2 * (reg)))
|
#define cd_inb(iobase, reg, cy_align) (++cd_inbs, *((iobase) + ((reg)*2 << (cy_align))))
|
||||||
#define cy_inb(iobase, reg) (++cy_inbs, *((iobase) + (reg)))
|
#define cy_inb(iobase, reg) (++cy_inbs, *((iobase) + (reg)))
|
||||||
#define cd_outb(iobase, reg, val) (++cd_outbs, (void)(*((iobase) + 2 * (reg)) = (val)))
|
#define cd_outb(iobase, reg, cy_align, val) (++cd_outbs, (void)(*((iobase) + ((reg)*2 << (cy_align))) = (val)))
|
||||||
#define cy_outb(iobase, reg, val) (++cy_outbs, (void)(*((iobase) + (reg)) = (val)))
|
#define cy_outb(iobase, reg, val) (++cy_outbs, (void)(*((iobase) + (reg)) = (val)))
|
||||||
#else
|
#else
|
||||||
#define cd_inb(iobase, reg) (*((iobase) + 2 * (reg)))
|
#define cd_inb(iobase, reg, cy_align) (*((iobase) + ((reg)*2 << (cy_align))))
|
||||||
#define cy_inb(iobase, reg) (*((iobase) + (reg)))
|
#define cy_inb(iobase, reg) (*((iobase) + (reg)))
|
||||||
#define cd_outb(iobase, reg, val) ((void)(*((iobase) + 2 * (reg)) = (val)))
|
#define cd_outb(iobase, reg, cy_align, val) ((void)(*((iobase) + ((reg)*2 << (cy_align))) = (val)))
|
||||||
#define cy_outb(iobase, reg, val) ((void)(*((iobase) + (reg)) = (val)))
|
#define cy_outb(iobase, reg, val) ((void)(*((iobase) + (reg)) = (val)))
|
||||||
#endif
|
#endif
|
||||||
|
132
sys/pci/cy_pci.c
Normal file
132
sys/pci/cy_pci.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, David Greenman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice unmodified, this list of conditions, and the following
|
||||||
|
* disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cyclades Y PCI serial interface driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <pci.h>
|
||||||
|
#if NPCI > 0
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/malloc.h>
|
||||||
|
#include <sys/kernel.h>
|
||||||
|
#include <vm/vm.h>
|
||||||
|
#include <vm/pmap.h>
|
||||||
|
|
||||||
|
#include <pci/pcivar.h>
|
||||||
|
|
||||||
|
#include <pci/cy_pcireg.h>
|
||||||
|
|
||||||
|
static char *cy_probe __P((pcici_t, pcidi_t));
|
||||||
|
static void cy_attach __P((pcici_t, int));
|
||||||
|
|
||||||
|
extern int cyattach_common(void *, int); /* Not exactly correct */
|
||||||
|
extern void cyintr(int);
|
||||||
|
|
||||||
|
static u_long cy_count;
|
||||||
|
|
||||||
|
static struct pci_device cy_device = {
|
||||||
|
"cy",
|
||||||
|
cy_probe,
|
||||||
|
cy_attach,
|
||||||
|
&cy_count,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
DATA_SET(pcidevice_set, cy_device);
|
||||||
|
|
||||||
|
static char *
|
||||||
|
cy_probe(config_id, device_id)
|
||||||
|
pcici_t config_id;
|
||||||
|
pcidi_t device_id;
|
||||||
|
{
|
||||||
|
if ((device_id & 0xffff) == CY_VENDORID_CYCLADES &&
|
||||||
|
((device_id >> 16) == CY_DEVICEID_CYCLOM_Y_1 ||
|
||||||
|
(device_id >> 16) == CY_DEVICEID_CYCLOM_Y_2))
|
||||||
|
return ("Cyclades Cyclom-Y Serial Adapter");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cy_attach(config_id, unit)
|
||||||
|
pcici_t config_id;
|
||||||
|
int unit;
|
||||||
|
{
|
||||||
|
vm_offset_t paddr;
|
||||||
|
void *vaddr;
|
||||||
|
u_int32_t ioport;
|
||||||
|
int adapter;
|
||||||
|
|
||||||
|
ioport = (u_int32_t) pci_conf_read(config_id, CY_PCI_BASE_ADDR1) & ~0x3;
|
||||||
|
paddr = pci_conf_read(config_id, CY_PCI_BASE_ADDR2) & ~0xf;
|
||||||
|
#if 0
|
||||||
|
if (!pci_map_mem(config_id, CY_PCI_BASE_ADDR2, &vaddr, &paddr)) {
|
||||||
|
printf("cy%d: couldn't map shared memory\n", unit);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
vaddr = pmap_mapdev(paddr, 0x4000);
|
||||||
|
|
||||||
|
adapter = cyattach_common(vaddr, 1);
|
||||||
|
if (adapter < 0) {
|
||||||
|
/*
|
||||||
|
* No ports found. Release resources and punt.
|
||||||
|
*/
|
||||||
|
printf("cy%d: no ports found!", unit);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate our interrupt.
|
||||||
|
* XXX Using the ISA interrupt handler directly is a bit of a violation
|
||||||
|
* since it doesn't actually take the same argument. For PCI, the
|
||||||
|
* argument is a void * token, but for ISA it is a unit. Since
|
||||||
|
* there is no overlap in PCI/ISA unit numbers for this driver, and
|
||||||
|
* since the ISA driver must handle the interrupt anyway, we use
|
||||||
|
* the unit number as the token even for PCI.
|
||||||
|
*/
|
||||||
|
if (!pci_map_int(config_id, (pci_inthand_t *)cyintr, (void *)adapter, &tty_imask)) {
|
||||||
|
printf("cy%d: couldn't map interrupt\n", unit);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Enable the "local" interrupt input to generate a
|
||||||
|
* PCI interrupt.
|
||||||
|
*/
|
||||||
|
outw(ioport + CY_PLX_ICS, inw(CY_PLX_ICS) |
|
||||||
|
CY_PLX_ICS_IENABLE | CY_PLX_ICS_LOCAL_IENABLE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* XXX should release any allocated virtual memory */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NPCI > 0 */
|
40
sys/pci/cy_pcireg.h
Normal file
40
sys/pci/cy_pcireg.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, David Greenman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice unmodified, this list of conditions, and the following
|
||||||
|
* disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define CY_VENDORID_CYCLADES 0x120e
|
||||||
|
#define CY_DEVICEID_CYCLOM_Y_1 0x100
|
||||||
|
#define CY_DEVICEID_CYCLOM_Y_2 0x101
|
||||||
|
|
||||||
|
#define CY_PCI_BASE_ADDR0 0x10
|
||||||
|
#define CY_PCI_BASE_ADDR1 0x14
|
||||||
|
#define CY_PCI_BASE_ADDR2 0x18
|
||||||
|
|
||||||
|
#define CY_PLX_ICS 0x68
|
||||||
|
#define CY_PLX_ICS_IENABLE 0x100
|
||||||
|
#define CY_PLX_ICS_LOCAL_IENABLE 0x800
|
Loading…
x
Reference in New Issue
Block a user