X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=drivers%2Fchar%2Fsynclink.c;h=fee2aca3f6a5c7eb77c8c07135489644e5ec8ab2;hb=0dd4b21f517e138ea113db255645fbae1bf5eef3;hp=82c6abde68dff226982f198ad9000bdd31dc30fe;hpb=2ecc26b87a2b3e8650d3c7fe3fc85a8c73d5560d;p=powerpc.git diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 82c6abde68..fee2aca3f6 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c @@ -1,7 +1,7 @@ /* * linux/drivers/char/synclink.c * - * $Id: synclink.c,v 4.37 2005/09/07 13:13:19 paulkf Exp $ + * $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $ * * Device driver for Microgate SyncLink ISA and PCI * high speed multiprotocol serial adapters. @@ -101,6 +101,7 @@ #include #include #include +#include #ifdef CONFIG_HDLC_MODULE #define CONFIG_HDLC 1 @@ -148,6 +149,7 @@ typedef struct _DMABUFFERENTRY u32 link; /* 32-bit flat link to next buffer entry */ char *virt_addr; /* virtual address of data buffer */ u32 phys_entry; /* physical address of this buffer entry */ + dma_addr_t dma_addr; } DMABUFFERENTRY, *DMAPBUFFERENTRY; /* The queue of BH actions to be performed */ @@ -233,7 +235,8 @@ struct mgsl_struct { int ri_chkcount; char *buffer_list; /* virtual address of Rx & Tx buffer lists */ - unsigned long buffer_list_phys; + u32 buffer_list_phys; + dma_addr_t buffer_list_dma_addr; unsigned int rx_buffer_count; /* count of total allocated Rx buffers */ DMABUFFERENTRY *rx_buffer_list; /* list of receive buffer entries */ @@ -896,7 +899,7 @@ module_param_array(txdmabufs, int, NULL, 0); module_param_array(txholdbufs, int, NULL, 0); static char *driver_name = "SyncLink serial driver"; -static char *driver_version = "$Revision: 4.37 $"; +static char *driver_version = "$Revision: 4.38 $"; static int synclink_init_one (struct pci_dev *dev, const struct pci_device_id *ent); @@ -938,18 +941,6 @@ static void* mgsl_get_text_ptr(void) return mgsl_get_text_ptr; } -/* - * tmp_buf is used as a temporary buffer by mgsl_write. We need to - * lock it in case the COPY_FROM_USER blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ioports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char *tmp_buf; -static DECLARE_MUTEX(tmp_buf_sem); - static inline int mgsl_paranoia_check(struct mgsl_struct *info, char *name, const char *routine) { @@ -1464,6 +1455,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) { int Fifocount; u16 status; + int work = 0; unsigned char DataByte; struct tty_struct *tty = info->tty; struct mgsl_icount *icount = &info->icount; @@ -1484,6 +1476,8 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) /* flush the receive FIFO */ while( (Fifocount = (usc_InReg(info,RICR) >> 8)) ) { + int flag; + /* read one byte from RxFIFO */ outw( (inw(info->io_base + CCAR) & 0x0780) | (RDR+LSBONLY), info->io_base + CCAR ); @@ -1495,13 +1489,9 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) usc_UnlatchRxstatusBits(info,RXSTATUS_ALL); - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - continue; - - *tty->flip.char_buf_ptr = DataByte; icount->rx++; - *tty->flip.flag_buf_ptr = 0; + flag = 0; if ( status & (RXSTATUS_FRAMING_ERROR + RXSTATUS_PARITY_ERROR + RXSTATUS_OVERRUN + RXSTATUS_BREAK_RECEIVED) ) { printk("rxerr=%04X\n",status); @@ -1527,41 +1517,31 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info ) status &= info->read_status_mask; if (status & RXSTATUS_BREAK_RECEIVED) { - *tty->flip.flag_buf_ptr = TTY_BREAK; + flag = TTY_BREAK; if (info->flags & ASYNC_SAK) do_SAK(tty); } else if (status & RXSTATUS_PARITY_ERROR) - *tty->flip.flag_buf_ptr = TTY_PARITY; + flag = TTY_PARITY; else if (status & RXSTATUS_FRAMING_ERROR) - *tty->flip.flag_buf_ptr = TTY_FRAME; - if (status & RXSTATUS_OVERRUN) { - /* Overrun is special, since it's - * reported immediately, and doesn't - * affect the current character - */ - if (tty->flip.count < TTY_FLIPBUF_SIZE) { - tty->flip.count++; - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - *tty->flip.flag_buf_ptr = TTY_OVERRUN; - } - } + flag = TTY_FRAME; } /* end of if (error) */ - - tty->flip.flag_buf_ptr++; - tty->flip.char_buf_ptr++; - tty->flip.count++; + tty_insert_flip_char(tty, DataByte, flag); + if (status & RXSTATUS_OVERRUN) { + /* Overrun is special, since it's + * reported immediately, and doesn't + * affect the current character + */ + work += tty_insert_flip_char(tty, 0, TTY_OVERRUN); + } } if ( debug_level >= DEBUG_LEVEL_ISR ) { - printk("%s(%d):mgsl_isr_receive_data flip count=%d\n", - __FILE__,__LINE__,tty->flip.count); printk("%s(%d):rx=%d brk=%d parity=%d frame=%d overrun=%d\n", __FILE__,__LINE__,icount->rx,icount->brk, icount->parity,icount->frame,icount->overrun); } - if ( tty->flip.count ) + if(work) tty_flip_buffer_push(tty); } @@ -2159,7 +2139,7 @@ static int mgsl_write(struct tty_struct * tty, if (mgsl_paranoia_check(info, tty->name, "mgsl_write")) goto cleanup; - if (!tty || !info->xmit_buf || !tmp_buf) + if (!tty || !info->xmit_buf) goto cleanup; if ( info->params.mode == MGSL_MODE_HDLC || @@ -3447,7 +3427,6 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) { struct mgsl_struct *info; int retval, line; - unsigned long page; unsigned long flags; /* verify range of specified line number */ @@ -3481,18 +3460,6 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp) goto cleanup; } - if (!tmp_buf) { - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - retval = -ENOMEM; - goto cleanup; - } - if (tmp_buf) - free_page(page); - else - tmp_buf = (unsigned char *) page; - } - info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; spin_lock_irqsave(&info->netlock, flags); @@ -3811,11 +3778,10 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) /* inspect portions of the buffer while other portions are being */ /* updated by the adapter using Bus Master DMA. */ - info->buffer_list = kmalloc(BUFFERLISTSIZE, GFP_KERNEL | GFP_DMA); - if ( info->buffer_list == NULL ) + info->buffer_list = dma_alloc_coherent(NULL, BUFFERLISTSIZE, &info->buffer_list_dma_addr, GFP_KERNEL); + if (info->buffer_list == NULL) return -ENOMEM; - - info->buffer_list_phys = isa_virt_to_bus(info->buffer_list); + info->buffer_list_phys = (u32)(info->buffer_list_dma_addr); } /* We got the memory for the buffer entry lists. */ @@ -3882,8 +3848,8 @@ static int mgsl_alloc_buffer_list_memory( struct mgsl_struct *info ) */ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) { - if ( info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI ) - kfree(info->buffer_list); + if (info->buffer_list && info->bus_type != MGSL_BUS_TYPE_PCI) + dma_free_coherent(NULL, BUFFERLISTSIZE, info->buffer_list, info->buffer_list_dma_addr); info->buffer_list = NULL; info->rx_buffer_list = NULL; @@ -3910,7 +3876,7 @@ static void mgsl_free_buffer_list_memory( struct mgsl_struct *info ) static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *BufferList,int Buffercount) { int i; - unsigned long phys_addr; + u32 phys_addr; /* Allocate page sized buffers for the receive buffer list */ @@ -3922,11 +3888,10 @@ static int mgsl_alloc_frame_memory(struct mgsl_struct *info,DMABUFFERENTRY *Buff info->last_mem_alloc += DMABUFFERSIZE; } else { /* ISA adapter uses system memory. */ - BufferList[i].virt_addr = - kmalloc(DMABUFFERSIZE, GFP_KERNEL | GFP_DMA); - if ( BufferList[i].virt_addr == NULL ) + BufferList[i].virt_addr = dma_alloc_coherent(NULL, DMABUFFERSIZE, &BufferList[i].dma_addr, GFP_KERNEL); + if (BufferList[i].virt_addr == NULL) return -ENOMEM; - phys_addr = isa_virt_to_bus(BufferList[i].virt_addr); + phys_addr = (u32)(BufferList[i].dma_addr); } BufferList[i].phys_addr = phys_addr; } @@ -3957,7 +3922,7 @@ static void mgsl_free_frame_memory(struct mgsl_struct *info, DMABUFFERENTRY *Buf for ( i = 0 ; i < Buffercount ; i++ ) { if ( BufferList[i].virt_addr ) { if ( info->bus_type != MGSL_BUS_TYPE_PCI ) - kfree(BufferList[i].virt_addr); + dma_free_coherent(NULL, DMABUFFERSIZE, BufferList[i].virt_addr, BufferList[i].dma_addr); BufferList[i].virt_addr = NULL; } } @@ -4513,11 +4478,6 @@ static void synclink_cleanup(void) kfree(tmp); } - if (tmp_buf) { - free_page((unsigned long) tmp_buf); - tmp_buf = NULL; - } - if (pci_registered) pci_unregister_driver(&synclink_pci_driver); } @@ -6036,7 +5996,7 @@ static void usc_set_async_mode( struct mgsl_struct *info ) * <15..8> ? RxFIFO IRQ Request Level * * Note: For async mode the receive FIFO level must be set - * to 0 to aviod the situation where the FIFO contains fewer bytes + * to 0 to avoid the situation where the FIFO contains fewer bytes * than the trigger level and no more data is expected. * * <7> 0 Exited Hunt IA (Interrupt Arm) @@ -7057,7 +7017,7 @@ static BOOLEAN mgsl_register_test( struct mgsl_struct *info ) { static unsigned short BitPatterns[] = { 0x0000, 0xffff, 0xaaaa, 0x5555, 0x1234, 0x6969, 0x9696, 0x0f0f }; - static unsigned int Patterncount = sizeof(BitPatterns)/sizeof(unsigned short); + static unsigned int Patterncount = ARRAY_SIZE(BitPatterns); unsigned int i; BOOLEAN rc = TRUE; unsigned long flags; @@ -7500,9 +7460,9 @@ static int mgsl_adapter_test( struct mgsl_struct *info ) */ static BOOLEAN mgsl_memory_test( struct mgsl_struct *info ) { - static unsigned long BitPatterns[] = { 0x0, 0x55555555, 0xaaaaaaaa, - 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; - unsigned long Patterncount = sizeof(BitPatterns)/sizeof(unsigned long); + static unsigned long BitPatterns[] = + { 0x0, 0x55555555, 0xaaaaaaaa, 0x66666666, 0x99999999, 0xffffffff, 0x12345678 }; + unsigned long Patterncount = ARRAY_SIZE(BitPatterns); unsigned long i; unsigned long TestLimit = SHARED_MEM_ADDRESS_SIZE/sizeof(unsigned long); unsigned long * TestAddr; @@ -7781,7 +7741,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding, } info->params.encoding = new_encoding; - info->params.crc_type = new_crctype;; + info->params.crc_type = new_crctype; /* if network interface up, reprogram hardware */ if (info->netcount)