Totally untested (and very probably broken) patch to ipwireless_Linux driver for T-Mobile 4G pcmcia cart (Czech Republic). Can't currently test, don't have the HW. diff -rup ipwireless_Linux.orig/pccard/ipwireless_cs_main.c ipwireless_Linux/pccard/ipwireless_cs_main.c --- ipwireless_Linux.orig/pccard/ipwireless_cs_main.c 2005-09-14 22:28:00.000000000 +0200 +++ ipwireless_Linux/pccard/ipwireless_cs_main.c 2006-10-19 16:11:53.000000000 +0200 @@ -44,7 +44,7 @@ static ipw_config_t default_config = { /* Prototypes */ static void -ipwireless_detach(dev_link_t * link); +ipwireless_detach(struct pcmcia_device * link); /* Options configurable through the proc filesystem. */ __u16 ipwireless_cs_debug = 0; @@ -60,15 +60,14 @@ MODULE_PARM_DESC(vendor, "vendor (0 or 1 MODULE_PARM(loopback, "i"); MODULE_PARM_DESC(loopback, "loopback (0 or 1) [0]"); #endif -MODULE_PARM(major, "i"); +module_param(major, int, 0); MODULE_PARM_DESC(major, "ttyIPWp major number [0]"); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static char* drv_name = IPWIRELESS_PCCARD_NAME; #endif -static dev_info_t dev_info = IPWIRELESS_PCCARD_NAME; -static dev_link_t *dev_list; +static struct pcmcia_device *dev_list; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) @@ -80,45 +79,45 @@ static void cs_error(client_handle_t han #endif static inline int -reset_cor(dev_link_t* link, u_short cor_value) +reset_cor(struct pcmcia_device* link, u_short cor_value) { int i; conf_reg_t reg = { 0, CS_READ, CISREG_COR, 0 }; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - i = CardServices(AccessConfigurationRegister, link->handle, ®); + i = CardServices(AccessConfigurationRegister, link, ®); #else - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); #endif if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return -1; } reg.Action = CS_WRITE; reg.Value = reg.Value | 0x80; /* SRESET Software reset */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - i = CardServices(AccessConfigurationRegister, link->handle, ®); + i = CardServices(AccessConfigurationRegister, link, ®); #else - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); #endif if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return -1; } reg.Action = CS_WRITE; reg.Value = cor_value; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - i = CardServices(AccessConfigurationRegister, link->handle, ®); + i = CardServices(AccessConfigurationRegister, link, ®); #else - i = pcmcia_access_configuration_register(link->handle, ®); + i = pcmcia_access_configuration_register(link, ®); #endif if(i != CS_SUCCESS) { - cs_error(link->handle, AccessConfigurationRegister, i); + cs_error(link, AccessConfigurationRegister, i); return -1; } @@ -128,10 +127,9 @@ reset_cor(dev_link_t* link, u_short cor_ static int config_ipwireless(ipw_dev_t* ipw) { - dev_link_t *link = &ipw->link; + struct pcmcia_device *link = ipw->link; /*win_req_t req;*/ int ret; - config_info_t conf; tuple_t tuple; u_short buf[64]; cisparse_t parse; @@ -144,53 +142,53 @@ config_ipwireless(ipw_dev_t* ipw) tuple.DesiredTuple = RETURN_FIRST_TUPLE; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetFirstTuple, link->handle, &tuple); + ret = CardServices(GetFirstTuple, link, &tuple); #else - ret = pcmcia_get_first_tuple(link->handle, &tuple); + ret = pcmcia_get_first_tuple(link, &tuple); #endif while (ret == 0) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetTupleData, link->handle, &tuple); + ret = CardServices(GetTupleData, link, &tuple); #else - ret = pcmcia_get_tuple_data(link->handle, &tuple); + ret = pcmcia_get_tuple_data(link, &tuple); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); goto exit0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetNextTuple, link->handle, &tuple); + ret = CardServices(GetNextTuple, link, &tuple); #else - ret = pcmcia_get_next_tuple(link->handle, &tuple); + ret = pcmcia_get_next_tuple(link, &tuple); #endif } tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetFirstTuple, link->handle, &tuple); + ret = CardServices(GetFirstTuple, link, &tuple); #else - ret = pcmcia_get_first_tuple(link->handle, &tuple); + ret = pcmcia_get_first_tuple(link, &tuple); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetFirstTuple, ret); + cs_error(link, GetFirstTuple, ret); goto exit0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetTupleData, link->handle, &tuple); + ret = CardServices(GetTupleData, link, &tuple); #else - ret = pcmcia_get_tuple_data(link->handle, &tuple); + ret = pcmcia_get_tuple_data(link, &tuple); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); goto exit0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(ParseTuple, link->handle, &tuple, &parse); + ret = CardServices(ParseTuple, link, &tuple, &parse); #else - ret = pcmcia_parse_tuple(link->handle, &tuple, &parse); + ret = pcmcia_parse_tuple(link, &tuple, &parse); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); goto exit0; } link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -207,30 +205,30 @@ config_ipwireless(ipw_dev_t* ipw) tuple.DesiredTuple = CISTPL_CONFIG; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetFirstTuple, link->handle, &tuple); + ret = CardServices(GetFirstTuple, link, &tuple); #else - ret = pcmcia_get_first_tuple(link->handle, &tuple); + ret = pcmcia_get_first_tuple(link, &tuple); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetFirstTuple, ret); + cs_error(link, GetFirstTuple, ret); goto exit0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetTupleData, link->handle, &tuple); + ret = CardServices(GetTupleData, link, &tuple); #else - ret = pcmcia_get_tuple_data(link->handle, &tuple); + ret = pcmcia_get_tuple_data(link, &tuple); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); goto exit0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(ParseTuple, link->handle, &tuple, &parse); + ret = CardServices(ParseTuple, link, &tuple, &parse); #else - ret = pcmcia_parse_tuple(link->handle, &tuple, &parse); + ret = pcmcia_parse_tuple(link, &tuple, &parse); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, GetTupleData, ret); + cs_error(link, GetTupleData, ret); goto exit0; } link->conf.Attributes = CONF_ENABLE_IRQ; @@ -243,52 +241,47 @@ config_ipwireless(ipw_dev_t* ipw) link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Instance = ipw->hardware; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(RequestIRQ, link->handle, &link->irq); + ret = CardServices(RequestIRQ, link, &link->irq); #else - ret = pcmcia_request_irq(link->handle, &link->irq); + ret = pcmcia_request_irq(link, &link->irq); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, RequestIRQ, ret); + cs_error(link, RequestIRQ, ret); goto exit2; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(RequestIO, link->handle, &link->io); + ret = CardServices(RequestIO, link, &link->io); #else - ret = pcmcia_request_io(link->handle, &link->io); + ret = pcmcia_request_io(link, &link->io); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, RequestIO, ret); + cs_error(link, RequestIO, ret); goto exit3; } /* Look up current Vcc */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(GetConfigurationInfo, link->handle, &conf); -#else - ret = pcmcia_get_configuration_info(link->handle, &conf); -#endif + ret = CardServices(GetConfigurationInfo, link, &conf); if (ret != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, ret); + cs_error(link, RequestConfiguration, ret); goto exit3; } link->conf.Vcc = conf.Vcc; +#endif /*reset_cor(link, cor_value);*/ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(RequestConfiguration, link->handle, &link->conf); + ret = CardServices(RequestConfiguration, link, &link->conf); #else - ret = pcmcia_request_configuration(link->handle, &link->conf); + ret = pcmcia_request_configuration(link, &link->conf); #endif if (ret != CS_SUCCESS) { - cs_error(link->handle, RequestConfiguration, ret); + cs_error(link, RequestConfiguration, ret); goto exit4; } - link->state &= ~DEV_CONFIG_PENDING; - link->state |= DEV_CONFIG; - printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": I/O ports 0x%04x-0x%04x irq %d\n", (unsigned int) link->io.BasePort1, (unsigned int) (link->io.BasePort1+link->io.NumPorts1-1), @@ -301,21 +294,21 @@ config_ipwireless(ipw_dev_t* ipw) ipwireless_init_hardware2(ipw->hardware); - link->dev = &ipw->nodes[0]; + link->dev_node = &ipw->nodes[0]; return 0; exit4: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(ReleaseIO, link->handle, &link->io); + CardServices(ReleaseIO, link, &link->io); #else - pcmcia_release_io(link->handle, &link->io); + pcmcia_disable_device(link); #endif exit3: #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(ReleaseIRQ, link->handle, &link->irq); + CardServices(ReleaseIRQ, link, &link->irq); #else - pcmcia_release_irq(link->handle, &link->irq); + pcmcia_disable_device(link); #endif exit2: exit0: @@ -325,7 +318,7 @@ exit0: static void release_ipwireless(ipw_dev_t* ipw) /* Address of the interface struct */ { - dev_link_t *link = &ipw->link; + struct pcmcia_device *link = ipw->link; if (ipw->tty != NULL) { ipwireless_tty_free(ipw->tty); @@ -333,16 +326,12 @@ release_ipwireless(ipw_dev_t* ipw) /* Ad } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(ReleaseConfiguration, link->handle); - CardServices(ReleaseIO, link->handle, &link->io); - CardServices(ReleaseIRQ, link->handle, &link->irq); + CardServices(ReleaseConfiguration, link); + CardServices(ReleaseIO, link, &link->io); + CardServices(ReleaseIRQ, link, &link->irq); #else - pcmcia_release_configuration(link->handle); - pcmcia_release_io(link->handle, &link->io); - pcmcia_release_irq(link->handle, &link->irq); + pcmcia_disable_device(link); #endif - - link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG); } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) @@ -367,7 +356,7 @@ ipwireless_event(event_t event, /* The event_callback_args_t* args) { ipw_dev_t * ipw = (ipw_dev_t *) args->client_data; - dev_link_t * link = &ipw->link; + struct pcmcia_device * link = ipw->link; printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": PCMCIA event - %s\n", ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" : @@ -384,49 +373,37 @@ ipwireless_event(event_t event, /* The case CS_EVENT_CARD_REMOVAL: /* Eeets gorn! */ - link->state &= ~DEV_PRESENT; - if(link->state & DEV_CONFIG) - { - /* Release the card */ - release_ipwireless(ipw); - } + /* Release the card */ + release_ipwireless(ipw); break; case CS_EVENT_CARD_INSERTION: /* Reset and configure the card */ - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; config_ipwireless(ipw); break; case CS_EVENT_PM_SUSPEND: /* The card is now suspended */ - link->state |= DEV_SUSPEND; /* Fall through... */ case CS_EVENT_RESET_PHYSICAL: - if(link->state & DEV_CONFIG) - { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(ReleaseConfiguration, link->handle); + CardServices(ReleaseConfiguration, link); #else - pcmcia_release_configuration(link->handle); + pcmcia_disable_device(link); #endif - } break; case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; /* Fall through... */ case CS_EVENT_CARD_RESET: - if(link->state & DEV_CONFIG) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(RequestConfiguration, link->handle, &link->conf); + CardServices(RequestConfiguration, link, &link->conf); #else - pcmcia_request_configuration(link->handle, &link->conf); + pcmcia_request_configuration(link, &link->conf); #endif - if (link->open) { /* If RESET -> True, If RESUME -> False ? */ + if (link->open) { /* If RESET -> True, If RESUME -> False ? */ ipwireless_init_hardware1(ipw->hardware, link->io.BasePort1); ipwireless_init_hardware2(ipw->hardware); - } } break; } @@ -450,14 +427,7 @@ ipwireless_event(event_t event, /* The static void ipwireless_flush_stale_links(void) { - dev_link_t * link; /* Current node in linked list */ - dev_link_t * next; /* Next node in linked list */ - - /* Go through the list */ - for (link = dev_list; link; link = next) { - next = link->next; - ipwireless_detach(link); - } + printk(KERN_ERR "ipwireless_flush_stale_links(): FIXME this is broken\n"); } /* @@ -469,12 +439,9 @@ ipwireless_flush_stale_links(void) * configure the card at this point -- we wait until we receive a * card insertion event. */ -static dev_link_t * -ipwireless_attach(void) +static int ipwireless_attach(struct pcmcia_device *link) { ipw_dev_t* ipw; - dev_link_t *link; - client_reg_t client_reg; int ret; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) @@ -483,7 +450,7 @@ ipwireless_attach(void) ipw = (ipw_dev_t*) kmalloc(sizeof(ipw_dev_t), GFP_KERNEL); memset(ipw, 0, sizeof(ipw_dev_t)); - link = &ipw->link; + ipw->link = link; link->priv = link->irq.Instance = ipw; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) @@ -492,36 +459,24 @@ ipwireless_attach(void) #endif /* Link this device into our device list. */ - link->next = dev_list; + link->dev_node = &ipw->nodes[0]; dev_list = link; - /* Register with Card Services */ - client_reg.dev_info = &dev_info; - client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; - client_reg.EventMask = - /*CS_EVENT_REGISTRATION_COMPLETE |*/ - CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | - CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | - CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; - client_reg.event_handler = &ipwireless_event; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = ipw; - ipw->hardware = ipwireless_hardware_create(&default_config); /* RegisterClient will call config_ipwireless */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - ret = CardServices(RegisterClient, &link->handle, &client_reg); + ret = CardServices(RegisterClient, &link, &client_reg); #else - ret = pcmcia_register_client(&link->handle, &client_reg); + ret = config_ipwireless(ipw); #endif if(ret != 0) { - cs_error(link->handle, RegisterClient, ret); + cs_error(link, RegisterClient, ret); ipwireless_detach(link); - return NULL; + return ret; } - return link; + return 0; } /*------------------------------------------------------------------*/ @@ -532,53 +487,24 @@ ipwireless_attach(void) * is released. */ static void -ipwireless_detach(dev_link_t * link) +ipwireless_detach(struct pcmcia_device * link) { ipw_dev_t* ipw = (ipw_dev_t*) link->priv; - /* - * If the device is currently configured and active, we won't - * actually delete it yet. Instead, it is marked so that when the - * release() function is called, that will trigger a proper - * detach(). - */ - if(link->state & DEV_CONFIG) { - release_ipwireless(ipw); - if(link->state & DEV_STALE_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } - } + release_ipwireless(ipw); if (ipw->hardware != NULL) ipwireless_hardware_free(ipw->hardware); /* Break the link with Card Services */ - if (link->handle) { + if (link) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - CardServices(DeregisterClient, link->handle); + CardServices(DeregisterClient, link); #else - pcmcia_deregister_client(link->handle); + pcmcia_disable_device(link); #endif } - /* Remove the interface data from the linked list */ - if (dev_list == link) - dev_list = link->next; - else { - dev_link_t * prev = dev_list; - - while((prev != (dev_link_t *) NULL) && (prev->next != link)) - prev = prev->next; - - if(prev == (dev_link_t *) NULL) { - printk(KERN_ERR IPWIRELESS_PCCARD_NAME ": Attempting to remove a nonexistent device.\n"); - return; - } - - prev->next = link->next; - } - if (ipw->tty != NULL) ipwireless_tty_free(ipw->tty); if (ipw->network != NULL) @@ -607,13 +533,10 @@ static struct pcmcia_driver me; static int __init init_ipwireless_cs(void) { - servinfo_t serv; int ret; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) CardServices(GetCardServicesInfo, &serv); -#else - pcmcia_get_card_services_info(&serv); #endif /* if (serv.Revision != CS_RELEASE_CODE) { @@ -627,8 +550,8 @@ init_ipwireless_cs(void) register_pccard_driver(&dev_info, &ipwireless_attach, &ipwireless_detach); #else me.owner = THIS_MODULE; - me.attach = ipwireless_attach; - me.detach = ipwireless_detach; + me.probe = ipwireless_attach; + me.remove = ipwireless_detach; me.drv.name = drv_name; pcmcia_register_driver(&me); #endif diff -rup ipwireless_Linux.orig/pccard/ipwireless_cs_main.h ipwireless_Linux/pccard/ipwireless_cs_main.h --- ipwireless_Linux.orig/pccard/ipwireless_cs_main.h 2005-09-14 22:28:00.000000000 +0200 +++ ipwireless_Linux/pccard/ipwireless_cs_main.h 2006-10-19 15:00:29.000000000 +0200 @@ -36,7 +36,7 @@ typedef struct ipw_config_t { } ipw_config_t; typedef struct ipw_dev_t { - dev_link_t link; /* Linux PCMCIA structure */ + struct pcmcia_device *link; /* Linux PCMCIA structure */ dev_node_t nodes[4]; void* attribute_memory; /* Reference to attribute memory, containing CIS data */ @@ -45,6 +45,8 @@ typedef struct ipw_dev_t { struct ipw_tty_t* tty; /* TTY device context */ } ipw_dev_t; +typedef struct pcmcia_device dev_link_t; + /* Options configurable through the proc filesystem. */ extern __u16 ipwireless_cs_debug; extern __u16 ipwireless_cs_vendor; diff -rup ipwireless_Linux.orig/pccard/ipwireless_cs_tty.c ipwireless_Linux/pccard/ipwireless_cs_tty.c --- ipwireless_Linux.orig/pccard/ipwireless_cs_tty.c 2005-09-14 22:28:00.000000000 +0200 +++ ipwireless_Linux/pccard/ipwireless_cs_tty.c 2006-10-19 16:15:41.000000000 +0200 @@ -71,7 +71,7 @@ typedef struct ipw_tty_t { struct ipw_network_t* network; struct tty_struct* linux_tty; int open_count; - dev_link_t* link; + struct pcmcia_device* link; unsigned int control_lines; struct semaphore sem; /* locks this structure */ int tx_bytes_queued; @@ -212,6 +212,7 @@ ipwireless_tty_received(struct ipw_tty_t { struct tty_struct* linux_tty = tty->linux_tty; int i; + int work = 0; down(&tty->sem); if (linux_tty == NULL) { @@ -224,14 +225,11 @@ ipwireless_tty_received(struct ipw_tty_t return; } - for (i = 0; i < length ; ++i) { - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ - if (linux_tty->flip.count >= TTY_FLIPBUF_SIZE) - tty_flip_buffer_push(linux_tty); - /* this doesn't actually push the data through unless tty->low_latency is set */ - tty_insert_flip_char(linux_tty, data[i], 0); - } - tty_flip_buffer_push(linux_tty); + tty_buffer_request_room(linux_tty, length); + for (i = 0; i < length ; ++i) + work += tty_insert_flip_char(linux_tty, data[i], 0); + if (work) + tty_flip_buffer_push(linux_tty); up(&tty->sem); } @@ -579,7 +577,7 @@ void tty_flush_buffer(struct tty_struct } static void add_tty(int first, int* j, dev_node_t** nodesp, - dev_link_t* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, + struct pcmcia_device* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, int channelIdx, int secondaryChannelIdx, int ttyType) { ttys[*j] = (ipw_tty_t*) kmalloc(sizeof(ipw_tty_t), GFP_KERNEL); @@ -609,7 +607,7 @@ static void add_tty(int first, int* j, d } struct ipw_tty_t* -ipwireless_tty_create(dev_link_t* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, dev_node_t* nodes) +ipwireless_tty_create(struct pcmcia_device* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, dev_node_t* nodes) { int i; for (i = 0; i < 8; i++) { diff -rup ipwireless_Linux.orig/pccard/ipwireless_cs_tty.h ipwireless_Linux/pccard/ipwireless_cs_tty.h --- ipwireless_Linux.orig/pccard/ipwireless_cs_tty.h 2005-09-14 22:28:00.000000000 +0200 +++ ipwireless_Linux/pccard/ipwireless_cs_tty.h 2006-10-19 14:45:15.000000000 +0200 @@ -34,7 +34,7 @@ void ipwireless_tty_release(void); struct ipw_tty_t* -ipwireless_tty_create(dev_link_t* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, dev_node_t* nodes); +ipwireless_tty_create(struct pcmcia_device* link, struct ipw_hardware_t* hardware, struct ipw_network_t* network, dev_node_t* nodes); /*! * Must be called before ipwireless_network_free(). diff -rup ipwireless_Linux.orig/usb/ipwireless_usb.c ipwireless_Linux/usb/ipwireless_usb.c --- ipwireless_Linux.orig/usb/ipwireless_usb.c 2005-09-14 22:28:00.000000000 +0200 +++ ipwireless_Linux/usb/ipwireless_usb.c 2006-10-19 14:37:35.000000000 +0200 @@ -408,9 +408,6 @@ static void usb_serial_disconnect(struct #endif static struct usb_driver ipwireless_usb_driver = { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - owner: THIS_MODULE, -#endif name: "ipwireless_usb", probe: usb_serial_probe, disconnect: usb_serial_disconnect, @@ -1489,6 +1486,7 @@ static void ipwireless_read_callback_sof int i; unsigned char *data = urb->transfer_buffer; int length = urb->actual_length; + int work = 0; tty = port->tty; @@ -1501,25 +1499,14 @@ static void ipwireless_read_callback_sof } if (length != 0) { - for (i = 0; i < length ; ++i) { - /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */ - /* Note: tty_flip_buffer_push can sleep, so this is why we must and do run it - * here in a scheduled task. */ - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { - up(&port->sem); - tty_flip_buffer_push(tty); - down(&port->sem); - if (!PORT_IS_ACTIVE(port)) { - up(&port->sem); - return; - } - } - /* this doesn't actually push the data through unless tty->low_latency is set */ - tty_insert_flip_char(tty, data[i], 0); - } - up(&port->sem); - tty_flip_buffer_push(tty); - down(&port->sem); + tty_buffer_request_room(tty, length); + for (i = 0; i < length ; ++i) + work += tty_insert_flip_char(tty, data[i], TTY_NORMAL); + if (work) { + up(&port->sem); + tty_flip_buffer_push(tty); + down(&port->sem); + } if (!PORT_IS_ACTIVE(port)) { up(&port->sem); return;