diff --git a/[refs] b/[refs] index 4d947a8751bd..0df5d11b9fc1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a01386924874c4d6d67f8a34e66f04452c2abb69 +refs/heads/master: 399dee2371787825a1845de87c0cbee7b7c30ad6 diff --git a/trunk/drivers/char/pcmcia/ipwireless/hardware.c b/trunk/drivers/char/pcmcia/ipwireless/hardware.c index 7d500f82195a..929101ecbae2 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/hardware.c +++ b/trunk/drivers/char/pcmcia/ipwireless/hardware.c @@ -30,11 +30,11 @@ static void ipw_send_setup_packet(struct ipw_hardware *hw); static void handle_received_SETUP_packet(struct ipw_hardware *ipw, unsigned int address, - const unsigned char *data, int len, + unsigned char *data, int len, int is_last); static void ipwireless_setup_timer(unsigned long data); static void handle_received_CTRL_packet(struct ipw_hardware *hw, - unsigned int channel_idx, const unsigned char *data, int len); + unsigned int channel_idx, unsigned char *data, int len); /*#define TIMING_DIAGNOSTICS*/ @@ -79,7 +79,8 @@ static void report_timing(void) timing_stats.last_report_time = jiffies; if (!first) printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": %u us elapsed - read %lu bytes in %u us, wrote %lu bytes in %u us\n", + ": %u us elapsed - read %lu bytes in %u us, " + "wrote %lu bytes in %u us\n", jiffies_to_usecs(since), timing_stats.read_bytes, jiffies_to_usecs(timing_stats.read_time), @@ -132,17 +133,29 @@ enum { #define NL_FOLLOWING_PACKET_HEADER_SIZE 1 struct nl_first_packet_header { +#if defined(__BIG_ENDIAN_BITFIELD) + unsigned char packet_rank:2; + unsigned char address:3; + unsigned char protocol:3; +#else unsigned char protocol:3; unsigned char address:3; unsigned char packet_rank:2; +#endif unsigned char length_lsb; unsigned char length_msb; }; struct nl_packet_header { +#if defined(__BIG_ENDIAN_BITFIELD) + unsigned char packet_rank:2; + unsigned char address:3; + unsigned char protocol:3; +#else unsigned char protocol:3; unsigned char address:3; unsigned char packet_rank:2; +#endif }; /* Value of 'packet_rank' above */ @@ -214,12 +227,15 @@ struct MEMINFREG { unsigned short memreg_tx_new; /* TX2 (new) Register (R/W) */ }; +#define IODMADPR 0x00 /* DMA Data Port Register (R/W) */ + #define CARD_PRESENT_VALUE (0xBEEFCAFEUL) #define MEMTX_TX 0x0001 #define MEMRX_RX 0x0001 #define MEMRX_RX_DONE 0x0001 #define MEMRX_PCINTACKK 0x0001 +#define MEMRX_MEMSPURIOUSINT 0x0001 #define NL_NUM_OF_PRIORITIES 3 #define NL_NUM_OF_PROTOCOLS 3 @@ -229,7 +245,7 @@ struct ipw_hardware { unsigned int base_port; short hw_version; unsigned short ll_mtu; - spinlock_t lock; + spinlock_t spinlock; int initializing; int init_loops; @@ -370,52 +386,26 @@ static void dump_data_bytes(const char *type, const unsigned char *data, length < DUMP_MAX_BYTES ? length : DUMP_MAX_BYTES); } -static void swap_packet_bitfield_to_le(unsigned char *data) -{ -#ifdef __BIG_ENDIAN_BITFIELD - unsigned char tmp = *data, ret = 0; - - /* - * transform bits from aa.bbb.ccc to ccc.bbb.aa - */ - ret |= tmp & 0xc0 >> 6; - ret |= tmp & 0x38 >> 1; - ret |= tmp & 0x07 << 5; - *data = ret & 0xff; -#endif -} - -static void swap_packet_bitfield_from_le(unsigned char *data) -{ -#ifdef __BIG_ENDIAN_BITFIELD - unsigned char tmp = *data, ret = 0; - - /* - * transform bits from ccc.bbb.aa to aa.bbb.ccc - */ - ret |= tmp & 0xe0 >> 5; - ret |= tmp & 0x1c << 1; - ret |= tmp & 0x03 << 6; - *data = ret & 0xff; -#endif -} - -static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, +static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, unsigned length) { - unsigned i; + int i; unsigned long flags; start_timing(); - BUG_ON(length > hw->ll_mtu); + + if (length == 0) + return 0; + + if (length > hw->ll_mtu) + return -1; if (ipwireless_debug) dump_data_bytes("send", data, length); - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->tx_ready = 0; - swap_packet_bitfield_to_le(data); if (hw->hw_version == HW_VERSION_1) { outw((unsigned short) length, hw->base_port + IODWR); @@ -424,7 +414,7 @@ static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, unsigned short d = data[i]; __le16 raw_data; - if (i + 1 < length) + if (likely(i + 1 < length)) d |= data[i + 1] << 8; raw_data = cpu_to_le16(d); outw(raw_data, hw->base_port + IODWR); @@ -432,30 +422,32 @@ static void do_send_fragment(struct ipw_hardware *hw, unsigned char *data, outw(DCR_TXDONE, hw->base_port + IODCR); } else if (hw->hw_version == HW_VERSION_2) { - outw((unsigned short) length, hw->base_port); + outw((unsigned short) length, hw->base_port + IODMADPR); for (i = 0; i < length; i += 2) { unsigned short d = data[i]; __le16 raw_data; - if (i + 1 < length) + if ((i + 1 < length)) d |= data[i + 1] << 8; raw_data = cpu_to_le16(d); - outw(raw_data, hw->base_port); + outw(raw_data, hw->base_port + IODMADPR); } while ((i & 3) != 2) { - outw((unsigned short) 0xDEAD, hw->base_port); + outw((unsigned short) 0xDEAD, hw->base_port + IODMADPR); i += 2; } writew(MEMRX_RX, &hw->memory_info_regs->memreg_rx); } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); end_write_timing(length); + + return 0; } -static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) +static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) { unsigned short fragment_data_len; unsigned short data_left = packet->length - packet->offset; @@ -470,10 +462,6 @@ static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet if (data_left < fragment_data_len) fragment_data_len = data_left; - /* - * hdr_first is now in machine bitfield order, which will be swapped - * to le just before it goes to hw - */ pkt.hdr_first.protocol = packet->protocol; pkt.hdr_first.address = packet->dest_addr; pkt.hdr_first.packet_rank = 0; @@ -505,23 +493,25 @@ static void do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet */ unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); list_add(&packet->queue, &hw->tx_queue[0]); hw->tx_queued++; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } else { if (packet->packet_callback) packet->packet_callback(packet->callback_data, packet->length); kfree(packet); } + + return 0; } static void ipw_setup_hardware(struct ipw_hardware *hw) { unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); if (hw->hw_version == HW_VERSION_1) { /* Reset RX FIFO */ outw(DCR_RXRESET, hw->base_port + IODCR); @@ -540,7 +530,7 @@ static void ipw_setup_hardware(struct ipw_hardware *hw) csr |= 1; writew(csr, &hw->memregs_CCR->reg_config_and_status); } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } /* @@ -559,23 +549,28 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, if (!packet) { unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + /* + * If this is the first fragment, then we will need to fetch a + * packet to put it in. + */ + spin_lock_irqsave(&hw->spinlock, flags); + /* If we have one in our pool, then pull it out. */ if (!list_empty(&hw->rx_pool)) { packet = list_first_entry(&hw->rx_pool, struct ipw_rx_packet, queue); - hw->rx_pool_size--; - spin_unlock_irqrestore(&hw->lock, flags); list_del(&packet->queue); + hw->rx_pool_size--; + spin_unlock_irqrestore(&hw->spinlock, flags); } else { - const int min_capacity = - ipwireless_ppp_mru(hw->network + 2); + /* Otherwise allocate a new one. */ + static int min_capacity = 256; int new_capacity; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); new_capacity = - (minimum_free_space > min_capacity - ? minimum_free_space - : min_capacity); + minimum_free_space > min_capacity + ? minimum_free_space + : min_capacity; packet = kmalloc(sizeof(struct ipw_rx_packet) + new_capacity, GFP_ATOMIC); if (!packet) @@ -585,6 +580,10 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw, packet->length = 0; } + /* + * If this packet does not have sufficient capacity for the data we + * want to add, then make it bigger. + */ if (packet->length + minimum_free_space > packet->capacity) { struct ipw_rx_packet *old_packet = packet; @@ -611,15 +610,13 @@ static void pool_free(struct ipw_hardware *hw, struct ipw_rx_packet *packet) kfree(packet); else { hw->rx_pool_size++; - list_add(&packet->queue, &hw->rx_pool); + list_add_tail(&packet->queue, &hw->rx_pool); } } static void queue_received_packet(struct ipw_hardware *hw, - unsigned int protocol, - unsigned int address, - const unsigned char *data, int length, - int is_last) + unsigned int protocol, unsigned int address, + unsigned char *data, int length, int is_last) { unsigned int channel_idx = address - 1; struct ipw_rx_packet *packet = NULL; @@ -661,9 +658,9 @@ static void queue_received_packet(struct ipw_hardware *hw, packet = *assem; *assem = NULL; /* Count queued DATA bytes only */ - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->rx_bytes_queued += packet->length; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } } else { /* If it's a CTRL packet, don't assemble, just queue it. */ @@ -685,13 +682,13 @@ static void queue_received_packet(struct ipw_hardware *hw, * network layer. */ if (packet) { - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); list_add_tail(&packet->queue, &hw->rx_queue); /* Block reception of incoming packets if queue is full. */ hw->blocking_rx = - (hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE); + hw->rx_bytes_queued >= IPWIRELESS_RX_QUEUE_SIZE; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); schedule_work(&hw->work_rx); } } @@ -705,7 +702,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) container_of(work_rx, struct ipw_hardware, work_rx); unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); while (!list_empty(&hw->rx_queue)) { struct ipw_rx_packet *packet = list_first_entry(&hw->rx_queue, @@ -723,7 +720,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) if (packet->protocol == TL_PROTOCOLID_COM_DATA) { if (hw->network != NULL) { /* If the network hasn't been disconnected. */ - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); /* * This must run unlocked due to tty processing * and mutex locking @@ -734,7 +731,7 @@ static void ipw_receive_data_work(struct work_struct *work_rx) (unsigned char *)packet + sizeof(struct ipw_rx_packet), packet->length); - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); } /* Count queued DATA bytes only */ hw->rx_bytes_queued -= packet->length; @@ -758,15 +755,15 @@ static void ipw_receive_data_work(struct work_struct *work_rx) if (hw->shutting_down) break; } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } static void handle_received_CTRL_packet(struct ipw_hardware *hw, unsigned int channel_idx, - const unsigned char *data, int len) + unsigned char *data, int len) { - const struct ipw_control_packet_body *body = - (const struct ipw_control_packet_body *) data; + struct ipw_control_packet_body *body = + (struct ipw_control_packet_body *) data; unsigned int changed_mask; if (len != sizeof(struct ipw_control_packet_body)) { @@ -808,13 +805,13 @@ static void handle_received_CTRL_packet(struct ipw_hardware *hw, } static void handle_received_packet(struct ipw_hardware *hw, - const union nl_packet *packet, + union nl_packet *packet, unsigned short len) { unsigned int protocol = packet->hdr.protocol; unsigned int address = packet->hdr.address; unsigned int header_length; - const unsigned char *data; + unsigned char *data; unsigned int data_len; int is_last = packet->hdr.packet_rank & NL_LAST_PACKET; @@ -853,7 +850,7 @@ static void acknowledge_data_read(struct ipw_hardware *hw) static void do_receive_packet(struct ipw_hardware *hw) { unsigned len; - unsigned i; + unsigned int i; unsigned char pkt[LL_MTU_MAX]; start_timing(); @@ -862,7 +859,8 @@ static void do_receive_packet(struct ipw_hardware *hw) len = inw(hw->base_port + IODRR); if (len > hw->ll_mtu) { printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": received a packet of %u bytes - longer than the MTU!\n", len); + ": received a packet of %u bytes - " + "longer than the MTU!\n", len); outw(DCR_RXDONE | DCR_RXRESET, hw->base_port + IODCR); return; } @@ -875,17 +873,18 @@ static void do_receive_packet(struct ipw_hardware *hw) pkt[i + 1] = (unsigned char) (data >> 8); } } else { - len = inw(hw->base_port); + len = inw(hw->base_port + IODMADPR); if (len > hw->ll_mtu) { printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": received a packet of %u bytes - longer than the MTU!\n", len); + ": received a packet of %u bytes - " + "longer than the MTU!\n", len); writew(MEMRX_PCINTACKK, &hw->memory_info_regs->memreg_pc_interrupt_ack); return; } for (i = 0; i < len; i += 2) { - __le16 raw_data = inw(hw->base_port); + __le16 raw_data = inw(hw->base_port + IODMADPR); unsigned short data = le16_to_cpu(raw_data); pkt[i] = (unsigned char) data; @@ -893,15 +892,13 @@ static void do_receive_packet(struct ipw_hardware *hw) } while ((i & 3) != 2) { - inw(hw->base_port); + inw(hw->base_port + IODMADPR); i += 2; } } acknowledge_data_read(hw); - swap_packet_bitfield_from_le(pkt); - if (ipwireless_debug) dump_data_bytes("recv", pkt, len); @@ -919,7 +916,8 @@ static int get_current_packet_priority(struct ipw_hardware *hw) * until setup is complete. */ return (hw->to_setup || hw->initializing - ? PRIO_SETUP + 1 : NL_NUM_OF_PRIORITIES); + ? PRIO_SETUP + 1 : + NL_NUM_OF_PRIORITIES); } /* @@ -930,17 +928,17 @@ static int get_packets_from_hw(struct ipw_hardware *hw) int received = 0; unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); while (hw->rx_ready && !hw->blocking_rx) { received = 1; hw->rx_ready--; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); do_receive_packet(hw); - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); return received; } @@ -956,7 +954,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) int more_to_send = 0; unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); if (hw->tx_queued && hw->tx_ready) { int priority; struct ipw_tx_packet *packet = NULL; @@ -977,17 +975,17 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) } if (!packet) { hw->tx_queued = 0; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); return 0; } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); /* Send */ do_send_packet(hw, packet); /* Check if more to send */ - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); for (priority = 0; priority < priority_limit; priority++) if (!list_empty(&hw->tx_queue[priority])) { more_to_send = 1; @@ -997,7 +995,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) if (!more_to_send) hw->tx_queued = 0; } - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); return more_to_send; } @@ -1010,9 +1008,9 @@ static void ipwireless_do_tasklet(unsigned long hw_) struct ipw_hardware *hw = (struct ipw_hardware *) hw_; unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); if (hw->shutting_down) { - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); return; } @@ -1021,7 +1019,7 @@ static void ipwireless_do_tasklet(unsigned long hw_) * Initial setup data sent to hardware */ hw->to_setup = 2; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); ipw_setup_hardware(hw); ipw_send_setup_packet(hw); @@ -1032,7 +1030,7 @@ static void ipwireless_do_tasklet(unsigned long hw_) int priority_limit = get_current_packet_priority(hw); int again; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); do { again = send_pending_packet(hw, priority_limit); @@ -1070,16 +1068,16 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq, /* Transmit complete. */ if (irqn & IR_TXINTR) { ack |= IR_TXINTR; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } /* Received data */ if (irqn & IR_RXINTR) { ack |= IR_RXINTR; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } if (ack != 0) { outw(ack, hw->base_port + IOIR); @@ -1130,8 +1128,9 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, } else { return IRQ_NONE; } - } else + } else { return IRQ_NONE; + } } /* @@ -1150,9 +1149,9 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, if (hw->serial_number_detected) { if (memtx_serial != hw->last_memtx_serial) { hw->last_memtx_serial = memtx_serial; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); rx = 1; } else /* Ignore 'Timer Recovery' duplicates. */ @@ -1167,18 +1166,18 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": memreg_tx serial num detected\n"); - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->rx_ready++; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); } rx = 1; } } if (memrxdone & MEMRX_RX_DONE) { writew(0, &hw->memory_info_regs->memreg_rx_done); - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); tx = 1; } if (tx) @@ -1196,7 +1195,8 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, ": spurious interrupt - new_tx mode\n"); else { printk(KERN_WARNING IPWIRELESS_PCCARD_NAME - ": no valid memreg_tx value - switching to the old memreg_tx\n"); + ": no valid memreg_tx value - " + "switching to the old memreg_tx\n"); hw->memreg_tx = &hw->memory_info_regs->memreg_tx_old; try_mem_tx_old = 1; @@ -1211,7 +1211,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, return IRQ_HANDLED; } -irqreturn_t ipwireless_interrupt(int irq, void *dev_id) +irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct ipw_hardware *hw = dev_id; @@ -1226,9 +1226,9 @@ static void flush_packets_to_hw(struct ipw_hardware *hw) int priority_limit; unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); priority_limit = get_current_packet_priority(hw); - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); while (send_pending_packet(hw, priority_limit)); } @@ -1238,10 +1238,10 @@ static void send_packet(struct ipw_hardware *hw, int priority, { unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); list_add_tail(&packet->queue, &hw->tx_queue[priority]); hw->tx_queued++; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); flush_packets_to_hw(hw); } @@ -1291,20 +1291,21 @@ static void *alloc_ctrl_packet(int header_size, } int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, - const unsigned char *data, unsigned int length, + unsigned char *data, unsigned int length, void (*callback) (void *cb, unsigned int length), void *callback_data) { struct ipw_tx_packet *packet; - packet = alloc_data_packet(length, (channel_idx + 1), - TL_PROTOCOLID_COM_DATA); + packet = alloc_data_packet(length, + (unsigned char) (channel_idx + 1), + TL_PROTOCOLID_COM_DATA); if (!packet) return -ENOMEM; packet->packet_callback = callback; packet->callback_data = callback_data; - memcpy((unsigned char *) packet + sizeof(struct ipw_tx_packet), data, - length); + memcpy((unsigned char *) packet + + sizeof(struct ipw_tx_packet), data, length); send_packet(hw, PRIO_DATA, packet); return 0; @@ -1320,11 +1321,12 @@ static int set_control_line(struct ipw_hardware *hw, int prio, protocolid = TL_PROTOCOLID_SETUP; packet = alloc_ctrl_packet(sizeof(struct ipw_control_packet), - (channel_idx + 1), protocolid, line); + (unsigned char) (channel_idx + 1), + protocolid, line); if (!packet) return -ENOMEM; packet->header.length = sizeof(struct ipw_control_packet_body); - packet->body.value = (state == 0 ? 0 : 1); + packet->body.value = (unsigned char) (state == 0 ? 0 : 1); send_packet(hw, prio, &packet->header); return 0; } @@ -1502,7 +1504,8 @@ static void handle_setup_get_version_rsp(struct ipw_hardware *hw, if (vers_no == TL_SETUP_VERSION) __handle_setup_get_version_rsp(hw); else - printk(KERN_ERR IPWIRELESS_PCCARD_NAME + printk(KERN_ERR + IPWIRELESS_PCCARD_NAME ": invalid hardware version no %u\n", (unsigned int) vers_no); } @@ -1525,10 +1528,10 @@ static void ipw_send_setup_packet(struct ipw_hardware *hw) static void handle_received_SETUP_packet(struct ipw_hardware *hw, unsigned int address, - const unsigned char *data, int len, + unsigned char *data, int len, int is_last) { - const union ipw_setup_rx_msg *rx_msg = (const union ipw_setup_rx_msg *) data; + union ipw_setup_rx_msg *rx_msg = (union ipw_setup_rx_msg *) data; if (address != ADDR_SETUP_PROT) { printk(KERN_INFO IPWIRELESS_PCCARD_NAME @@ -1626,7 +1629,7 @@ struct ipw_hardware *ipwireless_hardware_create(void) INIT_LIST_HEAD(&hw->rx_queue); INIT_LIST_HEAD(&hw->rx_pool); - spin_lock_init(&hw->lock); + spin_lock_init(&hw->spinlock); tasklet_init(&hw->tasklet, ipwireless_do_tasklet, (unsigned long) hw); INIT_WORK(&hw->work_rx, ipw_receive_data_work); setup_timer(&hw->setup_timer, ipwireless_setup_timer, @@ -1648,8 +1651,8 @@ void ipwireless_init_hardware_v1(struct ipw_hardware *hw, enable_irq(hw->irq); } hw->base_port = base_port; - hw->hw_version = (is_v2_card ? HW_VERSION_2 : HW_VERSION_1); - hw->ll_mtu = (hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2); + hw->hw_version = is_v2_card ? HW_VERSION_2 : HW_VERSION_1; + hw->ll_mtu = hw->hw_version == HW_VERSION_1 ? LL_MTU_V1 : LL_MTU_V2; hw->memregs_CCR = (struct MEMCCR __iomem *) ((unsigned short __iomem *) attr_memory + 0x200); hw->memory_info_regs = (struct MEMINFREG __iomem *) common_memory; @@ -1692,10 +1695,10 @@ static void ipwireless_setup_timer(unsigned long data) if (is_card_present(hw)) { unsigned long flags; - spin_lock_irqsave(&hw->lock, flags); + spin_lock_irqsave(&hw->spinlock, flags); hw->to_setup = 1; hw->tx_ready = 1; - spin_unlock_irqrestore(&hw->lock, flags); + spin_unlock_irqrestore(&hw->spinlock, flags); tasklet_schedule(&hw->tasklet); } diff --git a/trunk/drivers/char/pcmcia/ipwireless/hardware.h b/trunk/drivers/char/pcmcia/ipwireless/hardware.h index 90a8590e43b0..19ce5eb266b1 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/hardware.h +++ b/trunk/drivers/char/pcmcia/ipwireless/hardware.h @@ -34,14 +34,14 @@ struct ipw_network; struct ipw_hardware *ipwireless_hardware_create(void); void ipwireless_hardware_free(struct ipw_hardware *hw); -irqreturn_t ipwireless_interrupt(int irq, void *dev_id); +irqreturn_t ipwireless_interrupt(int irq, void *dev_id, struct pt_regs *regs); int ipwireless_set_DTR(struct ipw_hardware *hw, unsigned int channel_idx, int state); int ipwireless_set_RTS(struct ipw_hardware *hw, unsigned int channel_idx, int state); int ipwireless_send_packet(struct ipw_hardware *hw, unsigned int channel_idx, - const unsigned char *data, + unsigned char *data, unsigned int length, void (*packet_sent_callback) (void *cb, unsigned int length), diff --git a/trunk/drivers/char/pcmcia/ipwireless/main.c b/trunk/drivers/char/pcmcia/ipwireless/main.c index 5eca7a99afe6..cc7dcea2d283 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/main.c +++ b/trunk/drivers/char/pcmcia/ipwireless/main.c @@ -49,7 +49,7 @@ static void ipwireless_detach(struct pcmcia_device *link); /* Debug mode: more verbose, print sent/recv bytes */ int ipwireless_debug; int ipwireless_loopback; -int ipwireless_out_queue = 10; +int ipwireless_out_queue = 1; module_param_named(debug, ipwireless_debug, int, 0); module_param_named(loopback, ipwireless_loopback, int, 0); @@ -57,7 +57,7 @@ module_param_named(out_queue, ipwireless_out_queue, int, 0); MODULE_PARM_DESC(debug, "switch on debug messages [0]"); MODULE_PARM_DESC(loopback, "debug: enable ras_raw channel [0]"); -MODULE_PARM_DESC(out_queue, "debug: set size of outgoing PPP queue [10]"); +MODULE_PARM_DESC(out_queue, "debug: set size of outgoing queue [1]"); /* Executes in process context. */ static void signalled_reboot_work(struct work_struct *work_reboot) @@ -88,6 +88,8 @@ static int config_ipwireless(struct ipw_dev *ipw) unsigned short buf[64]; cisparse_t parse; unsigned short cor_value; + win_req_t request_attr_memory; + win_req_t request_common_memory; memreq_t memreq_attr_memory; memreq_t memreq_common_memory; @@ -186,9 +188,6 @@ static int config_ipwireless(struct ipw_dev *ipw) goto exit0; } - request_region(link->io.BasePort1, link->io.NumPorts1, - IPWIRELESS_PCCARD_NAME); - /* memory settings */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; @@ -215,16 +214,16 @@ static int config_ipwireless(struct ipw_dev *ipw) } if (parse.cftable_entry.mem.nwin > 0) { - ipw->request_common_memory.Attributes = + request_common_memory.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE; - ipw->request_common_memory.Base = + request_common_memory.Base = parse.cftable_entry.mem.win[0].host_addr; - ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len; - if (ipw->request_common_memory.Size < 0x1000) - ipw->request_common_memory.Size = 0x1000; - ipw->request_common_memory.AccessSpeed = 0; + request_common_memory.Size = parse.cftable_entry.mem.win[0].len; + if (request_common_memory.Size < 0x1000) + request_common_memory.Size = 0x1000; + request_common_memory.AccessSpeed = 0; - ret = pcmcia_request_window(&link, &ipw->request_common_memory, + ret = pcmcia_request_window(&link, &request_common_memory, &ipw->handle_common_memory); if (ret != CS_SUCCESS) { @@ -247,18 +246,16 @@ static int config_ipwireless(struct ipw_dev *ipw) ipw->is_v2_card = parse.cftable_entry.mem.win[0].len == 0x100; - ipw->common_memory = ioremap(ipw->request_common_memory.Base, - ipw->request_common_memory.Size); - request_mem_region(ipw->request_common_memory.Base, - ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME); + ipw->common_memory = ioremap(request_common_memory.Base, + request_common_memory.Size); - ipw->request_attr_memory.Attributes = + request_attr_memory.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE; - ipw->request_attr_memory.Base = 0; - ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */ - ipw->request_attr_memory.AccessSpeed = 0; + request_attr_memory.Base = 0; + request_attr_memory.Size = 0; /* this used to be 0x1000 */ + request_attr_memory.AccessSpeed = 0; - ret = pcmcia_request_window(&link, &ipw->request_attr_memory, + ret = pcmcia_request_window(&link, &request_attr_memory, &ipw->handle_attr_memory); if (ret != CS_SUCCESS) { @@ -277,10 +274,8 @@ static int config_ipwireless(struct ipw_dev *ipw) goto exit2; } - ipw->attr_memory = ioremap(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size); - request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size, - IPWIRELESS_PCCARD_NAME); + ipw->attr_memory = ioremap(request_attr_memory.Base, + request_attr_memory.Size); } INIT_WORK(&ipw->work_reboot, signalled_reboot_work); @@ -316,13 +311,14 @@ static int config_ipwireless(struct ipw_dev *ipw) (unsigned int) link->irq.AssignedIRQ); if (ipw->attr_memory && ipw->common_memory) printk(KERN_INFO IPWIRELESS_PCCARD_NAME - ": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n", - ipw->request_attr_memory.Base, - ipw->request_attr_memory.Base - + ipw->request_attr_memory.Size - 1, - ipw->request_common_memory.Base, - ipw->request_common_memory.Base - + ipw->request_common_memory.Size - 1); + ": attr memory 0x%08lx-0x%08lx, " + "common memory 0x%08lx-0x%08lx\n", + request_attr_memory.Base, + request_attr_memory.Base + + request_attr_memory.Size - 1, + request_common_memory.Base, + request_common_memory.Base + + request_common_memory.Size - 1); ipw->network = ipwireless_network_create(ipw->hardware); if (!ipw->network) @@ -354,16 +350,12 @@ static int config_ipwireless(struct ipw_dev *ipw) pcmcia_disable_device(link); exit3: if (ipw->attr_memory) { - release_mem_region(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size); iounmap(ipw->attr_memory); pcmcia_release_window(ipw->handle_attr_memory); pcmcia_disable_device(link); } exit2: if (ipw->common_memory) { - release_mem_region(ipw->request_common_memory.Base, - ipw->request_common_memory.Size); iounmap(ipw->common_memory); pcmcia_release_window(ipw->handle_common_memory); } @@ -375,25 +367,19 @@ static int config_ipwireless(struct ipw_dev *ipw) static void release_ipwireless(struct ipw_dev *ipw) { - pcmcia_disable_device(ipw->link); + struct pcmcia_device *link = ipw->link; - if (ipw->common_memory) { - release_mem_region(ipw->request_common_memory.Base, - ipw->request_common_memory.Size); + pcmcia_disable_device(link); + + if (ipw->common_memory) iounmap(ipw->common_memory); - } - if (ipw->attr_memory) { - release_mem_region(ipw->request_attr_memory.Base, - ipw->request_attr_memory.Size); + if (ipw->attr_memory) iounmap(ipw->attr_memory); - } if (ipw->common_memory) pcmcia_release_window(ipw->handle_common_memory); if (ipw->attr_memory) pcmcia_release_window(ipw->handle_attr_memory); - - /* Break the link with Card Services */ - pcmcia_disable_device(ipw->link); + pcmcia_disable_device(link); } /* @@ -451,6 +437,10 @@ static void ipwireless_detach(struct pcmcia_device *link) release_ipwireless(ipw); + /* Break the link with Card Services */ + if (link) + pcmcia_disable_device(link); + if (ipw->tty != NULL) ipwireless_tty_free(ipw->tty); if (ipw->network != NULL) diff --git a/trunk/drivers/char/pcmcia/ipwireless/main.h b/trunk/drivers/char/pcmcia/ipwireless/main.h index 0e0363af9ab2..1bfdcc8d47d6 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/main.h +++ b/trunk/drivers/char/pcmcia/ipwireless/main.h @@ -45,15 +45,10 @@ struct ipw_tty; struct ipw_dev { struct pcmcia_device *link; int is_v2_card; - window_handle_t handle_attr_memory; void __iomem *attr_memory; - win_req_t request_attr_memory; - window_handle_t handle_common_memory; void __iomem *common_memory; - win_req_t request_common_memory; - dev_node_t nodes[2]; /* Reference to attribute memory, containing CIS data */ void *attribute_memory; diff --git a/trunk/drivers/char/pcmcia/ipwireless/network.c b/trunk/drivers/char/pcmcia/ipwireless/network.c index 590762a7f217..fe914d34f7f6 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/network.c +++ b/trunk/drivers/char/pcmcia/ipwireless/network.c @@ -29,6 +29,7 @@ #include "main.h" #include "tty.h" +#define MAX_OUTGOING_PACKETS_QUEUED ipwireless_out_queue #define MAX_ASSOCIATED_TTYS 2 #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP) @@ -45,7 +46,7 @@ struct ipw_network { /* Number of packets queued up in hardware module. */ int outgoing_packets_queued; /* Spinlock to avoid interrupts during shutdown */ - spinlock_t lock; + spinlock_t spinlock; struct mutex close_lock; /* PPP ioctl data, not actually used anywere */ @@ -67,20 +68,20 @@ static void notify_packet_sent(void *callback_data, unsigned int packet_length) struct ipw_network *network = callback_data; unsigned long flags; - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); network->outgoing_packets_queued--; if (network->ppp_channel != NULL) { if (network->ppp_blocked) { network->ppp_blocked = 0; - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); ppp_output_wakeup(network->ppp_channel); if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME + printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": ppp unblocked\n"); } else - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); } else - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); } /* @@ -92,8 +93,8 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, struct ipw_network *network = ppp_channel->private; unsigned long flags; - spin_lock_irqsave(&network->lock, flags); - if (network->outgoing_packets_queued < ipwireless_out_queue) { + spin_lock_irqsave(&network->spinlock, flags); + if (network->outgoing_packets_queued < MAX_OUTGOING_PACKETS_QUEUED) { unsigned char *buf; static unsigned char header[] = { PPP_ALLSTATIONS, /* 0xff */ @@ -102,7 +103,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, int ret; network->outgoing_packets_queued++; - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); /* * If we have the requested amount of headroom in the skb we @@ -143,9 +144,7 @@ static int ipwireless_ppp_start_xmit(struct ppp_channel *ppp_channel, * needs to be unblocked once we are ready to send. */ network->ppp_blocked = 1; - spin_unlock_irqrestore(&network->lock, flags); - if (ipwireless_debug) - printk(KERN_DEBUG IPWIRELESS_PCCARD_NAME ": ppp blocked\n"); + spin_unlock_irqrestore(&network->spinlock, flags); return 0; } } @@ -250,11 +249,11 @@ static void do_go_online(struct work_struct *work_go_online) work_go_online); unsigned long flags; - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); if (!network->ppp_channel) { struct ppp_channel *channel; - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); if (!channel) { printk(KERN_ERR IPWIRELESS_PCCARD_NAME @@ -274,10 +273,10 @@ static void do_go_online(struct work_struct *work_go_online) network->xaccm[3] = 0x60000000U; network->raccm = ~0U; ppp_register_channel(channel); - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); network->ppp_channel = channel; } - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); } static void do_go_offline(struct work_struct *work_go_offline) @@ -288,16 +287,16 @@ static void do_go_offline(struct work_struct *work_go_offline) unsigned long flags; mutex_lock(&network->close_lock); - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); if (network->ppp_channel != NULL) { struct ppp_channel *channel = network->ppp_channel; network->ppp_channel = NULL; - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); mutex_unlock(&network->close_lock); ppp_unregister_channel(channel); } else { - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); mutex_unlock(&network->close_lock); } } @@ -382,18 +381,18 @@ void ipwireless_network_packet_received(struct ipw_network *network, * the PPP layer. */ mutex_lock(&network->close_lock); - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); if (network->ppp_channel != NULL) { struct sk_buff *skb; - spin_unlock_irqrestore(&network->lock, + spin_unlock_irqrestore(&network->spinlock, flags); /* Send the data to the ppp_generic module. */ skb = ipw_packet_received_skb(data, length); ppp_input(network->ppp_channel, skb); } else - spin_unlock_irqrestore(&network->lock, + spin_unlock_irqrestore(&network->spinlock, flags); mutex_unlock(&network->close_lock); } @@ -411,7 +410,7 @@ struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) if (!network) return NULL; - spin_lock_init(&network->lock); + spin_lock_init(&network->spinlock); mutex_init(&network->close_lock); network->hardware = hw; @@ -479,10 +478,10 @@ int ipwireless_ppp_channel_index(struct ipw_network *network) int ret = -1; unsigned long flags; - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); if (network->ppp_channel != NULL) ret = ppp_channel_index(network->ppp_channel); - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); return ret; } @@ -492,15 +491,10 @@ int ipwireless_ppp_unit_number(struct ipw_network *network) int ret = -1; unsigned long flags; - spin_lock_irqsave(&network->lock, flags); + spin_lock_irqsave(&network->spinlock, flags); if (network->ppp_channel != NULL) ret = ppp_unit_number(network->ppp_channel); - spin_unlock_irqrestore(&network->lock, flags); + spin_unlock_irqrestore(&network->spinlock, flags); return ret; } - -int ipwireless_ppp_mru(const struct ipw_network *network) -{ - return network->mru; -} diff --git a/trunk/drivers/char/pcmcia/ipwireless/network.h b/trunk/drivers/char/pcmcia/ipwireless/network.h index 561f765b3334..ccacd26fc7ef 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/network.h +++ b/trunk/drivers/char/pcmcia/ipwireless/network.h @@ -48,6 +48,5 @@ void ipwireless_ppp_open(struct ipw_network *net); void ipwireless_ppp_close(struct ipw_network *net); int ipwireless_ppp_channel_index(struct ipw_network *net); int ipwireless_ppp_unit_number(struct ipw_network *net); -int ipwireless_ppp_mru(const struct ipw_network *net); #endif diff --git a/trunk/drivers/char/pcmcia/ipwireless/tty.c b/trunk/drivers/char/pcmcia/ipwireless/tty.c index b1414507997c..42f3815c5ce3 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/tty.c +++ b/trunk/drivers/char/pcmcia/ipwireless/tty.c @@ -259,7 +259,7 @@ static int ipw_write(struct tty_struct *linux_tty, } ret = ipwireless_send_packet(tty->hardware, IPW_CHANNEL_RAS, - buf, count, + (unsigned char *) buf, count, ipw_write_packet_sent_callback, tty); if (ret == -1) { mutex_unlock(&tty->ipw_tty_mutex); diff --git a/trunk/drivers/i2c/busses/i2c-s3c2410.c b/trunk/drivers/i2c/busses/i2c-s3c2410.c index 007390ad9810..eef35d3f6073 100644 --- a/trunk/drivers/i2c/busses/i2c-s3c2410.c +++ b/trunk/drivers/i2c/busses/i2c-s3c2410.c @@ -752,9 +752,12 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c) static int s3c24xx_i2c_probe(struct platform_device *pdev) { struct s3c24xx_i2c *i2c = &s3c24xx_i2c; + struct s3c2410_platform_i2c *pdata; struct resource *res; int ret; + pdata = s3c24xx_i2c_get_platformdata(&pdev->dev); + /* find the clock and enable it */ i2c->dev = &pdev->dev; @@ -832,7 +835,15 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev) dev_dbg(&pdev->dev, "irq resource %p (%lu)\n", res, (unsigned long)res->start); - ret = i2c_add_adapter(&i2c->adap); + /* Note, previous versions of the driver used i2c_add_adapter() + * to add the bus at any number. We now pass the bus number via + * the platform data, so if unset it will now default to always + * being bus 0. + */ + + i2c->adap.nr = pdata->bus_num; + + ret = i2c_add_numbered_adapter(&i2c->adap); if (ret < 0) { dev_err(&pdev->dev, "failed to add bus to i2c core\n"); goto err_irq; diff --git a/trunk/include/asm-arm/plat-s3c/iic.h b/trunk/include/asm-arm/plat-s3c/iic.h index 71211c8b5384..d08a1f2863e4 100644 --- a/trunk/include/asm-arm/plat-s3c/iic.h +++ b/trunk/include/asm-arm/plat-s3c/iic.h @@ -21,6 +21,7 @@ */ struct s3c2410_platform_i2c { + int bus_num; /* bus number to use */ unsigned int flags; unsigned int slave_addr; /* slave address for controller */ unsigned long bus_freq; /* standard bus frequency */