1 /* $NetBSD: magma.c,v 1.53 2009/09/17 16:28:12 tsutsui Exp $ */
4 * Copyright (c) 1998 Iain Hibbert
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * Driver for Magma SBus Serial/Parallel cards using the Cirrus Logic
30 * CD1400 & CD1190 chips
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: magma.c,v 1.53 2009/09/17 16:28:12 tsutsui Exp $");
43 #include <sys/param.h>
44 #include <sys/systm.h>
46 #include <sys/device.h>
48 #include <sys/ioctl.h>
49 #include <sys/malloc.h>
52 #include <sys/kernel.h>
53 #include <sys/syslog.h>
55 #include <sys/errno.h>
56 #include <sys/kauth.h>
60 #include <machine/autoconf.h>
62 #include <dev/sbus/sbusvar.h>
64 #include <dev/ic/cd1400reg.h>
65 #include <dev/ic/cd1190reg.h>
67 #include <dev/sbus/mbppio.h>
68 #include <dev/sbus/magmareg.h>
74 * The table below lists the cards that this driver is likely to
77 * Cards with parallel ports: except for the LC2+1Sp, they all use
78 * the CD1190 chip which I know nothing about. I've tried to leave
79 * hooks for it so it shouldn't be too hard to add support later.
80 * (I think somebody is working on this separately)
82 * Thanks to Bruce at Magma for telling me the hardware offsets.
84 static struct magma_board_info supported_cards
[] = {
86 "MAGMA_Sp", "MAGMA,4_Sp", "Magma 4 Sp", 4, 0,
87 1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 },
91 "MAGMA_Sp", "MAGMA,8_Sp", "Magma 8 Sp", 8, 0,
92 2, 0xa000, 0xc000, 0xe000, { 0x4000, 0x6000, 0, 0 },
96 "MAGMA_Sp", "MAGMA,_8HS_Sp", "Magma Fast 8 Sp", 8, 0,
97 2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 },
101 "MAGMA_Sp", "MAGMA,_8SP_422", "Magma 8 Sp - 422", 8, 0,
102 2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 },
106 "MAGMA_Sp", "MAGMA,12_Sp", "Magma 12 Sp", 12, 0,
107 3, 0xa000, 0xc000, 0xe000, { 0x2000, 0x4000, 0x6000, 0 },
111 "MAGMA_Sp", "MAGMA,16_Sp", "Magma 16 Sp", 16, 0,
112 4, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0xa000, 0xb000 },
116 "MAGMA_Sp", "MAGMA,16_Sp_2", "Magma 16 Sp", 16, 0,
117 4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 },
121 "MAGMA_Sp", "MAGMA,16HS_Sp", "Magma Fast 16 Sp", 16, 0,
122 4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 },
126 "MAGMA_Sp", "MAGMA,21_Sp", "Magma LC 2+1 Sp", 2, 1,
127 1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 },
131 "MAGMA_Sp", "MAGMA,21HS_Sp", "Magma 2+1 Sp", 2, 1,
132 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
136 "MAGMA_Sp", "MAGMA,41_Sp", "Magma 4+1 Sp", 4, 1,
137 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
141 "MAGMA_Sp", "MAGMA,82_Sp", "Magma 8+2 Sp", 8, 2,
142 2, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0, 0 },
143 2, { 0xa000, 0xb000 }
146 "MAGMA_Sp", "MAGMA,P1_Sp", "Magma P1 Sp", 0, 1,
147 0, 0, 0, 0, { 0, 0, 0, 0 },
151 "MAGMA_Sp", "MAGMA,P2_Sp", "Magma P2 Sp", 0, 2,
152 0, 0, 0, 0, { 0, 0, 0, 0 },
153 2, { 0x4000, 0x8000 }
156 "MAGMA 2+1HS Sp", "", "Magma 2+1HS Sp", 2, 0,
157 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 },
161 NULL
, NULL
, NULL
, 0, 0,
162 0, 0, 0, 0, { 0, 0, 0, 0 },
167 /************************************************************************
172 CFATTACH_DECL(magma
, sizeof(struct magma_softc
),
173 magma_match
, magma_attach
, NULL
, NULL
);
175 CFATTACH_DECL(mtty
, sizeof(struct mtty_softc
),
176 mtty_match
, mtty_attach
, NULL
, NULL
);
178 CFATTACH_DECL(mbpp
, sizeof(struct mbpp_softc
),
179 mbpp_match
, mbpp_attach
, NULL
, NULL
);
181 dev_type_open(mttyopen
);
182 dev_type_close(mttyclose
);
183 dev_type_read(mttyread
);
184 dev_type_write(mttywrite
);
185 dev_type_ioctl(mttyioctl
);
186 dev_type_stop(mttystop
);
187 dev_type_tty(mttytty
);
188 dev_type_poll(mttypoll
);
190 const struct cdevsw mtty_cdevsw
= {
191 mttyopen
, mttyclose
, mttyread
, mttywrite
, mttyioctl
,
192 mttystop
, mttytty
, mttypoll
, nommap
, ttykqfilter
, D_TTY
195 dev_type_open(mbppopen
);
196 dev_type_close(mbppclose
);
197 dev_type_read(mbpp_rw
);
198 dev_type_ioctl(mbppioctl
);
200 const struct cdevsw mbpp_cdevsw
= {
201 mbppopen
, mbppclose
, mbpp_rw
, mbpp_rw
, mbppioctl
,
202 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
205 /************************************************************************
209 * cd1400_compute_baud calculate COR/BPR register values
210 * cd1400_write_ccr write a value to CD1400 ccr
211 * cd1400_read_reg read from a CD1400 register
212 * cd1400_write_reg write to a CD1400 register
213 * cd1400_enable_transmitter enable transmitting on CD1400 channel
217 * compute the bpr/cor pair for any baud rate
218 * returns 0 for success, 1 for failure
221 cd1400_compute_baud(speed_t speed
, int clock
, int *cor
, int *bpr
)
225 if( speed
< 50 || speed
> 150000 )
228 for( c
= 0, co
= 8 ; co
<= 2048 ; co
<<= 2, c
++ ) {
229 br
= ((clock
* 1000000) + (co
* speed
) / 2) / (co
* speed
);
241 * Write a CD1400 channel command, should have a timeout?
244 cd1400_write_ccr(struct cd1400
*cd
, u_char cmd
)
246 while( cd1400_read_reg(cd
, CD1400_CCR
) )
249 cd1400_write_reg(cd
, CD1400_CCR
, cmd
);
253 * read a value from a cd1400 register
256 cd1400_read_reg(struct cd1400
*cd
, int reg
)
258 return(cd
->cd_reg
[reg
]);
262 * write a value to a cd1400 register
265 cd1400_write_reg(struct cd1400
*cd
, int reg
, u_char value
)
267 cd
->cd_reg
[reg
] = value
;
271 * enable transmit service requests for cd1400 channel
274 cd1400_enable_transmitter(struct cd1400
*cd
, int channel
)
279 cd1400_write_reg(cd
, CD1400_CAR
, channel
);
280 srer
= cd1400_read_reg(cd
, CD1400_SRER
);
281 SET(srer
, CD1400_SRER_TXRDY
);
282 cd1400_write_reg(cd
, CD1400_SRER
, srer
);
286 /************************************************************************
291 /* well, there are none yet */
293 /************************************************************************
297 * magma_match reports if we have a magma board available
298 * magma_attach attaches magma boards to the sbus
299 * magma_hard hardware level interrupt routine
300 * magma_soft software level interrupt routine
304 magma_match(device_t parent
, cfdata_t cf
, void *aux
)
306 struct sbus_attach_args
*sa
= aux
;
307 struct magma_board_info
*card
;
309 /* See if we support this device */
310 for (card
= supported_cards
; ; card
++) {
311 if (card
->mb_sbusname
== NULL
)
312 /* End of table: no match */
314 if (strcmp(sa
->sa_name
, card
->mb_sbusname
) == 0)
318 dprintf(("magma: matched `%s'\n", sa
->sa_name
));
319 dprintf(("magma: magma_prom `%s'\n",
320 prom_getpropstring(sa
->sa_node
, "magma_prom")));
321 dprintf(("magma: intlevels `%s'\n",
322 prom_getpropstring(sa
->sa_node
, "intlevels")));
323 dprintf(("magma: chiprev `%s'\n",
324 prom_getpropstring(sa
->sa_node
, "chiprev")));
325 dprintf(("magma: clock `%s'\n",
326 prom_getpropstring(sa
->sa_node
, "clock")));
332 magma_attach(device_t parent
, device_t self
, void *aux
)
334 struct sbus_attach_args
*sa
= aux
;
335 struct magma_softc
*sc
= device_private(self
);
336 struct magma_board_info
*card
;
337 bus_space_handle_t bh
;
338 char *magma_prom
, *clockstr
;
345 * Find the card model.
346 * Older models all have sbus node name `MAGMA_Sp' (see
347 * `supported_cards[]' above), and must be distinguished
348 * by the `magma_prom' property.
350 magma_prom
= prom_getpropstring(node
, "magma_prom");
352 for (card
= supported_cards
; card
->mb_name
!= NULL
; card
++) {
353 if (strcmp(sa
->sa_name
, card
->mb_sbusname
) != 0)
354 /* Sbus node name doesn't match */
356 if (strcmp(magma_prom
, card
->mb_name
) == 0)
357 /* Model name match */
361 if( card
->mb_name
== NULL
) {
362 printf(": %s (unsupported)\n", magma_prom
);
366 dprintf((" addr %p", sc
));
367 printf(": %s\n", card
->mb_realname
);
370 sc
->ms_ncd1400
= card
->mb_ncd1400
;
371 sc
->ms_ncd1190
= card
->mb_ncd1190
;
373 if (sbus_bus_map(sa
->sa_bustag
,
374 sa
->sa_slot
, sa
->sa_offset
, sa
->sa_size
,
375 BUS_SPACE_MAP_LINEAR
, &bh
) != 0) {
376 aprint_error("%s @ sbus: cannot map registers\n",
381 /* the SVCACK* lines are daisychained */
382 sc
->ms_svcackr
= (char *)bus_space_vaddr(sa
->sa_bustag
, bh
)
384 sc
->ms_svcackt
= (char *)bus_space_vaddr(sa
->sa_bustag
, bh
)
386 sc
->ms_svcackm
= (char *)bus_space_vaddr(sa
->sa_bustag
, bh
)
390 * Find the clock speed; it's the same for all CD1400 chips
393 clockstr
= prom_getpropstring(node
, "clock");
394 if (*clockstr
== '\0')
395 /* Default to 25MHz */
399 while (*clockstr
!= '\0')
400 cd_clock
= (cd_clock
* 10) + (*clockstr
++ - '0');
403 /* init the cd1400 chips */
404 for( chip
= 0 ; chip
< card
->mb_ncd1400
; chip
++ ) {
405 struct cd1400
*cd
= &sc
->ms_cd1400
[chip
];
407 cd
->cd_clock
= cd_clock
;
408 cd
->cd_reg
= (char *)bus_space_vaddr(sa
->sa_bustag
, bh
) +
409 card
->mb_cd1400
[chip
];
411 /* prom_getpropstring(node, "chiprev"); */
412 /* seemingly the Magma drivers just ignore the propstring */
413 cd
->cd_chiprev
= cd1400_read_reg(cd
, CD1400_GFRCR
);
415 dprintf(("%s attach CD1400 %d addr %p rev %x clock %dMHz\n",
416 device_xname(&sc
->ms_dev
), chip
,
417 cd
->cd_reg
, cd
->cd_chiprev
, cd
->cd_clock
));
420 cd1400_write_reg(cd
, CD1400_GFRCR
, 0x00);
422 /* reset whole chip */
423 cd1400_write_ccr(cd
, CD1400_CCR_CMDRESET
| CD1400_CCR_FULLRESET
);
425 /* wait for revision code to be restored */
426 while( cd1400_read_reg(cd
, CD1400_GFRCR
) != cd
->cd_chiprev
)
429 /* set the Prescaler Period Register to tick at 1ms */
430 cd1400_write_reg(cd
, CD1400_PPR
,
431 ((cd
->cd_clock
* 1000000 / CD1400_PPR_PRESCALER
+ 500) / 1000));
433 /* The LC2+1Sp card is the only card that doesn't have
434 * a CD1190 for the parallel port, but uses channel 0 of
435 * the CD1400, so we make a note of it for later and set up
436 * the CD1400 for parallel mode operation.
438 if( card
->mb_npar
&& card
->mb_ncd1190
== 0 ) {
439 cd1400_write_reg(cd
, CD1400_GCR
, CD1400_GCR_PARALLEL
);
444 /* init the cd1190 chips */
445 for( chip
= 0 ; chip
< card
->mb_ncd1190
; chip
++ ) {
446 struct cd1190
*cd
= &sc
->ms_cd1190
[chip
];
448 cd
->cd_reg
= (char *)bus_space_vaddr(sa
->sa_bustag
, bh
) +
449 card
->mb_cd1190
[chip
];
451 /* XXX don't know anything about these chips yet */
452 printf("%s: CD1190 %d addr %p (unsupported)\n",
453 device_xname(self
), chip
, cd
->cd_reg
);
456 /* configure the children */
457 (void)config_found(self
, mtty_match
, NULL
);
458 (void)config_found(self
, mbpp_match
, NULL
);
461 * Establish the interrupt handlers.
463 if (sa
->sa_nintr
== 0)
464 return; /* No interrupts to service!? */
466 (void)bus_intr_establish(sa
->sa_bustag
, sa
->sa_pri
, IPL_SERIAL
,
468 sc
->ms_sicookie
= softint_establish(SOFTINT_SERIAL
, magma_soft
, sc
);
469 if (sc
->ms_sicookie
== NULL
) {
471 aprint_error_dev(&sc
->ms_dev
, "cannot establish soft int handler\n");
474 evcnt_attach_dynamic(&sc
->ms_intrcnt
, EVCNT_TYPE_INTR
, NULL
,
475 device_xname(&sc
->ms_dev
), "intr");
479 * hard interrupt routine
481 * returns 1 if it handled it, otherwise 0
486 magma_hard(void *arg
)
488 struct magma_softc
*sc
= arg
;
490 int chip
, status
= 0;
495 * check status of all the CD1400 chips
497 for( chip
= 0 ; chip
< sc
->ms_ncd1400
; chip
++ )
498 status
|= cd1400_read_reg(&sc
->ms_cd1400
[chip
], CD1400_SVRR
);
500 if( ISSET(status
, CD1400_SVRR_RXRDY
) ) {
501 u_char rivr
= *sc
->ms_svcackr
; /* enter rx service context */
502 int port
= rivr
>> 4;
504 if( rivr
& (1<<3) ) { /* parallel port */
505 struct mbpp_port
*mbpp
;
508 mbpp
= &sc
->ms_mbpp
->ms_port
[port
];
509 cd
= mbpp
->mp_cd1400
;
511 /* don't think we have to handle exceptions */
512 n_chars
= cd1400_read_reg(cd
, CD1400_RDCR
);
514 if( mbpp
->mp_cnt
== 0 ) {
515 SET(mbpp
->mp_flags
, MBPPF_WAKEUP
);
519 *mbpp
->mp_ptr
= cd1400_read_reg(cd
,CD1400_RDSR
);
523 } else { /* serial port */
524 struct mtty_port
*mtty
;
525 u_char
*ptr
, n_chars
, line_stat
;
527 mtty
= &sc
->ms_mtty
->ms_port
[port
];
528 cd
= mtty
->mp_cd1400
;
530 if( ISSET(rivr
, CD1400_RIVR_EXCEPTION
) ) {
531 line_stat
= cd1400_read_reg(cd
, CD1400_RDSR
);
533 } else { /* no exception, received data OK */
535 n_chars
= cd1400_read_reg(cd
, CD1400_RDCR
);
541 *ptr
++ = cd1400_read_reg(cd
, CD1400_RDSR
);
542 if( ptr
== mtty
->mp_rend
) ptr
= mtty
->mp_rbuf
;
543 if( ptr
== mtty
->mp_rget
) {
544 if( ptr
== mtty
->mp_rbuf
)
547 SET(mtty
->mp_flags
, MTTYF_RING_OVERFLOW
);
556 cd1400_write_reg(cd
, CD1400_EOSRR
, 0); /* end service context */
558 } /* if(rx_service...) */
560 if( ISSET(status
, CD1400_SVRR_MDMCH
) ) {
561 u_char mivr
= *sc
->ms_svcackm
; /* enter mdm service context */
562 int port
= mivr
>> 4;
563 struct mtty_port
*mtty
;
568 * Handle CD (LC2+1Sp = DSR) changes.
570 mtty
= &sc
->ms_mtty
->ms_port
[port
];
571 cd
= mtty
->mp_cd1400
;
572 msvr
= cd1400_read_reg(cd
, CD1400_MSVR2
);
573 carrier
= ISSET(msvr
, cd
->cd_parmode
? CD1400_MSVR2_DSR
: CD1400_MSVR2_CD
);
575 if( mtty
->mp_carrier
!= carrier
) {
576 SET(mtty
->mp_flags
, MTTYF_CARRIER_CHANGED
);
577 mtty
->mp_carrier
= carrier
;
581 cd1400_write_reg(cd
, CD1400_EOSRR
, 0); /* end service context */
583 } /* if(mdm_service...) */
585 if( ISSET(status
, CD1400_SVRR_TXRDY
) ) {
586 u_char tivr
= *sc
->ms_svcackt
; /* enter tx service context */
587 int port
= tivr
>> 4;
589 if( tivr
& (1<<3) ) { /* parallel port */
590 struct mbpp_port
*mbpp
;
592 mbpp
= &sc
->ms_mbpp
->ms_port
[port
];
593 cd
= mbpp
->mp_cd1400
;
599 while (mbpp
->mp_cnt
&&
600 count
++ < CD1400_PAR_FIFO_SIZE
) {
601 cd1400_write_reg(cd
, CD1400_TDR
,
608 * fifo is empty and we got no more data
609 * to send, so shut off interrupts and
610 * signal for a wakeup, which can't be
611 * done here in case we beat mbpp_send to
612 * the tsleep call (we are running at >spltty)
614 cd1400_write_reg(cd
, CD1400_SRER
, 0);
615 SET(mbpp
->mp_flags
, MBPPF_WAKEUP
);
618 } else { /* serial port */
619 struct mtty_port
*mtty
;
622 mtty
= &sc
->ms_mtty
->ms_port
[port
];
623 cd
= mtty
->mp_cd1400
;
626 if( !ISSET(mtty
->mp_flags
, MTTYF_STOP
) ) {
629 /* check if we should start/stop a break */
630 if( ISSET(mtty
->mp_flags
, MTTYF_SET_BREAK
) ) {
631 cd1400_write_reg(cd
, CD1400_TDR
, 0);
632 cd1400_write_reg(cd
, CD1400_TDR
, 0x81);
633 /* should we delay too? */
634 CLR(mtty
->mp_flags
, MTTYF_SET_BREAK
);
638 if( ISSET(mtty
->mp_flags
, MTTYF_CLR_BREAK
) ) {
639 cd1400_write_reg(cd
, CD1400_TDR
, 0);
640 cd1400_write_reg(cd
, CD1400_TDR
, 0x83);
641 CLR(mtty
->mp_flags
, MTTYF_CLR_BREAK
);
645 /* I don't quite fill the fifo in case the last one is a
646 * NULL which I have to double up because its the escape
647 * code for embedded transmit characters.
649 while( mtty
->mp_txc
> 0 && count
< CD1400_TX_FIFO_SIZE
- 1 ) {
658 cd1400_write_reg(cd
, CD1400_TDR
, ch
);
662 cd1400_write_reg(cd
, CD1400_TDR
, ch
);
667 /* if we ran out of work or are requested to STOP then
668 * shut off the txrdy interrupts and signal DONE to flush
669 * out the chars we have sent.
671 if( mtty
->mp_txc
== 0 || ISSET(mtty
->mp_flags
, MTTYF_STOP
) ) {
674 srer
= cd1400_read_reg(cd
, CD1400_SRER
);
675 CLR(srer
, CD1400_SRER_TXRDY
);
676 cd1400_write_reg(cd
, CD1400_SRER
, srer
);
677 CLR(mtty
->mp_flags
, MTTYF_STOP
);
679 SET(mtty
->mp_flags
, MTTYF_DONE
);
684 cd1400_write_reg(cd
, CD1400_EOSRR
, 0); /* end service context */
686 } /* if(tx_service...) */
688 /* XXX service CD1190 interrupts too
689 for( chip = 0 ; chip < sc->ms_ncd1190 ; chip++ ) {
694 /* trigger the soft interrupt */
695 softint_schedule(sc
->ms_sicookie
);
701 * magma soft interrupt handler
703 * runs at IPL_SOFTSERIAL
706 magma_soft(void *arg
)
708 struct magma_softc
*sc
= arg
;
709 struct mtty_softc
*mtty
= sc
->ms_mtty
;
710 struct mbpp_softc
*mbpp
= sc
->ms_mbpp
;
718 * check the tty ports to see what needs doing
720 for( port
= 0 ; port
< mtty
->ms_nports
; port
++ ) {
721 struct mtty_port
*mp
= &mtty
->ms_port
[port
];
722 struct tty
*tp
= mp
->mp_tty
;
724 if( !ISSET(tp
->t_state
, TS_ISOPEN
) )
728 * handle any received data
730 while( mp
->mp_rget
!= mp
->mp_rput
) {
734 stat
= mp
->mp_rget
[0];
735 data
= mp
->mp_rget
[1];
736 mp
->mp_rget
= ((mp
->mp_rget
+ 2) == mp
->mp_rend
)
737 ? mp
->mp_rbuf
: (mp
->mp_rget
+ 2);
739 if( stat
& (CD1400_RDSR_BREAK
| CD1400_RDSR_FE
) )
741 if( stat
& CD1400_RDSR_PE
)
744 if( stat
& CD1400_RDSR_OE
)
745 log(LOG_WARNING
, "%s%x: fifo overflow\n",
746 device_xname(&mtty
->ms_dev
), port
);
748 (*tp
->t_linesw
->l_rint
)(data
, tp
);
751 s
= splserial(); /* block out hard interrupt routine */
752 flags
= mp
->mp_flags
;
753 CLR(mp
->mp_flags
, MTTYF_DONE
| MTTYF_CARRIER_CHANGED
| MTTYF_RING_OVERFLOW
);
756 if( ISSET(flags
, MTTYF_CARRIER_CHANGED
) ) {
757 dprintf(("%s%x: cd %s\n", device_xname(&mtty
->ms_dev
),
758 port
, mp
->mp_carrier
? "on" : "off"));
759 (*tp
->t_linesw
->l_modem
)(tp
, mp
->mp_carrier
);
762 if( ISSET(flags
, MTTYF_RING_OVERFLOW
) ) {
763 log(LOG_WARNING
, "%s%x: ring buffer overflow\n",
764 device_xname(&mtty
->ms_dev
), port
);
767 if( ISSET(flags
, MTTYF_DONE
) ) {
768 ndflush(&tp
->t_outq
, mp
->mp_txp
- tp
->t_outq
.c_cf
);
769 CLR(tp
->t_state
, TS_BUSY
);
770 (*tp
->t_linesw
->l_start
)(tp
); /* might be some more */
772 } /* for(each mtty...) */
777 * Check the bpp ports (if any) to see what needs doing
782 for( port
= 0 ; port
< mbpp
->ms_nports
; port
++ ) {
783 struct mbpp_port
*mp
= &mbpp
->ms_port
[port
];
785 if( !ISSET(mp
->mp_flags
, MBPPF_OPEN
) )
789 flags
= mp
->mp_flags
;
790 CLR(mp
->mp_flags
, MBPPF_WAKEUP
);
793 if( ISSET(flags
, MBPPF_WAKEUP
) ) {
797 } /* for(each mbpp...) */
800 /************************************************************************
804 * mtty_match match one mtty device
805 * mtty_attach attach mtty devices
806 * mttyopen open mtty device
807 * mttyclose close mtty device
808 * mttyread read from mtty
809 * mttywrite write to mtty
810 * mttyioctl do ioctl on mtty
811 * mttytty return tty pointer for mtty
812 * mttystop stop mtty device
813 * mtty_start start mtty device
814 * mtty_param set mtty parameters
815 * mtty_modem_control set modem control lines
819 mtty_match(device_t parent
, cfdata_t cf
, void *args
)
821 struct magma_softc
*sc
= device_private(parent
);
823 return( args
== mtty_match
&& sc
->ms_board
->mb_nser
&& sc
->ms_mtty
== NULL
);
827 mtty_attach(device_t parent
, device_t dev
, void *args
)
829 struct magma_softc
*sc
= device_private(parent
);
830 struct mtty_softc
*ms
= device_private(dev
);
831 int port
, chip
, chan
;
834 dprintf((" addr %p", ms
));
836 for( port
= 0, chip
= 0, chan
= 0 ; port
< sc
->ms_board
->mb_nser
; port
++ ) {
837 struct mtty_port
*mp
= &ms
->ms_port
[port
];
840 mp
->mp_cd1400
= &sc
->ms_cd1400
[chip
];
841 if (mp
->mp_cd1400
->cd_parmode
&& chan
== 0)
842 chan
= 1; /* skip channel 0 if parmode */
843 mp
->mp_channel
= chan
;
846 if (tp
== NULL
) break;
848 tp
->t_oproc
= mtty_start
;
849 tp
->t_param
= mtty_param
;
853 mp
->mp_rbuf
= malloc(MTTY_RBUF_SIZE
, M_DEVBUF
, M_NOWAIT
);
854 if (mp
->mp_rbuf
== NULL
) break;
856 mp
->mp_rend
= mp
->mp_rbuf
+ MTTY_RBUF_SIZE
;
858 chan
= (chan
+ 1) % CD1400_NO_OF_CHANNELS
;
863 ms
->ms_nports
= port
;
864 printf(": %d tty%s\n", port
, port
== 1 ? "" : "s");
868 * open routine. returns zero if successful, else error code
871 mttyopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
873 int card
= MAGMA_CARD(dev
);
874 int port
= MAGMA_PORT(dev
);
875 struct mtty_softc
*ms
;
876 struct mtty_port
*mp
;
881 if ((ms
= device_lookup_private(&mtty_cd
, card
)) == NULL
882 || port
>= ms
->ms_nports
)
883 return(ENXIO
); /* device not configured */
885 mp
= &ms
->ms_port
[port
];
889 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
))
894 if( !ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
898 tp
->t_iflag
= TTYDEF_IFLAG
;
899 tp
->t_oflag
= TTYDEF_OFLAG
;
900 tp
->t_cflag
= TTYDEF_CFLAG
;
901 if( ISSET(mp
->mp_openflags
, TIOCFLAG_CLOCAL
) )
902 SET(tp
->t_cflag
, CLOCAL
);
903 if( ISSET(mp
->mp_openflags
, TIOCFLAG_CRTSCTS
) )
904 SET(tp
->t_cflag
, CRTSCTS
);
905 if( ISSET(mp
->mp_openflags
, TIOCFLAG_MDMBUF
) )
906 SET(tp
->t_cflag
, MDMBUF
);
907 tp
->t_lflag
= TTYDEF_LFLAG
;
908 tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
910 /* init ring buffer */
911 mp
->mp_rput
= mp
->mp_rget
= mp
->mp_rbuf
;
913 /* reset CD1400 channel */
915 cd1400_write_reg(cd
, CD1400_CAR
, mp
->mp_channel
);
916 cd1400_write_ccr(cd
, CD1400_CCR_CMDRESET
);
918 /* encode the port number in top half of LIVR */
919 cd1400_write_reg(cd
, CD1400_LIVR
, port
<< 4 );
921 /* sets parameters and raises DTR */
922 (void)mtty_param(tp
, &tp
->t_termios
);
924 /* set tty watermarks */
927 /* enable service requests */
928 cd1400_write_reg(cd
, CD1400_SRER
,
929 CD1400_SRER_RXDATA
| CD1400_SRER_MDMCH
);
931 /* tell the tty about the carrier status */
932 if( ISSET(mp
->mp_openflags
, TIOCFLAG_SOFTCAR
) ||
934 SET(tp
->t_state
, TS_CARR_ON
);
936 CLR(tp
->t_state
, TS_CARR_ON
);
940 error
= ttyopen(tp
, MTTY_DIALOUT(dev
), ISSET(flags
, O_NONBLOCK
));
944 error
= (*tp
->t_linesw
->l_open
)(dev
, tp
);
949 if (!ISSET(tp
->t_state
, TS_ISOPEN
) && tp
->t_wopen
== 0) {
951 * We failed to open the device, and nobody else had it opened.
952 * Clean up the state as appropriate.
954 /* XXX - do that here */
961 * close routine. returns zero if successful, else error code
964 mttyclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
966 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
968 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
969 struct tty
*tp
= mp
->mp_tty
;
972 (*tp
->t_linesw
->l_close
)(tp
, flag
);
977 /* if HUPCL is set, and the tty is no longer open
980 if( ISSET(tp
->t_cflag
, HUPCL
) || !ISSET(tp
->t_state
, TS_ISOPEN
) ) {
981 /* XXX wait until FIFO is empty before turning off the channel
982 struct cd1400 *cd = mp->mp_cd1400;
985 /* drop DTR and RTS */
986 (void)mtty_modem_control(mp
, 0, DMSET
);
988 /* turn off the channel
989 cd1400_write_reg(cd, CD1400_CAR, mp->mp_channel);
990 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET);
1003 mttyread(dev_t dev
, struct uio
*uio
, int flags
)
1005 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1007 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1008 struct tty
*tp
= mp
->mp_tty
;
1010 return( (*tp
->t_linesw
->l_read
)(tp
, uio
, flags
) );
1017 mttywrite(dev_t dev
, struct uio
*uio
, int flags
)
1019 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1021 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1022 struct tty
*tp
= mp
->mp_tty
;
1024 return( (*tp
->t_linesw
->l_write
)(tp
, uio
, flags
) );
1031 mttypoll(dev_t dev
, int events
, struct lwp
*l
)
1033 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1035 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1036 struct tty
*tp
= mp
->mp_tty
;
1038 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
1042 * return tty pointer
1047 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1049 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1058 mttyioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
1060 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1062 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1063 struct tty
*tp
= mp
->mp_tty
;
1066 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flags
, l
);
1067 if( error
!= EPASSTHROUGH
) return(error
);
1069 error
= ttioctl(tp
, cmd
, data
, flags
, l
);
1070 if( error
!= EPASSTHROUGH
) return(error
);
1075 case TIOCSBRK
: /* set break */
1076 SET(mp
->mp_flags
, MTTYF_SET_BREAK
);
1077 cd1400_enable_transmitter(mp
->mp_cd1400
, mp
->mp_channel
);
1080 case TIOCCBRK
: /* clear break */
1081 SET(mp
->mp_flags
, MTTYF_CLR_BREAK
);
1082 cd1400_enable_transmitter(mp
->mp_cd1400
, mp
->mp_channel
);
1085 case TIOCSDTR
: /* set DTR */
1086 mtty_modem_control(mp
, TIOCM_DTR
, DMBIS
);
1089 case TIOCCDTR
: /* clear DTR */
1090 mtty_modem_control(mp
, TIOCM_DTR
, DMBIC
);
1093 case TIOCMSET
: /* set modem lines */
1094 mtty_modem_control(mp
, *((int *)data
), DMSET
);
1097 case TIOCMBIS
: /* bit set modem lines */
1098 mtty_modem_control(mp
, *((int *)data
), DMBIS
);
1101 case TIOCMBIC
: /* bit clear modem lines */
1102 mtty_modem_control(mp
, *((int *)data
), DMBIC
);
1105 case TIOCMGET
: /* get modem lines */
1106 *((int *)data
) = mtty_modem_control(mp
, 0, DMGET
);
1110 *((int *)data
) = mp
->mp_openflags
;
1114 if (kauth_authorize_device_tty(l
->l_cred
,
1115 KAUTH_DEVICE_TTY_PRIVSET
, tp
))
1118 mp
->mp_openflags
= *((int *)data
) &
1119 (TIOCFLAG_SOFTCAR
| TIOCFLAG_CLOCAL
|
1120 TIOCFLAG_CRTSCTS
| TIOCFLAG_MDMBUF
);
1124 error
= EPASSTHROUGH
;
1131 * Stop output, e.g., for ^S or output flush.
1134 mttystop(struct tty
*tp
, int flags
)
1136 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1137 MAGMA_CARD(tp
->t_dev
));
1138 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(tp
->t_dev
)];
1143 if( ISSET(tp
->t_state
, TS_BUSY
) ) {
1144 if( !ISSET(tp
->t_state
, TS_TTSTOP
) )
1145 SET(tp
->t_state
, TS_FLUSH
);
1148 * the transmit interrupt routine will disable transmit when it
1149 * notices that MTTYF_STOP has been set.
1151 SET(mp
->mp_flags
, MTTYF_STOP
);
1158 * Start output, after a stop.
1161 mtty_start(struct tty
*tp
)
1163 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1164 MAGMA_CARD(tp
->t_dev
));
1165 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(tp
->t_dev
)];
1170 /* we only need to do something if we are not already busy
1171 * or delaying or stopped
1173 if( !ISSET(tp
->t_state
, TS_TTSTOP
| TS_TIMEOUT
| TS_BUSY
) ) {
1175 mp
->mp_txc
= ndqb(&tp
->t_outq
, 0);
1176 mp
->mp_txp
= tp
->t_outq
.c_cf
;
1177 SET(tp
->t_state
, TS_BUSY
);
1178 cd1400_enable_transmitter(mp
->mp_cd1400
, mp
->mp_channel
);
1186 * set/get modem line status
1188 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR
1190 * note that DTR and RTS lines are exchanged, and that DSR is
1191 * not available on the LC2+1Sp card (used as CD)
1193 * only let them fiddle with RTS if CRTSCTS is not enabled
1196 mtty_modem_control(struct mtty_port
*mp
, int bits
, int howto
)
1198 struct cd1400
*cd
= mp
->mp_cd1400
;
1199 struct tty
*tp
= mp
->mp_tty
;
1204 cd1400_write_reg(cd
, CD1400_CAR
, mp
->mp_channel
);
1207 case DMGET
: /* get bits */
1212 msvr
= cd1400_read_reg(cd
, CD1400_MSVR1
);
1213 if( msvr
& CD1400_MSVR1_RTS
) bits
|= TIOCM_DTR
;
1215 msvr
= cd1400_read_reg(cd
, CD1400_MSVR2
);
1216 if( msvr
& CD1400_MSVR2_DTR
) bits
|= TIOCM_RTS
;
1217 if( msvr
& CD1400_MSVR2_CTS
) bits
|= TIOCM_CTS
;
1218 if( msvr
& CD1400_MSVR2_RI
) bits
|= TIOCM_RI
;
1219 if( msvr
& CD1400_MSVR2_DSR
) bits
|= (cd
->cd_parmode
? TIOCM_CD
: TIOCM_DSR
);
1220 if( msvr
& CD1400_MSVR2_CD
) bits
|= (cd
->cd_parmode
? 0 : TIOCM_CD
);
1224 case DMSET
: /* reset bits */
1225 if( !ISSET(tp
->t_cflag
, CRTSCTS
) )
1226 cd1400_write_reg(cd
, CD1400_MSVR2
, ((bits
& TIOCM_RTS
) ? CD1400_MSVR2_DTR
: 0));
1228 cd1400_write_reg(cd
, CD1400_MSVR1
, ((bits
& TIOCM_DTR
) ? CD1400_MSVR1_RTS
: 0));
1232 case DMBIS
: /* set bits */
1233 if( (bits
& TIOCM_RTS
) && !ISSET(tp
->t_cflag
, CRTSCTS
) )
1234 cd1400_write_reg(cd
, CD1400_MSVR2
, CD1400_MSVR2_DTR
);
1236 if( bits
& TIOCM_DTR
)
1237 cd1400_write_reg(cd
, CD1400_MSVR1
, CD1400_MSVR1_RTS
);
1241 case DMBIC
: /* clear bits */
1242 if( (bits
& TIOCM_RTS
) && !ISSET(tp
->t_cflag
, CRTSCTS
) )
1243 cd1400_write_reg(cd
, CD1400_MSVR2
, 0);
1245 if( bits
& TIOCM_DTR
)
1246 cd1400_write_reg(cd
, CD1400_MSVR1
, 0);
1256 * Set tty parameters, returns error or 0 on success
1259 mtty_param(struct tty
*tp
, struct termios
*t
)
1261 struct mtty_softc
*ms
= device_lookup_private(&mtty_cd
,
1262 MAGMA_CARD(tp
->t_dev
));
1263 struct mtty_port
*mp
= &ms
->ms_port
[MAGMA_PORT(tp
->t_dev
)];
1264 struct cd1400
*cd
= mp
->mp_cd1400
;
1265 int rbpr
, tbpr
, rcor
, tcor
;
1266 u_char mcor1
= 0, mcor2
= 0;
1269 if( t
->c_ospeed
&& cd1400_compute_baud(t
->c_ospeed
, cd
->cd_clock
, &tcor
, &tbpr
) )
1272 if( t
->c_ispeed
&& cd1400_compute_baud(t
->c_ispeed
, cd
->cd_clock
, &rcor
, &rbpr
) )
1277 /* hang up the line if ospeed is zero, else raise DTR */
1278 (void)mtty_modem_control(mp
, TIOCM_DTR
, (t
->c_ospeed
== 0 ? DMBIC
: DMBIS
));
1280 /* select channel, done in mtty_modem_control() */
1281 /* cd1400_write_reg(cd, CD1400_CAR, mp->mp_channel); */
1283 /* set transmit speed */
1285 cd1400_write_reg(cd
, CD1400_TCOR
, tcor
);
1286 cd1400_write_reg(cd
, CD1400_TBPR
, tbpr
);
1289 /* set receive speed */
1291 cd1400_write_reg(cd
, CD1400_RCOR
, rcor
);
1292 cd1400_write_reg(cd
, CD1400_RBPR
, rbpr
);
1295 /* enable transmitting and receiving on this channel */
1296 opt
= CD1400_CCR_CMDCHANCTL
| CD1400_CCR_XMTEN
| CD1400_CCR_RCVEN
;
1297 cd1400_write_ccr(cd
, opt
);
1299 /* set parity, data and stop bits */
1301 if( ISSET(t
->c_cflag
, PARENB
) )
1302 opt
|= (ISSET(t
->c_cflag
, PARODD
) ? CD1400_COR1_PARODD
: CD1400_COR1_PARNORMAL
);
1304 if( !ISSET(t
->c_iflag
, INPCK
) )
1305 opt
|= CD1400_COR1_NOINPCK
; /* no parity checking */
1307 if( ISSET(t
->c_cflag
, CSTOPB
) )
1308 opt
|= CD1400_COR1_STOP2
;
1310 switch( t
->c_cflag
& CSIZE
) {
1312 opt
|= CD1400_COR1_CS5
;
1316 opt
|= CD1400_COR1_CS6
;
1320 opt
|= CD1400_COR1_CS7
;
1324 opt
|= CD1400_COR1_CS8
;
1328 cd1400_write_reg(cd
, CD1400_COR1
, opt
);
1331 * enable Embedded Transmit Commands (for breaks)
1332 * use the CD1400 automatic CTS flow control if CRTSCTS is set
1334 opt
= CD1400_COR2_ETC
;
1335 if( ISSET(t
->c_cflag
, CRTSCTS
) ) opt
|= CD1400_COR2_CCTS_OFLOW
;
1336 cd1400_write_reg(cd
, CD1400_COR2
, opt
);
1338 cd1400_write_reg(cd
, CD1400_COR3
, MTTY_RX_FIFO_THRESHOLD
);
1340 cd1400_write_ccr(cd
, CD1400_CCR_CMDCORCHG
| CD1400_CCR_COR1
| CD1400_CCR_COR2
| CD1400_CCR_COR3
);
1342 cd1400_write_reg(cd
, CD1400_COR4
, CD1400_COR4_PFO_EXCEPTION
);
1343 cd1400_write_reg(cd
, CD1400_COR5
, 0);
1346 * if automatic RTS handshaking enabled, set DTR threshold
1347 * (RTS and DTR lines are switched, CD1400 thinks its DTR)
1349 if( ISSET(t
->c_cflag
, CRTSCTS
) )
1350 mcor1
= MTTY_RX_DTR_THRESHOLD
;
1352 /* set up `carrier detect' interrupts */
1353 if( cd
->cd_parmode
) {
1354 SET(mcor1
, CD1400_MCOR1_DSRzd
);
1355 SET(mcor2
, CD1400_MCOR2_DSRod
);
1357 SET(mcor1
, CD1400_MCOR1_CDzd
);
1358 SET(mcor2
, CD1400_MCOR2_CDod
);
1361 cd1400_write_reg(cd
, CD1400_MCOR1
, mcor1
);
1362 cd1400_write_reg(cd
, CD1400_MCOR2
, mcor2
);
1364 /* receive timeout 2ms */
1365 cd1400_write_reg(cd
, CD1400_RTPR
, 2);
1371 /************************************************************************
1375 * mbpp_match match one mbpp device
1376 * mbpp_attach attach mbpp devices
1377 * mbppopen open mbpp device
1378 * mbppclose close mbpp device
1379 * mbppioctl do ioctl on mbpp
1380 * mbpp_rw general rw routine
1381 * mbpp_timeout rw timeout
1382 * mbpp_start rw start after delay
1383 * mbpp_send send data
1384 * mbpp_recv recv data
1388 mbpp_match(device_t parent
, cfdata_t cf
, void *args
)
1390 struct magma_softc
*sc
= device_private(parent
);
1392 return( args
== mbpp_match
&& sc
->ms_board
->mb_npar
&& sc
->ms_mbpp
== NULL
);
1396 mbpp_attach(device_t parent
, device_t dev
, void *args
)
1398 struct magma_softc
*sc
= device_private(parent
);
1399 struct mbpp_softc
*ms
= device_private(dev
);
1400 struct mbpp_port
*mp
;
1404 dprintf((" addr %p", ms
));
1406 for( port
= 0 ; port
< sc
->ms_board
->mb_npar
; port
++ ) {
1407 mp
= &ms
->ms_port
[port
];
1409 callout_init(&mp
->mp_timeout_ch
, 0);
1410 callout_init(&mp
->mp_start_ch
, 0);
1412 if( sc
->ms_ncd1190
)
1413 mp
->mp_cd1190
= &sc
->ms_cd1190
[port
];
1415 mp
->mp_cd1400
= &sc
->ms_cd1400
[0];
1418 ms
->ms_nports
= port
;
1419 printf(": %d port%s\n", port
, port
== 1 ? "" : "s");
1423 * open routine. returns zero if successful, else error code
1426 mbppopen(dev_t dev
, int flags
, int mode
, struct lwp
*l
)
1428 int card
= MAGMA_CARD(dev
);
1429 int port
= MAGMA_PORT(dev
);
1430 struct mbpp_softc
*ms
;
1431 struct mbpp_port
*mp
;
1434 if ((ms
= device_lookup_private(&mbpp_cd
, card
)) == NULL
1435 || port
>= ms
->ms_nports
)
1438 mp
= &ms
->ms_port
[port
];
1441 if( ISSET(mp
->mp_flags
, MBPPF_OPEN
) ) {
1445 SET(mp
->mp_flags
, MBPPF_OPEN
);
1449 mp
->mp_burst
= MBPP_BURST
;
1450 mp
->mp_timeout
= mbpp_mstohz(MBPP_TIMEOUT
);
1451 mp
->mp_delay
= mbpp_mstohz(MBPP_DELAY
);
1454 if( mp
->mp_cd1400
) { /* CD1400 */
1455 struct cd1400
*cd
= mp
->mp_cd1400
;
1457 /* set up CD1400 channel */
1459 cd1400_write_reg(cd
, CD1400_CAR
, 0);
1460 cd1400_write_ccr(cd
, CD1400_CCR_CMDRESET
);
1461 cd1400_write_reg(cd
, CD1400_LIVR
, (1<<3));
1463 } else { /* CD1190 */
1472 * close routine. returns zero if successful, else error code
1475 mbppclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
1477 struct mbpp_softc
*ms
= device_lookup_private(&mbpp_cd
,
1479 struct mbpp_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1489 mbppioctl(dev_t dev
, u_long cmd
, void *data
, int flags
, struct lwp
*l
)
1491 struct mbpp_softc
*ms
= device_lookup_private(&mbpp_cd
,
1493 struct mbpp_port
*mp
= &ms
->ms_port
[MAGMA_PORT(dev
)];
1494 struct mbpp_param
*bp
;
1500 bp
= (struct mbpp_param
*)data
;
1501 if( bp
->bp_burst
< MBPP_BURST_MIN
|| bp
->bp_burst
> MBPP_BURST_MAX
||
1502 bp
->bp_delay
< MBPP_DELAY_MIN
|| bp
->bp_delay
> MBPP_DELAY_MIN
) {
1505 mp
->mp_burst
= bp
->bp_burst
;
1506 mp
->mp_timeout
= mbpp_mstohz(bp
->bp_timeout
);
1507 mp
->mp_delay
= mbpp_mstohz(bp
->bp_delay
);
1511 bp
= (struct mbpp_param
*)data
;
1512 bp
->bp_burst
= mp
->mp_burst
;
1513 bp
->bp_timeout
= mbpp_hztoms(mp
->mp_timeout
);
1514 bp
->bp_delay
= mbpp_hztoms(mp
->mp_delay
);
1517 /* XXX make this more generic */
1519 cd1400_write_reg(mp
->mp_cd1400
, CD1400_CAR
, 0);
1520 *(int *)data
= cd1400_read_reg(mp
->mp_cd1400
, CD1400_PSVR
);
1531 mbpp_rw(dev_t dev
, struct uio
*uio
, int flag
)
1533 int card
= MAGMA_CARD(dev
);
1534 int port
= MAGMA_PORT(dev
);
1535 struct mbpp_softc
*ms
= device_lookup_private(&mbpp_cd
, card
);
1536 struct mbpp_port
*mp
= &ms
->ms_port
[port
];
1538 int buflen
, cnt
, len
;
1542 if( uio
->uio_resid
== 0 )
1545 buflen
= min(uio
->uio_resid
, mp
->mp_burst
);
1546 buffer
= malloc(buflen
, M_DEVBUF
, M_WAITOK
);
1547 if( buffer
== NULL
)
1550 SET(mp
->mp_flags
, MBPPF_UIO
);
1553 * start timeout, if needed
1555 if( mp
->mp_timeout
> 0 ) {
1556 SET(mp
->mp_flags
, MBPPF_TIMEOUT
);
1557 callout_reset(&mp
->mp_timeout_ch
, mp
->mp_timeout
,
1562 while( uio
->uio_resid
> 0 ) {
1563 len
= min(buflen
, uio
->uio_resid
);
1566 if( uio
->uio_rw
== UIO_WRITE
) {
1567 error
= uiomove(ptr
, len
, uio
);
1570 again
: /* goto bad */
1572 if( !ISSET(mp
->mp_flags
, MBPPF_UIO
) )
1576 * perform the operation
1578 if( uio
->uio_rw
== UIO_WRITE
) {
1579 cnt
= mbpp_send(mp
, ptr
, len
);
1581 cnt
= mbpp_recv(mp
, ptr
, len
);
1584 if( uio
->uio_rw
== UIO_READ
) {
1586 error
= uiomove(ptr
, cnt
, uio
);
1590 else if( gotdata
) /* consider us done */
1595 if( !ISSET(mp
->mp_flags
, MBPPF_UIO
) )
1601 if( mp
->mp_delay
> 0 ) {
1603 SET(mp
->mp_flags
, MBPPF_DELAY
);
1604 callout_reset(&mp
->mp_start_ch
, mp
->mp_delay
,
1606 error
= tsleep(mp
, PCATCH
| PZERO
, "mbppdelay", 0);
1612 * don't call uiomove again until we used all the data we grabbed
1614 if( uio
->uio_rw
== UIO_WRITE
&& cnt
!= len
) {
1626 if( ISSET(mp
->mp_flags
, MBPPF_TIMEOUT
) ) {
1627 callout_stop(&mp
->mp_timeout_ch
);
1628 CLR(mp
->mp_flags
, MBPPF_TIMEOUT
);
1630 if( ISSET(mp
->mp_flags
, MBPPF_DELAY
) ) {
1631 callout_stop(&mp
->mp_start_ch
);
1632 CLR(mp
->mp_flags
, MBPPF_DELAY
);
1637 * adjust for those chars that we uiomoved but never actually wrote
1639 if( uio
->uio_rw
== UIO_WRITE
&& cnt
!= len
) {
1640 uio
->uio_resid
+= (len
- cnt
);
1643 free(buffer
, M_DEVBUF
);
1648 mbpp_timeout(void *arg
)
1650 struct mbpp_port
*mp
= arg
;
1652 CLR(mp
->mp_flags
, MBPPF_UIO
| MBPPF_TIMEOUT
);
1657 mbpp_start(void *arg
)
1659 struct mbpp_port
*mp
= arg
;
1661 CLR(mp
->mp_flags
, MBPPF_DELAY
);
1666 mbpp_send(struct mbpp_port
*mp
, void *ptr
, int len
)
1669 struct cd1400
*cd
= mp
->mp_cd1400
;
1671 /* set up io information */
1675 /* start transmitting */
1678 cd1400_write_reg(cd
, CD1400_CAR
, 0);
1680 /* output strobe width ~1microsecond */
1681 cd1400_write_reg(cd
, CD1400_TBPR
, 10);
1683 /* enable channel */
1684 cd1400_write_ccr(cd
, CD1400_CCR_CMDCHANCTL
| CD1400_CCR_XMTEN
);
1685 cd1400_write_reg(cd
, CD1400_SRER
, CD1400_SRER_TXRDY
);
1689 tsleep(mp
, PCATCH
| PZERO
, "mbpp_send", 0);
1691 /* stop transmitting */
1693 cd1400_write_reg(cd
, CD1400_CAR
, 0);
1695 /* disable transmitter */
1696 cd1400_write_reg(cd
, CD1400_SRER
, 0);
1697 cd1400_write_ccr(cd
, CD1400_CCR_CMDCHANCTL
| CD1400_CCR_XMTDIS
);
1700 cd1400_write_ccr(cd
, CD1400_CCR_CMDRESET
| CD1400_CCR_FTF
);
1704 /* return number of chars sent */
1705 return(len
- mp
->mp_cnt
);
1709 mbpp_recv(struct mbpp_port
*mp
, void *ptr
, int len
)
1712 struct cd1400
*cd
= mp
->mp_cd1400
;
1714 /* set up io information */
1718 /* start receiving */
1723 cd1400_write_reg(cd
, CD1400_CAR
, 0);
1725 /* input strobe at 100kbaud (10microseconds) */
1726 cd1400_compute_baud(100000, cd
->cd_clock
, &rcor
, &rbpr
);
1727 cd1400_write_reg(cd
, CD1400_RCOR
, rcor
);
1728 cd1400_write_reg(cd
, CD1400_RBPR
, rbpr
);
1731 cd1400_write_reg(cd
, CD1400_COR3
, MBPP_RX_FIFO_THRESHOLD
);
1732 cd1400_write_ccr(cd
, CD1400_CCR_CMDCORCHG
| CD1400_CCR_COR3
);
1734 /* enable channel */
1735 cd1400_write_ccr(cd
, CD1400_CCR_CMDCHANCTL
| CD1400_CCR_RCVEN
);
1736 cd1400_write_reg(cd
, CD1400_SRER
, CD1400_SRER_RXDATA
);
1740 tsleep(mp
, PCATCH
| PZERO
, "mbpp_recv", 0);
1742 /* stop receiving */
1744 cd1400_write_reg(cd
, CD1400_CAR
, 0);
1746 /* disable receiving */
1747 cd1400_write_reg(cd
, CD1400_SRER
, 0);
1748 cd1400_write_ccr(cd
, CD1400_CCR_CMDCHANCTL
| CD1400_CCR_RCVDIS
);
1752 /* return number of chars received */
1753 return(len
- mp
->mp_cnt
);