diff --git a/[refs] b/[refs] index 03f3fe58e3b2..5780b9b62ce4 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4852ba24f647199be797545226c6d325db231937 +refs/heads/master: dd3bec63f80e663cdb655b8bdc9c1a0ea938f1c5 diff --git a/trunk/.gitignore b/trunk/.gitignore index b1f5b9df2ae1..27fd37621255 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -30,11 +30,6 @@ include/config include/linux/autoconf.h include/linux/compile.h include/linux/version.h -include/linux/utsrelease.h # stgit generated dirs patches-* - -# quilt's files -patches -series diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index f8fe882e33dc..1ae4dc0fd856 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -58,9 +58,6 @@ !Iinclude/linux/ktime.h !Iinclude/linux/hrtimer.h !Ekernel/hrtimer.c - - Workqueues and Kevents -!Ekernel/workqueue.c Internal Functions !Ikernel/exit.c @@ -303,7 +300,7 @@ X!Ekernel/module.c Resources Management -!Ikernel/resource.c +!Ekernel/resource.c MTRR Handling @@ -315,7 +312,9 @@ X!Ekernel/module.c !Edrivers/pci/pci-driver.c !Edrivers/pci/remove.c !Edrivers/pci/pci-acpi.c -!Edrivers/pci/search.c + !Edrivers/pci/msi.c !Edrivers/pci/bus.c size-4096 slab */ @@ -3148,6 +3148,7 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) adapter->rx_buffer_len = E1000_RXBUFFER_16384; /* adjust allocation if LPE protects us, and we aren't using SBP */ +#define MAXIMUM_ETHERNET_VLAN_SIZE 1522 if (!adapter->hw.tbi_compatibility_on && ((max_frame == MAXIMUM_ETHERNET_FRAME_SIZE) || (max_frame == MAXIMUM_ETHERNET_VLAN_SIZE))) @@ -3386,8 +3387,8 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) E1000_WRITE_REG(hw, IMC, ~0); E1000_WRITE_FLUSH(hw); } - if (likely(netif_rx_schedule_prep(netdev))) - __netif_rx_schedule(netdev); + if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0]))) + __netif_rx_schedule(&adapter->polling_netdev[0]); else e1000_irq_enable(adapter); #else @@ -3430,26 +3431,34 @@ e1000_clean(struct net_device *poll_dev, int *budget) { struct e1000_adapter *adapter; int work_to_do = min(*budget, poll_dev->quota); - int tx_cleaned = 0, work_done = 0; + int tx_cleaned = 0, i = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; /* Keep link state information with original netdev */ - if (!netif_carrier_ok(poll_dev)) + if (!netif_carrier_ok(adapter->netdev)) goto quit_polling; - /* e1000_clean is called per-cpu. This lock protects - * tx_ring[0] from being cleaned by multiple cpus - * simultaneously. A failure obtaining the lock means - * tx_ring[0] is currently being cleaned anyway. */ - if (spin_trylock(&adapter->tx_queue_lock)) { - tx_cleaned = e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); - spin_unlock(&adapter->tx_queue_lock); + while (poll_dev != &adapter->polling_netdev[i]) { + i++; + BUG_ON(i == adapter->num_rx_queues); } - adapter->clean_rx(adapter, &adapter->rx_ring[0], + if (likely(adapter->num_tx_queues == 1)) { + /* e1000_clean is called per-cpu. This lock protects + * tx_ring[0] from being cleaned by multiple cpus + * simultaneously. A failure obtaining the lock means + * tx_ring[0] is currently being cleaned anyway. */ + if (spin_trylock(&adapter->tx_queue_lock)) { + tx_cleaned = e1000_clean_tx_irq(adapter, + &adapter->tx_ring[0]); + spin_unlock(&adapter->tx_queue_lock); + } + } else + tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]); + + adapter->clean_rx(adapter, &adapter->rx_ring[i], &work_done, work_to_do); *budget -= work_done; @@ -3457,7 +3466,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) /* If no Tx and not enough Rx work done, exit the polling mode */ if ((!tx_cleaned && (work_done == 0)) || - !netif_running(poll_dev)) { + !netif_running(adapter->netdev)) { quit_polling: netif_rx_complete(poll_dev); e1000_irq_enable(adapter); @@ -3672,9 +3681,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, length = le16_to_cpu(rx_desc->length); - /* adjust length to remove Ethernet CRC */ - length -= 4; - if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" @@ -3708,7 +3714,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, #define E1000_CB_LENGTH 256 if (length < E1000_CB_LENGTH) { struct sk_buff *new_skb = - netdev_alloc_skb(netdev, length + NET_IP_ALIGN); + dev_alloc_skb(length + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); new_skb->dev = netdev; @@ -3879,9 +3885,8 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, pci_dma_sync_single_for_device(pdev, ps_page_dma->ps_page_dma[0], PAGE_SIZE, PCI_DMA_FROMDEVICE); - /* remove the CRC */ - l1 -= 4; skb_put(skb, l1); + length += l1; goto copydone; } /* if */ } @@ -3900,10 +3905,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, skb->truesize += length; } - /* strip the ethernet crc, problem is we're using pages now so - * this whole operation can get a little cpu intensive */ - pskb_trim(skb, skb->len - 4); - copydone: e1000_rx_checksum(adapter, staterr, le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); @@ -3979,7 +3980,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, while (cleaned_count--) { if (!(skb = buffer_info->skb)) - skb = netdev_alloc_skb(netdev, bufsz); + skb = dev_alloc_skb(bufsz); else { skb_trim(skb, 0); goto map_skb; @@ -3997,7 +3998,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes " "at %p\n", bufsz, skb->data); /* Try again, without freeing the previous */ - skb = netdev_alloc_skb(netdev, bufsz); + skb = dev_alloc_skb(bufsz); /* Failed allocation, critical failure */ if (!skb) { dev_kfree_skb(oldskb); @@ -4121,8 +4122,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, rx_desc->read.buffer_addr[j+1] = ~0; } - skb = netdev_alloc_skb(netdev, - adapter->rx_ps_bsize0 + NET_IP_ALIGN); + skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN); if (unlikely(!skb)) { adapter->alloc_rx_buff_failed++; @@ -4752,7 +4752,6 @@ static void e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - disable_irq(adapter->pdev->irq); e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_clean_tx_irq(adapter, adapter->tx_ring); diff --git a/trunk/drivers/net/ifb.c b/trunk/drivers/net/ifb.c index 43e3f33ed5e2..3a42afab5036 100644 --- a/trunk/drivers/net/ifb.c +++ b/trunk/drivers/net/ifb.c @@ -271,7 +271,6 @@ static int __init ifb_init_module(void) for (i = 0; i < numifbs && !err; i++) err = ifb_init_one(i); if (err) { - i--; while (--i >= 0) ifb_free_one(i); } diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 06440a86baef..07ca9480a6fe 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -177,7 +177,6 @@ struct myri10ge_priv { struct work_struct watchdog_work; struct timer_list watchdog_timer; int watchdog_tx_done; - int watchdog_tx_req; int watchdog_resets; int tx_linearized; int pause; @@ -449,7 +448,6 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) struct mcp_gen_header *hdr; size_t hdr_offset; int status; - unsigned i; if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { dev_err(dev, "Unable to load %s firmware image via hotplug\n", @@ -481,12 +479,18 @@ static int myri10ge_load_hotplug_firmware(struct myri10ge_priv *mgp, u32 * size) goto abort_with_fw; crc = crc32(~0, fw->data, fw->size); - for (i = 0; i < fw->size; i += 256) { - myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET + i, - fw->data + i, - min(256U, (unsigned)(fw->size - i))); - mb(); - readb(mgp->sram); + if (mgp->tx.boundary == 2048) { + /* Avoid PCI burst on chipset with unaligned completions. */ + int i; + __iomem u32 *ptr = (__iomem u32 *) (mgp->sram + + MYRI10GE_FW_OFFSET); + for (i = 0; i < fw->size / 4; i++) { + __raw_writel(((u32 *) fw->data)[i], ptr + i); + wmb(); + } + } else { + myri10ge_pio_copy(mgp->sram + MYRI10GE_FW_OFFSET, fw->data, + fw->size); } /* corruption checking is good for parity recovery and buggy chipset */ memcpy_fromio(fw->data, mgp->sram + MYRI10GE_FW_OFFSET, fw->size); @@ -616,7 +620,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) return -ENXIO; } dev_info(&mgp->pdev->dev, "handoff confirmed\n"); - myri10ge_dummy_rdma(mgp, 1); + myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); return 0; } @@ -2543,8 +2547,7 @@ static void myri10ge_watchdog_timer(unsigned long arg) mgp = (struct myri10ge_priv *)arg; if (mgp->tx.req != mgp->tx.done && - mgp->tx.done == mgp->watchdog_tx_done && - mgp->watchdog_tx_req != mgp->watchdog_tx_done) + mgp->tx.done == mgp->watchdog_tx_done) /* nic seems like it might be stuck.. */ schedule_work(&mgp->watchdog_work); else @@ -2553,7 +2556,6 @@ static void myri10ge_watchdog_timer(unsigned long arg) jiffies + myri10ge_watchdog_timeout * HZ); mgp->watchdog_tx_done = mgp->tx.done; - mgp->watchdog_tx_req = mgp->tx.req; } static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/trunk/drivers/net/phy/phy.c b/trunk/drivers/net/phy/phy.c index f5aad77288f9..7d5c2233c252 100644 --- a/trunk/drivers/net/phy/phy.c +++ b/trunk/drivers/net/phy/phy.c @@ -419,8 +419,9 @@ void phy_start_machine(struct phy_device *phydev, /* phy_stop_machine * - * description: Stops the state machine timer, sets the state to UP - * (unless it wasn't up yet). This function must be called BEFORE + * description: Stops the state machine timer, sets the state to + * UP (unless it wasn't up yet), and then frees the interrupt, + * if it is in use. This function must be called BEFORE * phy_detach. */ void phy_stop_machine(struct phy_device *phydev) @@ -432,6 +433,9 @@ void phy_stop_machine(struct phy_device *phydev) phydev->state = PHY_UP; spin_unlock(&phydev->lock); + if (phydev->irq != PHY_POLL) + phy_stop_interrupts(phydev); + phydev->adjust_state = NULL; } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 132ed32bce1a..e1fe3a0a7b0b 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -76,7 +76,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.15.2" +#define DRV_VERSION "2.0.14.2" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -370,50 +370,38 @@ static const u64 fix_mac[] = { END_SIGN }; -MODULE_AUTHOR("Raghavendra Koushik "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - - /* Module Loadable parameters. */ -S2IO_PARM_INT(tx_fifo_num, 1); -S2IO_PARM_INT(rx_ring_num, 1); - - -S2IO_PARM_INT(rx_ring_mode, 1); -S2IO_PARM_INT(use_continuous_tx_intrs, 1); -S2IO_PARM_INT(rmac_pause_time, 0x100); -S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); -S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); -S2IO_PARM_INT(shared_splits, 0); -S2IO_PARM_INT(tmac_util_period, 5); -S2IO_PARM_INT(rmac_util_period, 5); -S2IO_PARM_INT(bimodal, 0); -S2IO_PARM_INT(l3l4hdr_size, 128); -/* Frequency of Rx desc syncs expressed as power of 2 */ -S2IO_PARM_INT(rxsync_frequency, 3); -/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ -S2IO_PARM_INT(intr_type, 0); -/* Large receive offload feature */ -S2IO_PARM_INT(lro, 0); -/* Max pkts to be aggregated by LRO at one time. If not specified, - * aggregation happens until we hit max IP pkt size(64K) - */ -S2IO_PARM_INT(lro_max_pkts, 0xFFFF); -#ifndef CONFIG_S2IO_NAPI -S2IO_PARM_INT(indicate_max_pkts, 0); -#endif - +static unsigned int tx_fifo_num = 1; static unsigned int tx_fifo_len[MAX_TX_FIFOS] = {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; +static unsigned int rx_ring_num = 1; static unsigned int rx_ring_sz[MAX_RX_RINGS] = {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; static unsigned int rts_frm_len[MAX_RX_RINGS] = {[0 ...(MAX_RX_RINGS - 1)] = 0 }; - -module_param_array(tx_fifo_len, uint, NULL, 0); -module_param_array(rx_ring_sz, uint, NULL, 0); -module_param_array(rts_frm_len, uint, NULL, 0); +static unsigned int rx_ring_mode = 1; +static unsigned int use_continuous_tx_intrs = 1; +static unsigned int rmac_pause_time = 0x100; +static unsigned int mc_pause_threshold_q0q3 = 187; +static unsigned int mc_pause_threshold_q4q7 = 187; +static unsigned int shared_splits; +static unsigned int tmac_util_period = 5; +static unsigned int rmac_util_period = 5; +static unsigned int bimodal = 0; +static unsigned int l3l4hdr_size = 128; +#ifndef CONFIG_S2IO_NAPI +static unsigned int indicate_max_pkts; +#endif +/* Frequency of Rx desc syncs expressed as power of 2 */ +static unsigned int rxsync_frequency = 3; +/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ +static unsigned int intr_type = 0; +/* Large receive offload feature */ +static unsigned int lro = 0; +/* Max pkts to be aggregated by LRO at one time. If not specified, + * aggregation happens until we hit max IP pkt size(64K) + */ +static unsigned int lro_max_pkts = 0xFFFF; /* * S2IO device table. @@ -476,9 +464,10 @@ static int init_shared_mem(struct s2io_nic *nic) size += config->tx_cfg[i].fifo_len; } if (size > MAX_AVAILABLE_TXDS) { - DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, "); + DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", + __FUNCTION__); DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); - return -EINVAL; + return FAILURE; } lst_size = (sizeof(TxD_t) * config->max_txds); @@ -558,7 +547,6 @@ static int init_shared_mem(struct s2io_nic *nic) nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); if (!nic->ufo_in_band_v) return -ENOMEM; - memset(nic->ufo_in_band_v, 0, size); /* Allocation and initialization of RXDs in Rings */ size = 0; @@ -1225,7 +1213,7 @@ static int init_nic(struct s2io_nic *nic) break; } - /* Enable all configured Tx FIFO partitions */ + /* Enable Tx FIFO partition 0. */ val64 = readq(&bar0->tx_fifo_partition_0); val64 |= (TX_FIFO_PARTITION_EN); writeq(val64, &bar0->tx_fifo_partition_0); @@ -1662,7 +1650,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) writeq(temp64, &bar0->general_int_mask); /* * If Hercules adapter enable GPIO otherwise - * disable all PCIX, Flash, MDIO, IIC and GPIO + * disabled all PCIX, Flash, MDIO, IIC and GPIO * interrupts for now. * TODO */ @@ -2131,7 +2119,7 @@ static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, in frag->size, PCI_DMA_TODEVICE); } } - memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); + txdlp->Host_Control = 0; return(skb); } @@ -2383,14 +2371,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) skb->data = (void *) (unsigned long)tmp; skb->tail = (void *) (unsigned long)tmp; - if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) - ((RxD3_t*)rxdp)->Buffer0_ptr = - pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, + ((RxD3_t*)rxdp)->Buffer0_ptr = + pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - else - pci_dma_sync_single_for_device(nic->pdev, - (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, - BUF0_LEN, PCI_DMA_FROMDEVICE); rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (nic->rxd_mode == RXD_MODE_3B) { /* Two buffer mode */ @@ -2403,13 +2386,10 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) (nic->pdev, skb->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - /* Buffer-1 will be dummy buffer. Not used */ - if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { - ((RxD3_t*)rxdp)->Buffer1_ptr = - pci_map_single(nic->pdev, - ba->ba_1, BUF1_LEN, - PCI_DMA_FROMDEVICE); - } + /* Buffer-1 will be dummy buffer not used */ + ((RxD3_t*)rxdp)->Buffer1_ptr = + pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, + PCI_DMA_FROMDEVICE); rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 (dev->mtu + 4); @@ -2634,23 +2614,23 @@ static int s2io_poll(struct net_device *dev, int *budget) } #endif -#ifdef CONFIG_NET_POLL_CONTROLLER /** - * s2io_netpoll - netpoll event handler entry point + * s2io_netpoll - Rx interrupt service handler for netpoll support * @dev : pointer to the device structure. * Description: - * This function will be called by upper layer to check for events on the - * interface in situations where interrupts are disabled. It is used for - * specific in-kernel networking tasks, such as remote consoles and kernel - * debugging over the network (example netdump in RedHat). + * Polling 'interrupt' - used by things like netconsole to send skbs + * without having to re-enable interrupts. It's not called while + * the interrupt routine is executing. */ + +#ifdef CONFIG_NET_POLL_CONTROLLER static void s2io_netpoll(struct net_device *dev) { nic_t *nic = dev->priv; mac_info_t *mac_control; struct config_param *config; XENA_dev_config_t __iomem *bar0 = nic->bar0; - u64 val64 = 0xFFFFFFFFFFFFFFFFULL; + u64 val64; int i; disable_irq(dev->irq); @@ -2659,17 +2639,9 @@ static void s2io_netpoll(struct net_device *dev) mac_control = &nic->mac_control; config = &nic->config; + val64 = readq(&bar0->rx_traffic_int); writeq(val64, &bar0->rx_traffic_int); - writeq(val64, &bar0->tx_traffic_int); - /* we need to free up the transmitted skbufs or else netpoll will - * run out of skbs and will fail and eventually netpoll application such - * as netdump will fail. - */ - for (i = 0; i < config->tx_fifo_num; i++) - tx_intr_handler(&mac_control->fifos[i]); - - /* check for received packet and indicate up to network */ for (i = 0; i < config->rx_ring_num; i++) rx_intr_handler(&mac_control->rings[i]); @@ -2736,7 +2708,7 @@ static void rx_intr_handler(ring_info_t *ring_data) /* If your are next to put index then it's FIFO full condition */ if ((get_block == put_block) && (get_info.offset + 1) == put_info.offset) { - DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); + DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name); break; } skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); @@ -2756,15 +2728,18 @@ static void rx_intr_handler(ring_info_t *ring_data) HEADER_SNAP_SIZE, PCI_DMA_FROMDEVICE); } else if (nic->rxd_mode == RXD_MODE_3B) { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) + pci_unmap_single(nic->pdev, (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); + pci_unmap_single(nic->pdev, (dma_addr_t) + ((RxD3_t*)rxdp)->Buffer1_ptr, + BUF1_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) ((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); } else { - pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) + pci_unmap_single(nic->pdev, (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); pci_unmap_single(nic->pdev, (dma_addr_t) @@ -3352,7 +3327,7 @@ static void s2io_reset(nic_t * sp) /* Clear certain PCI/PCI-X fields after reset */ if (sp->device_type == XFRAME_II_DEVICE) { - /* Clear "detected parity error" bit */ + /* Clear parity err detect bit */ pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); /* Clearing PCIX Ecc status register */ @@ -3553,7 +3528,7 @@ static void restore_xmsi_data(nic_t *nic) u64 val64; int i; - for (i=0; i < MAX_REQUESTED_MSI_X; i++) { + for (i=0; i< nic->avail_msix_vectors; i++) { writeq(nic->msix_info[i].addr, &bar0->xmsi_address); writeq(nic->msix_info[i].data, &bar0->xmsi_data); val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); @@ -3572,7 +3547,7 @@ static void store_xmsi_data(nic_t *nic) int i; /* Store and display */ - for (i=0; i < MAX_REQUESTED_MSI_X; i++) { + for (i=0; i< nic->avail_msix_vectors; i++) { val64 = (BIT(15) | vBIT(i, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, i)) { @@ -3833,11 +3808,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) TxD_t *txdp; TxFIFO_element_t __iomem *tx_fifo; unsigned long flags; +#ifdef NETIF_F_TSO + int mss; +#endif u16 vlan_tag = 0; int vlan_priority = 0; mac_info_t *mac_control; struct config_param *config; - int offload_type; mac_control = &sp->mac_control; config = &sp->config; @@ -3885,11 +3862,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - offload_type = s2io_offload_type(skb); + txdp->Control_1 = 0; + txdp->Control_2 = 0; #ifdef NETIF_F_TSO - if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { + mss = skb_shinfo(skb)->gso_size; + if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { txdp->Control_1 |= TXD_TCP_LSO_EN; - txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); + txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); } #endif if (skb->ip_summed == CHECKSUM_HW) { @@ -3907,10 +3886,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) } frg_len = skb->len - skb->data_len; - if (offload_type == SKB_GSO_UDP) { + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) { int ufo_size; - ufo_size = s2io_udp_mss(skb); + ufo_size = skb_shinfo(skb)->gso_size; ufo_size &= ~7; txdp->Control_1 |= TXD_UFO_EN; txdp->Control_1 |= TXD_UFO_MSS(ufo_size); @@ -3927,13 +3906,16 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) sp->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); txdp++; + txdp->Control_1 = 0; + txdp->Control_2 = 0; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); txdp->Host_Control = (unsigned long) skb; txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); - if (offload_type == SKB_GSO_UDP) + + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) txdp->Control_1 |= TXD_UFO_EN; frg_cnt = skb_shinfo(skb)->nr_frags; @@ -3948,12 +3930,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) (sp->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); - if (offload_type == SKB_GSO_UDP) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) txdp->Control_1 |= TXD_UFO_EN; } txdp->Control_1 |= TXD_GATHER_CODE_LAST; - if (offload_type == SKB_GSO_UDP) + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) frg_cnt++; /* as Txd0 was used for inband header */ tx_fifo = mac_control->tx_FIFO_start[queue]; @@ -3962,9 +3944,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | TX_FIFO_LAST_LIST); - if (offload_type) - val64 |= TX_FIFO_SPECIAL_FUNC; +#ifdef NETIF_F_TSO + if (mss) + val64 |= TX_FIFO_SPECIAL_FUNC; +#endif + if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) + val64 |= TX_FIFO_SPECIAL_FUNC; writeq(val64, &tx_fifo->List_Control); mmiowb(); @@ -3998,41 +3984,13 @@ s2io_alarm_handle(unsigned long data) mod_timer(&sp->alarm_timer, jiffies + HZ / 2); } -static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) -{ - int rxb_size, level; - - if (!sp->lro) { - rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); - level = rx_buffer_level(sp, rxb_size, rng_n); - - if ((level == PANIC) && (!TASKLET_IN_USE)) { - int ret; - DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); - DBG_PRINT(INTR_DBG, "PANIC levels\n"); - if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "Out of memory in %s", - __FUNCTION__); - clear_bit(0, (&sp->tasklet_status)); - return -1; - } - clear_bit(0, (&sp->tasklet_status)); - } else if (level == LOW) - tasklet_schedule(&sp->task); - - } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { - DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); - DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); - } - return 0; -} - static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) { struct net_device *dev = (struct net_device *) dev_id; nic_t *sp = dev->priv; int i; + int ret; mac_info_t *mac_control; struct config_param *config; @@ -4054,8 +4012,35 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) * reallocate the buffers from the interrupt handler itself, * else schedule a tasklet to reallocate the buffers. */ - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); + for (i = 0; i < config->rx_ring_num; i++) { + if (!sp->lro) { + int rxb_size = atomic_read(&sp->rx_bufs_left[i]); + int level = rx_buffer_level(sp, rxb_size, i); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", + dev->name); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in ISR!!\n"); + clear_bit(0, (&sp->tasklet_status)); + atomic_dec(&sp->isr_cnt); + return IRQ_HANDLED; + } + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); + } + } + else if (fill_rx_buffers(sp, i) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); + break; + } + } atomic_dec(&sp->isr_cnt); return IRQ_HANDLED; @@ -4066,13 +4051,39 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) { ring_info_t *ring = (ring_info_t *)dev_id; nic_t *sp = ring->nic; + struct net_device *dev = (struct net_device *) dev_id; + int rxb_size, level, rng_n; atomic_inc(&sp->isr_cnt); - rx_intr_handler(ring); - s2io_chk_rx_buffers(sp, ring->ring_no); + + rng_n = ring->ring_no; + if (!sp->lro) { + rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); + level = rx_buffer_level(sp, rxb_size, rng_n); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + int ret; + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "Out of memory in %s", + __FUNCTION__); + clear_bit(0, (&sp->tasklet_status)); + return IRQ_HANDLED; + } + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); + } + } + else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); + DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); + } atomic_dec(&sp->isr_cnt); + return IRQ_HANDLED; } @@ -4237,8 +4248,37 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) * else schedule a tasklet to reallocate the buffers. */ #ifndef CONFIG_S2IO_NAPI - for (i = 0; i < config->rx_ring_num; i++) - s2io_chk_rx_buffers(sp, i); + for (i = 0; i < config->rx_ring_num; i++) { + if (!sp->lro) { + int ret; + int rxb_size = atomic_read(&sp->rx_bufs_left[i]); + int level = rx_buffer_level(sp, rxb_size, i); + + if ((level == PANIC) && (!TASKLET_IN_USE)) { + DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", + dev->name); + DBG_PRINT(INTR_DBG, "PANIC levels\n"); + if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in ISR!!\n"); + clear_bit(0, (&sp->tasklet_status)); + atomic_dec(&sp->isr_cnt); + writeq(org_mask, &bar0->general_int_mask); + return IRQ_HANDLED; + } + clear_bit(0, (&sp->tasklet_status)); + } else if (level == LOW) { + tasklet_schedule(&sp->task); + } + } + else if (fill_rx_buffers(sp, i) == -ENOMEM) { + DBG_PRINT(ERR_DBG, "%s:Out of memory", + dev->name); + DBG_PRINT(ERR_DBG, " in Rx intr!!\n"); + break; + } + } #endif writeq(org_mask, &bar0->general_int_mask); atomic_dec(&sp->isr_cnt); @@ -4268,8 +4308,6 @@ static void s2io_updt_stats(nic_t *sp) if (cnt == 5) break; /* Updt failed */ } while(1); - } else { - memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); } } @@ -4904,8 +4942,7 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) } static void s2io_vpd_read(nic_t *nic) { - u8 *vpd_data; - u8 data; + u8 vpd_data[256],data; int i=0, cnt, fail = 0; int vpd_addr = 0x80; @@ -4918,10 +4955,6 @@ static void s2io_vpd_read(nic_t *nic) vpd_addr = 0x50; } - vpd_data = kmalloc(256, GFP_KERNEL); - if (!vpd_data) - return; - for (i = 0; i < 256; i +=4 ) { pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); @@ -4944,7 +4977,6 @@ static void s2io_vpd_read(nic_t *nic) memset(nic->product_name, 0, vpd_data[1]); memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); } - kfree(vpd_data); } /** @@ -5263,7 +5295,7 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) else *data = 0; - return *data; + return 0; } /** @@ -5721,19 +5753,6 @@ static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) return 0; } -static u32 s2io_ethtool_op_get_tso(struct net_device *dev) -{ - return (dev->features & NETIF_F_TSO) != 0; -} -static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) -{ - if (data) - dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); - else - dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); - - return 0; -} static struct ethtool_ops netdev_ethtool_ops = { .get_settings = s2io_ethtool_gset, @@ -5754,8 +5773,8 @@ static struct ethtool_ops netdev_ethtool_ops = { .get_sg = ethtool_op_get_sg, .set_sg = ethtool_op_set_sg, #ifdef NETIF_F_TSO - .get_tso = s2io_ethtool_op_get_tso, - .set_tso = s2io_ethtool_op_set_tso, + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, #endif .get_ufo = ethtool_op_get_ufo, .set_ufo = ethtool_op_set_ufo, @@ -6318,7 +6337,7 @@ static int s2io_card_up(nic_t * sp) s2io_set_multicast(dev); if (sp->lro) { - /* Initialize max aggregatable pkts per session based on MTU */ + /* Initialize max aggregatable pkts based on MTU */ sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; /* Check if we can use(if specified) user provided value */ if (lro_max_pkts < sp->lro_max_aggr_per_sess) @@ -6419,7 +6438,7 @@ static void s2io_tx_watchdog(struct net_device *dev) * @cksum : FCS checksum of the frame. * @ring_no : the ring from which this RxD was extracted. * Description: - * This function is called by the Rx interrupt serivce routine to perform + * This function is called by the Tx interrupt serivce routine to perform * some OS related operations on the SKB before passing it to the upper * layers. It mainly checks if the checksum is OK, if so adds it to the * SKBs cksum variable, increments the Rx packet count and passes the SKB @@ -6679,6 +6698,33 @@ static void s2io_init_pci(nic_t * sp) pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); } +MODULE_AUTHOR("Raghavendra Koushik "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); + +module_param(tx_fifo_num, int, 0); +module_param(rx_ring_num, int, 0); +module_param(rx_ring_mode, int, 0); +module_param_array(tx_fifo_len, uint, NULL, 0); +module_param_array(rx_ring_sz, uint, NULL, 0); +module_param_array(rts_frm_len, uint, NULL, 0); +module_param(use_continuous_tx_intrs, int, 1); +module_param(rmac_pause_time, int, 0); +module_param(mc_pause_threshold_q0q3, int, 0); +module_param(mc_pause_threshold_q4q7, int, 0); +module_param(shared_splits, int, 0); +module_param(tmac_util_period, int, 0); +module_param(rmac_util_period, int, 0); +module_param(bimodal, bool, 0); +module_param(l3l4hdr_size, int , 0); +#ifndef CONFIG_S2IO_NAPI +module_param(indicate_max_pkts, int, 0); +#endif +module_param(rxsync_frequency, int, 0); +module_param(intr_type, int, 0); +module_param(lro, int, 0); +module_param(lro_max_pkts, int, 0); + static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) { if ( tx_fifo_num > 8) { @@ -6786,8 +6832,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) } if (dev_intr_type != MSI_X) { if (pci_request_regions(pdev, s2io_driver_name)) { - DBG_PRINT(ERR_DBG, "Request Regions failed\n"); - pci_disable_device(pdev); + DBG_PRINT(ERR_DBG, "Request Regions failed\n"), + pci_disable_device(pdev); return -ENODEV; } } @@ -6911,7 +6957,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* initialize the shared memory used by the NIC and the host */ if (init_shared_mem(sp)) { DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", - dev->name); + __FUNCTION__); ret = -ENOMEM; goto mem_alloc_failed; } @@ -7048,9 +7094,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->addr_len = ETH_ALEN; memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); - /* reset Nic and bring it to known state */ - s2io_reset(sp); - /* * Initialize the tasklet status and link state flags * and the card state parameter @@ -7088,11 +7131,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) goto register_failed; } s2io_vpd_read(sp); + DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); + DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", + get_xena_rev_id(sp->pdev), + s2io_driver_version); DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); - DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, - sp->product_name, get_xena_rev_id(sp->pdev)); - DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, - s2io_driver_version); DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, sp->def_mac_addr[0].mac_addr[0], @@ -7393,13 +7436,8 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, if (ip->ihl != 5) /* IP has options */ return -1; - /* If we see CE codepoint in IP header, packet is not mergeable */ - if (INET_ECN_is_ce(ipv4_get_dsfield(ip))) - return -1; - - /* If we see ECE or CWR flags in TCP header, packet is not mergeable */ if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || - tcp->ece || tcp->cwr || !tcp->ack) { + !tcp->ack) { /* * Currently recognize only the ack control word and * any other control field being set would result in @@ -7553,16 +7591,18 @@ static void queue_rx_frame(struct sk_buff *skb) static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len) { - struct sk_buff *first = lro->parent; + struct sk_buff *tmp, *first = lro->parent; first->len += tcp_len; first->data_len = lro->frags_len; skb_pull(skb, (skb->len - tcp_len)); - if (skb_shinfo(first)->frag_list) - lro->last_frag->next = skb; + if ((tmp = skb_shinfo(first)->frag_list)) { + while (tmp->next) + tmp = tmp->next; + tmp->next = skb; + } else skb_shinfo(first)->frag_list = skb; - lro->last_frag = skb; sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; return; } diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index 5ed49c3be1e9..217097bc22f1 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -719,7 +719,6 @@ struct msix_info_st { /* Data structure to represent a LRO session */ typedef struct lro { struct sk_buff *parent; - struct sk_buff *last_frag; u8 *l2h; struct iphdr *iph; struct tcphdr *tcph; @@ -1012,13 +1011,4 @@ static void clear_lro_session(lro_t *lro); static void queue_rx_frame(struct sk_buff *skb); static void update_L3L4_header(nic_t *sp, lro_t *lro); static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, u32 tcp_len); - -#define s2io_tcp_mss(skb) skb_shinfo(skb)->gso_size -#define s2io_udp_mss(skb) skb_shinfo(skb)->gso_size -#define s2io_offload_type(skb) skb_shinfo(skb)->gso_type - -#define S2IO_PARM_INT(X, def_val) \ - static unsigned int X = def_val;\ - module_param(X , uint, 0); - #endif /* _S2IO_H */ diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 7de9a07b2ac2..82200bfaa8ed 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -516,7 +516,10 @@ static int skge_set_pauseparam(struct net_device *dev, /* Chip internal frequency for clock calculations */ static inline u32 hwkhz(const struct skge_hw *hw) { - return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125; + if (hw->chip_id == CHIP_ID_GENESIS) + return 53215; /* or: 53.125 MHz */ + else + return 78215; /* or: 78.125 MHz */ } /* Chip HZ to microseconds */ diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index de91609ca112..d98f28c34e5c 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -50,7 +50,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.5" +#define DRV_VERSION "1.4" #define PFX DRV_NAME " " /* @@ -2204,6 +2204,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); + if (!~status) + goto out; + if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -2240,7 +2243,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) if (sky2_more_work(hw)) return 1; - +out: netif_rx_complete(dev0); sky2_read32(hw, B0_Y2_SP_LISR); diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 647f62e9707d..fb1d5a8a45cf 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -84,7 +84,7 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl); * * returns the content of the specified SMMIO register. */ -static inline u32 +static u32 spider_net_read_reg(struct spider_net_card *card, u32 reg) { u32 value; @@ -101,7 +101,7 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg) * @reg: register to write to * @value: value to write into the specified SMMIO register */ -static inline void +static void spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) { value = cpu_to_le32(value); @@ -259,10 +259,39 @@ spider_net_get_mac_address(struct net_device *netdev) * * returns the status as in the dmac_cmd_status field of the descriptor */ -static inline int +static enum spider_net_descr_status spider_net_get_descr_status(struct spider_net_descr *descr) { - return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; + u32 cmd_status; + + cmd_status = descr->dmac_cmd_status; + cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT; + /* no need to mask out any bits, as cmd_status is 32 bits wide only + * (and unsigned) */ + return cmd_status; +} + +/** + * spider_net_set_descr_status -- sets the status of a descriptor + * @descr: descriptor to change + * @status: status to set in the descriptor + * + * changes the status to the specified value. Doesn't change other bits + * in the status + */ +static void +spider_net_set_descr_status(struct spider_net_descr *descr, + enum spider_net_descr_status status) +{ + u32 cmd_status; + /* read the status */ + cmd_status = descr->dmac_cmd_status; + /* clean the upper 4 bits */ + cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO; + /* add the status to it */ + cmd_status |= ((u32)status)<dmac_cmd_status = cmd_status; } /** @@ -299,23 +328,24 @@ spider_net_free_chain(struct spider_net_card *card, static int spider_net_init_chain(struct spider_net_card *card, struct spider_net_descr_chain *chain, - struct spider_net_descr *start_descr, - int direction, int no) + struct spider_net_descr *start_descr, int no) { int i; struct spider_net_descr *descr; dma_addr_t buf; + atomic_set(&card->rx_chain_refill,0); + descr = start_descr; memset(descr, 0, sizeof(*descr) * no); /* set up the hardware pointers in each descriptor */ for (i=0; idmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; + spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); buf = pci_map_single(card->pdev, descr, SPIDER_NET_DESCR_SIZE, - direction); + PCI_DMA_BIDIRECTIONAL); if (buf == DMA_ERROR_CODE) goto iommu_error; @@ -330,11 +360,10 @@ spider_net_init_chain(struct spider_net_card *card, start_descr->prev = descr-1; descr = start_descr; - if (direction == PCI_DMA_FROMDEVICE) - for (i=0; i < no; i++, descr++) - descr->next_descr_addr = descr->next->bus_addr; + for (i=0; i < no; i++, descr++) { + descr->next_descr_addr = descr->next->bus_addr; + } - spin_lock_init(&chain->lock); chain->head = start_descr; chain->tail = start_descr; @@ -346,7 +375,7 @@ spider_net_init_chain(struct spider_net_card *card, if (descr->bus_addr) pci_unmap_single(card->pdev, descr->bus_addr, SPIDER_NET_DESCR_SIZE, - direction); + PCI_DMA_BIDIRECTIONAL); return -ENOMEM; } @@ -367,7 +396,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) dev_kfree_skb(descr->skb); pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, - PCI_DMA_FROMDEVICE); + PCI_DMA_BIDIRECTIONAL); } descr = descr->next; } @@ -417,16 +446,15 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ buf = pci_map_single(card->pdev, descr->skb->data, - SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); + SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); descr->buf_addr = buf; if (buf == DMA_ERROR_CODE) { dev_kfree_skb_any(descr->skb); if (netif_msg_rx_err(card) && net_ratelimit()) pr_err("Could not iommu-map rx buffer\n"); - descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; + spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); } else { - descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | - SPIDER_NET_DMAC_NOINTR_COMPLETE; + descr->dmac_cmd_status = SPIDER_NET_DMAC_RX_CARDOWNED; } return error; @@ -440,7 +468,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, * chip by writing to the appropriate register. DMA is enabled in * spider_net_enable_rxdmac. */ -static inline void +static void spider_net_enable_rxchtails(struct spider_net_card *card) { /* assume chain is aligned correctly */ @@ -455,7 +483,7 @@ spider_net_enable_rxchtails(struct spider_net_card *card) * spider_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN * in the GDADMACCNTR register */ -static inline void +static void spider_net_enable_rxdmac(struct spider_net_card *card) { wmb(); @@ -472,24 +500,23 @@ spider_net_enable_rxdmac(struct spider_net_card *card) static void spider_net_refill_rx_chain(struct spider_net_card *card) { - struct spider_net_descr_chain *chain = &card->rx_chain; - unsigned long flags; + struct spider_net_descr_chain *chain; + + chain = &card->rx_chain; /* one context doing the refill (and a second context seeing that * and omitting it) is ok. If called by NAPI, we'll be called again * as spider_net_decode_one_descr is called several times. If some * interrupt calls us, the NAPI is about to clean up anyway. */ - if (!spin_trylock_irqsave(&chain->lock, flags)) - return; - - while (spider_net_get_descr_status(chain->head) == - SPIDER_NET_DESCR_NOT_IN_USE) { - if (spider_net_prepare_rx_descr(card, chain->head)) - break; - chain->head = chain->head->next; - } + if (atomic_inc_return(&card->rx_chain_refill) == 1) + while (spider_net_get_descr_status(chain->head) == + SPIDER_NET_DESCR_NOT_IN_USE) { + if (spider_net_prepare_rx_descr(card, chain->head)) + break; + chain->head = chain->head->next; + } - spin_unlock_irqrestore(&chain->lock, flags); + atomic_dec(&card->rx_chain_refill); } /** @@ -526,6 +553,111 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card) return result; } +/** + * spider_net_release_tx_descr - processes a used tx descriptor + * @card: card structure + * @descr: descriptor to release + * + * releases a used tx descriptor (unmapping, freeing of skb) + */ +static void +spider_net_release_tx_descr(struct spider_net_card *card, + struct spider_net_descr *descr) +{ + struct sk_buff *skb; + + /* unmap the skb */ + skb = descr->skb; + pci_unmap_single(card->pdev, descr->buf_addr, skb->len, + PCI_DMA_BIDIRECTIONAL); + + dev_kfree_skb_any(skb); + + /* set status to not used */ + spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); +} + +/** + * spider_net_release_tx_chain - processes sent tx descriptors + * @card: adapter structure + * @brutal: if set, don't care about whether descriptor seems to be in use + * + * returns 0 if the tx ring is empty, otherwise 1. + * + * spider_net_release_tx_chain releases the tx descriptors that spider has + * finished with (if non-brutal) or simply release tx descriptors (if brutal). + * If some other context is calling this function, we return 1 so that we're + * scheduled again (if we were scheduled) and will not loose initiative. + */ +static int +spider_net_release_tx_chain(struct spider_net_card *card, int brutal) +{ + struct spider_net_descr_chain *tx_chain = &card->tx_chain; + enum spider_net_descr_status status; + + if (atomic_inc_return(&card->tx_chain_release) != 1) { + atomic_dec(&card->tx_chain_release); + return 1; + } + + for (;;) { + status = spider_net_get_descr_status(tx_chain->tail); + switch (status) { + case SPIDER_NET_DESCR_CARDOWNED: + if (!brutal) + goto out; + /* fallthrough, if we release the descriptors + * brutally (then we don't care about + * SPIDER_NET_DESCR_CARDOWNED) */ + case SPIDER_NET_DESCR_RESPONSE_ERROR: + case SPIDER_NET_DESCR_PROTECTION_ERROR: + case SPIDER_NET_DESCR_FORCE_END: + if (netif_msg_tx_err(card)) + pr_err("%s: forcing end of tx descriptor " + "with status x%02x\n", + card->netdev->name, status); + card->netdev_stats.tx_dropped++; + break; + + case SPIDER_NET_DESCR_COMPLETE: + card->netdev_stats.tx_packets++; + card->netdev_stats.tx_bytes += + tx_chain->tail->skb->len; + break; + + default: /* any other value (== SPIDER_NET_DESCR_NOT_IN_USE) */ + goto out; + } + spider_net_release_tx_descr(card, tx_chain->tail); + tx_chain->tail = tx_chain->tail->next; + } +out: + atomic_dec(&card->tx_chain_release); + + netif_wake_queue(card->netdev); + + if (status == SPIDER_NET_DESCR_CARDOWNED) + return 1; + return 0; +} + +/** + * spider_net_cleanup_tx_ring - cleans up the TX ring + * @card: card structure + * + * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use + * interrupts to cleanup our TX ring) and returns sent packets to the stack + * by freeing them + */ +static void +spider_net_cleanup_tx_ring(struct spider_net_card *card) +{ + if ( (spider_net_release_tx_chain(card, 0)) && + (card->netdev->flags & IFF_UP) ) { + mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); + } +} + /** * spider_net_get_multicast_hash - generates hash for multicast filter table * @addr: multicast address @@ -629,128 +761,129 @@ spider_net_disable_rxdmac(struct spider_net_card *card) } /** - * spider_net_prepare_tx_descr - fill tx descriptor with skb data - * @card: card structure - * @descr: descriptor structure to fill out - * @skb: packet to use - * - * returns 0 on success, <0 on failure. + * spider_net_stop - called upon ifconfig down + * @netdev: interface device structure * - * fills out the descriptor structure with skb data and len. Copies data, - * if needed (32bit DMA!) + * always returns 0 */ -static int -spider_net_prepare_tx_descr(struct spider_net_card *card, - struct sk_buff *skb) +int +spider_net_stop(struct net_device *netdev) { - struct spider_net_descr *descr = card->tx_chain.head; - dma_addr_t buf; + struct spider_net_card *card = netdev_priv(netdev); - buf = pci_map_single(card->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - if (buf == DMA_ERROR_CODE) { - if (netif_msg_tx_err(card) && net_ratelimit()) - pr_err("could not iommu-map packet (%p, %i). " - "Dropping packet\n", skb->data, skb->len); - return -ENOMEM; - } + tasklet_kill(&card->rxram_full_tl); + netif_poll_disable(netdev); + netif_carrier_off(netdev); + netif_stop_queue(netdev); + del_timer_sync(&card->tx_timer); - descr->buf_addr = buf; - descr->buf_size = skb->len; - descr->next_descr_addr = 0; - descr->skb = skb; - descr->data_status = 0; + /* disable/mask all interrupts */ + spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); + spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); - descr->dmac_cmd_status = - SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; - if (skb->protocol == htons(ETH_P_IP)) - switch (skb->nh.iph->protocol) { - case IPPROTO_TCP: - descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; - break; - case IPPROTO_UDP: - descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; - break; - } + /* free_irq(netdev->irq, netdev);*/ + free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); - descr->prev->next_descr_addr = descr->bus_addr; + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, + SPIDER_NET_DMA_TX_FEND_VALUE); + + /* turn off DMA, force end */ + spider_net_disable_rxdmac(card); + + /* release chains */ + spider_net_release_tx_chain(card, 1); + + spider_net_free_chain(card, &card->tx_chain); + spider_net_free_chain(card, &card->rx_chain); return 0; } /** - * spider_net_release_tx_descr - processes a used tx descriptor - * @card: card structure - * @descr: descriptor to release + * spider_net_get_next_tx_descr - returns the next available tx descriptor + * @card: device structure to get descriptor from * - * releases a used tx descriptor (unmapping, freeing of skb) + * returns the address of the next descriptor, or NULL if not available. */ -static inline void -spider_net_release_tx_descr(struct spider_net_card *card) +static struct spider_net_descr * +spider_net_get_next_tx_descr(struct spider_net_card *card) { - struct spider_net_descr *descr = card->tx_chain.tail; - struct sk_buff *skb; + /* check, if head points to not-in-use descr */ + if ( spider_net_get_descr_status(card->tx_chain.head) == + SPIDER_NET_DESCR_NOT_IN_USE ) { + return card->tx_chain.head; + } else { + return NULL; + } +} + +/** + * spider_net_set_txdescr_cmdstat - sets the tx descriptor command field + * @descr: descriptor structure to fill out + * @skb: packet to consider + * + * fills out the command and status field of the descriptor structure, + * depending on hardware checksum settings. + */ +static void +spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, + struct sk_buff *skb) +{ + /* make sure the other fields in the descriptor are written */ + wmb(); - card->tx_chain.tail = card->tx_chain.tail->next; - descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; + if (skb->ip_summed != CHECKSUM_HW) { + descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; + return; + } - /* unmap the skb */ - skb = descr->skb; - pci_unmap_single(card->pdev, descr->buf_addr, skb->len, - PCI_DMA_TODEVICE); - dev_kfree_skb_any(skb); + /* is packet ip? + * if yes: tcp? udp? */ + if (skb->protocol == htons(ETH_P_IP)) { + if (skb->nh.iph->protocol == IPPROTO_TCP) + descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS; + else if (skb->nh.iph->protocol == IPPROTO_UDP) + descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS; + else /* the stack should checksum non-tcp and non-udp + packets on his own: NETIF_F_IP_CSUM */ + descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; + } } /** - * spider_net_release_tx_chain - processes sent tx descriptors - * @card: adapter structure - * @brutal: if set, don't care about whether descriptor seems to be in use + * spider_net_prepare_tx_descr - fill tx descriptor with skb data + * @card: card structure + * @descr: descriptor structure to fill out + * @skb: packet to use * - * returns 0 if the tx ring is empty, otherwise 1. + * returns 0 on success, <0 on failure. * - * spider_net_release_tx_chain releases the tx descriptors that spider has - * finished with (if non-brutal) or simply release tx descriptors (if brutal). - * If some other context is calling this function, we return 1 so that we're - * scheduled again (if we were scheduled) and will not loose initiative. + * fills out the descriptor structure with skb data and len. Copies data, + * if needed (32bit DMA!) */ static int -spider_net_release_tx_chain(struct spider_net_card *card, int brutal) +spider_net_prepare_tx_descr(struct spider_net_card *card, + struct spider_net_descr *descr, + struct sk_buff *skb) { - struct spider_net_descr_chain *chain = &card->tx_chain; - int status; - - spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR); - - while (chain->tail != chain->head) { - status = spider_net_get_descr_status(chain->tail); - switch (status) { - case SPIDER_NET_DESCR_COMPLETE: - card->netdev_stats.tx_packets++; - card->netdev_stats.tx_bytes += chain->tail->skb->len; - break; + dma_addr_t buf; - case SPIDER_NET_DESCR_CARDOWNED: - if (!brutal) - return 1; - /* fallthrough, if we release the descriptors - * brutally (then we don't care about - * SPIDER_NET_DESCR_CARDOWNED) */ + buf = pci_map_single(card->pdev, skb->data, + skb->len, PCI_DMA_BIDIRECTIONAL); + if (buf == DMA_ERROR_CODE) { + if (netif_msg_tx_err(card) && net_ratelimit()) + pr_err("could not iommu-map packet (%p, %i). " + "Dropping packet\n", skb->data, skb->len); + return -ENOMEM; + } - case SPIDER_NET_DESCR_RESPONSE_ERROR: - case SPIDER_NET_DESCR_PROTECTION_ERROR: - case SPIDER_NET_DESCR_FORCE_END: - if (netif_msg_tx_err(card)) - pr_err("%s: forcing end of tx descriptor " - "with status x%02x\n", - card->netdev->name, status); - card->netdev_stats.tx_errors++; - break; + descr->buf_addr = buf; + descr->buf_size = skb->len; + descr->skb = skb; + descr->data_status = 0; - default: - card->netdev_stats.tx_dropped++; - return 1; - } - spider_net_release_tx_descr(card); - } + spider_net_set_txdescr_cmdstat(descr,skb); return 0; } @@ -763,32 +896,18 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) * spider_net_kick_tx_dma writes the current tx chain head as start address * of the tx descriptor chain and enables the transmission DMA engine */ -static inline void -spider_net_kick_tx_dma(struct spider_net_card *card) +static void +spider_net_kick_tx_dma(struct spider_net_card *card, + struct spider_net_descr *descr) { - struct spider_net_descr *descr; + /* this is the only descriptor in the output chain. + * Enable TX DMA */ - if (spider_net_read_reg(card, SPIDER_NET_GDTDMACCNTR) & - SPIDER_NET_TX_DMA_EN) - goto out; - - descr = card->tx_chain.tail; - for (;;) { - if (spider_net_get_descr_status(descr) == - SPIDER_NET_DESCR_CARDOWNED) { - spider_net_write_reg(card, SPIDER_NET_GDTDCHA, - descr->bus_addr); - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_DMA_TX_VALUE); - break; - } - if (descr == card->tx_chain.head) - break; - descr = descr->next; - } + spider_net_write_reg(card, SPIDER_NET_GDTDCHA, + descr->bus_addr); -out: - mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); + spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, + SPIDER_NET_DMA_TX_VALUE); } /** @@ -796,69 +915,47 @@ spider_net_kick_tx_dma(struct spider_net_card *card) * @skb: packet to send out * @netdev: interface device structure * - * returns 0 on success, !0 on failure + * returns 0 on success, <0 on failure */ static int spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); - struct spider_net_descr_chain *chain = &card->tx_chain; - struct spider_net_descr *descr = chain->head; - unsigned long flags; + struct spider_net_descr *descr; int result; - spin_lock_irqsave(&chain->lock, flags); - spider_net_release_tx_chain(card, 0); - if (chain->head->next == chain->tail->prev) { - card->netdev_stats.tx_dropped++; - result = NETDEV_TX_LOCKED; - goto out; - } - - if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { - result = NETDEV_TX_LOCKED; - goto out; - } + descr = spider_net_get_next_tx_descr(card); - if (spider_net_prepare_tx_descr(card, skb) != 0) { - card->netdev_stats.tx_dropped++; - result = NETDEV_TX_BUSY; - goto out; - } + if (!descr) + goto error; - result = NETDEV_TX_OK; + result = spider_net_prepare_tx_descr(card, descr, skb); + if (result) + goto error; - spider_net_kick_tx_dma(card); card->tx_chain.head = card->tx_chain.head->next; -out: - spin_unlock_irqrestore(&chain->lock, flags); - netif_wake_queue(netdev); - return result; -} - -/** - * spider_net_cleanup_tx_ring - cleans up the TX ring - * @card: card structure - * - * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use - * interrupts to cleanup our TX ring) and returns sent packets to the stack - * by freeing them - */ -static void -spider_net_cleanup_tx_ring(struct spider_net_card *card) -{ - unsigned long flags; + if (spider_net_get_descr_status(descr->prev) != + SPIDER_NET_DESCR_CARDOWNED) { + /* make sure the current descriptor is in memory. Then + * kicking it on again makes sense, if the previous is not + * card-owned anymore. Check the previous descriptor twice + * to omit an mb() in heavy traffic cases */ + mb(); + if (spider_net_get_descr_status(descr->prev) != + SPIDER_NET_DESCR_CARDOWNED) + spider_net_kick_tx_dma(card, descr); + } - spin_lock_irqsave(&card->tx_chain.lock, flags); + mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); - if ((spider_net_release_tx_chain(card, 0) != 0) && - (card->netdev->flags & IFF_UP)) - spider_net_kick_tx_dma(card); + return NETDEV_TX_OK; - spin_unlock_irqrestore(&card->tx_chain.lock, flags); +error: + card->netdev_stats.tx_dropped++; + return NETDEV_TX_BUSY; } /** @@ -905,7 +1002,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, /* unmap descriptor */ pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, - PCI_DMA_FROMDEVICE); + PCI_DMA_BIDIRECTIONAL); /* the cases we'll throw away the packet immediately */ if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { @@ -970,11 +1067,14 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, static int spider_net_decode_one_descr(struct spider_net_card *card, int napi) { - struct spider_net_descr_chain *chain = &card->rx_chain; - struct spider_net_descr *descr = chain->tail; - int status; + enum spider_net_descr_status status; + struct spider_net_descr *descr; + struct spider_net_descr_chain *chain; int result; + chain = &card->rx_chain; + descr = chain->tail; + status = spider_net_get_descr_status(descr); if (status == SPIDER_NET_DESCR_CARDOWNED) { @@ -1003,7 +1103,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) card->netdev->name, status); card->netdev_stats.rx_dropped++; pci_unmap_single(card->pdev, descr->buf_addr, - SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); + SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); dev_kfree_skb_irq(descr->skb); goto refill; } @@ -1019,7 +1119,7 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) /* ok, we've got a packet in descr */ result = spider_net_pass_skb_up(descr, card, napi); refill: - descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; + spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); /* change the descriptor state: */ if (!napi) spider_net_refill_rx_chain(card); @@ -1190,6 +1290,21 @@ spider_net_set_mac(struct net_device *netdev, void *p) return 0; } +/** + * spider_net_enable_txdmac - enables a TX DMA controller + * @card: card structure + * + * spider_net_enable_txdmac enables the TX DMA controller by setting the + * descriptor chain tail address + */ +static void +spider_net_enable_txdmac(struct spider_net_card *card) +{ + /* assume chain is aligned correctly */ + spider_net_write_reg(card, SPIDER_NET_GDTDCHA, + card->tx_chain.tail->bus_addr); +} + /** * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt * @card: card structure @@ -1538,6 +1653,7 @@ spider_net_enable_card(struct spider_net_card *card) { SPIDER_NET_GMRWOLCTRL, 0 }, { SPIDER_NET_GTESTMD, 0x10000000 }, { SPIDER_NET_GTTQMSK, 0x00400040 }, + { SPIDER_NET_GTESTMD, 0 }, { SPIDER_NET_GMACINTEN, 0 }, @@ -1576,6 +1692,9 @@ spider_net_enable_card(struct spider_net_card *card) spider_net_write_reg(card, SPIDER_NET_GRXDMAEN, SPIDER_NET_WOL_VALUE); + /* set chain tail adress for TX chain */ + spider_net_enable_txdmac(card); + spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, SPIDER_NET_LENLMT_VALUE); spider_net_write_reg(card, SPIDER_NET_GMACMODE, @@ -1590,9 +1709,6 @@ spider_net_enable_card(struct spider_net_card *card) SPIDER_NET_INT1_MASK_VALUE); spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, SPIDER_NET_INT2_MASK_VALUE); - - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_GDTDCEIDIS); } /** @@ -1612,12 +1728,10 @@ spider_net_open(struct net_device *netdev) result = -ENOMEM; if (spider_net_init_chain(card, &card->tx_chain, - card->descr, - PCI_DMA_TODEVICE, tx_descriptors)) + card->descr, tx_descriptors)) goto alloc_tx_failed; if (spider_net_init_chain(card, &card->rx_chain, - card->descr + tx_descriptors, - PCI_DMA_FROMDEVICE, rx_descriptors)) + card->descr + tx_descriptors, rx_descriptors)) goto alloc_rx_failed; /* allocate rx skbs */ @@ -1824,7 +1938,7 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) /* empty sequencer data */ for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; sequencer++) { - spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + + spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + sequencer * 8, 0x0); for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + @@ -1840,49 +1954,6 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) SPIDER_NET_CKRCTRL_STOP_VALUE); } -/** - * spider_net_stop - called upon ifconfig down - * @netdev: interface device structure - * - * always returns 0 - */ -int -spider_net_stop(struct net_device *netdev) -{ - struct spider_net_card *card = netdev_priv(netdev); - - tasklet_kill(&card->rxram_full_tl); - netif_poll_disable(netdev); - netif_carrier_off(netdev); - netif_stop_queue(netdev); - del_timer_sync(&card->tx_timer); - - /* disable/mask all interrupts */ - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); - spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); - - /* free_irq(netdev->irq, netdev);*/ - free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev); - - spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, - SPIDER_NET_DMA_TX_FEND_VALUE); - - /* turn off DMA, force end */ - spider_net_disable_rxdmac(card); - - /* release chains */ - if (spin_trylock(&card->tx_chain.lock)) { - spider_net_release_tx_chain(card, 1); - spin_unlock(&card->tx_chain.lock); - } - - spider_net_free_chain(card, &card->tx_chain); - spider_net_free_chain(card, &card->rx_chain); - - return 0; -} - /** * spider_net_tx_timeout_task - task scheduled by the watchdog timeout * function (to be called not under interrupt status) @@ -1911,7 +1982,7 @@ spider_net_tx_timeout_task(void *data) goto out; spider_net_open(netdev); - spider_net_kick_tx_dma(card); + spider_net_kick_tx_dma(card, card->tx_chain.head); netif_device_attach(netdev); out: @@ -1994,6 +2065,7 @@ spider_net_setup_netdev(struct spider_net_card *card) pci_set_drvdata(card->pdev, netdev); + atomic_set(&card->tx_chain_release,0); card->rxram_full_tl.data = (unsigned long) card; card->rxram_full_tl.func = (void (*)(unsigned long)) spider_net_handle_rxram_full; @@ -2007,7 +2079,7 @@ spider_net_setup_netdev(struct spider_net_card *card) spider_net_setup_netdev_ops(netdev); - netdev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX; + netdev->features = NETIF_F_HW_CSUM; /* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX | * NETIF_F_HW_VLAN_FILTER */ diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index f6dcf180ae3d..3b8d951cf73c 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -208,10 +208,7 @@ extern char spider_net_driver_name[]; #define SPIDER_NET_DMA_RX_VALUE 0x80000000 #define SPIDER_NET_DMA_RX_FEND_VALUE 0x00030003 /* to set TX_DMA_EN */ -#define SPIDER_NET_TX_DMA_EN 0x80000000 -#define SPIDER_NET_GDTDCEIDIS 0x00000002 -#define SPIDER_NET_DMA_TX_VALUE SPIDER_NET_TX_DMA_EN | \ - SPIDER_NET_GDTDCEIDIS +#define SPIDER_NET_DMA_TX_VALUE 0x80000000 #define SPIDER_NET_DMA_TX_FEND_VALUE 0x00030003 /* SPIDER_NET_UA_DESCR_VALUE is OR'ed with the unicast address */ @@ -332,23 +329,55 @@ enum spider_net_int2_status { (~SPIDER_NET_TXINT) & \ (~SPIDER_NET_RXINT) ) -#define SPIDER_NET_GPREXEC 0x80000000 -#define SPIDER_NET_GPRDAT_MASK 0x0000ffff +#define SPIDER_NET_GPREXEC 0x80000000 +#define SPIDER_NET_GPRDAT_MASK 0x0000ffff -#define SPIDER_NET_DMAC_NOINTR_COMPLETE 0x00800000 -#define SPIDER_NET_DMAC_NOCS 0x00040000 -#define SPIDER_NET_DMAC_TCP 0x00020000 -#define SPIDER_NET_DMAC_UDP 0x00030000 -#define SPIDER_NET_TXDCEST 0x08000000 - -#define SPIDER_NET_DESCR_IND_PROC_MASK 0xF0000000 -#define SPIDER_NET_DESCR_COMPLETE 0x00000000 /* used in rx and tx */ -#define SPIDER_NET_DESCR_RESPONSE_ERROR 0x10000000 /* used in rx and tx */ -#define SPIDER_NET_DESCR_PROTECTION_ERROR 0x20000000 /* used in rx and tx */ -#define SPIDER_NET_DESCR_FRAME_END 0x40000000 /* used in rx */ -#define SPIDER_NET_DESCR_FORCE_END 0x50000000 /* used in rx and tx */ -#define SPIDER_NET_DESCR_CARDOWNED 0xA0000000 /* used in rx and tx */ -#define SPIDER_NET_DESCR_NOT_IN_USE 0xF0000000 +/* descriptor bits + * + * 1010 descriptor ready + * 0 descr in middle of chain + * 000 fixed to 0 + * + * 0 no interrupt on completion + * 000 fixed to 0 + * 1 no ipsec processing + * 1 last descriptor for this frame + * 00 no checksum + * 10 tcp checksum + * 11 udp checksum + * + * 00 fixed to 0 + * 0 fixed to 0 + * 0 no interrupt on response errors + * 0 no interrupt on invalid descr + * 0 no interrupt on dma process termination + * 0 no interrupt on descr chain end + * 0 no interrupt on descr complete + * + * 000 fixed to 0 + * 0 response error interrupt status + * 0 invalid descr status + * 0 dma termination status + * 0 descr chain end status + * 0 descr complete status */ +#define SPIDER_NET_DMAC_CMDSTAT_NOCS 0xa00c0000 +#define SPIDER_NET_DMAC_CMDSTAT_TCPCS 0xa00e0000 +#define SPIDER_NET_DMAC_CMDSTAT_UDPCS 0xa00f0000 +#define SPIDER_NET_DESCR_IND_PROC_SHIFT 28 +#define SPIDER_NET_DESCR_IND_PROC_MASKO 0x0fffffff + +/* descr ready, descr is in middle of chain, get interrupt on completion */ +#define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 + +enum spider_net_descr_status { + SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ + SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ + SPIDER_NET_DESCR_PROTECTION_ERROR = 0x02, /* used in rx and tx */ + SPIDER_NET_DESCR_FRAME_END = 0x04, /* used in rx */ + SPIDER_NET_DESCR_FORCE_END = 0x05, /* used in rx and tx */ + SPIDER_NET_DESCR_CARDOWNED = 0x0a, /* used in rx and tx */ + SPIDER_NET_DESCR_NOT_IN_USE /* any other value */ +}; struct spider_net_descr { /* as defined by the hardware */ @@ -369,7 +398,7 @@ struct spider_net_descr { } __attribute__((aligned(32))); struct spider_net_descr_chain { - spinlock_t lock; + /* we walk from tail to head */ struct spider_net_descr *head; struct spider_net_descr *tail; }; @@ -424,6 +453,8 @@ struct spider_net_card { struct spider_net_descr_chain tx_chain; struct spider_net_descr_chain rx_chain; + atomic_t rx_chain_refill; + atomic_t tx_chain_release; struct net_device_stats netdev_stats; diff --git a/trunk/drivers/net/sunhme.c b/trunk/drivers/net/sunhme.c index c6f5bc3c042f..8673fd4c08c7 100644 --- a/trunk/drivers/net/sunhme.c +++ b/trunk/drivers/net/sunhme.c @@ -3255,7 +3255,12 @@ static void __devexit happy_meal_pci_remove(struct pci_dev *pdev) } static struct pci_device_id happymeal_pci_ids[] = { - { PCI_DEVICE(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_HAPPYMEAL) }, + { + .vendor = PCI_VENDOR_ID_SUN, + .device = PCI_DEVICE_ID_SUN_HAPPYMEAL, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, { } /* Terminating entry */ }; @@ -3270,7 +3275,7 @@ static struct pci_driver hme_pci_driver = { static int __init happy_meal_pci_init(void) { - return pci_register_driver(&hme_pci_driver); + return pci_module_init(&hme_pci_driver); } static void happy_meal_pci_exit(void) diff --git a/trunk/drivers/net/sunlance.c b/trunk/drivers/net/sunlance.c index 0e3fdf7c6dd3..1ef9fd39a79a 100644 --- a/trunk/drivers/net/sunlance.c +++ b/trunk/drivers/net/sunlance.c @@ -1537,7 +1537,7 @@ static int __init sparc_lance_init(void) { if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || (idprom->id_machtype == (SM_SUN4|SM_4_470))) { - memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); + memset(&sun4_sdev, 0, sizeof(sdev)); sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; sun4_sdev.irqs[0] = 6; return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); @@ -1547,16 +1547,16 @@ static int __init sparc_lance_init(void) static int __exit sunlance_sun4_remove(void) { - struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); + struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); struct net_device *net_dev = lp->dev; unregister_netdevice(net_dev); - lance_free_hwresources(lp); + lance_free_hwresources(root_lance_dev); free_netdev(net_dev); - dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); + dev_set_drvdata(&sun4_sdev->dev, NULL); return 0; } diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index 6f97962dd06b..ce6f3be86da0 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.64" -#define DRV_MODULE_RELDATE "July 31, 2006" +#define DRV_MODULE_VERSION "3.62" +#define DRV_MODULE_RELDATE "June 30, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -3097,7 +3097,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key, * Callers depend upon this behavior and assume that * we leave everything unchanged if we fail. */ - skb = netdev_alloc_skb(tp->dev, skb_size); + skb = dev_alloc_skb(skb_size); if (skb == NULL) return -ENOMEM; @@ -3270,7 +3270,7 @@ static int tg3_rx(struct tg3 *tp, int budget) tg3_recycle_rx(tp, opaque_key, desc_idx, *post_ptr); - copy_skb = netdev_alloc_skb(tp->dev, len + 2); + copy_skb = dev_alloc_skb(len + 2); if (copy_skb == NULL) goto drop_it_no_recycle; @@ -3590,28 +3590,6 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, static int tg3_init_hw(struct tg3 *, int); static int tg3_halt(struct tg3 *, int, int); -/* Restart hardware after configuration changes, self-test, etc. - * Invoked with tp->lock held. - */ -static int tg3_restart_hw(struct tg3 *tp, int reset_phy) -{ - int err; - - err = tg3_init_hw(tp, reset_phy); - if (err) { - printk(KERN_ERR PFX "%s: Failed to re-initialize device, " - "aborting.\n", tp->dev->name); - tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_full_unlock(tp); - del_timer_sync(&tp->timer); - tp->irq_sync = 0; - netif_poll_enable(tp->dev); - dev_close(tp->dev); - tg3_full_lock(tp, 0); - } - return err; -} - #ifdef CONFIG_NET_POLL_CONTROLLER static void tg3_poll_controller(struct net_device *dev) { @@ -3652,15 +3630,13 @@ static void tg3_reset_task(void *_data) } tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); - if (tg3_init_hw(tp, 1)) - goto out; + tg3_init_hw(tp, 1); tg3_netif_start(tp); if (restart_timer) mod_timer(&tp->timer, jiffies + 1); -out: tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; tg3_full_unlock(tp); @@ -4148,7 +4124,6 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, static int tg3_change_mtu(struct net_device *dev, int new_mtu) { struct tg3 *tp = netdev_priv(dev); - int err; if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) return -EINVAL; @@ -4169,14 +4144,13 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) tg3_set_mtu(dev, tp, new_mtu); - err = tg3_restart_hw(tp, 0); + tg3_init_hw(tp, 0); - if (!err) - tg3_netif_start(tp); + tg3_netif_start(tp); tg3_full_unlock(tp); - return err; + return 0; } /* Free up pending packets in all rx/tx rings. @@ -4258,7 +4232,7 @@ static void tg3_free_rings(struct tg3 *tp) * end up in the driver. tp->{tx,}lock are held and thus * we may not sleep. */ -static int tg3_init_rings(struct tg3 *tp) +static void tg3_init_rings(struct tg3 *tp) { u32 i; @@ -4307,38 +4281,18 @@ static int tg3_init_rings(struct tg3 *tp) /* Now allocate fresh SKBs for each rx ring. */ for (i = 0; i < tp->rx_pending; i++) { - if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) { - printk(KERN_WARNING PFX - "%s: Using a smaller RX standard ring, " - "only %d out of %d buffers were allocated " - "successfully.\n", - tp->dev->name, i, tp->rx_pending); - if (i == 0) - return -ENOMEM; - tp->rx_pending = i; + if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, + -1, i) < 0) break; - } } if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { for (i = 0; i < tp->rx_jumbo_pending; i++) { if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, - -1, i) < 0) { - printk(KERN_WARNING PFX - "%s: Using a smaller RX jumbo ring, " - "only %d out of %d buffers were " - "allocated successfully.\n", - tp->dev->name, i, tp->rx_jumbo_pending); - if (i == 0) { - tg3_free_rings(tp); - return -ENOMEM; - } - tp->rx_jumbo_pending = i; + -1, i) < 0) break; - } } } - return 0; } /* @@ -5861,7 +5815,6 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) { struct tg3 *tp = netdev_priv(dev); struct sockaddr *addr = p; - int err = 0; if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -5879,9 +5832,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) tg3_full_lock(tp, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - err = tg3_restart_hw(tp, 0); - if (!err) - tg3_netif_start(tp); + tg3_init_hw(tp, 0); + + tg3_netif_start(tp); tg3_full_unlock(tp); } else { spin_lock_bh(&tp->lock); @@ -5889,7 +5842,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) spin_unlock_bh(&tp->lock); } - return err; + return 0; } /* tp->lock is held. */ @@ -5989,9 +5942,7 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) * can only do this after the hardware has been * successfully reset. */ - err = tg3_init_rings(tp); - if (err) - return err; + tg3_init_rings(tp); /* This value is determined during the probe time DMA * engine test, tg3_test_dma. @@ -8005,7 +7956,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct tg3 *tp = netdev_priv(dev); - int irq_sync = 0, err = 0; + int irq_sync = 0; if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || @@ -8029,14 +7980,13 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - err = tg3_restart_hw(tp, 1); - if (!err) - tg3_netif_start(tp); + tg3_init_hw(tp, 1); + tg3_netif_start(tp); } tg3_full_unlock(tp); - return err; + return 0; } static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) @@ -8051,7 +8001,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct tg3 *tp = netdev_priv(dev); - int irq_sync = 0, err = 0; + int irq_sync = 0; if (netif_running(dev)) { tg3_netif_stop(tp); @@ -8075,14 +8025,13 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - err = tg3_restart_hw(tp, 1); - if (!err) - tg3_netif_start(tp); + tg3_init_hw(tp, 1); + tg3_netif_start(tp); } tg3_full_unlock(tp); - return err; + return 0; } static u32 tg3_get_rx_csum(struct net_device *dev) @@ -8618,7 +8567,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) err = -EIO; tx_len = 1514; - skb = netdev_alloc_skb(tp->dev, tx_len); + skb = dev_alloc_skb(tx_len); if (!skb) return -ENOMEM; @@ -8717,9 +8666,7 @@ static int tg3_test_loopback(struct tg3 *tp) if (!netif_running(tp->dev)) return TG3_LOOPBACK_FAILED; - err = tg3_reset_hw(tp, 1); - if (err) - return TG3_LOOPBACK_FAILED; + tg3_reset_hw(tp, 1); if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) err |= TG3_MAC_LOOPBACK_FAILED; @@ -8793,8 +8740,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - if (!tg3_restart_hw(tp, 1)) - tg3_netif_start(tp); + tg3_init_hw(tp, 1); + tg3_netif_start(tp); } tg3_full_unlock(tp); @@ -11752,8 +11699,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - if (tg3_restart_hw(tp, 1)) - goto out; + tg3_init_hw(tp, 1); tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); @@ -11761,7 +11707,6 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_attach(dev); tg3_netif_start(tp); -out: tg3_full_unlock(tp); } @@ -11788,19 +11733,16 @@ static int tg3_resume(struct pci_dev *pdev) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - err = tg3_restart_hw(tp, 1); - if (err) - goto out; + tg3_init_hw(tp, 1); tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); tg3_netif_start(tp); -out: tg3_full_unlock(tp); - return err; + return 0; } static struct pci_driver tg3_driver = { diff --git a/trunk/drivers/net/via-velocity.c b/trunk/drivers/net/via-velocity.c index aa9cd92f46b2..f5b0078eb4ad 100644 --- a/trunk/drivers/net/via-velocity.c +++ b/trunk/drivers/net/via-velocity.c @@ -2742,7 +2742,7 @@ static u32 check_connection_type(struct mac_regs __iomem * regs) if (PHYSR0 & PHYSR0_SPDG) status |= VELOCITY_SPEED_1000; - else if (PHYSR0 & PHYSR0_SPD10) + if (PHYSR0 & PHYSR0_SPD10) status |= VELOCITY_SPEED_10; else status |= VELOCITY_SPEED_100; @@ -2851,17 +2851,8 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd u32 status; status = check_connection_type(vptr->mac_regs); - cmd->supported = SUPPORTED_TP | - SUPPORTED_Autoneg | - SUPPORTED_10baseT_Half | - SUPPORTED_10baseT_Full | - SUPPORTED_100baseT_Half | - SUPPORTED_100baseT_Full | - SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full; - if (status & VELOCITY_SPEED_1000) - cmd->speed = SPEED_1000; - else if (status & VELOCITY_SPEED_100) + cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + if (status & VELOCITY_SPEED_100) cmd->speed = SPEED_100; else cmd->speed = SPEED_10; @@ -2905,7 +2896,7 @@ static u32 velocity_get_link(struct net_device *dev) { struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; - return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; + return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; } static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/trunk/drivers/net/wan/c101.c b/trunk/drivers/net/wan/c101.c index 435e91ec4620..2c09ec908a3f 100644 --- a/trunk/drivers/net/wan/c101.c +++ b/trunk/drivers/net/wan/c101.c @@ -197,6 +197,7 @@ static int c101_open(struct net_device *dev) sca_out(IE0_TXINT, MSCI0_OFFSET + IE0, port); set_carrier(port); + printk(KERN_DEBUG "0x%X\n", sca_in(MSCI1_OFFSET + ST3, port)); /* enable MSCI1 CDCD interrupt */ sca_out(IE1_CDCD, MSCI1_OFFSET + IE1, port); @@ -448,5 +449,4 @@ module_exit(c101_cleanup); MODULE_AUTHOR("Krzysztof Halasa "); MODULE_DESCRIPTION("Moxa C101 serial port driver"); MODULE_LICENSE("GPL v2"); -module_param(hw, charp, 0444); -MODULE_PARM_DESC(hw, "irq,ram:irq,..."); +module_param(hw, charp, 0444); /* hw=irq,ram:irq,... */ diff --git a/trunk/drivers/net/wan/hdlc_ppp.c b/trunk/drivers/net/wan/hdlc_ppp.c index fbaab5bf71eb..b81263eaede0 100644 --- a/trunk/drivers/net/wan/hdlc_ppp.c +++ b/trunk/drivers/net/wan/hdlc_ppp.c @@ -107,7 +107,6 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) dev->hard_header = NULL; dev->type = ARPHRD_PPP; dev->addr_len = 0; - netif_dormant_off(dev); return 0; } diff --git a/trunk/drivers/net/wan/hdlc_raw.c b/trunk/drivers/net/wan/hdlc_raw.c index f15aa6ba77f1..9456d31cb1c1 100644 --- a/trunk/drivers/net/wan/hdlc_raw.c +++ b/trunk/drivers/net/wan/hdlc_raw.c @@ -82,7 +82,6 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) dev->type = ARPHRD_RAWHDLC; dev->flags = IFF_POINTOPOINT | IFF_NOARP; dev->addr_len = 0; - netif_dormant_off(dev); return 0; } diff --git a/trunk/drivers/net/wan/hdlc_raw_eth.c b/trunk/drivers/net/wan/hdlc_raw_eth.c index d1884987f94e..b1285cc8fee6 100644 --- a/trunk/drivers/net/wan/hdlc_raw_eth.c +++ b/trunk/drivers/net/wan/hdlc_raw_eth.c @@ -100,7 +100,6 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) dev->tx_queue_len = old_qlen; memcpy(dev->dev_addr, "\x00\x01", 2); get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2); - netif_dormant_off(dev); return 0; } diff --git a/trunk/drivers/net/wan/hdlc_x25.c b/trunk/drivers/net/wan/hdlc_x25.c index a867fb411f89..07e5eef1fe0f 100644 --- a/trunk/drivers/net/wan/hdlc_x25.c +++ b/trunk/drivers/net/wan/hdlc_x25.c @@ -212,7 +212,6 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) dev->hard_header = NULL; dev->type = ARPHRD_X25; dev->addr_len = 0; - netif_dormant_off(dev); return 0; } diff --git a/trunk/drivers/net/wan/n2.c b/trunk/drivers/net/wan/n2.c index dcf46add3adf..e013b817cab8 100644 --- a/trunk/drivers/net/wan/n2.c +++ b/trunk/drivers/net/wan/n2.c @@ -564,5 +564,4 @@ module_exit(n2_cleanup); MODULE_AUTHOR("Krzysztof Halasa "); MODULE_DESCRIPTION("RISCom/N2 serial port driver"); MODULE_LICENSE("GPL v2"); -module_param(hw, charp, 0444); -MODULE_PARM_DESC(hw, "io,irq,ram,ports:io,irq,..."); +module_param(hw, charp, 0444); /* hw=io,irq,ram,ports:io,irq,... */ diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index 2e8ac995d56f..fa9d2c4edc93 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -447,7 +447,6 @@ config AIRO_CS tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) select CRYPTO - select CRYPTO_AES ---help--- This is the standard Linux driver to support Cisco/Aironet PCMCIA 802.11 wireless cards. This driver is the same as the Aironet diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c index df317c1e12a8..3889f79e7128 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3701,7 +3701,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, } if (sec->flags & SEC_AUTH_MODE) { secinfo->auth_mode = sec->auth_mode; - dprintk(", .auth_mode = %d", sec->auth_mode); + dprintk(", .auth_mode = %d\n", sec->auth_mode); } dprintk("\n"); if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && diff --git a/trunk/drivers/net/wireless/orinoco.c b/trunk/drivers/net/wireless/orinoco.c index 317ace7f9aae..d6ed5781b93a 100644 --- a/trunk/drivers/net/wireless/orinoco.c +++ b/trunk/drivers/net/wireless/orinoco.c @@ -2875,7 +2875,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - if (erq->length > 0) { + if (erq->pointer) { if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) index = priv->tx_key; @@ -2918,7 +2918,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, if (erq->flags & IW_ENCODE_RESTRICTED) restricted = 1; - if (erq->pointer && erq->length > 0) { + if (erq->pointer) { priv->keys[index].len = cpu_to_le16(xlen); memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data)); diff --git a/trunk/drivers/net/wireless/zd1201.c b/trunk/drivers/net/wireless/zd1201.c index c52e9bcf8d02..662ecc8a33ff 100644 --- a/trunk/drivers/net/wireless/zd1201.c +++ b/trunk/drivers/net/wireless/zd1201.c @@ -1820,8 +1820,6 @@ static int zd1201_probe(struct usb_interface *interface, zd->dev->name); usb_set_intfdata(interface, zd); - zd1201_enable(zd); /* zd1201 likes to startup enabled, */ - zd1201_disable(zd); /* interfering with all the wifis in range */ return 0; err_net: diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c index da9d06bdb818..efc9c4bd826f 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.c @@ -797,7 +797,7 @@ static int zd1211_hw_init_hmac(struct zd_chip *chip) { CR_ADDA_MBIAS_WARMTIME, 0x30000808 }, { CR_ZD1211_RETRY_MAX, 0x2 }, { CR_SNIFFER_ON, 0 }, - { CR_RX_FILTER, STA_RX_FILTER }, + { CR_RX_FILTER, AP_RX_FILTER }, { CR_GROUP_HASH_P1, 0x00 }, { CR_GROUP_HASH_P2, 0x80000000 }, { CR_REG1, 0xa4 }, @@ -844,7 +844,7 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip) { CR_ZD1211B_AIFS_CTL2, 0x008C003C }, { CR_ZD1211B_TXOP, 0x01800824 }, { CR_SNIFFER_ON, 0 }, - { CR_RX_FILTER, STA_RX_FILTER }, + { CR_RX_FILTER, AP_RX_FILTER }, { CR_GROUP_HASH_P1, 0x00 }, { CR_GROUP_HASH_P2, 0x80000000 }, { CR_REG1, 0xa4 }, diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h index 069d2b467339..805121093ab5 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/trunk/drivers/net/wireless/zd1211rw/zd_chip.h @@ -461,15 +461,10 @@ #define CR_RX_FILTER CTL_REG(0x068c) #define RX_FILTER_ASSOC_RESPONSE 0x0002 -#define RX_FILTER_REASSOC_RESPONSE 0x0008 #define RX_FILTER_PROBE_RESPONSE 0x0020 #define RX_FILTER_BEACON 0x0100 -#define RX_FILTER_DISASSOC 0x0400 #define RX_FILTER_AUTH 0x0800 -#define AP_RX_FILTER 0x0400feff -#define STA_RX_FILTER 0x0000ffff - -/* Monitor mode sets filter to 0xfffff */ +/* Sniff modus sets filter to 0xfffff */ #define CR_ACK_TIMEOUT_EXT CTL_REG(0x0690) #define CR_BCN_FIFO_SEMAPHORE CTL_REG(0x0694) @@ -551,6 +546,9 @@ #define CR_ZD1211B_TXOP CTL_REG(0x0b20) #define CR_ZD1211B_RETRY_MAX CTL_REG(0x0b28) +#define AP_RX_FILTER 0x0400feff +#define STA_RX_FILTER 0x0000ffff + #define CWIN_SIZE 0x007f043f diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c index d6f3e02a0b54..3bdc54d128d0 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_mac.c @@ -108,9 +108,7 @@ int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) if (r) goto disable_int; - /* We must inform the device that we are doing encryption/decryption in - * software at the moment. */ - r = zd_set_encryption_type(chip, ENC_SNIFFER); + r = zd_set_encryption_type(chip, NO_WEP); if (r) goto disable_int; @@ -138,8 +136,10 @@ static int reset_mode(struct zd_mac *mac) { struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); struct zd_ioreq32 ioreqs[3] = { - { CR_RX_FILTER, STA_RX_FILTER }, + { CR_RX_FILTER, RX_FILTER_BEACON|RX_FILTER_PROBE_RESPONSE| + RX_FILTER_AUTH|RX_FILTER_ASSOC_RESPONSE }, { CR_SNIFFER_ON, 0U }, + { CR_ENCRYPTION_TYPE, NO_WEP }, }; if (ieee->iw_mode == IW_MODE_MONITOR) { @@ -713,10 +713,10 @@ static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) struct zd_rt_hdr { struct ieee80211_radiotap_header rt_hdr; u8 rt_flags; - u8 rt_rate; u16 rt_channel; u16 rt_chbitmask; -} __attribute__((packed)); + u16 rt_rate; +}; static void fill_rt_header(void *buffer, struct zd_mac *mac, const struct ieee80211_rx_stats *stats, @@ -735,14 +735,14 @@ static void fill_rt_header(void *buffer, struct zd_mac *mac, if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; - hdr->rt_rate = stats->rate / 5; - /* FIXME: 802.11a */ hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( _zd_chip_get_channel(&mac->chip))); hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); + + hdr->rt_rate = stats->rate / 5; } /* Returns 1 if the data packet is for us and 0 otherwise. */ diff --git a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c index 6320984126c7..72f90525bf68 100644 --- a/trunk/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/trunk/drivers/net/wireless/zd1211rw/zd_usb.c @@ -323,6 +323,7 @@ static void disable_read_regs_int(struct zd_usb *usb) { struct zd_usb_interrupt *intr = &usb->intr; + ZD_ASSERT(in_interrupt()); spin_lock(&intr->lock); intr->read_regs_enabled = 0; spin_unlock(&intr->lock); @@ -544,11 +545,11 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, * be padded. Unaligned access might also happen if the length_info * structure is not present. */ - if (get_unaligned(&length_info->tag) == cpu_to_le16(RX_LENGTH_INFO_TAG)) - { + if (get_unaligned(&length_info->tag) == RX_LENGTH_INFO_TAG) { unsigned int l, k, n; for (i = 0, l = 0;; i++) { - k = le16_to_cpu(get_unaligned(&length_info->length[i])); + k = le16_to_cpu(get_unaligned( + &length_info->length[i])); n = l+k; if (n > length) return; diff --git a/trunk/drivers/pci/hotplug/acpiphp_core.c b/trunk/drivers/pci/hotplug/acpiphp_core.c index e2fef60c2d06..34de5697983d 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_core.c +++ b/trunk/drivers/pci/hotplug/acpiphp_core.c @@ -27,7 +27,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to , + * * */ diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index ae67a8f55ba1..ef95d12fb32c 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -26,7 +26,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Send feedback to + * Send feedback to * */ diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index 478d0d28f7ad..50bfc1b2f3bf 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -30,6 +30,23 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; +static int pcie_portdrv_save_config(struct pci_dev *dev) +{ + return pci_save_state(dev); +} + +static int pcie_portdrv_restore_config(struct pci_dev *dev) +{ + int retval; + + pci_restore_state(dev); + retval = pci_enable_device(dev); + if (retval) + return retval; + pci_set_master(dev); + return 0; +} + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -56,10 +73,8 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", __FUNCTION__, dev->device, dev->vendor); } - if (pcie_port_device_register(dev)) { - pci_disable_device(dev); + if (pcie_port_device_register(dev)) return -ENOMEM; - } return 0; } @@ -71,23 +86,6 @@ static void pcie_portdrv_remove (struct pci_dev *dev) } #ifdef CONFIG_PM -static int pcie_portdrv_save_config(struct pci_dev *dev) -{ - return pci_save_state(dev); -} - -static int pcie_portdrv_restore_config(struct pci_dev *dev) -{ - int retval; - - pci_restore_state(dev); - retval = pci_enable_device(dev); - if (retval) - return retval; - pci_set_master(dev); - return 0; -} - static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) { int ret = pcie_port_device_suspend(dev, state); diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index fb08bc951ac0..e3c78c39b7e4 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -990,11 +990,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) case 0x8070: /* P4G8X Deluxe */ asus_hides_smbus = 1; } - if (dev->device == PCI_DEVICE_ID_INTEL_E7501_MCH) - switch (dev->subsystem_device) { - case 0x80c9: /* PU-DLS */ - asus_hides_smbus = 1; - } if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) switch (dev->subsystem_device) { case 0x1751: /* M2N notebook */ @@ -1063,7 +1058,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_HB, asu DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82850_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_7205_0, asus_hides_smbus_hostbridge ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7501_MCH, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge ); @@ -1087,7 +1081,6 @@ static void __init asus_hides_smbus_lpc(struct pci_dev *dev) } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc ); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc ); diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index d529462d1b53..622b3f8ba820 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -41,7 +41,7 @@ pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) * in the global list of PCI buses. If the bus is found, a pointer to its * data structure is returned. If no bus is found, %NULL is returned. */ -struct pci_bus * pci_find_bus(int domain, int busnr) +struct pci_bus * __devinit pci_find_bus(int domain, int busnr) { struct pci_bus *bus = NULL; struct pci_bus *tmp_bus; @@ -61,7 +61,7 @@ struct pci_bus * pci_find_bus(int domain, int busnr) * @from: Previous PCI bus found, or %NULL for new search. * * Iterates through the list of known PCI busses. A new search is - * initiated by passing %NULL as the @from argument. Otherwise if + * initiated by passing %NULL to the @from argument. Otherwise if * @from is not %NULL, searches continue from next device on the * global list. */ @@ -148,14 +148,13 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) * @from: Previous PCI device found in search, or %NULL for new search. * * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor, @device, @ss_vendor and @ss_device, a - * pointer to its device structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. + * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its + * device structure is returned. Otherwise, %NULL is returned. + * A new search is initiated by passing %NULL to the @from argument. + * Otherwise if @from is not %NULL, searches continue from next device on the global list. * - * NOTE: Do not use this function any more; use pci_get_subsys() instead, as - * the PCI device returned by this function can disappear at any moment in + * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as + * the pci device returned by this function can disappear at any moment in * time. */ static struct pci_dev * pci_find_subsys(unsigned int vendor, @@ -192,15 +191,14 @@ static struct pci_dev * pci_find_subsys(unsigned int vendor, * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor and @device, a pointer to its device structure is + * Iterates through the list of known PCI devices. If a PCI device is + * found with a matching @vendor and @device, a pointer to its device structure is * returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device - * on the global list. + * A new search is initiated by passing %NULL to the @from argument. + * Otherwise if @from is not %NULL, searches continue from next device on the global list. * - * NOTE: Do not use this function any more; use pci_get_device() instead, as - * the PCI device returned by this function can disappear at any moment in + * NOTE: Do not use this function anymore, use pci_get_device() instead, as + * the pci device returned by this function can disappear at any moment in * time. */ struct pci_dev * @@ -217,11 +215,11 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev * * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices. If a PCI device is found - * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its + * Iterates through the list of known PCI devices. If a PCI device is + * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its * device structure is returned, and the reference count to the device is * incremented. Otherwise, %NULL is returned. A new search is initiated by - * passing %NULL as the @from argument. Otherwise if @from is not %NULL, + * passing %NULL to the @from argument. Otherwise if @from is not %NULL, * searches continue from next device on the global list. * The reference count for @from is always decremented if it is not %NULL. */ @@ -264,7 +262,7 @@ pci_get_subsys(unsigned int vendor, unsigned int device, * found with a matching @vendor and @device, the reference count to the * device is incremented and a pointer to its device structure is returned. * Otherwise, %NULL is returned. A new search is initiated by passing %NULL - * as the @from argument. Otherwise if @from is not %NULL, searches continue + * to the @from argument. Otherwise if @from is not %NULL, searches continue * from next device on the global list. The reference count for @from is * always decremented if it is not %NULL. */ @@ -281,13 +279,11 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices in the reverse order of - * pci_find_device(). + * Iterates through the list of known PCI devices in the reverse order of pci_find_device(). * If a PCI device is found with a matching @vendor and @device, a pointer to * its device structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. - * Otherwise if @from is not %NULL, searches continue from previous device - * on the global list. + * A new search is initiated by passing %NULL to the @from argument. + * Otherwise if @from is not %NULL, searches continue from previous device on the global list. */ struct pci_dev * pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) @@ -321,7 +317,7 @@ pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct p * found with a matching @class, the reference count to the device is * incremented and a pointer to its device structure is returned. * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL as the @from argument. + * A new search is initiated by passing %NULL to the @from argument. * Otherwise if @from is not %NULL, searches continue from next device * on the global list. The reference count for @from is always decremented * if it is not %NULL. diff --git a/trunk/drivers/pcmcia/pcmcia_ioctl.c b/trunk/drivers/pcmcia/pcmcia_ioctl.c index 9ad18e62658d..738b1ef595a3 100644 --- a/trunk/drivers/pcmcia/pcmcia_ioctl.c +++ b/trunk/drivers/pcmcia/pcmcia_ioctl.c @@ -601,8 +601,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); - ret = pccard_get_configuration_info(s, p_dev, &buf->config); - pcmcia_put_dev(p_dev); + if (p_dev == NULL) + ret = CS_BAD_ARGS; + else { + ret = pccard_get_configuration_info(s, p_dev, &buf->config); + pcmcia_put_dev(p_dev); + } } break; case DS_GET_FIRST_TUPLE: @@ -632,8 +636,12 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); - ret = pccard_get_status(s, p_dev, &buf->status); - pcmcia_put_dev(p_dev); + if (p_dev == NULL) + ret = CS_BAD_ARGS; + else { + ret = pccard_get_status(s, p_dev, &buf->status); + pcmcia_put_dev(p_dev); + } } break; case DS_VALIDATE_CIS: diff --git a/trunk/drivers/pcmcia/pcmcia_resource.c b/trunk/drivers/pcmcia/pcmcia_resource.c index c8323399e9e4..7bf25b88ea31 100644 --- a/trunk/drivers/pcmcia/pcmcia_resource.c +++ b/trunk/drivers/pcmcia/pcmcia_resource.c @@ -245,17 +245,10 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, return CS_SUCCESS; } - config->Attributes = c->Attributes | CONF_VALID_CLIENT; - config->Vcc = s->socket.Vcc; - config->Vpp1 = config->Vpp2 = s->socket.Vpp; - config->IntType = c->IntType; - config->ConfigBase = c->ConfigBase; - config->Status = c->Status; - config->Pin = c->Pin; - config->Copy = c->Copy; - config->Option = c->Option; - config->ExtStatus = c->ExtStatus; - config->Present = config->CardValues = c->CardValues; + /* !!! This is a hack !!! */ + memcpy(&config->Attributes, &c->Attributes, sizeof(config_t)); + config->Attributes |= CONF_VALID_CLIENT; + config->CardValues = c->CardValues; config->IRQAttributes = c->irq.Attributes; config->AssignedIRQ = s->irq.AssignedIRQ; config->BasePort1 = c->io.BasePort1; diff --git a/trunk/drivers/pnp/interface.c b/trunk/drivers/pnp/interface.c index 9d8b415eca79..3163e3d73da1 100644 --- a/trunk/drivers/pnp/interface.c +++ b/trunk/drivers/pnp/interface.c @@ -265,8 +265,8 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," 0x%llx-0x%llx\n", - (unsigned long long)pnp_port_start(dev, i), - (unsigned long long)pnp_port_end(dev, i)); + pnp_port_start(dev, i), + pnp_port_end(dev, i)); } } for (i = 0; i < PNP_MAX_MEM; i++) { @@ -276,8 +276,8 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," 0x%llx-0x%llx\n", - (unsigned long long)pnp_mem_start(dev, i), - (unsigned long long)pnp_mem_end(dev, i)); + pnp_mem_start(dev, i), + pnp_mem_end(dev, i)); } } for (i = 0; i < PNP_MAX_IRQ; i++) { @@ -287,7 +287,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," %lld\n", - (unsigned long long)pnp_irq(dev, i)); + pnp_irq(dev, i)); } } for (i = 0; i < PNP_MAX_DMA; i++) { @@ -297,7 +297,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at pnp_printf(buffer," disabled\n"); else pnp_printf(buffer," %lld\n", - (unsigned long long)pnp_dma(dev, i)); + pnp_dma(dev, i)); } } ret = (buffer->curr - buf); diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index dc79b0a0059f..212268881857 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -173,9 +173,6 @@ pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res_table, return; } - if (p->producer_consumer == ACPI_PRODUCER) - return; - if (p->resource_type == ACPI_MEMORY_RANGE) pnpacpi_parse_allocated_memresource(res_table, p->minimum, p->address_length); @@ -255,14 +252,9 @@ static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: - if (res->data.ext_address64.producer_consumer == ACPI_PRODUCER) - return AE_OK; break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: - if (res->data.extended_irq.producer_consumer == ACPI_PRODUCER) - return AE_OK; - for (i = 0; i < res->data.extended_irq.interrupt_count; i++) { pnpacpi_parse_allocated_irqresource(res_table, res->data.extended_irq.interrupts[i], diff --git a/trunk/drivers/pnp/pnpbios/core.c b/trunk/drivers/pnp/pnpbios/core.c index 551f58e29810..b154b3f52cbe 100644 --- a/trunk/drivers/pnp/pnpbios/core.c +++ b/trunk/drivers/pnp/pnpbios/core.c @@ -346,7 +346,7 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node) dev->flags = node->flags; if (!(dev->flags & PNPBIOS_NO_CONFIG)) dev->capabilities |= PNP_CONFIGURABLE; - if (!(dev->flags & PNPBIOS_NO_DISABLE) && pnpbios_is_dynamic(dev)) + if (!(dev->flags & PNPBIOS_NO_DISABLE)) dev->capabilities |= PNP_DISABLE; dev->capabilities |= PNP_READ; if (pnpbios_is_dynamic(dev)) diff --git a/trunk/drivers/s390/block/xpram.c b/trunk/drivers/s390/block/xpram.c index 1140302ff11d..4cd879cb9bdd 100644 --- a/trunk/drivers/s390/block/xpram.c +++ b/trunk/drivers/s390/block/xpram.c @@ -304,7 +304,6 @@ static int __init xpram_setup_sizes(unsigned long pages) { unsigned long mem_needed; unsigned long mem_auto; - unsigned long long size; int mem_auto_no; int i; @@ -322,19 +321,9 @@ static int __init xpram_setup_sizes(unsigned long pages) mem_needed = 0; mem_auto_no = 0; for (i = 0; i < xpram_devs; i++) { - if (sizes[i]) { - size = simple_strtoull(sizes[i], &sizes[i], 0); - switch (sizes[i][0]) { - case 'g': - case 'G': - size <<= 20; - break; - case 'm': - case 'M': - size <<= 10; - } - xpram_sizes[i] = (size + 3) & -4UL; - } + if (sizes[i]) + xpram_sizes[i] = + (memparse(sizes[i], &sizes[i]) + 3) & -4UL; if (xpram_sizes[i]) mem_needed += xpram_sizes[i]; else diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index 7a84014f2037..95e285b2e25c 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -1106,10 +1106,10 @@ raw3270_delete_device(struct raw3270 *rp) /* Remove from device chain. */ mutex_lock(&raw3270_mutex); - if (rp->clttydev && !IS_ERR(rp->clttydev)) + if (rp->clttydev) class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); - if (rp->cltubdev && !IS_ERR(rp->cltubdev)) + if (rp->cltubdev) class_device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, rp->minor)); list_del_init(&rp->list); @@ -1173,37 +1173,21 @@ static struct attribute_group raw3270_attr_group = { .attrs = raw3270_attrs, }; -static int raw3270_create_attributes(struct raw3270 *rp) +static void +raw3270_create_attributes(struct raw3270 *rp) { - int rc; - - rc = sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); - if (rc) - goto out; - - rp->clttydev = class_device_create(class3270, NULL, - MKDEV(IBM_TTY3270_MAJOR, rp->minor), - &rp->cdev->dev, "tty%s", - rp->cdev->dev.bus_id); - if (IS_ERR(rp->clttydev)) { - rc = PTR_ERR(rp->clttydev); - goto out_ttydev; - } - - rp->cltubdev = class_device_create(class3270, NULL, - MKDEV(IBM_FS3270_MAJOR, rp->minor), - &rp->cdev->dev, "tub%s", - rp->cdev->dev.bus_id); - if (!IS_ERR(rp->cltubdev)) - goto out; - - rc = PTR_ERR(rp->cltubdev); - class_device_destroy(class3270, MKDEV(IBM_TTY3270_MAJOR, rp->minor)); - -out_ttydev: - sysfs_remove_group(&rp->cdev->dev.kobj, &raw3270_attr_group); -out: - return rc; + //FIXME: check return code + sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group); + rp->clttydev = + class_device_create(class3270, NULL, + MKDEV(IBM_TTY3270_MAJOR, rp->minor), + &rp->cdev->dev, "tty%s", + rp->cdev->dev.bus_id); + rp->cltubdev = + class_device_create(class3270, NULL, + MKDEV(IBM_FS3270_MAJOR, rp->minor), + &rp->cdev->dev, "tub%s", + rp->cdev->dev.bus_id); } /* @@ -1271,9 +1255,7 @@ raw3270_set_online (struct ccw_device *cdev) rc = raw3270_reset_device(rp); if (rc) goto failure; - rc = raw3270_create_attributes(rp); - if (rc) - goto failure; + raw3270_create_attributes(rp); set_bit(RAW3270_FLAGS_READY, &rp->flags); mutex_lock(&raw3270_mutex); list_for_each_entry(np, &raw3270_notifier, list) diff --git a/trunk/drivers/s390/char/tape_class.c b/trunk/drivers/s390/char/tape_class.c index 643b6d078563..a5c68e60fcf4 100644 --- a/trunk/drivers/s390/char/tape_class.c +++ b/trunk/drivers/s390/char/tape_class.c @@ -76,22 +76,14 @@ struct tape_class_device *register_tape_dev( device, "%s", tcd->device_name ); - rc = PTR_ERR(tcd->class_device); - if (rc) - goto fail_with_cdev; - rc = sysfs_create_link( + sysfs_create_link( &device->kobj, &tcd->class_device->kobj, tcd->mode_name ); - if (rc) - goto fail_with_class_device; return tcd; -fail_with_class_device: - class_device_destroy(tape_class, tcd->char_device->dev); - fail_with_cdev: cdev_del(tcd->char_device); diff --git a/trunk/drivers/s390/char/tape_core.c b/trunk/drivers/s390/char/tape_core.c index 2826aed91043..122b4d8965c3 100644 --- a/trunk/drivers/s390/char/tape_core.c +++ b/trunk/drivers/s390/char/tape_core.c @@ -543,24 +543,20 @@ int tape_generic_probe(struct ccw_device *cdev) { struct tape_device *device; - int ret; device = tape_alloc_device(); if (IS_ERR(device)) return -ENODEV; - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); - ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); - if (ret) { - tape_put_device(device); - PRINT_ERR("probe failed for tape device %s\n", cdev->dev.bus_id); - return ret; - } + PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); cdev->dev.driver_data = device; - cdev->handler = __tape_do_irq; device->cdev = cdev; device->cdev_id = busid_to_int(cdev->dev.bus_id); - PRINT_INFO("tape device %s found\n", cdev->dev.bus_id); - return ret; + cdev->handler = __tape_do_irq; + + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); + + return 0; } static inline void diff --git a/trunk/drivers/s390/cio/ccwgroup.c b/trunk/drivers/s390/cio/ccwgroup.c index 3cba6c9fab11..f26a2ee3aad8 100644 --- a/trunk/drivers/s390/cio/ccwgroup.c +++ b/trunk/drivers/s390/cio/ccwgroup.c @@ -152,6 +152,7 @@ ccwgroup_create(struct device *root, struct ccwgroup_device *gdev; int i; int rc; + int del_drvdata; if (argc > 256) /* disallow dumb users */ return -EINVAL; @@ -162,6 +163,7 @@ ccwgroup_create(struct device *root, atomic_set(&gdev->onoff, 0); + del_drvdata = 0; for (i = 0; i < argc; i++) { gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); @@ -178,8 +180,10 @@ ccwgroup_create(struct device *root, rc = -EINVAL; goto free_dev; } - gdev->cdev[i]->dev.driver_data = gdev; } + for (i = 0; i < argc; i++) + gdev->cdev[i]->dev.driver_data = gdev; + del_drvdata = 1; gdev->creator_id = creator_id; gdev->count = argc; @@ -222,9 +226,9 @@ ccwgroup_create(struct device *root, free_dev: for (i = 0; i < argc; i++) if (gdev->cdev[i]) { - if (gdev->cdev[i]->dev.driver_data == gdev) - gdev->cdev[i]->dev.driver_data = NULL; put_device(&gdev->cdev[i]->dev); + if (del_drvdata) + gdev->cdev[i]->dev.driver_data = NULL; } kfree(gdev); return rc; diff --git a/trunk/drivers/s390/cio/cmf.c b/trunk/drivers/s390/cio/cmf.c index 828b2d334f0a..0df3af1f08de 100644 --- a/trunk/drivers/s390/cio/cmf.c +++ b/trunk/drivers/s390/cio/cmf.c @@ -1068,7 +1068,6 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, if (count) { interval = cmb_data->last_update - cdev->private->cmb_start_time; - interval = (interval * 1000) >> 12; interval /= count; } else interval = -1; diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index 7a39e0b0386c..ac6e0c7e43d9 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -152,8 +152,7 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) if (cdev->private->iretry) { cdev->private->iretry--; ret = cio_halt(sch); - if (ret != -EBUSY) - return (ret == 0) ? -EBUSY : ret; + return (ret == 0) ? -EBUSY : ret; } /* halt io unsuccessful. */ cdev->private->iretry = 255; /* 255 clear retries. */ diff --git a/trunk/drivers/s390/net/ctcmain.c b/trunk/drivers/s390/net/ctcmain.c index 8a4b58120146..20c8eb16f464 100644 --- a/trunk/drivers/s390/net/ctcmain.c +++ b/trunk/drivers/s390/net/ctcmain.c @@ -2686,17 +2686,9 @@ static struct attribute_group ctc_attr_group = { static int ctc_add_attributes(struct device *dev) { - int rc; - - rc = device_create_file(dev, &dev_attr_loglevel); - if (rc) - goto out; - rc = device_create_file(dev, &dev_attr_stats); - if (!rc) - goto out; - device_remove_file(dev, &dev_attr_loglevel); -out: - return rc; + device_create_file(dev, &dev_attr_loglevel); + device_create_file(dev, &dev_attr_stats); + return 0; } static void @@ -2909,12 +2901,7 @@ ctc_new_device(struct ccwgroup_device *cgdev) goto out; } - if (ctc_add_attributes(&cgdev->dev)) { - ctc_netdev_unregister(dev); - dev->priv = NULL; - ctc_free_netdevice(dev, 1); - goto out; - } + ctc_add_attributes(&cgdev->dev); strlcpy(privptr->fsm->name, dev->name, sizeof (privptr->fsm->name)); diff --git a/trunk/drivers/s390/net/qeth_main.c b/trunk/drivers/s390/net/qeth_main.c index 5fff1f93973a..103c41470bd2 100644 --- a/trunk/drivers/s390/net/qeth_main.c +++ b/trunk/drivers/s390/net/qeth_main.c @@ -8451,11 +8451,10 @@ __qeth_reboot_event_card(struct device *dev, void *data) static int qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) { - int ret; - ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, - __qeth_reboot_event_card); - return ret ? NOTIFY_BAD : NOTIFY_DONE; + driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, + __qeth_reboot_event_card); + return NOTIFY_DONE; } diff --git a/trunk/drivers/sbus/sbus.c b/trunk/drivers/sbus/sbus.c index 935952ef88f1..16b59773c0bb 100644 --- a/trunk/drivers/sbus/sbus.c +++ b/trunk/drivers/sbus/sbus.c @@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus) sbus->ofdev.node = dp; sbus->ofdev.dev.parent = NULL; sbus->ofdev.dev.bus = &sbus_bus_type; - sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus); + strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name); if (of_device_register(&sbus->ofdev) != 0) printk(KERN_DEBUG "sbus: device registration error for %s!\n", diff --git a/trunk/drivers/scsi/53c7xx.c b/trunk/drivers/scsi/53c7xx.c index acf292736b4e..c690c2b89e41 100644 --- a/trunk/drivers/scsi/53c7xx.c +++ b/trunk/drivers/scsi/53c7xx.c @@ -3451,12 +3451,12 @@ create_cmd (Scsi_Cmnd *cmd) { for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; cmd_datain += 4, cmd_dataout += 4, ++i) { u32 vbuf = cmd->use_sg - ? (u32)page_address(((struct scatterlist *)cmd->request_buffer)[i].page)+ - ((struct scatterlist *)cmd->request_buffer)[i].offset + ? (u32)page_address(((struct scatterlist *)cmd->buffer)[i].page)+ + ((struct scatterlist *)cmd->buffer)[i].offset : (u32)(cmd->request_buffer); u32 bbuf = virt_to_bus((void *)vbuf); u32 count = cmd->use_sg ? - ((struct scatterlist *)cmd->request_buffer)[i].length : + ((struct scatterlist *)cmd->buffer)[i].length : cmd->request_bufflen; /* @@ -5417,7 +5417,7 @@ insn_to_offset (Scsi_Cmnd *cmd, u32 *insn) { if ((buffers = cmd->use_sg)) { for (offset = 0, - segment = (struct scatterlist *) cmd->request_buffer; + segment = (struct scatterlist *) cmd->buffer; buffers && !((found = ((ptr >= (char *)page_address(segment->page)+segment->offset) && (ptr < ((char *)page_address(segment->page)+segment->offset+segment->length))))); --buffers, offset += segment->length, ++segment) diff --git a/trunk/drivers/scsi/NCR53C9x.c b/trunk/drivers/scsi/NCR53C9x.c index bdc6bb262bce..8a4659e94105 100644 --- a/trunk/drivers/scsi/NCR53C9x.c +++ b/trunk/drivers/scsi/NCR53C9x.c @@ -911,7 +911,7 @@ static void esp_get_dmabufs(struct NCR_ESP *esp, Scsi_Cmnd *sp) sp->SCp.ptr = (char *) virt_to_phys(sp->request_buffer); } else { - sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; + sp->SCp.buffer = (struct scatterlist *) sp->buffer; sp->SCp.buffers_residual = sp->use_sg - 1; sp->SCp.this_residual = sp->SCp.buffer->length; if (esp->dma_mmu_get_scsi_sgl) @@ -2152,23 +2152,29 @@ static int esp_do_data_finale(struct NCR_ESP *esp, */ static int esp_should_clear_sync(Scsi_Cmnd *sp) { - unchar cmd = sp->cmnd[0]; + unchar cmd1 = sp->cmnd[0]; + unchar cmd2 = sp->data_cmnd[0]; /* These cases are for spinning up a disk and * waiting for that spinup to complete. */ - if(cmd == START_STOP) + if(cmd1 == START_STOP || + cmd2 == START_STOP) return 0; - if(cmd == TEST_UNIT_READY) + if(cmd1 == TEST_UNIT_READY || + cmd2 == TEST_UNIT_READY) return 0; /* One more special case for SCSI tape drives, * this is what is used to probe the device for * completion of a rewind or tape load operation. */ - if(sp->device->type == TYPE_TAPE && cmd == MODE_SENSE) - return 0; + if(sp->device->type == TYPE_TAPE) { + if(cmd1 == MODE_SENSE || + cmd2 == MODE_SENSE) + return 0; + } return 1; } diff --git a/trunk/drivers/scsi/NCR_D700.c b/trunk/drivers/scsi/NCR_D700.c index d05681f9d81a..a06f547e87f7 100644 --- a/trunk/drivers/scsi/NCR_D700.c +++ b/trunk/drivers/scsi/NCR_D700.c @@ -114,7 +114,7 @@ MODULE_DESCRIPTION("NCR Dual700 SCSI Driver"); MODULE_LICENSE("GPL"); module_param(NCR_D700, charp, 0); -static __u8 __devinitdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = +static __u8 __initdata id_array[2*(MCA_MAX_SLOT_NR + 1)] = { [0 ... 2*(MCA_MAX_SLOT_NR + 1)-1] = 7 }; #ifdef MODULE @@ -173,7 +173,7 @@ struct NCR_D700_private { char pad; }; -static int __devinit +static int NCR_D700_probe_one(struct NCR_D700_private *p, int siop, int irq, int slot, u32 region, int differential) { @@ -243,7 +243,7 @@ NCR_D700_intr(int irq, void *data, struct pt_regs *regs) * essentially connectecd to the MCA bus independently, it is easier * to set them up as two separate host adapters, rather than one * adapter with two channels */ -static int __devinit +static int NCR_D700_probe(struct device *dev) { struct NCR_D700_private *p; @@ -329,7 +329,7 @@ NCR_D700_probe(struct device *dev) for (i = 0; i < 2; i++) { int err; - if ((err = NCR_D700_probe_one(p, i, irq, slot, + if ((err = NCR_D700_probe_one(p, i, slot, irq, offset_addr + (0x80 * i), differential)) != 0) printk("D700: SIOP%d: probe failed, error = %d\n", @@ -349,7 +349,7 @@ NCR_D700_probe(struct device *dev) return 0; } -static void __devexit +static void NCR_D700_remove_one(struct Scsi_Host *host) { scsi_remove_host(host); @@ -359,7 +359,7 @@ NCR_D700_remove_one(struct Scsi_Host *host) release_region(host->base, 64); } -static int __devexit +static int NCR_D700_remove(struct device *dev) { struct NCR_D700_private *p = dev_get_drvdata(dev); @@ -380,7 +380,7 @@ static struct mca_driver NCR_D700_driver = { .name = "NCR_D700", .bus = &mca_bus_type, .probe = NCR_D700_probe, - .remove = __devexit_p(NCR_D700_remove), + .remove = NCR_D700_remove, }, }; diff --git a/trunk/drivers/scsi/aha152x.c b/trunk/drivers/scsi/aha152x.c index f974869ea323..36e63f82d9f8 100644 --- a/trunk/drivers/scsi/aha152x.c +++ b/trunk/drivers/scsi/aha152x.c @@ -551,11 +551,6 @@ struct aha152x_hostdata { struct aha152x_scdata { Scsi_Cmnd *next; /* next sc in queue */ struct semaphore *sem; /* semaphore to block on */ - unsigned char cmd_len; - unsigned char cmnd[MAX_COMMAND_SIZE]; - unsigned short use_sg; - unsigned request_bufflen; - void *request_buffer; }; @@ -1011,20 +1006,11 @@ static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int p return FAILED; } } else { - struct aha152x_scdata *sc; - SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC); if(SCpnt->host_scribble==0) { printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt)); return FAILED; } - - sc = SCDATA(SCpnt); - memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd)); - sc->request_buffer = SCpnt->request_buffer; - sc->request_bufflen = SCpnt->request_bufflen; - sc->use_sg = SCpnt->use_sg; - sc->cmd_len = SCpnt->cmd_len; } SCNEXT(SCpnt) = NULL; @@ -1179,10 +1165,6 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) DECLARE_MUTEX_LOCKED(sem); struct timer_list timer; int ret, issued, disconnected; - unsigned char old_cmd_len = SCpnt->cmd_len; - unsigned short old_use_sg = SCpnt->use_sg; - void *old_buffer = SCpnt->request_buffer; - unsigned old_bufflen = SCpnt->request_bufflen; unsigned long flags; #if defined(AHA152X_DEBUG) @@ -1216,11 +1198,11 @@ static int aha152x_device_reset(Scsi_Cmnd * SCpnt) add_timer(&timer); down(&sem); del_timer(&timer); - - SCpnt->cmd_len = old_cmd_len; - SCpnt->use_sg = old_use_sg; - SCpnt->request_buffer = old_buffer; - SCpnt->request_bufflen = old_bufflen; + + SCpnt->cmd_len = SCpnt->old_cmd_len; + SCpnt->use_sg = SCpnt->old_use_sg; + SCpnt->request_buffer = SCpnt->buffer; + SCpnt->request_bufflen = SCpnt->bufflen; DO_LOCK(flags); @@ -1583,9 +1565,6 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif if(DONE_SC->SCp.phase & check_condition) { - struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC; - struct aha152x_scdata *sc = SCDATA(cmd); - #if 0 if(HOSTDATA(shpnt)->debug & debug_eh) { printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC)); @@ -1594,13 +1573,13 @@ static void busfree_run(struct Scsi_Host *shpnt) #endif /* restore old command */ - memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd)); - cmd->request_buffer = sc->request_buffer; - cmd->request_bufflen = sc->request_bufflen; - cmd->use_sg = sc->use_sg; - cmd->cmd_len = sc->cmd_len; + memcpy((void *) DONE_SC->cmnd, (void *) DONE_SC->data_cmnd, sizeof(DONE_SC->data_cmnd)); + DONE_SC->request_buffer = DONE_SC->buffer; + DONE_SC->request_bufflen = DONE_SC->bufflen; + DONE_SC->use_sg = DONE_SC->old_use_sg; + DONE_SC->cmd_len = DONE_SC->old_cmd_len; - cmd->SCp.Status = 0x02; + DONE_SC->SCp.Status = 0x02; HOSTDATA(shpnt)->commands--; if (!HOSTDATA(shpnt)->commands) diff --git a/trunk/drivers/scsi/ahci.c b/trunk/drivers/scsi/ahci.c index 68fd7667a082..77e7202a0eba 100644 --- a/trunk/drivers/scsi/ahci.c +++ b/trunk/drivers/scsi/ahci.c @@ -92,9 +92,7 @@ enum { HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ - HOST_CAP_SSC = (1 << 14), /* Slumber capable */ HOST_CAP_CLO = (1 << 24), /* Command List Override support */ - HOST_CAP_SSS = (1 << 27), /* Staggered Spin-up */ HOST_CAP_NCQ = (1 << 30), /* Native Command Queueing */ HOST_CAP_64 = (1 << 31), /* PCI DAC (64-bit DMA) support */ @@ -157,7 +155,6 @@ enum { PORT_CMD_SPIN_UP = (1 << 1), /* Spin up device */ PORT_CMD_START = (1 << 0), /* Enable port DMA engine */ - PORT_CMD_ICC_MASK = (0xf << 28), /* i/f ICC state mask */ PORT_CMD_ICC_ACTIVE = (0x1 << 28), /* Put i/f in active state */ PORT_CMD_ICC_PARTIAL = (0x2 << 28), /* Put i/f in partial state */ PORT_CMD_ICC_SLUMBER = (0x6 << 28), /* Put i/f in slumber state */ @@ -215,10 +212,6 @@ static void ahci_freeze(struct ata_port *ap); static void ahci_thaw(struct ata_port *ap); static void ahci_error_handler(struct ata_port *ap); static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); -static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); -static int ahci_port_resume(struct ata_port *ap); -static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -static int ahci_pci_device_resume(struct pci_dev *pdev); static void ahci_remove_one (struct pci_dev *pdev); static struct scsi_host_template ahci_sht = { @@ -238,8 +231,6 @@ static struct scsi_host_template ahci_sht = { .slave_configure = ata_scsi_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, }; static const struct ata_port_operations ahci_ops = { @@ -266,9 +257,6 @@ static const struct ata_port_operations ahci_ops = { .error_handler = ahci_error_handler, .post_internal_cmd = ahci_post_internal_cmd, - .port_suspend = ahci_port_suspend, - .port_resume = ahci_port_resume, - .port_start = ahci_port_start, .port_stop = ahci_port_stop, }; @@ -362,14 +350,6 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, 0x044f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_ahci }, /* MCP65 */ - /* SiS */ - { PCI_VENDOR_ID_SI, 0x1184, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* SiS 966 */ - { PCI_VENDOR_ID_SI, 0x1185, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* SiS 966 */ - { PCI_VENDOR_ID_SI, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, - board_ahci }, /* SiS 968 */ - { } /* terminate list */ }; @@ -378,8 +358,6 @@ static struct pci_driver ahci_pci_driver = { .name = DRV_NAME, .id_table = ahci_pci_tbl, .probe = ahci_init_one, - .suspend = ahci_pci_device_suspend, - .resume = ahci_pci_device_resume, .remove = ahci_remove_one, }; @@ -394,288 +372,177 @@ static inline void __iomem *ahci_port_base (void __iomem *base, unsigned int por return (void __iomem *) ahci_port_base_ul((unsigned long)base, port); } -static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) +static int ahci_port_start(struct ata_port *ap) { - unsigned int sc_reg; - - switch (sc_reg_in) { - case SCR_STATUS: sc_reg = 0; break; - case SCR_CONTROL: sc_reg = 1; break; - case SCR_ERROR: sc_reg = 2; break; - case SCR_ACTIVE: sc_reg = 3; break; - default: - return 0xffffffffU; - } - - return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); -} + struct device *dev = ap->host_set->dev; + struct ahci_host_priv *hpriv = ap->host_set->private_data; + struct ahci_port_priv *pp; + void __iomem *mmio = ap->host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + void *mem; + dma_addr_t mem_dma; + int rc; + pp = kmalloc(sizeof(*pp), GFP_KERNEL); + if (!pp) + return -ENOMEM; + memset(pp, 0, sizeof(*pp)); -static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, - u32 val) -{ - unsigned int sc_reg; + rc = ata_pad_alloc(ap, dev); + if (rc) { + kfree(pp); + return rc; + } - switch (sc_reg_in) { - case SCR_STATUS: sc_reg = 0; break; - case SCR_CONTROL: sc_reg = 1; break; - case SCR_ERROR: sc_reg = 2; break; - case SCR_ACTIVE: sc_reg = 3; break; - default: - return; + mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); + if (!mem) { + ata_pad_free(ap, dev); + kfree(pp); + return -ENOMEM; } + memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); - writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); -} + /* + * First item in chunk of DMA memory: 32-slot command table, + * 32 bytes each in size + */ + pp->cmd_slot = mem; + pp->cmd_slot_dma = mem_dma; -static void ahci_start_engine(void __iomem *port_mmio) -{ - u32 tmp; + mem += AHCI_CMD_SLOT_SZ; + mem_dma += AHCI_CMD_SLOT_SZ; - /* start DMA */ - tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); - readl(port_mmio + PORT_CMD); /* flush */ -} + /* + * Second item: Received-FIS area + */ + pp->rx_fis = mem; + pp->rx_fis_dma = mem_dma; -static int ahci_stop_engine(void __iomem *port_mmio) -{ - u32 tmp; + mem += AHCI_RX_FIS_SZ; + mem_dma += AHCI_RX_FIS_SZ; - tmp = readl(port_mmio + PORT_CMD); + /* + * Third item: data area for storing a single command + * and its scatter-gather table + */ + pp->cmd_tbl = mem; + pp->cmd_tbl_dma = mem_dma; - /* check if the HBA is idle */ - if ((tmp & (PORT_CMD_START | PORT_CMD_LIST_ON)) == 0) - return 0; + ap->private_data = pp; - /* setting HBA to idle */ - tmp &= ~PORT_CMD_START; - writel(tmp, port_mmio + PORT_CMD); + if (hpriv->cap & HOST_CAP_64) + writel((pp->cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); + writel(pp->cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); + readl(port_mmio + PORT_LST_ADDR); /* flush */ - /* wait for engine to stop. This could be as long as 500 msec */ - tmp = ata_wait_register(port_mmio + PORT_CMD, - PORT_CMD_LIST_ON, PORT_CMD_LIST_ON, 1, 500); - if (tmp & PORT_CMD_LIST_ON) - return -EIO; + if (hpriv->cap & HOST_CAP_64) + writel((pp->rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); + writel(pp->rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); + readl(port_mmio + PORT_FIS_ADDR); /* flush */ + + writel(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | + PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | + PORT_CMD_START, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ return 0; } -static void ahci_start_fis_rx(void __iomem *port_mmio, u32 cap, - dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) -{ - u32 tmp; - - /* set FIS registers */ - if (cap & HOST_CAP_64) - writel((cmd_slot_dma >> 16) >> 16, port_mmio + PORT_LST_ADDR_HI); - writel(cmd_slot_dma & 0xffffffff, port_mmio + PORT_LST_ADDR); - if (cap & HOST_CAP_64) - writel((rx_fis_dma >> 16) >> 16, port_mmio + PORT_FIS_ADDR_HI); - writel(rx_fis_dma & 0xffffffff, port_mmio + PORT_FIS_ADDR); - - /* enable FIS reception */ - tmp = readl(port_mmio + PORT_CMD); - tmp |= PORT_CMD_FIS_RX; - writel(tmp, port_mmio + PORT_CMD); - - /* flush */ - readl(port_mmio + PORT_CMD); -} - -static int ahci_stop_fis_rx(void __iomem *port_mmio) +static void ahci_port_stop(struct ata_port *ap) { + struct device *dev = ap->host_set->dev; + struct ahci_port_priv *pp = ap->private_data; + void __iomem *mmio = ap->host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); u32 tmp; - /* disable FIS reception */ tmp = readl(port_mmio + PORT_CMD); - tmp &= ~PORT_CMD_FIS_RX; + tmp &= ~(PORT_CMD_START | PORT_CMD_FIS_RX); writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ - /* wait for completion, spec says 500ms, give it 1000 */ - tmp = ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_FIS_ON, - PORT_CMD_FIS_ON, 10, 1000); - if (tmp & PORT_CMD_FIS_ON) - return -EBUSY; - - return 0; -} - -static void ahci_power_up(void __iomem *port_mmio, u32 cap) -{ - u32 cmd; - - cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; - - /* spin up device */ - if (cap & HOST_CAP_SSS) { - cmd |= PORT_CMD_SPIN_UP; - writel(cmd, port_mmio + PORT_CMD); - } + /* spec says 500 msecs for each PORT_CMD_{START,FIS_RX} bit, so + * this is slightly incorrect. + */ + msleep(500); - /* wake up link */ - writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD); + ap->private_data = NULL; + dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, + pp->cmd_slot, pp->cmd_slot_dma); + ata_pad_free(ap, dev); + kfree(pp); } -static void ahci_power_down(void __iomem *port_mmio, u32 cap) +static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) { - u32 cmd, scontrol; - - cmd = readl(port_mmio + PORT_CMD) & ~PORT_CMD_ICC_MASK; - - if (cap & HOST_CAP_SSC) { - /* enable transitions to slumber mode */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - if ((scontrol & 0x0f00) > 0x100) { - scontrol &= ~0xf00; - writel(scontrol, port_mmio + PORT_SCR_CTL); - } - - /* put device into slumber mode */ - writel(cmd | PORT_CMD_ICC_SLUMBER, port_mmio + PORT_CMD); + unsigned int sc_reg; - /* wait for the transition to complete */ - ata_wait_register(port_mmio + PORT_CMD, PORT_CMD_ICC_SLUMBER, - PORT_CMD_ICC_SLUMBER, 1, 50); + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return 0xffffffffU; } - /* put device into listen mode */ - if (cap & HOST_CAP_SSS) { - /* first set PxSCTL.DET to 0 */ - scontrol = readl(port_mmio + PORT_SCR_CTL); - scontrol &= ~0xf; - writel(scontrol, port_mmio + PORT_SCR_CTL); - - /* then set PxCMD.SUD to 0 */ - cmd &= ~PORT_CMD_SPIN_UP; - writel(cmd, port_mmio + PORT_CMD); - } + return readl((void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); } -static void ahci_init_port(void __iomem *port_mmio, u32 cap, - dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) -{ - /* power up */ - ahci_power_up(port_mmio, cap); - - /* enable FIS reception */ - ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); - /* enable DMA */ - ahci_start_engine(port_mmio); -} - -static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg) +static void ahci_scr_write (struct ata_port *ap, unsigned int sc_reg_in, + u32 val) { - int rc; - - /* disable DMA */ - rc = ahci_stop_engine(port_mmio); - if (rc) { - *emsg = "failed to stop engine"; - return rc; - } + unsigned int sc_reg; - /* disable FIS reception */ - rc = ahci_stop_fis_rx(port_mmio); - if (rc) { - *emsg = "failed stop FIS RX"; - return rc; + switch (sc_reg_in) { + case SCR_STATUS: sc_reg = 0; break; + case SCR_CONTROL: sc_reg = 1; break; + case SCR_ERROR: sc_reg = 2; break; + case SCR_ACTIVE: sc_reg = 3; break; + default: + return; } - /* put device into slumber mode */ - ahci_power_down(port_mmio, cap); - - return 0; + writel(val, (void __iomem *) ap->ioaddr.scr_addr + (sc_reg * 4)); } -static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) +static int ahci_stop_engine(struct ata_port *ap) { - u32 cap_save, tmp; - - cap_save = readl(mmio + HOST_CAP); - cap_save &= ( (1<<28) | (1<<17) ); - cap_save |= (1 << 27); + void __iomem *mmio = ap->host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); + int work; + u32 tmp; - /* global controller reset */ - tmp = readl(mmio + HOST_CTL); - if ((tmp & HOST_RESET) == 0) { - writel(tmp | HOST_RESET, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ - } + tmp = readl(port_mmio + PORT_CMD); + tmp &= ~PORT_CMD_START; + writel(tmp, port_mmio + PORT_CMD); - /* reset must complete within 1 second, or - * the hardware should be considered fried. + /* wait for engine to stop. TODO: this could be + * as long as 500 msec */ - ssleep(1); - - tmp = readl(mmio + HOST_CTL); - if (tmp & HOST_RESET) { - dev_printk(KERN_ERR, &pdev->dev, - "controller reset failed (0x%x)\n", tmp); - return -EIO; - } - - writel(HOST_AHCI_EN, mmio + HOST_CTL); - (void) readl(mmio + HOST_CTL); /* flush */ - writel(cap_save, mmio + HOST_CAP); - writel(0xf, mmio + HOST_PORTS_IMPL); - (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ - - if (pdev->vendor == PCI_VENDOR_ID_INTEL) { - u16 tmp16; - - /* configure PCS */ - pci_read_config_word(pdev, 0x92, &tmp16); - tmp16 |= 0xf; - pci_write_config_word(pdev, 0x92, tmp16); + work = 1000; + while (work-- > 0) { + tmp = readl(port_mmio + PORT_CMD); + if ((tmp & PORT_CMD_LIST_ON) == 0) + return 0; + udelay(10); } - return 0; + return -EIO; } -static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, - int n_ports, u32 cap) +static void ahci_start_engine(struct ata_port *ap) { - int i, rc; + void __iomem *mmio = ap->host_set->mmio_base; + void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); u32 tmp; - for (i = 0; i < n_ports; i++) { - void __iomem *port_mmio = ahci_port_base(mmio, i); - const char *emsg = NULL; - -#if 0 /* BIOSen initialize this incorrectly */ - if (!(hpriv->port_map & (1 << i))) - continue; -#endif - - /* make sure port is not active */ - rc = ahci_deinit_port(port_mmio, cap, &emsg); - if (rc) - dev_printk(KERN_WARNING, &pdev->dev, - "%s (%d)\n", emsg, rc); - - /* clear SError */ - tmp = readl(port_mmio + PORT_SCR_ERR); - VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); - writel(tmp, port_mmio + PORT_SCR_ERR); - - /* clear port IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); - if (tmp) - writel(tmp, port_mmio + PORT_IRQ_STAT); - - writel(1 << i, mmio + HOST_IRQ_STAT); - } - - tmp = readl(mmio + HOST_CTL); - VPRINTK("HOST_CTL 0x%x\n", tmp); - writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); - tmp = readl(mmio + HOST_CTL); - VPRINTK("HOST_CTL 0x%x\n", tmp); + tmp = readl(port_mmio + PORT_CMD); + tmp |= PORT_CMD_START; + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ } static unsigned int ahci_dev_classify(struct ata_port *ap) @@ -759,7 +626,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* prepare for SRST (AHCI-1.1 10.4.1) */ - rc = ahci_stop_engine(port_mmio); + rc = ahci_stop_engine(ap); if (rc) { reason = "failed to stop engine"; goto fail_restart; @@ -780,7 +647,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) } /* restart engine */ - ahci_start_engine(port_mmio); + ahci_start_engine(ap); ata_tf_init(ap->device, &tf); fis = pp->cmd_tbl; @@ -839,7 +706,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) return 0; fail_restart: - ahci_start_engine(port_mmio); + ahci_start_engine(ap); fail: ata_port_printk(ap, KERN_ERR, "softreset failed (%s)\n", reason); return rc; @@ -850,13 +717,11 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) struct ahci_port_priv *pp = ap->private_data; u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG; struct ata_taskfile tf; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); int rc; DPRINTK("ENTER\n"); - ahci_stop_engine(port_mmio); + ahci_stop_engine(ap); /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(ap->device, &tf); @@ -865,7 +730,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class) rc = sata_std_hardreset(ap, class); - ahci_start_engine(port_mmio); + ahci_start_engine(ap); if (rc == 0 && ata_port_online(ap)) *class = ahci_dev_classify(ap); @@ -1075,8 +940,14 @@ static void ahci_host_intr(struct ata_port *ap) return; /* ignore interim PIO setup fis interrupts */ - if (ata_tag_valid(ap->active_tag) && (status & PORT_IRQ_PIOS_FIS)) - return; + if (ata_tag_valid(ap->active_tag)) { + struct ata_queued_cmd *qc = + ata_qc_from_tag(ap, ap->active_tag); + + if (qc && qc->tf.protocol == ATA_PROT_PIO && + (status & PORT_IRQ_PIOS_FIS)) + return; + } if (ata_ratelimit()) ata_port_printk(ap, KERN_INFO, "spurious interrupt " @@ -1181,13 +1052,10 @@ static void ahci_thaw(struct ata_port *ap) static void ahci_error_handler(struct ata_port *ap) { - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - if (!(ap->pflags & ATA_PFLAG_FROZEN)) { /* restart engine */ - ahci_stop_engine(port_mmio); - ahci_start_engine(port_mmio); + ahci_stop_engine(ap); + ahci_start_engine(ap); } /* perform recovery */ @@ -1198,176 +1066,15 @@ static void ahci_error_handler(struct ata_port *ap) static void ahci_post_internal_cmd(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); if (qc->flags & ATA_QCFLAG_FAILED) qc->err_mask |= AC_ERR_OTHER; if (qc->err_mask) { /* make DMA engine forget about the failed command */ - ahci_stop_engine(port_mmio); - ahci_start_engine(port_mmio); - } -} - -static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) -{ - struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - const char *emsg = NULL; - int rc; - - rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); - if (rc) { - ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); - ahci_init_port(port_mmio, hpriv->cap, - pp->cmd_slot_dma, pp->rx_fis_dma); - } - - return rc; -} - -static int ahci_port_resume(struct ata_port *ap) -{ - struct ahci_port_priv *pp = ap->private_data; - struct ahci_host_priv *hpriv = ap->host_set->private_data; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - - ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); - - return 0; -} - -static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) -{ - struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); - void __iomem *mmio = host_set->mmio_base; - u32 ctl; - - if (mesg.event == PM_EVENT_SUSPEND) { - /* AHCI spec rev1.1 section 8.3.3: - * Software must disable interrupts prior to requesting a - * transition of the HBA to D3 state. - */ - ctl = readl(mmio + HOST_CTL); - ctl &= ~HOST_IRQ_EN; - writel(ctl, mmio + HOST_CTL); - readl(mmio + HOST_CTL); /* flush */ + ahci_stop_engine(ap); + ahci_start_engine(ap); } - - return ata_pci_device_suspend(pdev, mesg); -} - -static int ahci_pci_device_resume(struct pci_dev *pdev) -{ - struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); - struct ahci_host_priv *hpriv = host_set->private_data; - void __iomem *mmio = host_set->mmio_base; - int rc; - - ata_pci_device_do_resume(pdev); - - if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - rc = ahci_reset_controller(mmio, pdev); - if (rc) - return rc; - - ahci_init_controller(mmio, pdev, host_set->n_ports, hpriv->cap); - } - - ata_host_set_resume(host_set); - - return 0; -} - -static int ahci_port_start(struct ata_port *ap) -{ - struct device *dev = ap->host_set->dev; - struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - void *mem; - dma_addr_t mem_dma; - int rc; - - pp = kmalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) - return -ENOMEM; - memset(pp, 0, sizeof(*pp)); - - rc = ata_pad_alloc(ap, dev); - if (rc) { - kfree(pp); - return rc; - } - - mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); - if (!mem) { - ata_pad_free(ap, dev); - kfree(pp); - return -ENOMEM; - } - memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); - - /* - * First item in chunk of DMA memory: 32-slot command table, - * 32 bytes each in size - */ - pp->cmd_slot = mem; - pp->cmd_slot_dma = mem_dma; - - mem += AHCI_CMD_SLOT_SZ; - mem_dma += AHCI_CMD_SLOT_SZ; - - /* - * Second item: Received-FIS area - */ - pp->rx_fis = mem; - pp->rx_fis_dma = mem_dma; - - mem += AHCI_RX_FIS_SZ; - mem_dma += AHCI_RX_FIS_SZ; - - /* - * Third item: data area for storing a single command - * and its scatter-gather table - */ - pp->cmd_tbl = mem; - pp->cmd_tbl_dma = mem_dma; - - ap->private_data = pp; - - /* initialize port */ - ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); - - return 0; -} - -static void ahci_port_stop(struct ata_port *ap) -{ - struct device *dev = ap->host_set->dev; - struct ahci_host_priv *hpriv = ap->host_set->private_data; - struct ahci_port_priv *pp = ap->private_data; - void __iomem *mmio = ap->host_set->mmio_base; - void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); - const char *emsg = NULL; - int rc; - - /* de-initialize port */ - rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); - if (rc) - ata_port_printk(ap, KERN_WARNING, "%s (%d)\n", emsg, rc); - - ap->private_data = NULL; - dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, - pp->cmd_slot, pp->cmd_slot_dma); - ata_pad_free(ap, dev); - kfree(pp); } static void ahci_setup_port(struct ata_ioports *port, unsigned long base, @@ -1388,12 +1095,47 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) struct ahci_host_priv *hpriv = probe_ent->private_data; struct pci_dev *pdev = to_pci_dev(probe_ent->dev); void __iomem *mmio = probe_ent->mmio_base; - unsigned int i, using_dac; + u32 tmp, cap_save; + unsigned int i, j, using_dac; int rc; + void __iomem *port_mmio; - rc = ahci_reset_controller(mmio, pdev); - if (rc) - return rc; + cap_save = readl(mmio + HOST_CAP); + cap_save &= ( (1<<28) | (1<<17) ); + cap_save |= (1 << 27); + + /* global controller reset */ + tmp = readl(mmio + HOST_CTL); + if ((tmp & HOST_RESET) == 0) { + writel(tmp | HOST_RESET, mmio + HOST_CTL); + readl(mmio + HOST_CTL); /* flush */ + } + + /* reset must complete within 1 second, or + * the hardware should be considered fried. + */ + ssleep(1); + + tmp = readl(mmio + HOST_CTL); + if (tmp & HOST_RESET) { + dev_printk(KERN_ERR, &pdev->dev, + "controller reset failed (0x%x)\n", tmp); + return -EIO; + } + + writel(HOST_AHCI_EN, mmio + HOST_CTL); + (void) readl(mmio + HOST_CTL); /* flush */ + writel(cap_save, mmio + HOST_CAP); + writel(0xf, mmio + HOST_PORTS_IMPL); + (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ + + if (pdev->vendor == PCI_VENDOR_ID_INTEL) { + u16 tmp16; + + pci_read_config_word(pdev, 0x92, &tmp16); + tmp16 |= 0xf; + pci_write_config_word(pdev, 0x92, tmp16); + } hpriv->cap = readl(mmio + HOST_CAP); hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); @@ -1429,10 +1171,63 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent) } } - for (i = 0; i < probe_ent->n_ports; i++) - ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); + for (i = 0; i < probe_ent->n_ports; i++) { +#if 0 /* BIOSen initialize this incorrectly */ + if (!(hpriv->port_map & (1 << i))) + continue; +#endif + + port_mmio = ahci_port_base(mmio, i); + VPRINTK("mmio %p port_mmio %p\n", mmio, port_mmio); + + ahci_setup_port(&probe_ent->port[i], + (unsigned long) mmio, i); + + /* make sure port is not active */ + tmp = readl(port_mmio + PORT_CMD); + VPRINTK("PORT_CMD 0x%x\n", tmp); + if (tmp & (PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | + PORT_CMD_FIS_RX | PORT_CMD_START)) { + tmp &= ~(PORT_CMD_LIST_ON | PORT_CMD_FIS_ON | + PORT_CMD_FIS_RX | PORT_CMD_START); + writel(tmp, port_mmio + PORT_CMD); + readl(port_mmio + PORT_CMD); /* flush */ + + /* spec says 500 msecs for each bit, so + * this is slightly incorrect. + */ + msleep(500); + } + + writel(PORT_CMD_SPIN_UP, port_mmio + PORT_CMD); + + j = 0; + while (j < 100) { + msleep(10); + tmp = readl(port_mmio + PORT_SCR_STAT); + if ((tmp & 0xf) == 0x3) + break; + j++; + } + + tmp = readl(port_mmio + PORT_SCR_ERR); + VPRINTK("PORT_SCR_ERR 0x%x\n", tmp); + writel(tmp, port_mmio + PORT_SCR_ERR); - ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); + /* ack any pending irq events for this port */ + tmp = readl(port_mmio + PORT_IRQ_STAT); + VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + + writel(1 << i, mmio + HOST_IRQ_STAT); + } + + tmp = readl(mmio + HOST_CTL); + VPRINTK("HOST_CTL 0x%x\n", tmp); + writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); + tmp = readl(mmio + HOST_CTL); + VPRINTK("HOST_CTL 0x%x\n", tmp); pci_set_master(pdev); diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c index 653818d2f802..a1e8ca758594 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_core.c @@ -7289,7 +7289,7 @@ ahd_reset_cmds_pending(struct ahd_softc *ahd) ahd->flags &= ~AHD_UPDATE_PEND_CMDS; } -static void +void ahd_done_with_status(struct ahd_softc *ahd, struct scb *scb, uint32_t status) { cam_status ostat; diff --git a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c index 998999c0a972..b244c7124179 100644 --- a/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -242,6 +242,25 @@ ahd_print_path(struct ahd_softc *ahd, struct scb *scb) */ static uint32_t aic79xx_no_reset; +/* + * Certain PCI motherboards will scan PCI devices from highest to lowest, + * others scan from lowest to highest, and they tend to do all kinds of + * strange things when they come into contact with PCI bridge chips. The + * net result of all this is that the PCI card that is actually used to boot + * the machine is very hard to detect. Most motherboards go from lowest + * PCI slot number to highest, and the first SCSI controller found is the + * one you boot from. The only exceptions to this are when a controller + * has its BIOS disabled. So, we by default sort all of our SCSI controllers + * from lowest PCI slot number to highest PCI slot number. We also force + * all controllers with their BIOS disabled to the end of the list. This + * works on *almost* all computers. Where it doesn't work, we have this + * option. Setting this option to non-0 will reverse the order of the sort + * to highest first, then lowest, but will still leave cards with their BIOS + * disabled at the very end. That should fix everyone up unless there are + * really strange cirumstances. + */ +static uint32_t aic79xx_reverse_scan; + /* * Should we force EXTENDED translation on a controller. * 0 == Use whatever is in the SEEPROM or default to off @@ -331,6 +350,7 @@ MODULE_PARM_DESC(aic79xx, " periodically to prevent tag starvation.\n" " This may be required by some older disk\n" " or drives/RAID arrays.\n" +" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" " tag_info: Set per-target tag depth\n" " global_tag_depth: Global tag depth for all targets on all buses\n" " slewrate:Set the signal slew rate (0-15).\n" @@ -1011,6 +1031,7 @@ aic79xx_setup(char *s) #ifdef AHD_DEBUG { "debug", &ahd_debug }, #endif + { "reverse_scan", &aic79xx_reverse_scan }, { "periodic_otag", &aic79xx_periodic_otag }, { "pci_parity", &aic79xx_pci_parity }, { "seltime", &aic79xx_seltime }, diff --git a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c index aa4be8a31415..debf3e2a0798 100644 --- a/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/trunk/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -353,6 +353,7 @@ MODULE_PARM_DESC(aic7xxx, " periodically to prevent tag starvation.\n" " This may be required by some older disk\n" " drives or RAID arrays.\n" +" reverse_scan Sort PCI devices highest Bus/Slot to lowest\n" " tag_info: Set per-target tag depth\n" " global_tag_depth: Global tag depth for every target\n" " on every bus\n" diff --git a/trunk/drivers/scsi/aic7xxx/aicasm/Makefile b/trunk/drivers/scsi/aic7xxx/aicasm/Makefile index b98c5c1056c3..8c91fda6482c 100644 --- a/trunk/drivers/scsi/aic7xxx/aicasm/Makefile +++ b/trunk/drivers/scsi/aic7xxx/aicasm/Makefile @@ -14,8 +14,6 @@ LIBS= -ldb clean-files:= ${GENSRCS} ${GENHDRS} $(YSRCS:.y=.output) $(PROG) # Override default kernel CFLAGS. This is a userland app. AICASM_CFLAGS:= -I/usr/include -I. -LEX= flex -YACC= bison YFLAGS= -d NOMAN= noman diff --git a/trunk/drivers/scsi/arm/fas216.c b/trunk/drivers/scsi/arm/fas216.c index 4cf7afc31cc7..3e1053f111dc 100644 --- a/trunk/drivers/scsi/arm/fas216.c +++ b/trunk/drivers/scsi/arm/fas216.c @@ -2427,7 +2427,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt) info->stats.aborts += 1; printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); - __scsi_print_command(SCpnt->cmnd); + __scsi_print_command(SCpnt->data_cmnd); print_debug_list(); fas216_dumpstate(info); diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 501755a606ed..19745a31072b 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -487,7 +487,7 @@ static void piix_pata_cbl_detect(struct ata_port *ap) goto cbl40; /* check BIOS cable detect results */ - mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; + mask = ap->hard_port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); if ((tmp & mask) == 0) goto cbl40; @@ -513,7 +513,7 @@ static int piix_pata_prereset(struct ata_port *ap) { struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); - if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no])) { + if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->hard_port_no])) { ata_port_printk(ap, KERN_INFO, "port disabled. ignoring.\n"); ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; return 0; @@ -550,7 +550,7 @@ static int piix_sata_prereset(struct ata_port *ap) struct pci_dev *pdev = to_pci_dev(ap->host_set->dev); struct piix_host_priv *hpriv = ap->host_set->private_data; const unsigned int *map = hpriv->map; - int base = 2 * ap->port_no; + int base = 2 * ap->hard_port_no; unsigned int present = 0; int port, i; u16 pcs; @@ -567,8 +567,8 @@ static int piix_sata_prereset(struct ata_port *ap) present = 1; } - DPRINTK("ata%u: LEAVE, pcs=0x%x present=0x%x\n", - ap->id, pcs, present); + DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n", + ap->id, pcs, present_mask); if (!present) { ata_port_printk(ap, KERN_INFO, "SATA port has no device.\n"); @@ -601,7 +601,7 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) unsigned int pio = adev->pio_mode - XFER_PIO_0; struct pci_dev *dev = to_pci_dev(ap->host_set->dev); unsigned int is_slave = (adev->devno != 0); - unsigned int master_port= ap->port_no ? 0x42 : 0x40; + unsigned int master_port= ap->hard_port_no ? 0x42 : 0x40; unsigned int slave_port = 0x44; u16 master_data; u8 slave_data; @@ -619,10 +619,10 @@ static void piix_set_piomode (struct ata_port *ap, struct ata_device *adev) /* enable PPE, IE and TIME */ master_data |= 0x0070; pci_read_config_byte(dev, slave_port, &slave_data); - slave_data &= (ap->port_no ? 0x0f : 0xf0); + slave_data &= (ap->hard_port_no ? 0x0f : 0xf0); slave_data |= (timings[pio][0] << 2) | - (timings[pio][1] << (ap->port_no ? 4 : 0)); + (timings[pio][1] << (ap->hard_port_no ? 4 : 0)); } else { master_data &= 0xccf8; /* enable PPE, IE and TIME */ @@ -652,9 +652,9 @@ static void piix_set_dmamode (struct ata_port *ap, struct ata_device *adev) { unsigned int udma = adev->dma_mode; /* FIXME: MWDMA too */ struct pci_dev *dev = to_pci_dev(ap->host_set->dev); - u8 maslave = ap->port_no ? 0x42 : 0x40; + u8 maslave = ap->hard_port_no ? 0x42 : 0x40; u8 speed = udma; - unsigned int drive_dn = (ap->port_no ? 2 : 0) + adev->devno; + unsigned int drive_dn = (ap->hard_port_no ? 2 : 0) + adev->devno; int a_speed = 3 << (drive_dn * 4); int u_flag = 1 << drive_dn; int v_flag = 0x01 << drive_dn; @@ -828,7 +828,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev, case IDE: WARN_ON((i & 1) || map[i + 1] != IDE); pinfo[i / 2] = piix_port_info[ich5_pata]; - pinfo[i / 2].private_data = hpriv; i++; printk(" IDE IDE"); break; @@ -932,6 +931,8 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) static void piix_host_stop(struct ata_host_set *host_set) { + if (host_set->next == NULL) + kfree(host_set->private_data); ata_host_stop(host_set); } diff --git a/trunk/drivers/scsi/atari_NCR5380.c b/trunk/drivers/scsi/atari_NCR5380.c index e397129c90d1..007a14e5c3fd 100644 --- a/trunk/drivers/scsi/atari_NCR5380.c +++ b/trunk/drivers/scsi/atari_NCR5380.c @@ -507,7 +507,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = (char *)page_address(cmd->SCp.buffer->page)+ cmd->SCp.buffer->offset; diff --git a/trunk/drivers/scsi/constants.c b/trunk/drivers/scsi/constants.c index 61f6024b61ba..dddd2acce76f 100644 --- a/trunk/drivers/scsi/constants.c +++ b/trunk/drivers/scsi/constants.c @@ -5,7 +5,6 @@ * Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 07 3 May 2002) * by D. Gilbert and aeb (20020609) * Additions for SPC-3 T10/1416-D Rev 21 22 Sept 2004, D. Gilbert 20041025 - * Update to SPC-4 T10/1713-D Rev 5a, 14 June 2006, D. Gilbert 20060702 */ #include @@ -37,56 +36,55 @@ static const char * cdb_byte0_names[] = { /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense", /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL, "Reasssign Blocks", -/* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL, +/* 08-0d */ "Read (6)", NULL, "Write (6)", "Seek (6)", NULL, NULL, /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)", - "Reserve(6)", -/* 17-1a */ "Release(6)", "Copy", "Erase", "Mode Sense(6)", +/* 13-16 */ "Verify (6)", "Recover Buffered Data", "Mode Select (6)", + "Reserve (6)", +/* 17-1a */ "Release (6)", "Copy", "Erase", "Mode Sense (6)", /* 1b-1d */ "Start/Stop Unit", "Receive Diagnostic", "Send Diagnostic", /* 1e-1f */ "Prevent/Allow Medium Removal", NULL, /* 20-22 */ NULL, NULL, NULL, /* 23-28 */ "Read Format Capacities", "Set Window", - "Read Capacity(10)", NULL, NULL, "Read(10)", -/* 29-2d */ "Read Generation", "Write(10)", "Seek(10)", "Erase(10)", - "Read updated block", -/* 2e-31 */ "Write Verify(10)", "Verify(10)", "Search High", "Search Equal", + "Read Capacity (10)", NULL, NULL, "Read (10)", +/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase (10)", + "Read updated block", +/* 2e-31 */ "Write Verify (10)", "Verify (10)", "Search High", "Search Equal", /* 32-34 */ "Search Low", "Set Limits", "Prefetch/Read Position", -/* 35-37 */ "Synchronize Cache(10)", "Lock/Unlock Cache(10)", +/* 35-37 */ "Synchronize Cache (10)", "Lock/Unlock Cache (10)", "Read Defect Data(10)", /* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", "Read Buffer", -/* 3d-3f */ "Update Block", "Read Long(10)", "Write Long(10)", -/* 40-41 */ "Change Definition", "Write Same(10)", +/* 3d-3f */ "Update Block", "Read Long (10)", "Write Long (10)", +/* 40-41 */ "Change Definition", "Write Same (10)", /* 42-48 */ "Read sub-channel", "Read TOC/PMA/ATIP", "Read density support", - "Play audio(10)", "Get configuration", "Play audio msf", + "Play audio (10)", "Get configuration", "Play audio msf", "Play audio track/index", -/* 49-4f */ "Play track relative(10)", "Get event status notification", +/* 49-4f */ "Play track relative (10)", "Get event status notification", "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", NULL, /* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", - "Reserve track", "Send OPC info", "Mode Select(10)", -/* 56-5b */ "Reserve(10)", "Release(10)", "Repair track", "Read master cue", - "Mode Sense(10)", "Close track/session", + "Reserve track", "Send OPC info", "Mode Select (10)", +/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue", + "Mode Sense (10)", "Close track/session", /* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", "Persistent reserve out", /* 60-67 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 68-6f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 70-77 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 78-7f */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Variable length", -/* 80-84 */ "Xdwrite(16)", "Rebuild(16)", "Regenerate(16)", "Extended copy", +/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy", "Receive copy results", -/* 85-89 */ "ATA command pass through(16)", "Access control in", - "Access control out", "Read(16)", "Memory Export Out(16)", -/* 8a-8f */ "Write(16)", NULL, "Read attributes", "Write attributes", - "Write and verify(16)", "Verify(16)", -/* 90-94 */ "Pre-fetch(16)", "Synchronize cache(16)", - "Lock/unlock cache(16)", "Write same(16)", NULL, +/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out", + "Read (16)", "Memory Export Out (16)", +/* 8a-8f */ "Write (16)", NULL, "Read attributes", "Write attributes", + "Write and verify (16)", "Verify (16)", +/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", + "Lock/unlock cache (16)", "Write same (16)", NULL, /* 95-99 */ NULL, NULL, NULL, NULL, NULL, -/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in(16)", - "Service action out(16)", -/* a0-a5 */ "Report luns", "ATA command pass through(12)/Blank", - "Security protocol in", "Maintenance in", "Maintenance out", - "Move medium/play audio(12)", +/* 9a-9f */ NULL, NULL, NULL, NULL, "Service action in (16)", + "Service action out (16)", +/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance in", + "Maintenance out", "Move medium/play audio(12)", /* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", "Play track relative(12)", /* aa-ae */ "Write(12)", NULL, "Erase(12), Get Performance", @@ -94,12 +92,12 @@ static const char * cdb_byte0_names[] = { /* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", /* b2-b4 */ "Search data low(12)", "Set limits(12)", "Read element status attached", -/* b5-b6 */ "Security protocol out", "Send volume tag, set streaming", +/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming", /* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", /* ba-bc */ "Redundancy group (in), Scan", - "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", -/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", - "Volume set (out), Send DVD structure", + "Redundancy group (out), Set cd-rom speed", "Spare in, Play cd", +/* bd-bf */ "Spare out, Mechanism status", "Volume set in, Read cd", + "Volume set out, Send DVD structure", }; struct value_name_pair { @@ -114,7 +112,6 @@ static const struct value_name_pair maint_in_arr[] = { {0xc, "Report supported operation codes"}, {0xd, "Report supported task management functions"}, {0xe, "Report priority"}, - {0xf, "Report timestamp"}, }; #define MAINT_IN_SZ ARRAY_SIZE(maint_in_arr) @@ -123,7 +120,6 @@ static const struct value_name_pair maint_out_arr[] = { {0xa, "Set target port groups"}, {0xb, "Change aliases"}, {0xe, "Set priority"}, - {0xe, "Set timestamp"}, }; #define MAINT_OUT_SZ ARRAY_SIZE(maint_out_arr) @@ -431,7 +427,6 @@ static struct error_info additional[] = {0x001A, "Rewind operation in progress"}, {0x001B, "Set capacity operation in progress"}, {0x001C, "Verify operation in progress"}, - {0x001D, "ATA pass through information available"}, {0x0100, "No index/sector signal"}, @@ -443,7 +438,7 @@ static struct error_info additional[] = {0x0400, "Logical unit not ready, cause not reportable"}, {0x0401, "Logical unit is in process of becoming ready"}, - {0x0402, "Logical unit not ready, initializing command required"}, + {0x0402, "Logical unit not ready, initializing cmd. required"}, {0x0403, "Logical unit not ready, manual intervention required"}, {0x0404, "Logical unit not ready, format in progress"}, {0x0405, "Logical unit not ready, rebuild in progress"}, @@ -483,9 +478,6 @@ static struct error_info additional[] = {0x0B00, "Warning"}, {0x0B01, "Warning - specified temperature exceeded"}, {0x0B02, "Warning - enclosure degraded"}, - {0x0B03, "Warning - background self-test failed"}, - {0x0B04, "Warning - background pre-scan detected medium error"}, - {0x0B05, "Warning - background medium scan detected medium error"}, {0x0C00, "Write error"}, {0x0C01, "Write error - recovered with auto reallocation"}, @@ -501,7 +493,6 @@ static struct error_info additional[] = {0x0C0B, "Auxiliary memory write error"}, {0x0C0C, "Write error - unexpected unsolicited data"}, {0x0C0D, "Write error - not enough unsolicited data"}, - {0x0C0F, "Defects in error window"}, {0x0D00, "Error detected by third party temporary initiator"}, {0x0D01, "Third party device failure"}, @@ -513,12 +504,11 @@ static struct error_info additional[] = {0x0E00, "Invalid information unit"}, {0x0E01, "Information unit too short"}, {0x0E02, "Information unit too long"}, - {0x0E03, "Invalid field in command information unit"}, {0x1000, "Id CRC or ECC error"}, - {0x1001, "Logical block guard check failed"}, - {0x1002, "Logical block application tag check failed"}, - {0x1003, "Logical block reference tag check failed"}, + {0x1001, "Data block guard check failed"}, + {0x1002, "Data block application tag check failed"}, + {0x1003, "Data block reference tag check failed"}, {0x1100, "Unrecovered read error"}, {0x1101, "Read retries exhausted"}, @@ -540,7 +530,6 @@ static struct error_info additional[] = {0x1111, "Read error - loss of streaming"}, {0x1112, "Auxiliary memory read error"}, {0x1113, "Read error - failed retransmission request"}, - {0x1114, "Read error - lba marked bad by application client"}, {0x1200, "Address mark not found for id field"}, @@ -621,14 +610,11 @@ static struct error_info additional[] = {0x2100, "Logical block address out of range"}, {0x2101, "Invalid element address"}, {0x2102, "Invalid address for write"}, - {0x2103, "Invalid write crossing layer jump"}, {0x2200, "Illegal function (use 20 00, 24 00, or 26 00)"}, {0x2400, "Invalid field in cdb"}, {0x2401, "CDB decryption error"}, - {0x2402, "Obsolete"}, - {0x2403, "Obsolete"}, {0x2404, "Security audit value frozen"}, {0x2405, "Security working key frozen"}, {0x2406, "Nonce not unique"}, @@ -651,10 +637,7 @@ static struct error_info additional[] = {0x260C, "Invalid operation for copy source or destination"}, {0x260D, "Copy segment granularity violation"}, {0x260E, "Invalid parameter while port is enabled"}, - {0x260F, "Invalid data-out buffer integrity check value"}, - {0x2610, "Data decryption key fail limit reached"}, - {0x2611, "Incomplete key-associated data set"}, - {0x2612, "Vendor specific key reference not found"}, + {0x260F, "Invalid data-out buffer integrity"}, {0x2700, "Write protected"}, {0x2701, "Hardware write protected"}, @@ -666,7 +649,6 @@ static struct error_info additional[] = {0x2800, "Not ready to ready change, medium may have changed"}, {0x2801, "Import or export element accessed"}, - {0x2802, "Format-layer may have changed"}, {0x2900, "Power on, reset, or bus device reset occurred"}, {0x2901, "Power on occurred"}, @@ -687,11 +669,6 @@ static struct error_info additional[] = {0x2A07, "Implicit asymmetric access state transition failed"}, {0x2A08, "Priority changed"}, {0x2A09, "Capacity data has changed"}, - {0x2A10, "Timestamp changed"}, - {0x2A11, "Data encryption parameters changed by another i_t nexus"}, - {0x2A12, "Data encryption parameters changed by vendor specific " - "event"}, - {0x2A13, "Data encryption key instance counter has changed"}, {0x2B00, "Copy cannot execute since host cannot disconnect"}, @@ -713,7 +690,6 @@ static struct error_info additional[] = {0x2E00, "Insufficient time for operation"}, {0x2F00, "Commands cleared by another initiator"}, - {0x2F01, "Commands cleared by power loss notification"}, {0x3000, "Incompatible medium installed"}, {0x3001, "Cannot read medium - unknown format"}, @@ -726,8 +702,7 @@ static struct error_info additional[] = {0x3008, "Cannot write - application code mismatch"}, {0x3009, "Current session not fixated for append"}, {0x300A, "Cleaning request rejected"}, - {0x300C, "WORM medium - overwrite attempted"}, - {0x300D, "WORM medium - integrity check"}, + {0x300C, "WORM medium, overwrite attempted"}, {0x3010, "Medium not formatted"}, {0x3100, "Medium format corrupted"}, @@ -815,9 +790,6 @@ static struct error_info additional[] = {0x3F0F, "Echo buffer overwritten"}, {0x3F10, "Medium loadable"}, {0x3F11, "Medium auxiliary memory accessible"}, - {0x3F12, "iSCSI IP address added"}, - {0x3F13, "iSCSI IP address removed"}, - {0x3F14, "iSCSI IP address changed"}, /* * {0x40NN, "Ram failure"}, * {0x40NN, "Diagnostic failure on component nn"}, @@ -827,7 +799,6 @@ static struct error_info additional[] = {0x4300, "Message error"}, {0x4400, "Internal target failure"}, - {0x4471, "ATA device failed set features"}, {0x4500, "Select or reselect failure"}, @@ -836,10 +807,9 @@ static struct error_info additional[] = {0x4700, "Scsi parity error"}, {0x4701, "Data phase CRC error detected"}, {0x4702, "Scsi parity error detected during st data phase"}, - {0x4703, "Information unit iuCRC error detected"}, + {0x4703, "Information unit CRC error detected"}, {0x4704, "Asynchronous information protection error detected"}, {0x4705, "Protocol service CRC error"}, - {0x4706, "Phy test function in progress"}, {0x477f, "Some commands cleared by iSCSI Protocol event"}, {0x4800, "Initiator detected error message received"}, @@ -874,8 +844,6 @@ static struct error_info additional[] = {0x5300, "Media load or eject failed"}, {0x5301, "Unload tape failure"}, {0x5302, "Medium removal prevented"}, - {0x5303, "Medium removal prevented by data transfer element"}, - {0x5304, "Medium thread or unthread failure"}, {0x5400, "Scsi to host system interface failure"}, @@ -887,7 +855,6 @@ static struct error_info additional[] = {0x5505, "Insufficient access control resources"}, {0x5506, "Auxiliary memory out of space"}, {0x5507, "Quota error"}, - {0x5508, "Maximum number of supplemental decryption keys exceeded"}, {0x5700, "Unable to recover table-of-contents"}, @@ -1037,7 +1004,6 @@ static struct error_info additional[] = {0x6708, "Assign failure occurred"}, {0x6709, "Multiply assigned logical unit"}, {0x670A, "Set target port groups command failed"}, - {0x670B, "ATA device feature not enabled"}, {0x6800, "Logical unit not configured"}, @@ -1064,8 +1030,6 @@ static struct error_info additional[] = {0x6F03, "Read of scrambled sector without authentication"}, {0x6F04, "Media region code is mismatched to logical unit region"}, {0x6F05, "Drive region must be permanent/region reset count error"}, - {0x6F06, "Insufficient block count for binding nonce recording"}, - {0x6F07, "Conflict in binding nonce recording"}, /* * {0x70NN, "Decompression exception short algorithm id of nn"}, */ @@ -1077,8 +1041,6 @@ static struct error_info additional[] = {0x7203, "Session fixation error - incomplete track in session"}, {0x7204, "Empty or partially written reserved track"}, {0x7205, "No more track reservations allowed"}, - {0x7206, "RMZ extension is not allowed"}, - {0x7207, "No more test zone extensions are allowed"}, {0x7300, "Cd control error"}, {0x7301, "Power calibration area almost full"}, @@ -1087,18 +1049,6 @@ static struct error_info additional[] = {0x7304, "Program memory area update failure"}, {0x7305, "Program memory area is full"}, {0x7306, "RMA/PMA is almost full"}, - {0x7310, "Current power calibration area almost full"}, - {0x7311, "Current power calibration area is full"}, - {0x7317, "RDZ is full"}, - - {0x7400, "Security error"}, - {0x7401, "Unable to decrypt data"}, - {0x7402, "Unencrypted data encountered while decrypting"}, - {0x7403, "Incorrect data encryption key"}, - {0x7404, "Cryptographic integrity validation failed"}, - {0x7405, "Error decrypting data"}, - {0x7471, "Logical unit access not authorized"}, - {0, NULL} }; diff --git a/trunk/drivers/scsi/esp.c b/trunk/drivers/scsi/esp.c index 98bd22714d0d..10573c24a50b 100644 --- a/trunk/drivers/scsi/esp.c +++ b/trunk/drivers/scsi/esp.c @@ -1397,7 +1397,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) sp->SCp.ptr = NULL; } } else { - sp->SCp.buffer = (struct scatterlist *) sp->request_buffer; + sp->SCp.buffer = (struct scatterlist *) sp->buffer; sp->SCp.buffers_residual = sbus_map_sg(esp->sdev, sp->SCp.buffer, sp->use_sg, @@ -1410,7 +1410,7 @@ static void esp_get_dmabufs(struct esp *esp, struct scsi_cmnd *sp) static void esp_release_dmabufs(struct esp *esp, struct scsi_cmnd *sp) { if (sp->use_sg) { - sbus_unmap_sg(esp->sdev, sp->request_buffer, sp->use_sg, + sbus_unmap_sg(esp->sdev, sp->buffer, sp->use_sg, sp->sc_data_direction); } else if (sp->request_bufflen) { sbus_unmap_single(esp->sdev, @@ -2754,15 +2754,18 @@ static int esp_do_data_finale(struct esp *esp) */ static int esp_should_clear_sync(struct scsi_cmnd *sp) { - u8 cmd = sp->cmnd[0]; + u8 cmd1 = sp->cmnd[0]; + u8 cmd2 = sp->data_cmnd[0]; /* These cases are for spinning up a disk and * waiting for that spinup to complete. */ - if (cmd == START_STOP) + if (cmd1 == START_STOP || + cmd2 == START_STOP) return 0; - if (cmd == TEST_UNIT_READY) + if (cmd1 == TEST_UNIT_READY || + cmd2 == TEST_UNIT_READY) return 0; /* One more special case for SCSI tape drives, @@ -2770,7 +2773,8 @@ static int esp_should_clear_sync(struct scsi_cmnd *sp) * completion of a rewind or tape load operation. */ if (sp->device->type == TYPE_TAPE) { - if (cmd == MODE_SENSE) + if (cmd1 == MODE_SENSE || + cmd2 == MODE_SENSE) return 0; } diff --git a/trunk/drivers/scsi/ibmvscsi/iseries_vscsi.c b/trunk/drivers/scsi/ibmvscsi/iseries_vscsi.c index 6aeb5f003c3c..7eed0b098171 100644 --- a/trunk/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/iseries_vscsi.c @@ -81,7 +81,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, int rc; single_host_data = hostdata; - rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, max_requests); + rc = viopath_open(viopath_hostLp, viomajorsubtype_scsi, 0); if (rc < 0) { printk("viopath_open failed with rc %d in open_event_path\n", rc); diff --git a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c index ed22b96580c6..242b8873b333 100644 --- a/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/rpa_vscsi.c @@ -238,7 +238,6 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, if (rc == 2) { /* Adapter is good, but other end is not ready */ printk(KERN_WARNING "ibmvscsi: Partner adapter not ready\n"); - retrc = 0; } else if (rc != 0) { printk(KERN_WARNING "ibmvscsi: Error %d opening adapter\n", rc); goto reg_crq_failed; diff --git a/trunk/drivers/scsi/jazz_esp.c b/trunk/drivers/scsi/jazz_esp.c index bfac4441d89f..3fd8a96f2af3 100644 --- a/trunk/drivers/scsi/jazz_esp.c +++ b/trunk/drivers/scsi/jazz_esp.c @@ -257,7 +257,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, struct scsi_cmnd *sp) static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) { int sz = sp->use_sg - 1; - struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; + struct scatterlist *sg = (struct scatterlist *)sp->buffer; while(sz >= 0) { vdma_free(sg[sz].dma_address); diff --git a/trunk/drivers/scsi/libata-bmdma.c b/trunk/drivers/scsi/libata-bmdma.c index 158f62dbf21b..9ce221f25954 100644 --- a/trunk/drivers/scsi/libata-bmdma.c +++ b/trunk/drivers/scsi/libata-bmdma.c @@ -797,6 +797,32 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc) } #ifdef CONFIG_PCI +static struct ata_probe_ent * +ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) +{ + struct ata_probe_ent *probe_ent; + + probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); + if (!probe_ent) { + printk(KERN_ERR DRV_NAME "(%s): out of memory\n", + kobject_name(&(dev->kobj))); + return NULL; + } + + INIT_LIST_HEAD(&probe_ent->node); + probe_ent->dev = dev; + + probe_ent->sht = port->sht; + probe_ent->host_flags = port->host_flags; + probe_ent->pio_mask = port->pio_mask; + probe_ent->mwdma_mask = port->mwdma_mask; + probe_ent->udma_mask = port->udma_mask; + probe_ent->port_ops = port->port_ops; + + return probe_ent; +} + + /** * ata_pci_init_native_mode - Initialize native-mode driver * @pdev: pci device to be initialized @@ -854,7 +880,7 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int if (bmdma) { bmdma += 8; if(inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; + probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; probe_ent->port[p].bmdma_addr = bmdma; } ata_std_ports(&probe_ent->port[p]); @@ -867,48 +893,44 @@ ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port, int static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, - struct ata_port_info **port, int port_mask) + struct ata_port_info *port, int port_num) { struct ata_probe_ent *probe_ent; - unsigned long bmdma = pci_resource_start(pdev, 4); + unsigned long bmdma; - probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port[0]); + probe_ent = ata_probe_ent_alloc(pci_dev_to_dev(pdev), port); if (!probe_ent) return NULL; - probe_ent->n_ports = 2; - probe_ent->private_data = port[0]->private_data; - - if (port_mask & ATA_PORT_PRIMARY) { - probe_ent->irq = 14; - probe_ent->port[0].cmd_addr = ATA_PRIMARY_CMD; - probe_ent->port[0].altstatus_addr = - probe_ent->port[0].ctl_addr = ATA_PRIMARY_CTL; - if (bmdma) { - probe_ent->port[0].bmdma_addr = bmdma; - if (inb(bmdma + 2) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - } - ata_std_ports(&probe_ent->port[0]); - } else - probe_ent->dummy_port_mask |= ATA_PORT_PRIMARY; - - if (port_mask & ATA_PORT_SECONDARY) { - if (probe_ent->irq) - probe_ent->irq2 = 15; - else + probe_ent->legacy_mode = 1; + probe_ent->n_ports = 1; + probe_ent->hard_port_no = port_num; + probe_ent->private_data = port->private_data; + + switch(port_num) + { + case 0: + probe_ent->irq = 14; + probe_ent->port[0].cmd_addr = 0x1f0; + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = 0x3f6; + break; + case 1: probe_ent->irq = 15; - probe_ent->port[1].cmd_addr = ATA_SECONDARY_CMD; - probe_ent->port[1].altstatus_addr = - probe_ent->port[1].ctl_addr = ATA_SECONDARY_CTL; - if (bmdma) { - probe_ent->port[1].bmdma_addr = bmdma + 8; - if (inb(bmdma + 10) & 0x80) - probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; - } - ata_std_ports(&probe_ent->port[1]); - } else - probe_ent->dummy_port_mask |= ATA_PORT_SECONDARY; + probe_ent->port[0].cmd_addr = 0x170; + probe_ent->port[0].altstatus_addr = + probe_ent->port[0].ctl_addr = 0x376; + break; + } + + bmdma = pci_resource_start(pdev, 4); + if (bmdma != 0) { + bmdma += 8 * port_num; + probe_ent->port[0].bmdma_addr = bmdma; + if (inb(bmdma + 2) & 0x80) + probe_ent->host_set_flags |= ATA_HOST_SIMPLEX; + } + ata_std_ports(&probe_ent->port[0]); return probe_ent; } @@ -928,10 +950,6 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, * regions, sets the dma mask, enables bus master mode, and calls * ata_device_add() * - * ASSUMPTION: - * Nobody makes a single channel controller that appears solely as - * the secondary legacy port on PCI. - * * LOCKING: * Inherited from PCI layer (may sleep). * @@ -942,7 +960,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev, int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, unsigned int n_ports) { - struct ata_probe_ent *probe_ent = NULL; + struct ata_probe_ent *probe_ent = NULL, *probe_ent2 = NULL; struct ata_port_info *port[2]; u8 tmp8, mask; unsigned int legacy_mode = 0; @@ -991,34 +1009,35 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, goto err_out; } + /* FIXME: Should use platform specific mappers for legacy port ranges */ if (legacy_mode) { - if (!request_region(ATA_PRIMARY_CMD, 8, "libata")) { + if (!request_region(0x1f0, 8, "libata")) { struct resource *conflict, res; - res.start = ATA_PRIMARY_CMD; - res.end = ATA_PRIMARY_CMD + 8 - 1; + res.start = 0x1f0; + res.end = 0x1f0 + 8 - 1; conflict = ____request_resource(&ioport_resource, &res); if (!strcmp(conflict->name, "libata")) - legacy_mode |= ATA_PORT_PRIMARY; + legacy_mode |= (1 << 0); else { disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x%0X IDE port busy\n", ATA_PRIMARY_CMD); + printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n"); } } else - legacy_mode |= ATA_PORT_PRIMARY; + legacy_mode |= (1 << 0); - if (!request_region(ATA_SECONDARY_CMD, 8, "libata")) { + if (!request_region(0x170, 8, "libata")) { struct resource *conflict, res; - res.start = ATA_SECONDARY_CMD; - res.end = ATA_SECONDARY_CMD + 8 - 1; + res.start = 0x170; + res.end = 0x170 + 8 - 1; conflict = ____request_resource(&ioport_resource, &res); if (!strcmp(conflict->name, "libata")) - legacy_mode |= ATA_PORT_SECONDARY; + legacy_mode |= (1 << 1); else { disable_dev_on_err = 0; - printk(KERN_WARNING "ata: 0x%X IDE port busy\n", ATA_SECONDARY_CMD); + printk(KERN_WARNING "ata: 0x170 IDE port busy\n"); } } else - legacy_mode |= ATA_PORT_SECONDARY; + legacy_mode |= (1 << 1); } /* we have legacy mode, but all ports are unavailable */ @@ -1036,14 +1055,17 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, goto err_out_regions; if (legacy_mode) { - probe_ent = ata_pci_init_legacy_port(pdev, port, legacy_mode); + if (legacy_mode & (1 << 0)) + probe_ent = ata_pci_init_legacy_port(pdev, port[0], 0); + if (legacy_mode & (1 << 1)) + probe_ent2 = ata_pci_init_legacy_port(pdev, port[1], 1); } else { if (n_ports == 2) probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); else probe_ent = ata_pci_init_native_mode(pdev, port, ATA_PORT_PRIMARY); } - if (!probe_ent) { + if (!probe_ent && !probe_ent2) { rc = -ENOMEM; goto err_out_regions; } @@ -1051,17 +1073,35 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, pci_set_master(pdev); /* FIXME: check ata_device_add return */ - ata_device_add(probe_ent); + if (legacy_mode) { + struct device *dev = &pdev->dev; + struct ata_host_set *host_set = NULL; + + if (legacy_mode & (1 << 0)) { + ata_device_add(probe_ent); + host_set = dev_get_drvdata(dev); + } + + if (legacy_mode & (1 << 1)) { + ata_device_add(probe_ent2); + if (host_set) { + host_set->next = dev_get_drvdata(dev); + dev_set_drvdata(dev, host_set); + } + } + } else + ata_device_add(probe_ent); kfree(probe_ent); + kfree(probe_ent2); return 0; err_out_regions: - if (legacy_mode & ATA_PORT_PRIMARY) - release_region(ATA_PRIMARY_CMD, 8); - if (legacy_mode & ATA_PORT_SECONDARY) - release_region(ATA_SECONDARY_CMD, 8); + if (legacy_mode & (1 << 0)) + release_region(0x1f0, 8); + if (legacy_mode & (1 << 1)) + release_region(0x170, 8); pci_release_regions(pdev); err_out: if (disable_dev_on_err) diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index 3f963f206d4a..386e5f21e191 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -1528,7 +1528,7 @@ int ata_dev_configure(struct ata_device *dev, int print_info) * Zero on success, negative errno otherwise. */ -int ata_bus_probe(struct ata_port *ap) +static int ata_bus_probe(struct ata_port *ap) { unsigned int classes[ATA_MAX_DEVICES]; int tries[ATA_MAX_DEVICES]; @@ -3040,6 +3040,10 @@ static int ata_dma_blacklisted(const struct ata_device *dev) * known limits including host controller limits, device * blacklist, etc... * + * FIXME: The current implementation limits all transfer modes to + * the fastest of the lowested device on the port. This is not + * required on most controllers. + * * LOCKING: * None. */ @@ -3048,8 +3052,8 @@ static void ata_dev_xfermask(struct ata_device *dev) struct ata_port *ap = dev->ap; struct ata_host_set *hs = ap->host_set; unsigned long xfer_mask; + int i; - /* controller modes available */ xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask, ap->udma_mask); @@ -3059,20 +3063,34 @@ static void ata_dev_xfermask(struct ata_device *dev) if (ap->cbl == ATA_CBL_PATA40) xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); - xfer_mask &= ata_pack_xfermask(dev->pio_mask, - dev->mwdma_mask, dev->udma_mask); - xfer_mask &= ata_id_xfermask(dev->id); + /* FIXME: Use port-wide xfermask for now */ + for (i = 0; i < ATA_MAX_DEVICES; i++) { + struct ata_device *d = &ap->device[i]; + + if (ata_dev_absent(d)) + continue; + + if (ata_dev_disabled(d)) { + /* to avoid violating device selection timing */ + xfer_mask &= ata_pack_xfermask(d->pio_mask, + UINT_MAX, UINT_MAX); + continue; + } + + xfer_mask &= ata_pack_xfermask(d->pio_mask, + d->mwdma_mask, d->udma_mask); + xfer_mask &= ata_id_xfermask(d->id); + if (ata_dma_blacklisted(d)) + xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); + } - if (ata_dma_blacklisted(dev)) { - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); + if (ata_dma_blacklisted(dev)) ata_dev_printk(dev, KERN_WARNING, "device is on DMA blacklist, disabling DMA\n"); - } - if ((hs->flags & ATA_HOST_SIMPLEX) && hs->simplex_claimed) { - xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); - ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by " - "other device, disabling DMA\n"); + if (hs->flags & ATA_HOST_SIMPLEX) { + if (hs->simplex_claimed) + xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); } if (ap->ops->mode_filter) @@ -5167,6 +5185,28 @@ void ata_host_stop (struct ata_host_set *host_set) iounmap(host_set->mmio_base); } + +/** + * ata_host_remove - Unregister SCSI host structure with upper layers + * @ap: Port to unregister + * @do_unregister: 1 if we fully unregister, 0 to just stop the port + * + * LOCKING: + * Inherited from caller. + */ + +static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) +{ + struct Scsi_Host *sh = ap->host; + + DPRINTK("ENTER\n"); + + if (do_unregister) + scsi_remove_host(sh); + + ap->ops->port_stop(ap); +} + /** * ata_dev_init - Initialize an ata_device structure * @dev: Device structure to initialize @@ -5200,29 +5240,41 @@ void ata_dev_init(struct ata_device *dev) } /** - * ata_port_init - Initialize an ata_port structure + * ata_host_init - Initialize an ata_port structure * @ap: Structure to initialize + * @host: associated SCSI mid-layer structure * @host_set: Collection of hosts to which @ap belongs * @ent: Probe information provided by low-level driver * @port_no: Port number associated with this ata_port * - * Initialize a new ata_port structure. + * Initialize a new ata_port structure, and its associated + * scsi_host. * * LOCKING: * Inherited from caller. */ -void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, - const struct ata_probe_ent *ent, unsigned int port_no) +static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, + struct ata_host_set *host_set, + const struct ata_probe_ent *ent, unsigned int port_no) { unsigned int i; + host->max_id = 16; + host->max_lun = 1; + host->max_channel = 1; + host->unique_id = ata_unique_id++; + host->max_cmd_len = 12; + ap->lock = &host_set->lock; ap->flags = ATA_FLAG_DISABLED; - ap->id = ata_unique_id++; + ap->id = host->unique_id; + ap->host = host; ap->ctl = ATA_DEVCTL_OBS; ap->host_set = host_set; ap->dev = ent->dev; ap->port_no = port_no; + ap->hard_port_no = + ent->legacy_mode ? ent->hard_port_no : port_no; ap->pio_mask = ent->pio_mask; ap->mwdma_mask = ent->mwdma_mask; ap->udma_mask = ent->udma_mask; @@ -5268,28 +5320,7 @@ void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, } /** - * ata_port_init_shost - Initialize SCSI host associated with ATA port - * @ap: ATA port to initialize SCSI host for - * @shost: SCSI host associated with @ap - * - * Initialize SCSI host @shost associated with ATA port @ap. - * - * LOCKING: - * Inherited from caller. - */ -static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) -{ - ap->host = shost; - - shost->unique_id = ap->id; - shost->max_id = 16; - shost->max_lun = 1; - shost->max_channel = 1; - shost->max_cmd_len = 12; -} - -/** - * ata_port_add - Attach low-level ATA driver to system + * ata_host_add - Attach low-level ATA driver to system * @ent: Information provided by low-level driver * @host_set: Collections of ports to which we add * @port_no: Port number associated with this host @@ -5302,12 +5333,14 @@ static void ata_port_init_shost(struct ata_port *ap, struct Scsi_Host *shost) * RETURNS: * New ata_port on success, for NULL on error. */ -static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, + +static struct ata_port * ata_host_add(const struct ata_probe_ent *ent, struct ata_host_set *host_set, unsigned int port_no) { - struct Scsi_Host *shost; + struct Scsi_Host *host; struct ata_port *ap; + int rc; DPRINTK("ENTER\n"); @@ -5318,40 +5351,25 @@ static struct ata_port * ata_port_add(const struct ata_probe_ent *ent, return NULL; } - shost = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); - if (!shost) + host = scsi_host_alloc(ent->sht, sizeof(struct ata_port)); + if (!host) return NULL; - shost->transportt = &ata_scsi_transport_template; + host->transportt = &ata_scsi_transport_template; - ap = ata_shost_to_port(shost); + ap = ata_shost_to_port(host); - ata_port_init(ap, host_set, ent, port_no); - ata_port_init_shost(ap, shost); + ata_host_init(ap, host, host_set, ent, port_no); - return ap; -} + rc = ap->ops->port_start(ap); + if (rc) + goto err_out; -/** - * ata_sas_host_init - Initialize a host_set struct - * @host_set: host_set to initialize - * @dev: device host_set is attached to - * @flags: host_set flags - * @ops: port_ops - * - * LOCKING: - * PCI/etc. bus probe sem. - * - */ + return ap; -void ata_host_set_init(struct ata_host_set *host_set, - struct device *dev, unsigned long flags, - const struct ata_port_operations *ops) -{ - spin_lock_init(&host_set->lock); - host_set->dev = dev; - host_set->flags = flags; - host_set->ops = ops; +err_out: + scsi_host_put(host); + return NULL; } /** @@ -5374,7 +5392,7 @@ void ata_host_set_init(struct ata_host_set *host_set, */ int ata_device_add(const struct ata_probe_ent *ent) { - unsigned int i; + unsigned int count = 0, i; struct device *dev = ent->dev; struct ata_host_set *host_set; int rc; @@ -5385,65 +5403,50 @@ int ata_device_add(const struct ata_probe_ent *ent) (ent->n_ports * sizeof(void *)), GFP_KERNEL); if (!host_set) return 0; + spin_lock_init(&host_set->lock); - ata_host_set_init(host_set, dev, ent->host_set_flags, ent->port_ops); + host_set->dev = dev; host_set->n_ports = ent->n_ports; host_set->irq = ent->irq; - host_set->irq2 = ent->irq2; host_set->mmio_base = ent->mmio_base; host_set->private_data = ent->private_data; + host_set->ops = ent->port_ops; + host_set->flags = ent->host_set_flags; /* register each port bound to this device */ - for (i = 0; i < host_set->n_ports; i++) { + for (i = 0; i < ent->n_ports; i++) { struct ata_port *ap; unsigned long xfer_mode_mask; - int irq_line = ent->irq; - ap = ata_port_add(ent, host_set, i); + ap = ata_host_add(ent, host_set, i); if (!ap) goto err_out; host_set->ports[i] = ap; - - /* dummy? */ - if (ent->dummy_port_mask & (1 << i)) { - ata_port_printk(ap, KERN_INFO, "DUMMY\n"); - ap->ops = &ata_dummy_port_ops; - continue; - } - - /* start port */ - rc = ap->ops->port_start(ap); - if (rc) { - host_set->ports[i] = NULL; - scsi_host_put(ap->host); - goto err_out; - } - - /* Report the secondary IRQ for second channel legacy */ - if (i == 1 && ent->irq2) - irq_line = ent->irq2; - xfer_mode_mask =(ap->udma_mask << ATA_SHIFT_UDMA) | (ap->mwdma_mask << ATA_SHIFT_MWDMA) | (ap->pio_mask << ATA_SHIFT_PIO); /* print per-port info to dmesg */ ata_port_printk(ap, KERN_INFO, "%cATA max %s cmd 0x%lX " - "ctl 0x%lX bmdma 0x%lX irq %d\n", + "ctl 0x%lX bmdma 0x%lX irq %lu\n", ap->flags & ATA_FLAG_SATA ? 'S' : 'P', ata_mode_string(xfer_mode_mask), ap->ioaddr.cmd_addr, ap->ioaddr.ctl_addr, ap->ioaddr.bmdma_addr, - irq_line); + ent->irq); ata_chk_status(ap); host_set->ops->irq_clear(ap); ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */ + count++; } - /* obtain irq, that may be shared between channels */ + if (!count) + goto err_free_ret; + + /* obtain irq, that is shared between channels */ rc = request_irq(ent->irq, ent->port_ops->irq_handler, ent->irq_flags, DRV_NAME, host_set); if (rc) { @@ -5452,28 +5455,15 @@ int ata_device_add(const struct ata_probe_ent *ent) goto err_out; } - /* do we have a second IRQ for the other channel, eg legacy mode */ - if (ent->irq2) { - /* We will get weird core code crashes later if this is true - so trap it now */ - BUG_ON(ent->irq == ent->irq2); - - rc = request_irq(ent->irq2, ent->port_ops->irq_handler, ent->irq_flags, - DRV_NAME, host_set); - if (rc) { - dev_printk(KERN_ERR, dev, "irq %lu request failed: %d\n", - ent->irq2, rc); - goto err_out_free_irq; - } - } - /* perform each probe synchronously */ DPRINTK("probe begin\n"); - for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; + for (i = 0; i < count; i++) { + struct ata_port *ap; u32 scontrol; int rc; + ap = host_set->ports[i]; + /* init sata_spd_limit to the current value */ if (sata_scr_read(ap, SCR_CONTROL, &scontrol) == 0) { int spd = (scontrol >> 4) & 0xf; @@ -5529,7 +5519,7 @@ int ata_device_add(const struct ata_probe_ent *ent) /* probes are done, now scan each port's disk(s) */ DPRINTK("host probe begin\n"); - for (i = 0; i < host_set->n_ports; i++) { + for (i = 0; i < count; i++) { struct ata_port *ap = host_set->ports[i]; ata_scsi_scan_host(ap); @@ -5540,17 +5530,12 @@ int ata_device_add(const struct ata_probe_ent *ent) VPRINTK("EXIT, returning %u\n", ent->n_ports); return ent->n_ports; /* success */ -err_out_free_irq: - free_irq(ent->irq, host_set); err_out: - for (i = 0; i < host_set->n_ports; i++) { - struct ata_port *ap = host_set->ports[i]; - if (ap) { - ap->ops->port_stop(ap); - scsi_host_put(ap->host); - } + for (i = 0; i < count; i++) { + ata_host_remove(host_set->ports[i], 1); + scsi_host_put(host_set->ports[i]->host); } - +err_free_ret: kfree(host_set); VPRINTK("EXIT, returning 0\n"); return 0; @@ -5573,7 +5558,7 @@ void ata_port_detach(struct ata_port *ap) int i; if (!ap->ops->error_handler) - goto skip_eh; + return; /* tell EH we're leaving & flush EH */ spin_lock_irqsave(ap->lock, flags); @@ -5609,7 +5594,6 @@ void ata_port_detach(struct ata_port *ap) cancel_delayed_work(&ap->hotplug_task); flush_workqueue(ata_aux_wq); - skip_eh: /* remove the associated SCSI host */ scsi_remove_host(ap->host); } @@ -5633,8 +5617,6 @@ void ata_host_set_remove(struct ata_host_set *host_set) ata_port_detach(host_set->ports[i]); free_irq(host_set->irq, host_set); - if (host_set->irq2) - free_irq(host_set->irq2, host_set); for (i = 0; i < host_set->n_ports; i++) { struct ata_port *ap = host_set->ports[i]; @@ -5644,11 +5626,10 @@ void ata_host_set_remove(struct ata_host_set *host_set) if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) { struct ata_ioports *ioaddr = &ap->ioaddr; - /* FIXME: Add -ac IDE pci mods to remove these special cases */ - if (ioaddr->cmd_addr == ATA_PRIMARY_CMD) - release_region(ATA_PRIMARY_CMD, 8); - else if (ioaddr->cmd_addr == ATA_SECONDARY_CMD) - release_region(ATA_SECONDARY_CMD, 8); + if (ioaddr->cmd_addr == 0x1f0) + release_region(0x1f0, 8); + else if (ioaddr->cmd_addr == 0x170) + release_region(0x170, 8); } scsi_host_put(ap->host); @@ -5681,37 +5662,12 @@ int ata_scsi_release(struct Scsi_Host *host) DPRINTK("ENTER\n"); ap->ops->port_disable(ap); - ap->ops->port_stop(ap); + ata_host_remove(ap, 0); DPRINTK("EXIT\n"); return 1; } -struct ata_probe_ent * -ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port) -{ - struct ata_probe_ent *probe_ent; - - probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL); - if (!probe_ent) { - printk(KERN_ERR DRV_NAME "(%s): out of memory\n", - kobject_name(&(dev->kobj))); - return NULL; - } - - INIT_LIST_HEAD(&probe_ent->node); - probe_ent->dev = dev; - - probe_ent->sht = port->sht; - probe_ent->host_flags = port->host_flags; - probe_ent->pio_mask = port->pio_mask; - probe_ent->mwdma_mask = port->mwdma_mask; - probe_ent->udma_mask = port->udma_mask; - probe_ent->port_ops = port->port_ops; - - return probe_ent; -} - /** * ata_std_ports - initialize ioaddr with standard port offsets. * @ioaddr: IO address structure to be initialized @@ -5766,8 +5722,11 @@ void ata_pci_remove_one (struct pci_dev *pdev) { struct device *dev = pci_dev_to_dev(pdev); struct ata_host_set *host_set = dev_get_drvdata(dev); + struct ata_host_set *host_set2 = host_set->next; ata_host_set_remove(host_set); + if (host_set2) + ata_host_set_remove(host_set2); pci_release_regions(pdev); pci_disable_device(pdev); @@ -5808,11 +5767,11 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits) return (tmp == bits->val) ? 1 : 0; } -void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg) +void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state) { pci_save_state(pdev); - if (mesg.event == PM_EVENT_SUSPEND) { + if (state.event == PM_EVENT_SUSPEND) { pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); } @@ -5826,16 +5785,24 @@ void ata_pci_device_do_resume(struct pci_dev *pdev) pci_set_master(pdev); } -int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) +int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state) { struct ata_host_set *host_set = dev_get_drvdata(&pdev->dev); int rc = 0; - rc = ata_host_set_suspend(host_set, mesg); + rc = ata_host_set_suspend(host_set, state); if (rc) return rc; - ata_pci_device_do_suspend(pdev, mesg); + if (host_set->next) { + rc = ata_host_set_suspend(host_set->next, state); + if (rc) { + ata_host_set_resume(host_set); + return rc; + } + } + + ata_pci_device_do_suspend(pdev, state); return 0; } @@ -5846,6 +5813,9 @@ int ata_pci_device_resume(struct pci_dev *pdev) ata_pci_device_do_resume(pdev); ata_host_set_resume(host_set); + if (host_set->next) + ata_host_set_resume(host_set->next); + return 0; } #endif /* CONFIG_PCI */ @@ -5944,39 +5914,6 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, return tmp; } -/* - * Dummy port_ops - */ -static void ata_dummy_noret(struct ata_port *ap) { } -static int ata_dummy_ret0(struct ata_port *ap) { return 0; } -static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { } - -static u8 ata_dummy_check_status(struct ata_port *ap) -{ - return ATA_DRDY; -} - -static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc) -{ - return AC_ERR_SYSTEM; -} - -const struct ata_port_operations ata_dummy_port_ops = { - .port_disable = ata_port_disable, - .check_status = ata_dummy_check_status, - .check_altstatus = ata_dummy_check_status, - .dev_select = ata_noop_dev_select, - .qc_prep = ata_noop_qc_prep, - .qc_issue = ata_dummy_qc_issue, - .freeze = ata_dummy_noret, - .thaw = ata_dummy_noret, - .error_handler = ata_dummy_noret, - .post_internal_cmd = ata_dummy_qc_noret, - .irq_clear = ata_dummy_noret, - .port_start = ata_dummy_ret0, - .port_stop = ata_dummy_noret, -}; - /* * libata is essentially a library of internal helper functions for * low-level ATA host controller drivers. As such, the API/ABI is @@ -5987,10 +5924,8 @@ const struct ata_port_operations ata_dummy_port_ops = { EXPORT_SYMBOL_GPL(sata_deb_timing_normal); EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug); EXPORT_SYMBOL_GPL(sata_deb_timing_long); -EXPORT_SYMBOL_GPL(ata_dummy_port_ops); EXPORT_SYMBOL_GPL(ata_std_bios_param); EXPORT_SYMBOL_GPL(ata_std_ports); -EXPORT_SYMBOL_GPL(ata_host_set_init); EXPORT_SYMBOL_GPL(ata_device_add); EXPORT_SYMBOL_GPL(ata_port_detach); EXPORT_SYMBOL_GPL(ata_host_set_remove); diff --git a/trunk/drivers/scsi/libata-eh.c b/trunk/drivers/scsi/libata-eh.c index 29f59345305d..4b6aa30f4d68 100644 --- a/trunk/drivers/scsi/libata-eh.c +++ b/trunk/drivers/scsi/libata-eh.c @@ -764,27 +764,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, unsigned int action) { unsigned long flags; - struct ata_eh_info *ehi = &ap->eh_info; - struct ata_eh_context *ehc = &ap->eh_context; spin_lock_irqsave(ap->lock, flags); - /* Reset is represented by combination of actions and EHI - * flags. Suck in all related bits before clearing eh_info to - * avoid losing requested action. - */ - if (action & ATA_EH_RESET_MASK) { - ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; - ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; - - /* make sure all reset actions are cleared & clear EHI flags */ - action |= ATA_EH_RESET_MASK; - ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; - } - - ata_eh_clear_action(dev, ehi, action); + ata_eh_clear_action(dev, &ap->eh_info, action); - if (!(ehc->i.flags & ATA_EHI_QUIET)) + if (!(ap->eh_context.i.flags & ATA_EHI_QUIET)) ap->pflags |= ATA_PFLAG_RECOVERED; spin_unlock_irqrestore(ap->lock, flags); @@ -805,12 +790,6 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, unsigned int action) { - /* if reset is complete, clear all reset actions & reset modifier */ - if (action & ATA_EH_RESET_MASK) { - action |= ATA_EH_RESET_MASK; - ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; - } - ata_eh_clear_action(dev, &ap->eh_context.i, action); } @@ -1297,6 +1276,8 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io, static void ata_eh_autopsy(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->eh_context; + unsigned int action = ehc->i.action; + struct ata_device *failed_dev = NULL; unsigned int all_err_mask = 0; int tag, is_io = 0; u32 serror; @@ -1313,7 +1294,7 @@ static void ata_eh_autopsy(struct ata_port *ap) ehc->i.serror |= serror; ata_eh_analyze_serror(ap); } else if (rc != -EOPNOTSUPP) - ehc->i.action |= ATA_EH_HARDRESET; + action |= ATA_EH_HARDRESET; /* analyze NCQ failure */ ata_eh_analyze_ncq_error(ap); @@ -1334,7 +1315,7 @@ static void ata_eh_autopsy(struct ata_port *ap) qc->err_mask |= ehc->i.err_mask; /* analyze TF */ - ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); + action |= ata_eh_analyze_tf(qc, &qc->result_tf); /* DEV errors are probably spurious in case of ATA_BUS error */ if (qc->err_mask & AC_ERR_ATA_BUS) @@ -1348,11 +1329,11 @@ static void ata_eh_autopsy(struct ata_port *ap) /* SENSE_VALID trumps dev/unknown error and revalidation */ if (qc->flags & ATA_QCFLAG_SENSE_VALID) { qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); - ehc->i.action &= ~ATA_EH_REVALIDATE; + action &= ~ATA_EH_REVALIDATE; } /* accumulate error info */ - ehc->i.dev = qc->dev; + failed_dev = qc->dev; all_err_mask |= qc->err_mask; if (qc->flags & ATA_QCFLAG_IO) is_io = 1; @@ -1361,22 +1342,25 @@ static void ata_eh_autopsy(struct ata_port *ap) /* enforce default EH actions */ if (ap->pflags & ATA_PFLAG_FROZEN || all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) - ehc->i.action |= ATA_EH_SOFTRESET; + action |= ATA_EH_SOFTRESET; else if (all_err_mask) - ehc->i.action |= ATA_EH_REVALIDATE; + action |= ATA_EH_REVALIDATE; /* if we have offending qcs and the associated failed device */ - if (ehc->i.dev) { + if (failed_dev) { /* speed down */ - ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io, - all_err_mask); + action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); /* perform per-dev EH action only on the offending device */ - ehc->i.dev_action[ehc->i.dev->devno] |= - ehc->i.action & ATA_EH_PERDEV_MASK; - ehc->i.action &= ~ATA_EH_PERDEV_MASK; + ehc->i.dev_action[failed_dev->devno] |= + action & ATA_EH_PERDEV_MASK; + action &= ~ATA_EH_PERDEV_MASK; } + /* record autopsy result */ + ehc->i.dev = failed_dev; + ehc->i.action |= action; + DPRINTK("EXIT\n"); } @@ -1499,9 +1483,6 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_reset_fn_t reset; int i, did_followup_srst, rc; - /* about to reset */ - ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); - /* Determine which reset to use and record in ehc->i.action. * prereset() may examine and modify it. */ @@ -1550,7 +1531,8 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_port_printk(ap, KERN_INFO, "%s resetting port\n", reset == softreset ? "soft" : "hard"); - /* mark that this EH session started with reset */ + /* reset */ + ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); ehc->i.flags |= ATA_EHI_DID_RESET; rc = ata_do_reset(ap, reset, classes); @@ -1613,7 +1595,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, postreset(ap, classes); /* reset successful, schedule revalidation */ - ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); + ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); ehc->i.action |= ATA_EH_REVALIDATE; } @@ -1866,16 +1848,15 @@ static int ata_eh_skip_recovery(struct ata_port *ap) for (i = 0; i < ata_port_max_devices(ap); i++) { struct ata_device *dev = &ap->device[i]; - if (!(dev->flags & ATA_DFLAG_SUSPENDED)) + if (ata_dev_absent(dev) || ata_dev_ready(dev)) break; } if (i == ata_port_max_devices(ap)) return 1; - /* thaw frozen port, resume link and recover failed devices */ - if ((ap->pflags & ATA_PFLAG_FROZEN) || - (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) + /* always thaw frozen port and recover failed devices */ + if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap)) return 0; /* skip if class codes for all vacant slots are ATA_DEV_NONE */ diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index d168e3413661..7ced41ecde86 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -400,7 +400,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) /** * ata_scsi_device_suspend - suspend ATA device associated with sdev * @sdev: the SCSI device to suspend - * @mesg: target power management message + * @state: target power management state * * Request suspend EH action on the ATA device associated with * @sdev and wait for the operation to complete. @@ -411,7 +411,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf) * RETURNS: * 0 on success, -errno otherwise. */ -int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) +int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t state) { struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev = ata_scsi_find_dev(ap, sdev); @@ -438,7 +438,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) /* request suspend */ action = ATA_EH_SUSPEND; - if (mesg.event != PM_EVENT_SUSPEND) + if (state.event != PM_EVENT_SUSPEND) action |= ATA_EH_PM_FREEZE; ap->eh_info.dev_action[dev->devno] |= action; ap->eh_info.flags |= ATA_EHI_QUIET; @@ -463,7 +463,7 @@ int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg) spin_unlock_irqrestore(ap->lock, flags); out: if (rc == 0) - sdev->sdev_gendev.power.power_state = mesg; + sdev->sdev_gendev.power.power_state = state; return rc; } @@ -2353,19 +2353,6 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc) ata_gen_ata_desc_sense(qc); } - /* SCSI EH automatically locks door if sdev->locked is - * set. Sometimes door lock request continues to - * fail, for example, when no media is present. This - * creates a loop - SCSI EH issues door lock which - * fails and gets invoked again to acquire sense data - * for the failed command. - * - * If door lock fails, always clear sdev->locked to - * avoid this infinite loop. - */ - if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL) - qc->dev->sdev->locked = 0; - qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; qc->scsidone(cmd); ata_qc_free(qc); @@ -3171,152 +3158,3 @@ void ata_scsi_dev_rescan(void *data) scsi_rescan_device(&(dev->sdev->sdev_gendev)); } } - -/** - * ata_sas_port_alloc - Allocate port for a SAS attached SATA device - * @pdev: PCI device that the scsi device is attached to - * @port_info: Information from low-level host driver - * @host: SCSI host that the scsi device is attached to - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * ata_port pointer on success / NULL on failure. - */ - -struct ata_port *ata_sas_port_alloc(struct ata_host_set *host_set, - struct ata_port_info *port_info, - struct Scsi_Host *host) -{ - struct ata_port *ap = kzalloc(sizeof(*ap), GFP_KERNEL); - struct ata_probe_ent *ent; - - if (!ap) - return NULL; - - ent = ata_probe_ent_alloc(host_set->dev, port_info); - if (!ent) { - kfree(ap); - return NULL; - } - - ata_port_init(ap, host_set, ent, 0); - ap->lock = host->host_lock; - kfree(ent); - return ap; -} -EXPORT_SYMBOL_GPL(ata_sas_port_alloc); - -/** - * ata_sas_port_start - Set port up for dma. - * @ap: Port to initialize - * - * Called just after data structures for each port are - * initialized. Allocates DMA pad. - * - * May be used as the port_start() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ -int ata_sas_port_start(struct ata_port *ap) -{ - return ata_pad_alloc(ap, ap->dev); -} -EXPORT_SYMBOL_GPL(ata_sas_port_start); - -/** - * ata_port_stop - Undo ata_sas_port_start() - * @ap: Port to shut down - * - * Frees the DMA pad. - * - * May be used as the port_stop() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ - -void ata_sas_port_stop(struct ata_port *ap) -{ - ata_pad_free(ap, ap->dev); -} -EXPORT_SYMBOL_GPL(ata_sas_port_stop); - -/** - * ata_sas_port_init - Initialize a SATA device - * @ap: SATA port to initialize - * - * LOCKING: - * PCI/etc. bus probe sem. - * - * RETURNS: - * Zero on success, non-zero on error. - */ - -int ata_sas_port_init(struct ata_port *ap) -{ - int rc = ap->ops->port_start(ap); - - if (!rc) - rc = ata_bus_probe(ap); - - return rc; -} -EXPORT_SYMBOL_GPL(ata_sas_port_init); - -/** - * ata_sas_port_destroy - Destroy a SATA port allocated by ata_sas_port_alloc - * @ap: SATA port to destroy - * - */ - -void ata_sas_port_destroy(struct ata_port *ap) -{ - ap->ops->port_stop(ap); - kfree(ap); -} -EXPORT_SYMBOL_GPL(ata_sas_port_destroy); - -/** - * ata_sas_slave_configure - Default slave_config routine for libata devices - * @sdev: SCSI device to configure - * @ap: ATA port to which SCSI device is attached - * - * RETURNS: - * Zero. - */ - -int ata_sas_slave_configure(struct scsi_device *sdev, struct ata_port *ap) -{ - ata_scsi_sdev_config(sdev); - ata_scsi_dev_config(sdev, ap->device); - return 0; -} -EXPORT_SYMBOL_GPL(ata_sas_slave_configure); - -/** - * ata_sas_queuecmd - Issue SCSI cdb to libata-managed device - * @cmd: SCSI command to be sent - * @done: Completion function, called when command is complete - * @ap: ATA port to which the command is being sent - * - * RETURNS: - * Zero. - */ - -int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), - struct ata_port *ap) -{ - ata_scsi_dump_cdb(ap, cmd); - - if (likely(ata_scsi_dev_enabled(ap->device))) - __ata_scsi_queuecmd(cmd, done, ap->device); - else { - cmd->result = (DID_BAD_TARGET << 16); - done(cmd); - } - return 0; -} -EXPORT_SYMBOL_GPL(ata_sas_queuecmd); diff --git a/trunk/drivers/scsi/libata.h b/trunk/drivers/scsi/libata.h index d4a4f82360ec..c325679d9b54 100644 --- a/trunk/drivers/scsi/libata.h +++ b/trunk/drivers/scsi/libata.h @@ -69,10 +69,6 @@ extern int ata_flush_cache(struct ata_device *dev); extern void ata_dev_init(struct ata_device *dev); extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg); extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg); -extern void ata_port_init(struct ata_port *ap, struct ata_host_set *host_set, - const struct ata_probe_ent *ent, unsigned int port_no); -extern struct ata_probe_ent *ata_probe_ent_alloc(struct device *dev, - const struct ata_port_info *port); /* libata-scsi.c */ @@ -111,7 +107,6 @@ extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, u8 *rbuf, unsigned int buflen)); extern void ata_schedule_scsi_eh(struct Scsi_Host *shost); extern void ata_scsi_dev_rescan(void *data); -extern int ata_bus_probe(struct ata_port *ap); /* libata-eh.c */ extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd); diff --git a/trunk/drivers/scsi/lpfc/lpfc.h b/trunk/drivers/scsi/lpfc/lpfc.h index d44f9aac6b8f..f81691fcf177 100644 --- a/trunk/drivers/scsi/lpfc/lpfc.h +++ b/trunk/drivers/scsi/lpfc/lpfc.h @@ -21,12 +21,10 @@ struct lpfc_sli2_slim; +#define LPFC_MAX_TARGET 256 /* max targets supported */ +#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els req */ +#define LPFC_MAX_NS_RETRY 3 /* max NameServer retries */ -#define LPFC_MAX_TARGET 256 /* max number of targets supported */ -#define LPFC_MAX_DISC_THREADS 64 /* max outstanding discovery els - requests */ -#define LPFC_MAX_NS_RETRY 3 /* Number of retry attempts to contact - the NameServer before giving up. */ #define LPFC_DFT_HBA_Q_DEPTH 2048 /* max cmds per hba */ #define LPFC_LC_HBA_Q_DEPTH 1024 /* max cmds per low cost hba */ #define LPFC_LP101_HBA_Q_DEPTH 128 /* max cmds per low cost hba */ @@ -43,6 +41,7 @@ struct lpfc_sli2_slim; (( (u64)(high)<<16 ) << 16)|( (u64)(low)))) /* Provide maximum configuration definitions. */ #define LPFC_DRVR_TIMEOUT 16 /* driver iocb timeout value in sec */ +#define MAX_FCP_TARGET 256 /* max num of FCP targets supported */ #define FC_MAX_ADPTMSG 64 #define MAX_HBAEVT 32 diff --git a/trunk/drivers/scsi/lpfc/lpfc_attr.c b/trunk/drivers/scsi/lpfc/lpfc_attr.c index 5c68cdd8736f..b62a72dfab29 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_attr.c +++ b/trunk/drivers/scsi/lpfc/lpfc_attr.c @@ -219,19 +219,9 @@ lpfc_issue_lip(struct Scsi_Host *host) return -ENOMEM; memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); - pmboxq->mb.mbxCommand = MBX_DOWN_LINK; - pmboxq->mb.mbxOwner = OWN_HOST; - + lpfc_init_link(phba, pmboxq, phba->cfg_topology, phba->cfg_link_speed); mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, phba->fc_ratov * 2); - if ((mbxstatus == MBX_SUCCESS) && (pmboxq->mb.mbxStatus == 0)) { - memset((void *)pmboxq, 0, sizeof (LPFC_MBOXQ_t)); - lpfc_init_link(phba, pmboxq, phba->cfg_topology, - phba->cfg_link_speed); - mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, - phba->fc_ratov * 2); - } - if (mbxstatus == MBX_TIMEOUT) pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; else @@ -243,53 +233,51 @@ lpfc_issue_lip(struct Scsi_Host *host) return 0; } -static int -lpfc_selective_reset(struct lpfc_hba *phba) +static ssize_t +lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) { - struct completion online_compl; - int status = 0; - - init_completion(&online_compl); - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_OFFLINE); - wait_for_completion(&online_compl); - - if (status != 0) - return -EIO; - - init_completion(&online_compl); - lpfc_workq_post_event(phba, &status, &online_compl, - LPFC_EVT_ONLINE); - wait_for_completion(&online_compl); - - if (status != 0) - return -EIO; - - return 0; + struct Scsi_Host *host = class_to_shost(cdev); + struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; + return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); } static ssize_t -lpfc_issue_reset(struct class_device *cdev, const char *buf, size_t count) +lpfc_board_online_show(struct class_device *cdev, char *buf) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - int status = -EINVAL; - - if (strncmp(buf, "selective", sizeof("selective") - 1) == 0) - status = lpfc_selective_reset(phba); - if (status == 0) - return strlen(buf); + if (phba->fc_flag & FC_OFFLINE_MODE) + return snprintf(buf, PAGE_SIZE, "0\n"); else - return status; + return snprintf(buf, PAGE_SIZE, "1\n"); } static ssize_t -lpfc_nport_evt_cnt_show(struct class_device *cdev, char *buf) +lpfc_board_online_store(struct class_device *cdev, const char *buf, + size_t count) { struct Scsi_Host *host = class_to_shost(cdev); struct lpfc_hba *phba = (struct lpfc_hba*)host->hostdata; - return snprintf(buf, PAGE_SIZE, "%d\n", phba->nport_event_cnt); + struct completion online_compl; + int val=0, status=0; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + init_completion(&online_compl); + + if (val) + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_ONLINE); + else + lpfc_workq_post_event(phba, &status, &online_compl, + LPFC_EVT_OFFLINE); + wait_for_completion(&online_compl); + if (!status) + return strlen(buf); + else + return -EIO; } static ssize_t @@ -544,9 +532,10 @@ static CLASS_DEVICE_ATTR(lpfc_drvr_version, S_IRUGO, lpfc_drvr_version_show, NULL); static CLASS_DEVICE_ATTR(management_version, S_IRUGO, management_version_show, NULL); +static CLASS_DEVICE_ATTR(board_online, S_IRUGO | S_IWUSR, + lpfc_board_online_show, lpfc_board_online_store); static CLASS_DEVICE_ATTR(board_mode, S_IRUGO | S_IWUSR, lpfc_board_mode_show, lpfc_board_mode_store); -static CLASS_DEVICE_ATTR(issue_reset, S_IWUSR, NULL, lpfc_issue_reset); static int lpfc_poll = 0; module_param(lpfc_poll, int, 0); @@ -706,12 +695,12 @@ LPFC_ATTR(discovery_threads, 32, 1, 64, "Maximum number of ELS commands " "during discovery"); /* -# lpfc_max_luns: maximum allowed LUN. -# Value range is [0,65535]. Default value is 255. -# NOTE: The SCSI layer might probe all allowed LUN on some old targets. +# lpfc_max_luns: maximum number of LUNs per target driver will support +# Value range is [1,32768]. Default value is 256. +# NOTE: The SCSI layer will scan each target for this many luns */ -LPFC_ATTR_R(max_luns, 255, 0, 65535, - "Maximum allowed LUN"); +LPFC_ATTR_R(max_luns, 256, 1, 32768, + "Maximum number of LUNs per target driver will support"); /* # lpfc_poll_tmo: .Milliseconds driver will wait between polling FCP ring. @@ -750,8 +739,8 @@ struct class_device_attribute *lpfc_host_attrs[] = { &class_device_attr_lpfc_max_luns, &class_device_attr_nport_evt_cnt, &class_device_attr_management_version, + &class_device_attr_board_online, &class_device_attr_board_mode, - &class_device_attr_issue_reset, &class_device_attr_lpfc_poll, &class_device_attr_lpfc_poll_tmo, NULL, diff --git a/trunk/drivers/scsi/lpfc/lpfc_crtn.h b/trunk/drivers/scsi/lpfc/lpfc_crtn.h index 517e9e4dd461..ee22173fce43 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_crtn.h +++ b/trunk/drivers/scsi/lpfc/lpfc_crtn.h @@ -147,7 +147,6 @@ int lpfc_sli_hba_setup(struct lpfc_hba *); int lpfc_sli_hba_down(struct lpfc_hba *); int lpfc_sli_issue_mbox(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t); int lpfc_sli_handle_mb_event(struct lpfc_hba *); -int lpfc_sli_flush_mbox_queue(struct lpfc_hba *); int lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, struct lpfc_sli_ring *, uint32_t); void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); diff --git a/trunk/drivers/scsi/lpfc/lpfc_els.c b/trunk/drivers/scsi/lpfc/lpfc_els.c index b89f6cb641e6..4126fd87956f 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_els.c +++ b/trunk/drivers/scsi/lpfc/lpfc_els.c @@ -648,32 +648,33 @@ lpfc_more_plogi(struct lpfc_hba * phba) } static struct lpfc_nodelist * -lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, +lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_nodelist *ndlp) { struct lpfc_nodelist *new_ndlp; + struct lpfc_dmabuf *pcmd, *prsp; uint32_t *lp; struct serv_parm *sp; uint8_t name[sizeof (struct lpfc_name)]; uint32_t rc; + pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; + prsp = (struct lpfc_dmabuf *) pcmd->list.next; lp = (uint32_t *) prsp->virt; sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); - memset(name, 0, sizeof (struct lpfc_name)); /* Now we to find out if the NPort we are logging into, matches the WWPN * we have for that ndlp. If not, we have some work to do. */ new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); - if (new_ndlp == ndlp) + memset(name, 0, sizeof (struct lpfc_name)); + rc = memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); + if (!rc || (new_ndlp == ndlp)) { return ndlp; + } if (!new_ndlp) { - rc = - memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)); - if (!rc) - return ndlp; new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC); if (!new_ndlp) return ndlp; @@ -682,21 +683,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, } lpfc_unreg_rpi(phba, new_ndlp); + new_ndlp->nlp_prev_state = ndlp->nlp_state; new_ndlp->nlp_DID = ndlp->nlp_DID; - new_ndlp->nlp_prev_state = ndlp->nlp_prev_state; - new_ndlp->nlp_state = ndlp->nlp_state; - lpfc_nlp_list(phba, new_ndlp, ndlp->nlp_flag & NLP_LIST_MASK); + new_ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; + lpfc_nlp_list(phba, new_ndlp, NLP_PLOGI_LIST); /* Move this back to NPR list */ - if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); - } - else { - lpfc_unreg_rpi(phba, ndlp); - ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ - ndlp->nlp_state = NLP_STE_NPR_NODE; - lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); - } + lpfc_unreg_rpi(phba, ndlp); + ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ + ndlp->nlp_state = NLP_STE_NPR_NODE; + lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); + return new_ndlp; } @@ -706,7 +703,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, { IOCB_t *irsp; struct lpfc_nodelist *ndlp; - struct lpfc_dmabuf *prsp; int disc, rc, did, type; @@ -773,10 +769,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, } } else { /* Good status, call state machine */ - prsp = list_entry(((struct lpfc_dmabuf *) - cmdiocb->context2)->list.next, - struct lpfc_dmabuf, list); - ndlp = lpfc_plogi_confirm_nport(phba, prsp, ndlp); + ndlp = lpfc_plogi_confirm_nport(phba, cmdiocb, ndlp); rc = lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_PLOGI); } @@ -3289,9 +3282,10 @@ lpfc_els_timeout_handler(struct lpfc_hba *phba) } else lpfc_sli_release_iocbq(phba, piocb); } - if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) - mod_timer(&phba->els_tmofunc, jiffies + HZ * timeout); - + if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt) { + phba->els_tmofunc.expires = jiffies + HZ * timeout; + add_timer(&phba->els_tmofunc); + } spin_unlock_irq(phba->host->host_lock); } @@ -3448,8 +3442,6 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, if ((did & Fabric_DID_MASK) == Fabric_DID_MASK) { ndlp->nlp_type |= NLP_FABRIC; } - ndlp->nlp_state = NLP_STE_UNUSED_NODE; - lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); } phba->fc_stat.elsRcvFrame++; @@ -3471,14 +3463,13 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, rjt_err = 1; break; } - ndlp = lpfc_plogi_confirm_nport(phba, mp, ndlp); lpfc_disc_state_machine(phba, ndlp, elsiocb, NLP_EVT_RCV_PLOGI); break; case ELS_CMD_FLOGI: phba->fc_stat.elsRcvFLOGI++; lpfc_els_rcv_flogi(phba, elsiocb, ndlp, newnode); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; case ELS_CMD_LOGO: @@ -3501,7 +3492,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, phba->fc_stat.elsRcvRSCN++; lpfc_els_rcv_rscn(phba, elsiocb, ndlp, newnode); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; case ELS_CMD_ADISC: @@ -3544,28 +3535,28 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, phba->fc_stat.elsRcvLIRR++; lpfc_els_rcv_lirr(phba, elsiocb, ndlp); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; case ELS_CMD_RPS: phba->fc_stat.elsRcvRPS++; lpfc_els_rcv_rps(phba, elsiocb, ndlp); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; case ELS_CMD_RPL: phba->fc_stat.elsRcvRPL++; lpfc_els_rcv_rpl(phba, elsiocb, ndlp); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; case ELS_CMD_RNID: phba->fc_stat.elsRcvRNID++; lpfc_els_rcv_rnid(phba, elsiocb, ndlp); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; default: @@ -3577,7 +3568,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, "%d:0115 Unknown ELS command x%x received from " "NPORT x%x\n", phba->brd_no, cmd, did); if (newnode) { - lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); + mempool_free( ndlp, phba->nlp_mem_pool); } break; } diff --git a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c index 4d6cf990c4fc..adb086009ae0 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1084,7 +1084,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, fc_remote_port_rolechg(rport, rport_ids.roles); if ((rport->scsi_target_id != -1) && - (rport->scsi_target_id < LPFC_MAX_TARGET)) { + (rport->scsi_target_id < MAX_FCP_TARGET)) { ndlp->nlp_sid = rport->scsi_target_id; } @@ -1313,7 +1313,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) if ((rport_add == mapped) && ((!nlp->rport) || (nlp->rport->scsi_target_id == -1) || - (nlp->rport->scsi_target_id >= LPFC_MAX_TARGET))) { + (nlp->rport->scsi_target_id >= MAX_FCP_TARGET))) { nlp->nlp_state = NLP_STE_UNMAPPED_NODE; spin_lock_irq(phba->host->host_lock); nlp->nlp_flag |= NLP_TGT_NO_SCSIID; diff --git a/trunk/drivers/scsi/lpfc/lpfc_init.c b/trunk/drivers/scsi/lpfc/lpfc_init.c index ef47b824cbed..81755a3f7c68 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_init.c +++ b/trunk/drivers/scsi/lpfc/lpfc_init.c @@ -71,7 +71,6 @@ lpfc_config_port_prep(struct lpfc_hba * phba) uint16_t offset = 0; static char licensed[56] = "key unlock for use with gnu public licensed code only\0"; - static int init_key = 1; pmb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmb) { @@ -83,13 +82,10 @@ lpfc_config_port_prep(struct lpfc_hba * phba) phba->hba_state = LPFC_INIT_MBX_CMDS; if (lpfc_is_LC_HBA(phba->pcidev->device)) { - if (init_key) { - uint32_t *ptext = (uint32_t *) licensed; + uint32_t *ptext = (uint32_t *) licensed; - for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) - *ptext = cpu_to_be32(*ptext); - init_key = 0; - } + for (i = 0; i < 56; i += sizeof (uint32_t), ptext++) + *ptext = cpu_to_be32(*ptext); lpfc_read_nv(phba, pmb); memset((char*)mb->un.varRDnvp.rsvd3, 0, @@ -409,26 +405,19 @@ lpfc_config_port_post(struct lpfc_hba * phba) } /* MBOX buffer will be freed in mbox compl */ - return (0); -} - -static int -lpfc_discovery_wait(struct lpfc_hba *phba) -{ - int i = 0; - + i = 0; while ((phba->hba_state != LPFC_HBA_READY) || (phba->num_disc_nodes) || (phba->fc_prli_sent) || ((phba->fc_map_cnt == 0) && (i<2)) || - (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE)) { + (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE)) { /* Check every second for 30 retries. */ i++; if (i > 30) { - return -ETIMEDOUT; + break; } if ((i >= 15) && (phba->hba_state <= LPFC_LINK_DOWN)) { /* The link is down. Set linkdown timeout */ - return -ETIMEDOUT; + break; } /* Delay for 1 second to give discovery time to complete. */ @@ -436,7 +425,12 @@ lpfc_discovery_wait(struct lpfc_hba *phba) } - return 0; + /* Since num_disc_nodes keys off of PLOGI, delay a bit to let + * any potential PRLIs to flush thru the SLI sub-system. + */ + msleep(50); + + return (0); } /************************************************************************/ @@ -1345,8 +1339,7 @@ lpfc_offline(struct lpfc_hba * phba) struct lpfc_sli_ring *pring; struct lpfc_sli *psli; unsigned long iflag; - int i; - int cnt = 0; + int i = 0; if (!phba) return 0; @@ -1355,27 +1348,17 @@ lpfc_offline(struct lpfc_hba * phba) return 0; psli = &phba->sli; + pring = &psli->ring[psli->fcp_ring]; lpfc_linkdown(phba); - lpfc_sli_flush_mbox_queue(phba); - for (i = 0; i < psli->num_rings; i++) { - pring = &psli->ring[i]; - /* The linkdown event takes 30 seconds to timeout. */ - while (pring->txcmplq_cnt) { - mdelay(10); - if (cnt++ > 3000) { - lpfc_printf_log(phba, - KERN_WARNING, LOG_INIT, - "%d:0466 Outstanding IO when " - "bringing Adapter offline\n", - phba->brd_no); - break; - } - } + /* The linkdown event takes 30 seconds to timeout. */ + while (pring->txcmplq_cnt) { + mdelay(10); + if (i++ > 3000) + break; } - /* stop all timers associated with this hba */ lpfc_stop_timer(phba); phba->work_hba_events = 0; @@ -1656,8 +1639,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_free_irq; } - lpfc_discovery_wait(phba); - if (phba->cfg_poll & DISABLE_FCP_RING_INT) { spin_lock_irq(phba->host->host_lock); lpfc_poll_start_timer(phba); diff --git a/trunk/drivers/scsi/lpfc/lpfc_mem.c b/trunk/drivers/scsi/lpfc/lpfc_mem.c index 066292d3995a..07017658ac56 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_mem.c +++ b/trunk/drivers/scsi/lpfc/lpfc_mem.c @@ -133,11 +133,6 @@ lpfc_mem_free(struct lpfc_hba * phba) pci_pool_destroy(phba->lpfc_scsi_dma_buf_pool); pci_pool_destroy(phba->lpfc_mbuf_pool); - - /* Free the iocb lookup array */ - kfree(psli->iocbq_lookup); - psli->iocbq_lookup = NULL; - } void * diff --git a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c index bd0b0e293d63..27d60ad897cd 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/trunk/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1110,17 +1110,6 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, phba->brd_no, did, mb->mbxStatus, phba->hba_state); - /* - * If RegLogin failed due to lack of HBA resources do not - * retry discovery. - */ - if (mb->mbxStatus == MBXERR_RPI_FULL) { - ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; - ndlp->nlp_state = NLP_STE_UNUSED_NODE; - lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); - return ndlp->nlp_state; - } - /* Put ndlp in npr list set plogi timer for 1 sec */ mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); spin_lock_irq(phba->host->host_lock); diff --git a/trunk/drivers/scsi/lpfc/lpfc_scsi.c b/trunk/drivers/scsi/lpfc/lpfc_scsi.c index a760a44173df..aea1ee472f3d 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_scsi.c +++ b/trunk/drivers/scsi/lpfc/lpfc_scsi.c @@ -153,6 +153,22 @@ static void lpfc_release_scsi_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) { unsigned long iflag = 0; + /* + * There are only two special cases to consider. (1) the scsi command + * requested scatter-gather usage or (2) the scsi command allocated + * a request buffer, but did not request use_sg. There is a third + * case, but it does not require resource deallocation. + */ + if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { + dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, + psb->seg_cnt, psb->pCmd->sc_data_direction); + } else { + if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { + dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, + psb->pCmd->request_bufflen, + psb->pCmd->sc_data_direction); + } + } spin_lock_irqsave(&phba->scsi_buf_list_lock, iflag); psb->pCmd = NULL; @@ -265,27 +281,6 @@ lpfc_scsi_prep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd) return 0; } -static void -lpfc_scsi_unprep_dma_buf(struct lpfc_hba * phba, struct lpfc_scsi_buf * psb) -{ - /* - * There are only two special cases to consider. (1) the scsi command - * requested scatter-gather usage or (2) the scsi command allocated - * a request buffer, but did not request use_sg. There is a third - * case, but it does not require resource deallocation. - */ - if ((psb->seg_cnt > 0) && (psb->pCmd->use_sg)) { - dma_unmap_sg(&phba->pcidev->dev, psb->pCmd->request_buffer, - psb->seg_cnt, psb->pCmd->sc_data_direction); - } else { - if ((psb->nonsg_phys) && (psb->pCmd->request_bufflen)) { - dma_unmap_single(&phba->pcidev->dev, psb->nonsg_phys, - psb->pCmd->request_bufflen, - psb->pCmd->sc_data_direction); - } - } -} - static void lpfc_handle_fcp_err(struct lpfc_scsi_buf *lpfc_cmd) { @@ -459,7 +454,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, cmd->scsi_done(cmd); if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) { - lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); return; } @@ -517,7 +511,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, } } - lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); } @@ -616,7 +609,6 @@ lpfc_scsi_prep_cmnd(struct lpfc_hba * phba, struct lpfc_scsi_buf * lpfc_cmd, static int lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd, - unsigned int lun, uint8_t task_mgmt_cmd) { struct lpfc_sli *psli; @@ -635,7 +627,8 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, piocb = &piocbq->iocb; fcp_cmnd = lpfc_cmd->fcp_cmnd; - int_to_scsilun(lun, &lpfc_cmd->fcp_cmnd->fcp_lun); + int_to_scsilun(lpfc_cmd->pCmd->device->lun, + &lpfc_cmd->fcp_cmnd->fcp_lun); fcp_cmnd->fcpCntl2 = task_mgmt_cmd; piocb->ulpCommand = CMD_FCP_ICMND64_CR; @@ -662,16 +655,14 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_hba *phba, static int lpfc_scsi_tgt_reset(struct lpfc_scsi_buf * lpfc_cmd, struct lpfc_hba * phba, - unsigned tgt_id, unsigned int lun, - struct lpfc_rport_data *rdata) + unsigned tgt_id, struct lpfc_rport_data *rdata) { struct lpfc_iocbq *iocbq; struct lpfc_iocbq *iocbqrsp; int ret; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, lun, - FCP_TARGET_RESET); + ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_TARGET_RESET); if (!ret) return FAILED; @@ -831,7 +822,6 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *)) return 0; out_host_busy_free_buf: - lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); lpfc_release_scsi_buf(phba, lpfc_cmd); out_host_busy: return SCSI_MLQUEUE_HOST_BUSY; @@ -979,12 +969,12 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) if (lpfc_cmd == NULL) goto out; + lpfc_cmd->pCmd = cmnd; lpfc_cmd->timeout = 60; lpfc_cmd->scsi_hba = phba; lpfc_cmd->rdata = rdata; - ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, cmnd->device->lun, - FCP_LUN_RESET); + ret = lpfc_scsi_prep_task_mgmt_cmd(phba, lpfc_cmd, FCP_LUN_RESET); if (!ret) goto out_free_scsi_buf; @@ -1011,6 +1001,7 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) cmd_status = iocbqrsp->iocb.ulpStatus; lpfc_sli_release_iocbq(phba, iocbqrsp); + lpfc_release_scsi_buf(phba, lpfc_cmd); /* * All outstanding txcmplq I/Os should have been aborted by the device. @@ -1049,8 +1040,6 @@ lpfc_reset_lun_handler(struct scsi_cmnd *cmnd) } out_free_scsi_buf: - lpfc_release_scsi_buf(phba, lpfc_cmd); - lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 SCSI layer issued LUN reset (%d, %d) " "Data: x%x x%x x%x\n", @@ -1081,6 +1070,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) /* The lpfc_cmd storage is reused. Set all loop invariants. */ lpfc_cmd->timeout = 60; + lpfc_cmd->pCmd = cmnd; lpfc_cmd->scsi_hba = phba; /* @@ -1088,7 +1078,7 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) * targets known to the driver. Should any target reset * fail, this routine returns failure to the midlayer. */ - for (i = 0; i < LPFC_MAX_TARGET; i++) { + for (i = 0; i < MAX_FCP_TARGET; i++) { /* Search the mapped list for this target ID */ match = 0; list_for_each_entry(ndlp, &phba->fc_nlpmap_list, nlp_listp) { @@ -1100,8 +1090,8 @@ lpfc_reset_bus_handler(struct scsi_cmnd *cmnd) if (!match) continue; - ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, i, cmnd->device->lun, - ndlp->rport->dd_data); + ret = lpfc_scsi_tgt_reset(lpfc_cmd, phba, + i, ndlp->rport->dd_data); if (ret != SUCCESS) { lpfc_printf_log(phba, KERN_ERR, LOG_FCP, "%d:0713 Bus Reset on target %d failed\n", diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index 350a625fa224..bb69a7a1ec59 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -191,12 +191,35 @@ static int lpfc_sli_ringtxcmpl_put(struct lpfc_hba * phba, struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocb) { + uint16_t iotag; + list_add_tail(&piocb->list, &pring->txcmplq); pring->txcmplq_cnt++; if (unlikely(pring->ringno == LPFC_ELS_RING)) mod_timer(&phba->els_tmofunc, jiffies + HZ * (phba->fc_ratov << 1)); + if (pring->fast_lookup) { + /* Setup fast lookup based on iotag for completion */ + iotag = piocb->iocb.ulpIoTag; + if (iotag && (iotag < pring->fast_iotag)) + *(pring->fast_lookup + iotag) = piocb; + else { + + /* Cmd ring put: iotag greater then + configured max wd0 */ + lpfc_printf_log(phba, + KERN_ERR, + LOG_SLI, + "%d:0316 Cmd ring %d put: iotag x%x " + "greater then configured max x%x " + "wd0 x%x\n", + phba->brd_no, + pring->ringno, iotag, + pring->fast_iotag, + *(((uint32_t *)(&piocb->iocb)) + 7)); + } + } return (0); } @@ -578,7 +601,7 @@ lpfc_sli_handle_mb_event(struct lpfc_hba * phba) /* Stray Mailbox Interrupt, mbxCommand mbxStatus */ lpfc_printf_log(phba, - KERN_WARNING, + KERN_ERR, LOG_MBOX | LOG_SLI, "%d:0304 Stray Mailbox Interrupt " "mbxCommand x%x mbxStatus x%x\n", @@ -1547,8 +1570,8 @@ lpfc_sli_brdready(struct lpfc_hba * phba, uint32_t mask) void lpfc_reset_barrier(struct lpfc_hba * phba) { - uint32_t __iomem *resp_buf; - uint32_t __iomem *mbox_buf; + uint32_t * resp_buf; + uint32_t * mbox_buf; volatile uint32_t mbox; uint32_t hc_copy; int i; @@ -1564,7 +1587,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) * Tell the other part of the chip to suspend temporarily all * its DMA activity. */ - resp_buf = phba->MBslimaddr; + resp_buf = (uint32_t *)phba->MBslimaddr; /* Disable the error attention */ hc_copy = readl(phba->HCregaddr); @@ -1582,7 +1605,7 @@ void lpfc_reset_barrier(struct lpfc_hba * phba) ((MAILBOX_t *)&mbox)->mbxOwner = OWN_CHIP; writel(BARRIER_TEST_PATTERN, (resp_buf + 1)); - mbox_buf = phba->MBslimaddr; + mbox_buf = (uint32_t *)phba->MBslimaddr; writel(mbox, mbox_buf); for (i = 0; @@ -1782,7 +1805,7 @@ lpfc_sli_brdrestart(struct lpfc_hba * phba) skip_post = 0; word0 = 0; /* This is really setting up word1 */ } - to_slim = phba->MBslimaddr + sizeof (uint32_t); + to_slim = (uint8_t *) phba->MBslimaddr + sizeof (uint32_t); writel(*(uint32_t *) mb, to_slim); readl(to_slim); /* flush */ @@ -2636,6 +2659,8 @@ lpfc_sli_hba_down(struct lpfc_hba * phba) INIT_LIST_HEAD(&(pring->txq)); + kfree(pring->fast_lookup); + pring->fast_lookup = NULL; } spin_unlock_irqrestore(phba->host->host_lock, flags); @@ -3085,24 +3110,6 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmboxq, return retval; } -int -lpfc_sli_flush_mbox_queue(struct lpfc_hba * phba) -{ - int i = 0; - - while (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE && !phba->stopped) { - if (i++ > LPFC_MBOX_TMO * 1000) - return 1; - - if (lpfc_sli_handle_mb_event(phba) == 0) - i = 0; - - msleep(1); - } - - return (phba->sli.sli_flag & LPFC_SLI_MBOX_ACTIVE) ? 1 : 0; -} - irqreturn_t lpfc_intr_handler(int irq, void *dev_id, struct pt_regs * regs) { diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.h b/trunk/drivers/scsi/lpfc/lpfc_sli.h index d8ef0d2894d4..a52d6c6cf083 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.h +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.h @@ -135,6 +135,8 @@ struct lpfc_sli_ring { uint32_t fast_iotag; /* max fastlookup based iotag */ uint32_t iotag_ctr; /* keeps track of the next iotag to use */ uint32_t iotag_max; /* max iotag value to use */ + struct lpfc_iocbq ** fast_lookup; /* array of IOCB ptrs indexed by + iotag */ struct list_head txq; uint16_t txq_cnt; /* current length of queue */ uint16_t txq_max; /* max length */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_version.h b/trunk/drivers/scsi/lpfc/lpfc_version.h index 10e89c6ae823..6b737568b831 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_version.h +++ b/trunk/drivers/scsi/lpfc/lpfc_version.h @@ -18,7 +18,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "8.1.7" +#define LPFC_DRIVER_VERSION "8.1.6" #define LPFC_DRIVER_NAME "lpfc" diff --git a/trunk/drivers/scsi/mac53c94.c b/trunk/drivers/scsi/mac53c94.c index 89ef34df5a1d..93edaa8696cf 100644 --- a/trunk/drivers/scsi/mac53c94.c +++ b/trunk/drivers/scsi/mac53c94.c @@ -378,7 +378,7 @@ static void set_dma_cmds(struct fsc_state *state, struct scsi_cmnd *cmd) int nseg; total = 0; - scl = (struct scatterlist *) cmd->request_buffer; + scl = (struct scatterlist *) cmd->buffer; nseg = pci_map_sg(state->pdev, scl, cmd->use_sg, cmd->sc_data_direction); for (i = 0; i < nseg; ++i) { diff --git a/trunk/drivers/scsi/mesh.c b/trunk/drivers/scsi/mesh.c index 5572981a9f92..c88717727be8 100644 --- a/trunk/drivers/scsi/mesh.c +++ b/trunk/drivers/scsi/mesh.c @@ -1268,7 +1268,7 @@ static void set_dma_cmds(struct mesh_state *ms, struct scsi_cmnd *cmd) if (cmd->use_sg > 0) { int nseg; total = 0; - scl = (struct scatterlist *) cmd->request_buffer; + scl = (struct scatterlist *) cmd->buffer; off = ms->data_ptr; nseg = pci_map_sg(ms->pdev, scl, cmd->use_sg, cmd->sc_data_direction); diff --git a/trunk/drivers/scsi/pluto.c b/trunk/drivers/scsi/pluto.c index 0bd9c60e6455..7abf64d1bfc9 100644 --- a/trunk/drivers/scsi/pluto.c +++ b/trunk/drivers/scsi/pluto.c @@ -169,6 +169,8 @@ int __init pluto_detect(struct scsi_host_template *tpnt) SCpnt->request->rq_status = RQ_SCSI_BUSY; SCpnt->done = pluto_detect_done; + SCpnt->bufflen = 256; + SCpnt->buffer = fcs[i].inquiry; SCpnt->request_bufflen = 256; SCpnt->request_buffer = fcs[i].inquiry; PLD(("set up %d %08lx\n", i, (long)SCpnt)) diff --git a/trunk/drivers/scsi/qlogicpti.c b/trunk/drivers/scsi/qlogicpti.c index 5b2f0741a55b..69e0551a81d2 100644 --- a/trunk/drivers/scsi/qlogicpti.c +++ b/trunk/drivers/scsi/qlogicpti.c @@ -874,7 +874,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, if (Cmnd->use_sg) { int sg_count; - sg = (struct scatterlist *) Cmnd->request_buffer; + sg = (struct scatterlist *) Cmnd->buffer; sg_count = sbus_map_sg(qpti->sdev, sg, Cmnd->use_sg, Cmnd->sc_data_direction); ds = cmd->dataseg; @@ -1278,7 +1278,7 @@ static struct scsi_cmnd *qlogicpti_intr_handler(struct qlogicpti *qpti) if (Cmnd->use_sg) { sbus_unmap_sg(qpti->sdev, - (struct scatterlist *)Cmnd->request_buffer, + (struct scatterlist *)Cmnd->buffer, Cmnd->use_sg, Cmnd->sc_data_direction); } else { diff --git a/trunk/drivers/scsi/sata_promise.c b/trunk/drivers/scsi/sata_promise.c index 4776f4e55839..64631bd38952 100644 --- a/trunk/drivers/scsi/sata_promise.c +++ b/trunk/drivers/scsi/sata_promise.c @@ -269,15 +269,8 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20619 }, -/* TODO: remove all associated board_20771 code, as it completely - * duplicates board_2037x code, unless reason for separation can be - * divined. - */ -#if 0 { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20771 }, -#endif - { } /* terminate list */ }; diff --git a/trunk/drivers/scsi/sata_sil.c b/trunk/drivers/scsi/sata_sil.c index d0a85073ebf7..f4e262b06cf2 100644 --- a/trunk/drivers/scsi/sata_sil.c +++ b/trunk/drivers/scsi/sata_sil.c @@ -141,12 +141,8 @@ static const struct sil_drivelist { { "ST330013AS", SIL_QUIRK_MOD15WRITE }, { "ST340017AS", SIL_QUIRK_MOD15WRITE }, { "ST360015AS", SIL_QUIRK_MOD15WRITE }, - { "ST380013AS", SIL_QUIRK_MOD15WRITE }, { "ST380023AS", SIL_QUIRK_MOD15WRITE }, { "ST3120023AS", SIL_QUIRK_MOD15WRITE }, - { "ST3160023AS", SIL_QUIRK_MOD15WRITE }, - { "ST3120026AS", SIL_QUIRK_MOD15WRITE }, - { "ST3200822AS", SIL_QUIRK_MOD15WRITE }, { "ST340014ASL", SIL_QUIRK_MOD15WRITE }, { "ST360014ASL", SIL_QUIRK_MOD15WRITE }, { "ST380011ASL", SIL_QUIRK_MOD15WRITE }, diff --git a/trunk/drivers/scsi/sata_sil24.c b/trunk/drivers/scsi/sata_sil24.c index 3f368c7d3ef9..2e0f4a4076af 100644 --- a/trunk/drivers/scsi/sata_sil24.c +++ b/trunk/drivers/scsi/sata_sil24.c @@ -1106,6 +1106,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) probe_ent->irq = pdev->irq; probe_ent->irq_flags = IRQF_SHARED; + probe_ent->mmio_base = port_base; probe_ent->private_data = hpriv; hpriv->host_base = host_base; diff --git a/trunk/drivers/scsi/scsi.c b/trunk/drivers/scsi/scsi.c index b332caddd5b3..2ab7df0dcfe8 100644 --- a/trunk/drivers/scsi/scsi.c +++ b/trunk/drivers/scsi/scsi.c @@ -346,7 +346,7 @@ void scsi_log_send(struct scsi_cmnd *cmd) if (level > 3) { printk(KERN_INFO "buffer = 0x%p, bufflen = %d," " done = 0x%p, queuecommand 0x%p\n", - cmd->request_buffer, cmd->request_bufflen, + cmd->buffer, cmd->bufflen, cmd->done, sdev->host->hostt->queuecommand); @@ -661,6 +661,11 @@ void __scsi_done(struct scsi_cmnd *cmd) */ int scsi_retry_command(struct scsi_cmnd *cmd) { + /* + * Restore the SCSI command state. + */ + scsi_setup_cmd_retry(cmd); + /* * Zero the sense information from the last time we tried * this command. @@ -706,6 +711,10 @@ void scsi_finish_command(struct scsi_cmnd *cmd) "Notifying upper driver of completion " "(result %x)\n", cmd->result)); + /* + * We can get here with use_sg=0, causing a panic in the upper level + */ + cmd->use_sg = cmd->old_use_sg; cmd->done(cmd); } EXPORT_SYMBOL(scsi_finish_command); diff --git a/trunk/drivers/scsi/scsi_debug.c b/trunk/drivers/scsi/scsi_debug.c index a80303c6b3fd..9c63b00773c4 100644 --- a/trunk/drivers/scsi/scsi_debug.c +++ b/trunk/drivers/scsi/scsi_debug.c @@ -286,7 +286,7 @@ static int inquiry_evpd_83(unsigned char * arr, int target_dev_id, int dev_id_num, const char * dev_id_str, int dev_id_str_len); static int inquiry_evpd_88(unsigned char * arr, int target_dev_id); -static int do_create_driverfs_files(void); +static void do_create_driverfs_files(void); static void do_remove_driverfs_files(void); static int sdebug_add_adapter(void); @@ -2487,22 +2487,19 @@ static ssize_t sdebug_add_host_store(struct device_driver * ddp, DRIVER_ATTR(add_host, S_IRUGO | S_IWUSR, sdebug_add_host_show, sdebug_add_host_store); -static int do_create_driverfs_files(void) +static void do_create_driverfs_files(void) { - int ret; - - ret = driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); - ret |= driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); - return ret; + driver_create_file(&sdebug_driverfs_driver, &driver_attr_add_host); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_delay); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_dev_size_mb); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_dsense); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_every_nth); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_max_luns); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_tgts); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_num_parts); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_ptype); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_opts); + driver_create_file(&sdebug_driverfs_driver, &driver_attr_scsi_level); } static void do_remove_driverfs_files(void) @@ -2525,7 +2522,6 @@ static int __init scsi_debug_init(void) unsigned int sz; int host_to_add; int k; - int ret; if (scsi_debug_dev_size_mb < 1) scsi_debug_dev_size_mb = 1; /* force minimum 1 MB ramdisk */ @@ -2564,33 +2560,13 @@ static int __init scsi_debug_init(void) if (scsi_debug_num_parts > 0) sdebug_build_parts(fake_storep); - ret = device_register(&pseudo_primary); - if (ret < 0) { - printk(KERN_WARNING "scsi_debug: device_register error: %d\n", - ret); - goto free_vm; - } - ret = bus_register(&pseudo_lld_bus); - if (ret < 0) { - printk(KERN_WARNING "scsi_debug: bus_register error: %d\n", - ret); - goto dev_unreg; - } - ret = driver_register(&sdebug_driverfs_driver); - if (ret < 0) { - printk(KERN_WARNING "scsi_debug: driver_register error: %d\n", - ret); - goto bus_unreg; - } - ret = do_create_driverfs_files(); - if (ret < 0) { - printk(KERN_WARNING "scsi_debug: driver_create_file error: %d\n", - ret); - goto del_files; - } - init_all_queued(); + device_register(&pseudo_primary); + bus_register(&pseudo_lld_bus); + driver_register(&sdebug_driverfs_driver); + do_create_driverfs_files(); + sdebug_driver_template.proc_name = (char *)sdebug_proc_name; host_to_add = scsi_debug_add_host; @@ -2609,18 +2585,6 @@ static int __init scsi_debug_init(void) scsi_debug_add_host); } return 0; - -del_files: - do_remove_driverfs_files(); - driver_unregister(&sdebug_driverfs_driver); -bus_unreg: - bus_unregister(&pseudo_lld_bus); -dev_unreg: - device_unregister(&pseudo_primary); -free_vm: - vfree(fake_storep); - - return ret; } static void __exit scsi_debug_exit(void) diff --git a/trunk/drivers/scsi/scsi_error.c b/trunk/drivers/scsi/scsi_error.c index 6a5b731bd5ba..6683d596234a 100644 --- a/trunk/drivers/scsi/scsi_error.c +++ b/trunk/drivers/scsi/scsi_error.c @@ -460,67 +460,19 @@ static void scsi_eh_done(struct scsi_cmnd *scmd) * Return value: * SUCCESS or FAILED or NEEDS_RETRY **/ -static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense) +static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout) { struct scsi_device *sdev = scmd->device; struct Scsi_Host *shost = sdev->host; - int old_result = scmd->result; DECLARE_COMPLETION(done); unsigned long timeleft; unsigned long flags; - unsigned char old_cmnd[MAX_COMMAND_SIZE]; - enum dma_data_direction old_data_direction; - unsigned short old_use_sg; - unsigned char old_cmd_len; - unsigned old_bufflen; - void *old_buffer; int rtn; - /* - * We need saved copies of a number of fields - this is because - * error handling may need to overwrite these with different values - * to run different commands, and once error handling is complete, - * we will need to restore these values prior to running the actual - * command. - */ - old_buffer = scmd->request_buffer; - old_bufflen = scmd->request_bufflen; - memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); - old_data_direction = scmd->sc_data_direction; - old_cmd_len = scmd->cmd_len; - old_use_sg = scmd->use_sg; - - if (copy_sense) { - int gfp_mask = GFP_ATOMIC; - - if (shost->hostt->unchecked_isa_dma) - gfp_mask |= __GFP_DMA; - - scmd->sc_data_direction = DMA_FROM_DEVICE; - scmd->request_bufflen = 252; - scmd->request_buffer = kzalloc(scmd->request_bufflen, gfp_mask); - if (!scmd->request_buffer) - return FAILED; - } else { - scmd->request_buffer = NULL; - scmd->request_bufflen = 0; - scmd->sc_data_direction = DMA_NONE; - } - - scmd->underflow = 0; - scmd->use_sg = 0; - scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); - if (sdev->scsi_level <= SCSI_2) scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | (sdev->lun << 5 & 0xe0); - /* - * Zero the sense buffer. The scsi spec mandates that any - * untransferred sense data should be interpreted as being zero. - */ - memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); - shost->eh_action = &done; spin_lock_irqsave(shost->host_lock, flags); @@ -570,29 +522,6 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense rtn = FAILED; } - - /* - * Last chance to have valid sense data. - */ - if (copy_sense) { - if (!SCSI_SENSE_VALID(scmd)) { - memcpy(scmd->sense_buffer, scmd->request_buffer, - sizeof(scmd->sense_buffer)); - } - kfree(scmd->request_buffer); - } - - - /* - * Restore original data - */ - scmd->request_buffer = old_buffer; - scmd->request_bufflen = old_bufflen; - memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); - scmd->sc_data_direction = old_data_direction; - scmd->cmd_len = old_cmd_len; - scmd->use_sg = old_use_sg; - scmd->result = old_result; return rtn; } @@ -608,10 +537,56 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout, int copy_sense static int scsi_request_sense(struct scsi_cmnd *scmd) { static unsigned char generic_sense[6] = - {REQUEST_SENSE, 0, 0, 0, 252, 0}; + {REQUEST_SENSE, 0, 0, 0, 252, 0}; + unsigned char *scsi_result; + int saved_result; + int rtn; memcpy(scmd->cmnd, generic_sense, sizeof(generic_sense)); - return scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 1); + + scsi_result = kmalloc(252, GFP_ATOMIC | ((scmd->device->host->hostt->unchecked_isa_dma) ? __GFP_DMA : 0)); + + + if (unlikely(!scsi_result)) { + printk(KERN_ERR "%s: cannot allocate scsi_result.\n", + __FUNCTION__); + return FAILED; + } + + /* + * zero the sense buffer. some host adapters automatically always + * request sense, so it is not a good idea that + * scmd->request_buffer and scmd->sense_buffer point to the same + * address (db). 0 is not a valid sense code. + */ + memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); + memset(scsi_result, 0, 252); + + saved_result = scmd->result; + scmd->request_buffer = scsi_result; + scmd->request_bufflen = 252; + scmd->use_sg = 0; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + scmd->sc_data_direction = DMA_FROM_DEVICE; + scmd->underflow = 0; + + rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); + + /* last chance to have valid sense data */ + if(!SCSI_SENSE_VALID(scmd)) { + memcpy(scmd->sense_buffer, scmd->request_buffer, + sizeof(scmd->sense_buffer)); + } + + kfree(scsi_result); + + /* + * when we eventually call scsi_finish, we really wish to complete + * the original request, so let's restore the original data. (db) + */ + scsi_setup_cmd_retry(scmd); + scmd->result = saved_result; + return rtn; } /** @@ -630,6 +605,12 @@ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) { scmd->device->host->host_failed--; scmd->eh_eflags = 0; + + /* + * set this back so that the upper level can correctly free up + * things. + */ + scsi_setup_cmd_retry(scmd); list_move_tail(&scmd->eh_entry, done_q); } EXPORT_SYMBOL(scsi_eh_finish_cmd); @@ -734,26 +715,47 @@ static int scsi_eh_tur(struct scsi_cmnd *scmd) { static unsigned char tur_command[6] = {TEST_UNIT_READY, 0, 0, 0, 0, 0}; int retry_cnt = 1, rtn; + int saved_result; retry_tur: memcpy(scmd->cmnd, tur_command, sizeof(tur_command)); + /* + * zero the sense buffer. the scsi spec mandates that any + * untransferred sense data should be interpreted as being zero. + */ + memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); + + saved_result = scmd->result; + scmd->request_buffer = NULL; + scmd->request_bufflen = 0; + scmd->use_sg = 0; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + scmd->underflow = 0; + scmd->sc_data_direction = DMA_NONE; - rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT, 0); + rtn = scsi_send_eh_cmnd(scmd, SENSE_TIMEOUT); + /* + * when we eventually call scsi_finish, we really wish to complete + * the original request, so let's restore the original data. (db) + */ + scsi_setup_cmd_retry(scmd); + scmd->result = saved_result; + + /* + * hey, we are done. let's look to see what happened. + */ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", __FUNCTION__, scmd, rtn)); - - switch (rtn) { - case NEEDS_RETRY: + if (rtn == SUCCESS) + return 0; + else if (rtn == NEEDS_RETRY) { if (retry_cnt--) goto retry_tur; - /*FALLTHRU*/ - case SUCCESS: return 0; - default: - return 1; } + return 1; } /** @@ -835,16 +837,44 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) static int scsi_eh_try_stu(struct scsi_cmnd *scmd) { static unsigned char stu_command[6] = {START_STOP, 0, 0, 0, 1, 0}; + int rtn; + int saved_result; - if (scmd->device->allow_restart) { - int rtn; + if (!scmd->device->allow_restart) + return 1; - memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); - rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT, 0); - if (rtn == SUCCESS) - return 0; - } + memcpy(scmd->cmnd, stu_command, sizeof(stu_command)); + + /* + * zero the sense buffer. the scsi spec mandates that any + * untransferred sense data should be interpreted as being zero. + */ + memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); + + saved_result = scmd->result; + scmd->request_buffer = NULL; + scmd->request_bufflen = 0; + scmd->use_sg = 0; + scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); + scmd->underflow = 0; + scmd->sc_data_direction = DMA_NONE; + + rtn = scsi_send_eh_cmnd(scmd, START_UNIT_TIMEOUT); + + /* + * when we eventually call scsi_finish, we really wish to complete + * the original request, so let's restore the original data. (db) + */ + scsi_setup_cmd_retry(scmd); + scmd->result = saved_result; + /* + * hey, we are done. let's look to see what happened. + */ + SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd %p rtn %x\n", + __FUNCTION__, scmd, rtn)); + if (rtn == SUCCESS) + return 0; return 1; } @@ -1654,6 +1684,8 @@ scsi_reset_provider(struct scsi_device *dev, int flag) scmd->scsi_done = scsi_reset_provider_done_command; scmd->done = NULL; + scmd->buffer = NULL; + scmd->bufflen = 0; scmd->request_buffer = NULL; scmd->request_bufflen = 0; diff --git a/trunk/drivers/scsi/scsi_ioctl.c b/trunk/drivers/scsi/scsi_ioctl.c index 32293f451669..a89c4115cfba 100644 --- a/trunk/drivers/scsi/scsi_ioctl.c +++ b/trunk/drivers/scsi/scsi_ioctl.c @@ -110,8 +110,11 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, sshdr.asc, sshdr.ascq); break; case NOT_READY: /* This happens if there is no disc in drive */ - if (sdev->removable) + if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) { + printk(KERN_INFO "Device not ready. Make sure" + " there is a disc in the drive.\n"); break; + } case UNIT_ATTENTION: if (sdev->removable) { sdev->changed = 1; diff --git a/trunk/drivers/scsi/scsi_lib.c b/trunk/drivers/scsi/scsi_lib.c index 077c1c691210..08af9aae7df3 100644 --- a/trunk/drivers/scsi/scsi_lib.c +++ b/trunk/drivers/scsi/scsi_lib.c @@ -436,16 +436,60 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); * * Arguments: cmd - command that is ready to be queued. * + * Returns: Nothing + * * Notes: This function has the job of initializing a number of * fields related to error handling. Typically this will * be called once for each command, as required. */ -static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) +static int scsi_init_cmd_errh(struct scsi_cmnd *cmd) { cmd->serial_number = 0; + memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); + if (cmd->cmd_len == 0) cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); + + /* + * We need saved copies of a number of fields - this is because + * error handling may need to overwrite these with different values + * to run different commands, and once error handling is complete, + * we will need to restore these values prior to running the actual + * command. + */ + cmd->old_use_sg = cmd->use_sg; + cmd->old_cmd_len = cmd->cmd_len; + cmd->sc_old_data_direction = cmd->sc_data_direction; + cmd->old_underflow = cmd->underflow; + memcpy(cmd->data_cmnd, cmd->cmnd, sizeof(cmd->cmnd)); + cmd->buffer = cmd->request_buffer; + cmd->bufflen = cmd->request_bufflen; + + return 1; +} + +/* + * Function: scsi_setup_cmd_retry() + * + * Purpose: Restore the command state for a retry + * + * Arguments: cmd - command to be restored + * + * Returns: Nothing + * + * Notes: Immediately prior to retrying a command, we need + * to restore certain fields that we saved above. + */ +void scsi_setup_cmd_retry(struct scsi_cmnd *cmd) +{ + memcpy(cmd->cmnd, cmd->data_cmnd, sizeof(cmd->data_cmnd)); + cmd->request_buffer = cmd->buffer; + cmd->request_bufflen = cmd->bufflen; + cmd->use_sg = cmd->old_use_sg; + cmd->cmd_len = cmd->old_cmd_len; + cmd->sc_data_direction = cmd->sc_old_data_direction; + cmd->underflow = cmd->old_underflow; } void scsi_device_unbusy(struct scsi_device *sdev) @@ -763,13 +807,22 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) */ static void scsi_release_buffers(struct scsi_cmnd *cmd) { + struct request *req = cmd->request; + + /* + * Free up any indirection buffers we allocated for DMA purposes. + */ if (cmd->use_sg) scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + else if (cmd->request_buffer != req->buffer) + kfree(cmd->request_buffer); /* * Zero these out. They now point to freed memory, and it is * dangerous to hang onto the pointers. */ + cmd->buffer = NULL; + cmd->bufflen = 0; cmd->request_buffer = NULL; cmd->request_bufflen = 0; } @@ -805,7 +858,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - int this_count = cmd->request_bufflen; + int this_count = cmd->bufflen; request_queue_t *q = cmd->device->request_queue; struct request *req = cmd->request; int clear_errors = 1; @@ -813,14 +866,28 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) int sense_valid = 0; int sense_deferred = 0; - scsi_release_buffers(cmd); + /* + * Free up any indirection buffers we allocated for DMA purposes. + * For the case of a READ, we need to copy the data out of the + * bounce buffer and into the real buffer. + */ + if (cmd->use_sg) + scsi_free_sgtable(cmd->buffer, cmd->sglist_len); + else if (cmd->buffer != req->buffer) { + if (rq_data_dir(req) == READ) { + unsigned long flags; + char *to = bio_kmap_irq(req->bio, &flags); + memcpy(to, cmd->buffer, cmd->bufflen); + bio_kunmap_irq(to, &flags); + } + kfree(cmd->buffer); + } if (result) { sense_valid = scsi_command_normalize_sense(cmd, &sshdr); if (sense_valid) sense_deferred = scsi_sense_is_deferred(&sshdr); } - if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ req->errors = result; if (result) { @@ -840,6 +907,15 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) req->data_len = cmd->resid; } + /* + * Zero these out. They now point to freed memory, and it is + * dangerous to hang onto the pointers. + */ + cmd->buffer = NULL; + cmd->bufflen = 0; + cmd->request_buffer = NULL; + cmd->request_bufflen = 0; + /* * Next deal with any sectors which we were able to correctly * handle. @@ -936,7 +1012,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) if (!(req->flags & REQ_QUIET)) { scmd_printk(KERN_INFO, cmd, "Volume overflow, CDB: "); - __scsi_print_command(cmd->cmnd); + __scsi_print_command(cmd->data_cmnd); scsi_print_sense("", cmd); } /* See SSC3rXX or current. */ @@ -1067,7 +1143,7 @@ static void scsi_blk_pc_done(struct scsi_cmnd *cmd) * successfully. Since this is a REQ_BLOCK_PC command the * caller should check the request's errors value */ - scsi_io_completion(cmd, cmd->request_bufflen); + scsi_io_completion(cmd, cmd->bufflen); } static void scsi_setup_blk_pc_cmnd(struct scsi_cmnd *cmd) diff --git a/trunk/drivers/scsi/scsi_priv.h b/trunk/drivers/scsi/scsi_priv.h index ae24c85aaeea..e2fbe9a9d5a9 100644 --- a/trunk/drivers/scsi/scsi_priv.h +++ b/trunk/drivers/scsi/scsi_priv.h @@ -57,6 +57,7 @@ extern int scsi_eh_scmd_add(struct scsi_cmnd *, int); /* scsi_lib.c */ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); +extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd); extern void scsi_device_unbusy(struct scsi_device *sdev); extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); extern void scsi_next_command(struct scsi_cmnd *cmd); diff --git a/trunk/drivers/scsi/scsi_transport_sas.c b/trunk/drivers/scsi/scsi_transport_sas.c index 5a625c3fddae..dd075627e605 100644 --- a/trunk/drivers/scsi/scsi_transport_sas.c +++ b/trunk/drivers/scsi/scsi_transport_sas.c @@ -41,7 +41,6 @@ struct sas_host_attrs { struct mutex lock; u32 next_target_id; u32 next_expander_id; - int next_port_id; }; #define to_sas_host_attrs(host) ((struct sas_host_attrs *)(host)->shost_data) @@ -147,7 +146,6 @@ static int sas_host_setup(struct transport_container *tc, struct device *dev, mutex_init(&sas_host->lock); sas_host->next_target_id = 0; sas_host->next_expander_id = 0; - sas_host->next_port_id = 0; return 0; } @@ -329,7 +327,7 @@ sas_phy_protocol_attr(identify.target_port_protocols, sas_phy_simple_attr(identify.sas_address, sas_address, "0x%016llx\n", unsigned long long); sas_phy_simple_attr(identify.phy_identifier, phy_identifier, "%d\n", u8); -//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", int); +//sas_phy_simple_attr(port_identifier, port_identifier, "%d\n", u8); sas_phy_linkspeed_attr(negotiated_linkrate); sas_phy_linkspeed_attr(minimum_linkrate_hw); sas_phy_linkspeed_attr(minimum_linkrate); @@ -592,38 +590,6 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id) } EXPORT_SYMBOL(sas_port_alloc); -/** sas_port_alloc_num - allocate and initialize a SAS port structure - * - * @parent: parent device - * - * Allocates a SAS port structure and a number to go with it. This - * interface is really for adapters where the port number has no - * meansing, so the sas class should manage them. It will be added to - * the device tree below the device specified by @parent which must be - * either a Scsi_Host or a sas_expander_device. - * - * Returns %NULL on error - */ -struct sas_port *sas_port_alloc_num(struct device *parent) -{ - int index; - struct Scsi_Host *shost = dev_to_shost(parent); - struct sas_host_attrs *sas_host = to_sas_host_attrs(shost); - - /* FIXME: use idr for this eventually */ - mutex_lock(&sas_host->lock); - if (scsi_is_sas_expander_device(parent)) { - struct sas_rphy *rphy = dev_to_rphy(parent); - struct sas_expander_device *exp = rphy_to_expander_device(rphy); - - index = exp->next_port_id++; - } else - index = sas_host->next_port_id++; - mutex_unlock(&sas_host->lock); - return sas_port_alloc(parent, index); -} -EXPORT_SYMBOL(sas_port_alloc_num); - /** * sas_port_add - add a SAS port to the device hierarchy * @@ -692,13 +658,6 @@ void sas_port_delete(struct sas_port *port) } mutex_unlock(&port->phy_list_mutex); - if (port->is_backlink) { - struct device *parent = port->dev.parent; - - sysfs_remove_link(&port->dev.kobj, parent->bus_id); - port->is_backlink = 0; - } - transport_remove_device(dev); device_del(dev); transport_destroy_device(dev); @@ -774,19 +733,6 @@ void sas_port_delete_phy(struct sas_port *port, struct sas_phy *phy) } EXPORT_SYMBOL(sas_port_delete_phy); -void sas_port_mark_backlink(struct sas_port *port) -{ - struct device *parent = port->dev.parent->parent->parent; - - if (port->is_backlink) - return; - port->is_backlink = 1; - sysfs_create_link(&port->dev.kobj, &parent->kobj, - parent->bus_id); - -} -EXPORT_SYMBOL(sas_port_mark_backlink); - /* * SAS remote PHY attributes. */ @@ -1194,7 +1140,7 @@ int sas_rphy_add(struct sas_rphy *rphy) if (identify->device_type == SAS_END_DEVICE && rphy->scsi_target_id != -1) { - scsi_scan_target(&rphy->dev, 0, + scsi_scan_target(&rphy->dev, parent->port_identifier, rphy->scsi_target_id, ~0, 0); } @@ -1296,13 +1242,15 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, mutex_lock(&sas_host->lock); list_for_each_entry(rphy, &sas_host->rphy_list, list) { + struct sas_port *parent = dev_to_sas_port(rphy->dev.parent); + if (rphy->identify.device_type != SAS_END_DEVICE || rphy->scsi_target_id == -1) continue; - if ((channel == SCAN_WILD_CARD || channel == 0) && + if ((channel == SCAN_WILD_CARD || channel == parent->port_identifier) && (id == SCAN_WILD_CARD || id == rphy->scsi_target_id)) { - scsi_scan_target(&rphy->dev, 0, + scsi_scan_target(&rphy->dev, parent->port_identifier, rphy->scsi_target_id, lun, 1); } } diff --git a/trunk/drivers/scsi/sd.c b/trunk/drivers/scsi/sd.c index 98bd3aab9739..3225d31449e1 100644 --- a/trunk/drivers/scsi/sd.c +++ b/trunk/drivers/scsi/sd.c @@ -502,7 +502,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) SCpnt->cmnd[4] = (unsigned char) this_count; SCpnt->cmnd[5] = 0; } - SCpnt->request_bufflen = this_count * sdp->sector_size; + SCpnt->request_bufflen = SCpnt->bufflen = + this_count * sdp->sector_size; /* * We shouldn't disconnect in the middle of a sector, so with a dumb diff --git a/trunk/drivers/scsi/seagate.c b/trunk/drivers/scsi/seagate.c index 2679ea8bff1a..3f312a84c6a7 100644 --- a/trunk/drivers/scsi/seagate.c +++ b/trunk/drivers/scsi/seagate.c @@ -1002,7 +1002,7 @@ static int internal_command (unsigned char target, unsigned char lun, } #endif - buffer = (struct scatterlist *) SCint->request_buffer; + buffer = (struct scatterlist *) SCint->buffer; len = buffer->length; data = page_address(buffer->page) + buffer->offset; } else { diff --git a/trunk/drivers/scsi/sr.c b/trunk/drivers/scsi/sr.c index fae6e95a6298..fd94408577e5 100644 --- a/trunk/drivers/scsi/sr.c +++ b/trunk/drivers/scsi/sr.c @@ -360,7 +360,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) "mismatch count %d, bytes %d\n", size, SCpnt->request_bufflen); if (SCpnt->request_bufflen > size) - SCpnt->request_bufflen = size; + SCpnt->request_bufflen = SCpnt->bufflen = size; } } @@ -387,7 +387,8 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) if (this_count > 0xffff) { this_count = 0xffff; - SCpnt->request_bufflen = this_count * s_size; + SCpnt->request_bufflen = SCpnt->bufflen = + this_count * s_size; } SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; diff --git a/trunk/drivers/scsi/st.c b/trunk/drivers/scsi/st.c index 7f669b600677..756ceb93ddc8 100644 --- a/trunk/drivers/scsi/st.c +++ b/trunk/drivers/scsi/st.c @@ -368,7 +368,7 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) SRpnt->cmd[0], SRpnt->cmd[1], SRpnt->cmd[2], SRpnt->cmd[3], SRpnt->cmd[4], SRpnt->cmd[5]); if (cmdstatp->have_sense) - __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); + __scsi_print_sense("st", SRpnt->sense, SCSI_SENSE_BUFFERSIZE); } ) /* end DEB */ if (!debugging) { /* Abnormal conditions for tape */ if (!cmdstatp->have_sense) @@ -384,8 +384,9 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) scode != VOLUME_OVERFLOW && SRpnt->cmd[0] != MODE_SENSE && SRpnt->cmd[0] != TEST_UNIT_READY) { - - __scsi_print_sense(name, SRpnt->sense, SCSI_SENSE_BUFFERSIZE); + printk(KERN_WARNING "%s: Error with sense data: ", name); + __scsi_print_sense("st", SRpnt->sense, + SCSI_SENSE_BUFFERSIZE); } } diff --git a/trunk/drivers/scsi/sun3_NCR5380.c b/trunk/drivers/scsi/sun3_NCR5380.c index 2f8073b73bf3..2ebe0d663899 100644 --- a/trunk/drivers/scsi/sun3_NCR5380.c +++ b/trunk/drivers/scsi/sun3_NCR5380.c @@ -517,7 +517,7 @@ static __inline__ void initialize_SCp(Scsi_Cmnd *cmd) */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = (char *) SGADDR(cmd->SCp.buffer); cmd->SCp.this_residual = cmd->SCp.buffer->length; diff --git a/trunk/drivers/scsi/sun3x_esp.c b/trunk/drivers/scsi/sun3x_esp.c index 6b60536ac92b..1f328cae5c05 100644 --- a/trunk/drivers/scsi/sun3x_esp.c +++ b/trunk/drivers/scsi/sun3x_esp.c @@ -347,7 +347,7 @@ static void dma_mmu_release_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) static void dma_mmu_release_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) { int sz = sp->use_sg - 1; - struct scatterlist *sg = (struct scatterlist *)sp->request_buffer; + struct scatterlist *sg = (struct scatterlist *)sp->buffer; while(sz >= 0) { dvma_unmap((char *)sg[sz].dma_address); diff --git a/trunk/drivers/scsi/wd33c93.c b/trunk/drivers/scsi/wd33c93.c index 2083454db511..680f38ab60d8 100644 --- a/trunk/drivers/scsi/wd33c93.c +++ b/trunk/drivers/scsi/wd33c93.c @@ -373,7 +373,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, */ if (cmd->use_sg) { - cmd->SCp.buffer = (struct scatterlist *) cmd->request_buffer; + cmd->SCp.buffer = (struct scatterlist *) cmd->buffer; cmd->SCp.buffers_residual = cmd->use_sg - 1; cmd->SCp.ptr = page_address(cmd->SCp.buffer->page) + cmd->SCp.buffer->offset; diff --git a/trunk/drivers/serial/sunsab.c b/trunk/drivers/serial/sunsab.c index dc673e1b6fd9..979497f108c8 100644 --- a/trunk/drivers/serial/sunsab.c +++ b/trunk/drivers/serial/sunsab.c @@ -1047,13 +1047,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * up = &sunsab_ports[inst * 2]; err = sunsab_init_one(&up[0], op, - 0, + sizeof(union sab82532_async_regs), (inst * 2) + 0); if (err) return err; - err = sunsab_init_one(&up[1], op, - sizeof(union sab82532_async_regs), + err = sunsab_init_one(&up[1], op, 0, (inst * 2) + 1); if (err) { of_iounmap(up[0].port.membase, @@ -1118,7 +1117,7 @@ static int __init sunsab_init(void) int err; num_channels = 0; - for_each_node_by_name(dp, "se") + for_each_node_by_name(dp, "su") num_channels += 2; for_each_node_by_name(dp, "serial") { if (of_device_is_compatible(dp, "sab82532")) diff --git a/trunk/drivers/serial/sunzilog.c b/trunk/drivers/serial/sunzilog.c index 47bc3d57e019..a1456d9352cb 100644 --- a/trunk/drivers/serial/sunzilog.c +++ b/trunk/drivers/serial/sunzilog.c @@ -68,6 +68,9 @@ static int num_sunzilog; #define NUM_SUNZILOG num_sunzilog #define NUM_CHANNELS (NUM_SUNZILOG * 2) +#define KEYBOARD_LINE 0x2 +#define MOUSE_LINE 0x3 + #define ZS_CLOCK 4915200 /* Zilog input clock rate. */ #define ZS_CLOCK_DIVISOR 16 /* Divisor this driver uses. */ @@ -1222,10 +1225,12 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe { int baud, brg; - if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { + if (channel == KEYBOARD_LINE) { + up->flags |= SUNZILOG_FLAG_CONS_KEYB; up->cflag = B1200 | CS8 | CLOCAL | CREAD; baud = 1200; } else { + up->flags |= SUNZILOG_FLAG_CONS_MOUSE; up->cflag = B4800 | CS8 | CLOCAL | CREAD; baud = 4800; } @@ -1238,14 +1243,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe } #ifdef CONFIG_SERIO -static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) +static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel) { struct serio *serio = &up->serio; serio->port_data = up; serio->id.type = SERIO_RS232; - if (up->flags & SUNZILOG_FLAG_CONS_KEYB) { + if (channel == KEYBOARD_LINE) { serio->id.proto = SERIO_SUNKBD; strlcpy(serio->name, "zskbd", sizeof(serio->name)); } else { @@ -1254,8 +1259,7 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up) strlcpy(serio->name, "zsms", sizeof(serio->name)); } strlcpy(serio->phys, - ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ? - "zs/serio0" : "zs/serio1"), + (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"), sizeof(serio->phys)); serio->write = sunzilog_serio_write; @@ -1282,8 +1286,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) (void) read_zsreg(channel, R0); } - if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | - SUNZILOG_FLAG_CONS_MOUSE)) { + if (up->port.line == KEYBOARD_LINE || + up->port.line == MOUSE_LINE) { sunzilog_init_kbdms(up, up->port.line); up->curregs[R9] |= (NV | MIE); write_zsreg(channel, R9, up->curregs[R9]); @@ -1309,26 +1313,37 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up) spin_unlock_irqrestore(&up->port.lock, flags); #ifdef CONFIG_SERIO - if (up->flags & (SUNZILOG_FLAG_CONS_KEYB | - SUNZILOG_FLAG_CONS_MOUSE)) - sunzilog_register_serio(up); + if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE) + sunzilog_register_serio(up, up->port.line); #endif } +static int __devinit zs_get_instance(struct device_node *dp) +{ + int ret; + + ret = of_getintprop_default(dp, "slave", -1); + if (ret != -1) + return ret; + + if (of_find_property(dp, "keyboard", NULL)) + ret = 1; + else + ret = 0; + + return ret; +} + static int zilog_irq = -1; -static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match) +static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match) { - static int inst; + struct of_device *op = to_of_device(&dev->dev); struct uart_sunzilog_port *up; struct zilog_layout __iomem *rp; - int keyboard_mouse; + int inst = zs_get_instance(dev->node); int err; - keyboard_mouse = 0; - if (of_find_property(op->node, "keyboard", NULL)) - keyboard_mouse = 1; - sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0, sizeof(struct zilog_layout), "zs"); @@ -1337,8 +1352,16 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m rp = sunzilog_chip_regs[inst]; - if (zilog_irq == -1) + if (zilog_irq == -1) { zilog_irq = op->irqs[0]; + err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, + "zs", sunzilog_irq_chain); + if (err) { + of_iounmap(rp, sizeof(struct zilog_layout)); + + return err; + } + } up = &sunzilog_port_table[inst * 2]; @@ -1355,7 +1378,7 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m up[0].port.line = (inst * 2) + 0; up[0].port.dev = &op->dev; up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; - if (keyboard_mouse) + if (inst == 1) up[0].flags |= SUNZILOG_FLAG_CONS_KEYB; sunzilog_init_hw(&up[0]); @@ -1372,11 +1395,11 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m up[1].port.line = (inst * 2) + 1; up[1].port.dev = &op->dev; up[1].flags |= 0; - if (keyboard_mouse) + if (inst == 1) up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE; sunzilog_init_hw(&up[1]); - if (!keyboard_mouse) { + if (inst != 1) { err = uart_add_one_port(&sunzilog_reg, &up[0].port); if (err) { of_iounmap(rp, sizeof(struct zilog_layout)); @@ -1388,18 +1411,9 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m of_iounmap(rp, sizeof(struct zilog_layout)); return err; } - } else { - printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) " - "is a zs\n", - op->dev.bus_id, up[0].port.mapbase, op->irqs[0]); - printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) " - "is a zs\n", - op->dev.bus_id, up[1].port.mapbase, op->irqs[0]); } - dev_set_drvdata(&op->dev, &up[0]); - - inst++; + dev_set_drvdata(&dev->dev, &up[0]); return 0; } @@ -1448,65 +1462,36 @@ static struct of_platform_driver zs_driver = { static int __init sunzilog_init(void) { struct device_node *dp; - int err, uart_count; - int num_keybms; + int err; NUM_SUNZILOG = 0; - num_keybms = 0; - for_each_node_by_name(dp, "zs") { + for_each_node_by_name(dp, "zs") NUM_SUNZILOG++; - if (of_find_property(dp, "keyboard", NULL)) - num_keybms++; - } - uart_count = 0; if (NUM_SUNZILOG) { int uart_count; err = sunzilog_alloc_tables(); if (err) - goto out; + return err; - uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms); + /* Subtract 1 for keyboard, 1 for mouse. */ + uart_count = (NUM_SUNZILOG * 2) - 2; sunzilog_reg.nr = uart_count; sunzilog_reg.minor = sunserial_current_minor; err = uart_register_driver(&sunzilog_reg); - if (err) - goto out_free_tables; - + if (err) { + sunzilog_free_tables(); + return err; + } sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64; sunzilog_reg.cons = SUNZILOG_CONSOLE(); sunserial_current_minor += uart_count; } - err = of_register_driver(&zs_driver, &of_bus_type); - if (err) - goto out_unregister_uart; - - if (zilog_irq != -1) { - err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, - "zs", sunzilog_irq_chain); - if (err) - goto out_unregister_driver; - } - -out: - return err; - -out_unregister_driver: - of_unregister_driver(&zs_driver); - -out_unregister_uart: - if (NUM_SUNZILOG) { - uart_unregister_driver(&sunzilog_reg); - sunzilog_reg.cons = NULL; - } - -out_free_tables: - sunzilog_free_tables(); - goto out; + return of_register_driver(&zs_driver, &of_bus_type); } static void __exit sunzilog_exit(void) diff --git a/trunk/drivers/usb/Kconfig b/trunk/drivers/usb/Kconfig index 005043197527..2ee742d40c43 100644 --- a/trunk/drivers/usb/Kconfig +++ b/trunk/drivers/usb/Kconfig @@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI default y if ARCH_S3C2410 default y if PXA27x default y if ARCH_EP93XX - default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261) + default y if ARCH_AT91RM9200 # PPC: default y if STB03xxx default y if PPC_MPC52xx diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 218621b9958e..f7bdd94b3aa8 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -517,19 +517,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig static struct usb_device *usbdev_lookup_minor(int minor) { - struct class_device *class_dev; - struct usb_device *dev = NULL; + struct device *device; + struct usb_device *udev = NULL; down(&usb_device_class->sem); - list_for_each_entry(class_dev, &usb_device_class->children, node) { - if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { - dev = class_dev->class_data; + list_for_each_entry(device, &usb_device_class->devices, node) { + if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { + udev = device->platform_data; break; } } up(&usb_device_class->sem); - return dev; + return udev; }; /* @@ -1580,16 +1580,16 @@ static void usbdev_add(struct usb_device *dev) { int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); - dev->class_dev = class_device_create(usb_device_class, NULL, - MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, + dev->usbfs_dev = device_create(usb_device_class, &dev->dev, + MKDEV(USB_DEVICE_MAJOR, minor), "usbdev%d.%d", dev->bus->busnum, dev->devnum); - dev->class_dev->class_data = dev; + dev->usbfs_dev->platform_data = dev; } static void usbdev_remove(struct usb_device *dev) { - class_device_unregister(dev->class_dev); + device_unregister(dev->usbfs_dev); } static int usbdev_notify(struct notifier_block *self, unsigned long action, diff --git a/trunk/drivers/usb/core/file.c b/trunk/drivers/usb/core/file.c index 8de4f8c99d61..abee0f5b6a66 100644 --- a/trunk/drivers/usb/core/file.c +++ b/trunk/drivers/usb/core/file.c @@ -194,14 +194,13 @@ int usb_register_dev(struct usb_interface *intf, ++temp; else temp = name; - intf->class_dev = class_device_create(usb_class->class, NULL, - MKDEV(USB_MAJOR, minor), - &intf->dev, "%s", temp); - if (IS_ERR(intf->class_dev)) { + intf->usb_dev = device_create(usb_class->class, &intf->dev, + MKDEV(USB_MAJOR, minor), "%s", temp); + if (IS_ERR(intf->usb_dev)) { spin_lock (&minor_lock); usb_minors[intf->minor] = NULL; spin_unlock (&minor_lock); - retval = PTR_ERR(intf->class_dev); + retval = PTR_ERR(intf->usb_dev); } exit: return retval; @@ -242,8 +241,8 @@ void usb_deregister_dev(struct usb_interface *intf, spin_unlock (&minor_lock); snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); - class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); - intf->class_dev = NULL; + device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); + intf->usb_dev = NULL; intf->minor = -1; destroy_usb_class(); } diff --git a/trunk/drivers/usb/gadget/Kconfig b/trunk/drivers/usb/gadget/Kconfig index 1a32d96774b4..363b2ad74ae6 100644 --- a/trunk/drivers/usb/gadget/Kconfig +++ b/trunk/drivers/usb/gadget/Kconfig @@ -207,7 +207,7 @@ config USB_AT91 config USB_GADGET_DUMMY_HCD boolean "Dummy HCD (DEVELOPMENT)" - depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL + depends on USB && EXPERIMENTAL select USB_GADGET_DUALSPEED help This host controller driver emulates USB, looping all data transfer diff --git a/trunk/drivers/usb/gadget/at91_udc.c b/trunk/drivers/usb/gadget/at91_udc.c index cfebca05ead5..1c459ff037ce 100644 --- a/trunk/drivers/usb/gadget/at91_udc.c +++ b/trunk/drivers/usb/gadget/at91_udc.c @@ -57,23 +57,19 @@ /* * This controller is simple and PIO-only. It's used in many AT91-series - * full speed USB controllers, including the at91rm9200 (arm920T, with MMU), - * at91sam926x (arm926ejs, with MMU), and several no-mmu versions. + * ARMv4T controllers, including the at91rm9200 (arm920T, with MMU), + * at91sam9261 (arm926ejs, with MMU), and several no-mmu versions. * * This driver expects the board has been wired with two GPIOs suppporting * a VBUS sensing IRQ, and a D+ pullup. (They may be omitted, but the - * testing hasn't covered such cases.) - * - * The pullup is most important (so it's integrated on sam926x parts). It + * testing hasn't covered such cases.) The pullup is most important; it * provides software control over whether the host enumerates the device. - * * The VBUS sensing helps during enumeration, and allows both USB clocks * (and the transceiver) to stay gated off until they're necessary, saving - * power. During USB suspend, the 48 MHz clock is gated off in hardware; - * it may also be gated off by software during some Linux sleep states. + * power. During USB suspend, the 48 MHz clock is gated off. */ -#define DRIVER_VERSION "3 May 2006" +#define DRIVER_VERSION "8 March 2005" static const char driver_name [] = "at91_udc"; static const char ep0name[] = "ep0"; @@ -320,15 +316,9 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status) * * There are also state bits like FORCESTALL, EPEDS, DIR, and EPTYPE * that shouldn't normally be changed. - * - * NOTE at91sam9260 docs mention synch between UDPCK and MCK clock domains, - * implying a need to wait for one write to complete (test relevant bits) - * before starting the next write. This shouldn't be an issue given how - * infrequently we write, except maybe for write-then-read idioms. */ #define SET_FX (AT91_UDP_TXPKTRDY) -#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \ - | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP) +#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP) /* pull OUT packet data from the endpoint's fifo */ static int read_fifo (struct at91_ep *ep, struct at91_request *req) @@ -482,8 +472,7 @@ static void nuke(struct at91_ep *ep, int status) /*-------------------------------------------------------------------------*/ -static int at91_ep_enable(struct usb_ep *_ep, - const struct usb_endpoint_descriptor *desc) +static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) { struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); struct at91_udc *dev = ep->udc; @@ -593,12 +582,11 @@ static int at91_ep_disable (struct usb_ep * _ep) * interesting for request or buffer allocation. */ -static struct usb_request * -at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags) +static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags) { struct at91_request *req; - req = kcalloc(1, sizeof (struct at91_request), gfp_flags); + req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL); if (!req) return NULL; @@ -874,7 +862,6 @@ static void stop_activity(struct at91_udc *udc) if (udc->gadget.speed == USB_SPEED_UNKNOWN) driver = NULL; udc->gadget.speed = USB_SPEED_UNKNOWN; - udc->suspended = 0; for (i = 0; i < NUM_ENDPOINTS; i++) { struct at91_ep *ep = &udc->ep[i]; @@ -902,8 +889,8 @@ static void clk_off(struct at91_udc *udc) return; udc->clocked = 0; udc->gadget.speed = USB_SPEED_UNKNOWN; - clk_disable(udc->fclk); clk_disable(udc->iclk); + clk_disable(udc->fclk); } /* @@ -924,6 +911,9 @@ static void pullup(struct at91_udc *udc, int is_on) at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); at91_set_gpio_value(udc->board.pullup_pin, 0); clk_off(udc); + + // REVISIT: with transceiver disabled, will D- float + // so that a host would falsely detect a device? } } @@ -1300,8 +1290,7 @@ static void handle_ep0(struct at91_udc *udc) if (udc->wait_for_addr_ack) { u32 tmp; - at91_udp_write(AT91_UDP_FADDR, - AT91_UDP_FEN | udc->addr); + at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr); tmp = at91_udp_read(AT91_UDP_GLB_STAT); tmp &= ~AT91_UDP_FADDEN; if (udc->addr) @@ -1372,10 +1361,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) u32 rescans = 5; while (rescans--) { - u32 status; + u32 status = at91_udp_read(AT91_UDP_ISR); - status = at91_udp_read(AT91_UDP_ISR) - & at91_udp_read(AT91_UDP_IMR); + status &= at91_udp_read(AT91_UDP_IMR); if (!status) break; @@ -1391,17 +1379,18 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) stop_activity(udc); /* enable ep0 */ - at91_udp_write(AT91_UDP_CSR(0), - AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); + at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); udc->gadget.speed = USB_SPEED_FULL; udc->suspended = 0; at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); /* * NOTE: this driver keeps clocks off unless the - * USB host is present. That saves power, but for - * boards that don't support VBUS detection, both - * clocks need to be active most of the time. + * USB host is present. That saves power, and also + * eliminates IRQs (reset, resume, suspend) that can + * otherwise flood from the controller. If your + * board doesn't support VBUS detection, suspend and + * resume irq logic may need more attention... */ /* host initiated suspend (3+ms bus idle) */ @@ -1463,19 +1452,13 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc, struct pt_regs *r) /*-------------------------------------------------------------------------*/ -static void nop_release(struct device *dev) -{ - /* nothing to free */ -} - static struct at91_udc controller = { .gadget = { - .ops = &at91_udc_ops, - .ep0 = &controller.ep[0].ep, - .name = driver_name, - .dev = { - .bus_id = "gadget", - .release = nop_release, + .ops = &at91_udc_ops, + .ep0 = &controller.ep[0].ep, + .name = driver_name, + .dev = { + .bus_id = "gadget" } }, .ep[0] = { @@ -1485,8 +1468,7 @@ static struct at91_udc controller = { }, .udc = &controller, .maxpacket = 8, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(0)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)), .int_mask = 1 << 0, }, .ep[1] = { @@ -1497,8 +1479,7 @@ static struct at91_udc controller = { .udc = &controller, .is_pingpong = 1, .maxpacket = 64, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(1)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)), .int_mask = 1 << 1, }, .ep[2] = { @@ -1509,8 +1490,7 @@ static struct at91_udc controller = { .udc = &controller, .is_pingpong = 1, .maxpacket = 64, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(2)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)), .int_mask = 1 << 2, }, .ep[3] = { @@ -1521,8 +1501,7 @@ static struct at91_udc controller = { }, .udc = &controller, .maxpacket = 8, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(3)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)), .int_mask = 1 << 3, }, .ep[4] = { @@ -1533,8 +1512,7 @@ static struct at91_udc controller = { .udc = &controller, .is_pingpong = 1, .maxpacket = 256, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(4)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)), .int_mask = 1 << 4, }, .ep[5] = { @@ -1545,11 +1523,10 @@ static struct at91_udc controller = { .udc = &controller, .is_pingpong = 1, .maxpacket = 256, - .creg = (void __iomem *)(AT91_VA_BASE_UDP - + AT91_UDP_CSR(5)), + .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)), .int_mask = 1 << 5, }, - /* ep6 and ep7 are also reserved (custom silicon might use them) */ + /* ep6 and ep7 are also reserved */ }; static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r) @@ -1616,7 +1593,6 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) local_irq_disable(); udc->enabled = 0; - at91_udp_write(AT91_UDP_IDR, ~0); pullup(udc, 0); local_irq_enable(); @@ -1648,16 +1624,6 @@ static int __devinit at91udc_probe(struct platform_device *pdev) return -ENODEV; } - if (pdev->num_resources != 2) { - DBG("invalid num_resources"); - return -ENODEV; - } - if ((pdev->resource[0].flags != IORESOURCE_MEM) - || (pdev->resource[1].flags != IORESOURCE_IRQ)) { - DBG("invalid resource type"); - return -ENODEV; - } - if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) { DBG("someone's using UDC memory\n"); return -EBUSY; @@ -1683,26 +1649,19 @@ static int __devinit at91udc_probe(struct platform_device *pdev) if (retval < 0) goto fail0; - /* don't do anything until we have both gadget driver and VBUS */ - clk_enable(udc->iclk); - at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); - at91_udp_write(AT91_UDP_IDR, 0xffffffff); - clk_disable(udc->iclk); + /* disable everything until there's a gadget driver and vbus */ + pullup(udc, 0); /* request UDC and maybe VBUS irqs */ - udc->udp_irq = platform_get_irq(pdev, 0); - if (request_irq(udc->udp_irq, at91_udc_irq, - IRQF_DISABLED, driver_name, udc)) { - DBG("request irq %d failed\n", udc->udp_irq); + if (request_irq(AT91_ID_UDP, at91_udc_irq, IRQF_DISABLED, driver_name, udc)) { + DBG("request irq %d failed\n", AT91_ID_UDP); retval = -EBUSY; goto fail1; } if (udc->board.vbus_pin > 0) { - if (request_irq(udc->board.vbus_pin, at91_vbus_irq, - IRQF_DISABLED, driver_name, udc)) { - DBG("request vbus irq %d failed\n", - udc->board.vbus_pin); - free_irq(udc->udp_irq, udc); + if (request_irq(udc->board.vbus_pin, at91_vbus_irq, IRQF_DISABLED, driver_name, udc)) { + DBG("request vbus irq %d failed\n", udc->board.vbus_pin); + free_irq(AT91_ID_UDP, udc); retval = -EBUSY; goto fail1; } @@ -1711,7 +1670,6 @@ static int __devinit at91udc_probe(struct platform_device *pdev) udc->vbus = 1; } dev_set_drvdata(dev, udc); - device_init_wakeup(dev, 1); create_debug_file(udc); INFO("%s version %s\n", driver_name, DRIVER_VERSION); @@ -1720,14 +1678,14 @@ static int __devinit at91udc_probe(struct platform_device *pdev) fail1: device_unregister(&udc->gadget.dev); fail0: - release_mem_region(AT91_BASE_UDP, SZ_16K); + release_mem_region(AT91_VA_BASE_UDP, SZ_16K); DBG("%s probe failed, %d\n", driver_name, retval); return retval; } -static int __devexit at91udc_remove(struct platform_device *pdev) +static int __devexit at91udc_remove(struct platform_device *dev) { - struct at91_udc *udc = platform_get_drvdata(pdev); + struct at91_udc *udc = platform_get_drvdata(dev); DBG("remove\n"); @@ -1736,11 +1694,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev) if (udc->driver != 0) usb_gadget_unregister_driver(udc->driver); - device_init_wakeup(&pdev->dev, 0); remove_debug_file(udc); if (udc->board.vbus_pin > 0) free_irq(udc->board.vbus_pin, udc); - free_irq(udc->udp_irq, udc); + free_irq(AT91_ID_UDP, udc); device_unregister(&udc->gadget.dev); release_mem_region(AT91_BASE_UDP, SZ_16K); @@ -1751,36 +1708,31 @@ static int __devexit at91udc_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) +static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg) { - struct at91_udc *udc = platform_get_drvdata(pdev); - int wake = udc->driver && device_may_wakeup(&pdev->dev); + struct at91_udc *udc = platform_get_drvdata(dev); - /* Unless we can act normally to the host (letting it wake us up - * whenever it has work for us) force disconnect. Wakeup requires - * PLLB for USB events (signaling for reset, wakeup, or incoming - * tokens) and VBUS irqs (on systems which support them). + /* + * The "safe" suspend transitions are opportunistic ... e.g. when + * the USB link is suspended (48MHz clock autogated off), or when + * it's disconnected (programmatically gated off, elsewhere). + * Then we can suspend, and the chip can enter slow clock mode. + * + * The problem case is some component (user mode?) suspending this + * device while it's active, with the 48 MHz clock in use. There + * are two basic approaches: (a) veto suspend levels involving slow + * clock mode, (b) disconnect, so 48 MHz will no longer be in use + * and we can enter slow clock mode. This uses (b) for now, since + * it's simplest until AT91 PM exists and supports the other option. */ - if ((!udc->suspended && udc->addr) - || !wake - || at91_suspend_entering_slow_clock()) { + if (udc->vbus && !udc->suspended) pullup(udc, 0); - disable_irq_wake(udc->udp_irq); - } else - enable_irq_wake(udc->udp_irq); - - if (udc->board.vbus_pin > 0) { - if (wake) - enable_irq_wake(udc->board.vbus_pin); - else - disable_irq_wake(udc->board.vbus_pin); - } return 0; } -static int at91udc_resume(struct platform_device *pdev) +static int at91udc_resume(struct platform_device *dev) { - struct at91_udc *udc = platform_get_drvdata(pdev); + struct at91_udc *udc = platform_get_drvdata(dev); /* maybe reconnect to host; if so, clocks on */ pullup(udc, 1); @@ -1796,7 +1748,7 @@ static struct platform_driver at91_udc = { .remove = __devexit_p(at91udc_remove), .shutdown = at91udc_shutdown, .suspend = at91udc_suspend, - .resume = at91udc_resume, + .resume = at91udc_resume, .driver = { .name = (char *) driver_name, .owner = THIS_MODULE, @@ -1815,6 +1767,6 @@ static void __devexit udc_exit_module(void) } module_exit(udc_exit_module); -MODULE_DESCRIPTION("AT91 udc driver"); +MODULE_DESCRIPTION("AT91RM9200 udc driver"); MODULE_AUTHOR("Thomas Rathbone, David Brownell"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/usb/gadget/at91_udc.h b/trunk/drivers/usb/gadget/at91_udc.h index 882af42e86cc..5a4799cedd19 100644 --- a/trunk/drivers/usb/gadget/at91_udc.h +++ b/trunk/drivers/usb/gadget/at91_udc.h @@ -141,7 +141,6 @@ struct at91_udc { struct clk *iclk, *fclk; struct platform_device *pdev; struct proc_dir_entry *pde; - int udp_irq; }; static inline struct at91_udc *to_udc(struct usb_gadget *g) diff --git a/trunk/drivers/usb/gadget/dummy_hcd.c b/trunk/drivers/usb/gadget/dummy_hcd.c index 7d1c22c34957..4be47195bd38 100644 --- a/trunk/drivers/usb/gadget/dummy_hcd.c +++ b/trunk/drivers/usb/gadget/dummy_hcd.c @@ -609,8 +609,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) if (!dum->driver) return -ESHUTDOWN; - local_irq_save (flags); - spin_lock (&dum->lock); + spin_lock_irqsave (&dum->lock, flags); list_for_each_entry (req, &ep->queue, queue) { if (&req->req == _req) { list_del_init (&req->queue); @@ -619,7 +618,7 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) break; } } - spin_unlock (&dum->lock); + spin_unlock_irqrestore (&dum->lock, flags); if (retval == 0) { dev_dbg (udc_dev(dum), @@ -627,7 +626,6 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) req, _ep->name, _req->length, _req->buf); _req->complete (_ep, _req); } - local_irq_restore (flags); return retval; } diff --git a/trunk/drivers/usb/host/ehci-hcd.c b/trunk/drivers/usb/host/ehci-hcd.c index d63177a8eaea..85b0b4ad4c16 100644 --- a/trunk/drivers/usb/host/ehci-hcd.c +++ b/trunk/drivers/usb/host/ehci-hcd.c @@ -892,7 +892,7 @@ MODULE_LICENSE ("GPL"); #define PCI_DRIVER ehci_pci_driver #endif -#ifdef CONFIG_MPC834x +#ifdef CONFIG_PPC_83xx #include "ehci-fsl.c" #define PLATFORM_DRIVER ehci_fsl_driver #endif diff --git a/trunk/drivers/usb/host/ohci-at91.c b/trunk/drivers/usb/host/ohci-at91.c index 85cc059705a6..cdbafb710000 100644 --- a/trunk/drivers/usb/host/ohci-at91.c +++ b/trunk/drivers/usb/host/ohci-at91.c @@ -4,7 +4,7 @@ * Copyright (C) 2004 SAN People (Pty) Ltd. * Copyright (C) 2005 Thibaut VARENE * - * AT91 Bus Glue + * AT91RM9200 Bus Glue * * Based on fragments of 2.4 driver by Rick Bronson. * Based on ohci-omap.c @@ -19,13 +19,12 @@ #include #include -#ifndef CONFIG_ARCH_AT91 -#error "CONFIG_ARCH_AT91 must be defined." +#ifndef CONFIG_ARCH_AT91RM9200 +#error "CONFIG_ARCH_AT91RM9200 must be defined." #endif /* interface and function clocks */ static struct clk *iclk, *fclk; -static int clocked; extern int usb_disabled(void); @@ -36,14 +35,13 @@ static void at91_start_hc(struct platform_device *pdev) struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_regs __iomem *regs = hcd->regs; - dev_dbg(&pdev->dev, "start\n"); + dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n"); /* * Start the USB clocks. */ clk_enable(iclk); clk_enable(fclk); - clocked = 1; /* * The USB host controller must remain in reset. @@ -56,7 +54,7 @@ static void at91_stop_hc(struct platform_device *pdev) struct usb_hcd *hcd = platform_get_drvdata(pdev); struct ohci_regs __iomem *regs = hcd->regs; - dev_dbg(&pdev->dev, "stop\n"); + dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n"); /* * Put the USB host controller into reset. @@ -68,7 +66,6 @@ static void at91_stop_hc(struct platform_device *pdev) */ clk_disable(fclk); clk_disable(iclk); - clocked = 0; } @@ -81,15 +78,14 @@ static int usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *); /** - * usb_hcd_at91_probe - initialize AT91-based HCDs + * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ -static int usb_hcd_at91_probe(const struct hc_driver *driver, - struct platform_device *pdev) +int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev) { int retval; struct usb_hcd *hcd = NULL; @@ -99,13 +95,12 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, return -ENODEV; } - if ((pdev->resource[0].flags != IORESOURCE_MEM) - || (pdev->resource[1].flags != IORESOURCE_IRQ)) { + if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) { pr_debug("hcd probe: invalid resource type\n"); return -ENODEV; } - hcd = usb_create_hcd(driver, &pdev->dev, "at91"); + hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200"); if (!hcd) return -ENOMEM; hcd->rsrc_start = pdev->resource[0].start; @@ -154,23 +149,21 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, /* may be called with controller, bus, and devices active */ /** - * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs + * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs * @dev: USB Host Controller being removed * Context: !in_interrupt() * * Reverses the effect of usb_hcd_at91_probe(), first invoking * the HCD's stop() method. It is always called from a thread - * context, "rmmod" or something similar. + * context, normally "rmmod", "apmd", or something similar. * */ -static int usb_hcd_at91_remove(struct usb_hcd *hcd, - struct platform_device *pdev) +static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev) { usb_remove_hcd(hcd); at91_stop_hc(pdev); iounmap(hcd->regs); release_mem_region(hcd->rsrc_start, hcd->rsrc_len); - disable_irq_wake(hcd->irq); clk_put(fclk); clk_put(iclk); @@ -185,21 +178,19 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, static int __devinit ohci_at91_start (struct usb_hcd *hcd) { - struct at91_usbh_data *board = hcd->self.controller->platform_data; +// struct at91_ohci_data *board = hcd->self.controller->platform_data; struct ohci_hcd *ohci = hcd_to_ohci (hcd); - struct usb_device *root = hcd->self.root_hub; int ret; if ((ret = ohci_init(ohci)) < 0) return ret; - root->maxchild = board->ports; - if ((ret = ohci_run(ohci)) < 0) { err("can't start %s", hcd->self.bus_name); ohci_stop(hcd); return ret; } +// hcd->self.root_hub->maxchild = board->ports; return 0; } @@ -207,7 +198,7 @@ ohci_at91_start (struct usb_hcd *hcd) static const struct hc_driver ohci_at91_hc_driver = { .description = hcd_name, - .product_desc = "AT91 OHCI", + .product_desc = "AT91RM9200 OHCI", .hcd_priv_size = sizeof(struct ohci_hcd), /* @@ -249,54 +240,33 @@ static const struct hc_driver ohci_at91_hc_driver = { /*-------------------------------------------------------------------------*/ -static int ohci_hcd_at91_drv_probe(struct platform_device *pdev) +static int ohci_hcd_at91_drv_probe(struct platform_device *dev) { - device_init_wakeup(&pdev->dev, 1); - return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev); + return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev); } -static int ohci_hcd_at91_drv_remove(struct platform_device *pdev) +static int ohci_hcd_at91_drv_remove(struct platform_device *dev) { - device_init_wakeup(&pdev->dev, 0); - return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev); + return usb_hcd_at91_remove(platform_get_drvdata(dev), dev); } #ifdef CONFIG_PM +/* REVISIT suspend/resume look "too" simple here */ + static int -ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) +ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg) { - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct ohci_hcd *ohci = hcd_to_ohci(hcd); - - if (device_may_wakeup(&pdev->dev)) - enable_irq_wake(hcd->irq); - else - disable_irq_wake(hcd->irq); - - /* - * The integrated transceivers seem unable to notice disconnect, - * reconnect, or wakeup without the 48 MHz clock active. so for - * correctness, always discard connection state (using reset). - * - * REVISIT: some boards will be able to turn VBUS off... - */ - if (at91_suspend_entering_slow_clock()) { - ohci_usb_reset (ohci); - clk_disable(fclk); - clk_disable(iclk); - clocked = 0; - } + clk_disable(fclk); + clk_disable(iclk); return 0; } -static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) +static int ohci_hcd_at91_drv_resume(struct platform_device *dev) { - if (!clocked) { - clk_enable(iclk); - clk_enable(fclk); - } + clk_enable(iclk); + clk_enable(fclk); return 0; } @@ -305,7 +275,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) #define ohci_hcd_at91_drv_resume NULL #endif -MODULE_ALIAS("at91_ohci"); +MODULE_ALIAS("at91rm9200-ohci"); static struct platform_driver ohci_hcd_at91_driver = { .probe = ohci_hcd_at91_drv_probe, @@ -313,7 +283,7 @@ static struct platform_driver ohci_hcd_at91_driver = { .suspend = ohci_hcd_at91_drv_suspend, .resume = ohci_hcd_at91_drv_resume, .driver = { - .name = "at91_ohci", + .name = "at91rm9200-ohci", .owner = THIS_MODULE, }, }; diff --git a/trunk/drivers/usb/host/ohci-hcd.c b/trunk/drivers/usb/host/ohci-hcd.c index 94d8cf4b36c1..afef5ac35b4a 100644 --- a/trunk/drivers/usb/host/ohci-hcd.c +++ b/trunk/drivers/usb/host/ohci-hcd.c @@ -913,7 +913,7 @@ MODULE_LICENSE ("GPL"); #include "ohci-ppc-soc.c" #endif -#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261) +#ifdef CONFIG_ARCH_AT91RM9200 #include "ohci-at91.c" #endif @@ -927,7 +927,6 @@ MODULE_LICENSE ("GPL"); || defined (CONFIG_SOC_AU1X00) \ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ || defined (CONFIG_ARCH_AT91RM9200) \ - || defined (CONFIG_ARCH_AT91SAM9261) \ ) #error "missing bus glue for ohci-hcd" #endif diff --git a/trunk/drivers/usb/host/uhci-q.c b/trunk/drivers/usb/host/uhci-q.c index 66c3f61bc9d1..c9d72ac0a1d7 100644 --- a/trunk/drivers/usb/host/uhci-q.c +++ b/trunk/drivers/usb/host/uhci-q.c @@ -943,9 +943,7 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) /* We received a short packet */ if (urb->transfer_flags & URB_SHORT_NOT_OK) ret = -EREMOTEIO; - - /* Fixup needed only if this isn't the URB's last TD */ - else if (&td->list != urbp->td_list.prev) + else if (ctrlstat & TD_CTRL_SPD) ret = 1; } diff --git a/trunk/drivers/usb/input/ati_remote.c b/trunk/drivers/usb/input/ati_remote.c index 3719fcb04b8f..05d2d6012eb2 100644 --- a/trunk/drivers/usb/input/ati_remote.c +++ b/trunk/drivers/usb/input/ati_remote.c @@ -111,28 +111,14 @@ #define NAME_BUFSIZE 80 /* size of product name, path buffers */ #define DATA_BUFSIZE 63 /* size of URB data buffers */ -/* - * Duplicate event filtering time. - * Sequential, identical KIND_FILTERED inputs with less than - * FILTER_TIME milliseconds between them are considered as repeat - * events. The hardware generates 5 events for the first keypress - * and we have to take this into account for an accurate repeat - * behaviour. - */ -#define FILTER_TIME 60 /* msec */ - static unsigned long channel_mask; -module_param(channel_mask, ulong, 0644); +module_param(channel_mask, ulong, 0444); MODULE_PARM_DESC(channel_mask, "Bitmask of remote control channels to ignore"); static int debug; -module_param(debug, int, 0644); +module_param(debug, int, 0444); MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); -static int repeat_filter = FILTER_TIME; -module_param(repeat_filter, int, 0644); -MODULE_PARM_DESC(repeat_filter, "Repeat filter time, default = 60 msec"); - #define dbginfo(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) #undef err #define err(format, arg...) printk(KERN_ERR format , ## arg) @@ -157,6 +143,19 @@ MODULE_DEVICE_TABLE(usb, ati_remote_table); static char init1[] = { 0x01, 0x00, 0x20, 0x14 }; static char init2[] = { 0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20 }; +/* Acceleration curve for directional control pad */ +static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; + +/* Duplicate event filtering time. + * Sequential, identical KIND_FILTERED inputs with less than + * FILTER_TIME jiffies between them are considered as repeat + * events. The hardware generates 5 events for the first keypress + * and we have to take this into account for an accurate repeat + * behaviour. + * (HZ / 20) == 50 ms and works well for me. + */ +#define FILTER_TIME (HZ / 20) + struct ati_remote { struct input_dev *idev; struct usb_device *udev; @@ -413,43 +412,6 @@ static int ati_remote_event_lookup(int rem, unsigned char d1, unsigned char d2) return -1; } -/* - * ati_remote_compute_accel - * - * Implements acceleration curve for directional control pad - * If elapsed time since last event is > 1/4 second, user "stopped", - * so reset acceleration. Otherwise, user is probably holding the control - * pad down, so we increase acceleration, ramping up over two seconds to - * a maximum speed. - */ -static int ati_remote_compute_accel(struct ati_remote *ati_remote) -{ - static const char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; - unsigned long now = jiffies; - int acc; - - if (time_after(now, ati_remote->old_jiffies + msecs_to_jiffies(250))) { - acc = 1; - ati_remote->acc_jiffies = now; - } - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(125))) - acc = accel[0]; - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(250))) - acc = accel[1]; - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(500))) - acc = accel[2]; - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1000))) - acc = accel[3]; - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(1500))) - acc = accel[4]; - else if (time_before(now, ati_remote->acc_jiffies + msecs_to_jiffies(2000))) - acc = accel[5]; - else - acc = accel[6]; - - return acc; -} - /* * ati_remote_report_input */ @@ -503,9 +465,9 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) if (ati_remote_tbl[index].kind == KIND_FILTERED) { /* Filter duplicate events which happen "too close" together. */ - if (ati_remote->old_data[0] == data[1] && - ati_remote->old_data[1] == data[2] && - time_before(jiffies, ati_remote->old_jiffies + msecs_to_jiffies(repeat_filter))) { + if ((ati_remote->old_data[0] == data[1]) && + (ati_remote->old_data[1] == data[2]) && + time_before(jiffies, ati_remote->old_jiffies + FILTER_TIME)) { ati_remote->repeat_count++; } else { ati_remote->repeat_count = 0; @@ -515,61 +477,75 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) ati_remote->old_data[1] = data[2]; ati_remote->old_jiffies = jiffies; - if (ati_remote->repeat_count > 0 && - ati_remote->repeat_count < 5) + if ((ati_remote->repeat_count > 0) + && (ati_remote->repeat_count < 5)) return; input_regs(dev, regs); input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, 1); - input_sync(dev); input_event(dev, ati_remote_tbl[index].type, ati_remote_tbl[index].code, 0); input_sync(dev); - } else { - - /* - * Other event kinds are from the directional control pad, and have an - * acceleration factor applied to them. Without this acceleration, the - * control pad is mostly unusable. - */ - acc = ati_remote_compute_accel(ati_remote); - - input_regs(dev, regs); - switch (ati_remote_tbl[index].kind) { - case KIND_ACCEL: - input_event(dev, ati_remote_tbl[index].type, - ati_remote_tbl[index].code, - ati_remote_tbl[index].value * acc); - break; - case KIND_LU: - input_report_rel(dev, REL_X, -acc); - input_report_rel(dev, REL_Y, -acc); - break; - case KIND_RU: - input_report_rel(dev, REL_X, acc); - input_report_rel(dev, REL_Y, -acc); - break; - case KIND_LD: - input_report_rel(dev, REL_X, -acc); - input_report_rel(dev, REL_Y, acc); - break; - case KIND_RD: - input_report_rel(dev, REL_X, acc); - input_report_rel(dev, REL_Y, acc); - break; - default: - dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", - ati_remote_tbl[index].kind); - } - input_sync(dev); + return; + } - ati_remote->old_jiffies = jiffies; - ati_remote->old_data[0] = data[1]; - ati_remote->old_data[1] = data[2]; + /* + * Other event kinds are from the directional control pad, and have an + * acceleration factor applied to them. Without this acceleration, the + * control pad is mostly unusable. + * + * If elapsed time since last event is > 1/4 second, user "stopped", + * so reset acceleration. Otherwise, user is probably holding the control + * pad down, so we increase acceleration, ramping up over two seconds to + * a maximum speed. The acceleration curve is #defined above. + */ + if (time_after(jiffies, ati_remote->old_jiffies + (HZ >> 2))) { + acc = 1; + ati_remote->acc_jiffies = jiffies; + } + else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 3))) acc = accel[0]; + else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 2))) acc = accel[1]; + else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ >> 1))) acc = accel[2]; + else if (time_before(jiffies, ati_remote->acc_jiffies + HZ)) acc = accel[3]; + else if (time_before(jiffies, ati_remote->acc_jiffies + HZ+(HZ>>1))) acc = accel[4]; + else if (time_before(jiffies, ati_remote->acc_jiffies + (HZ << 1))) acc = accel[5]; + else acc = accel[6]; + + input_regs(dev, regs); + switch (ati_remote_tbl[index].kind) { + case KIND_ACCEL: + input_event(dev, ati_remote_tbl[index].type, + ati_remote_tbl[index].code, + ati_remote_tbl[index].value * acc); + break; + case KIND_LU: + input_report_rel(dev, REL_X, -acc); + input_report_rel(dev, REL_Y, -acc); + break; + case KIND_RU: + input_report_rel(dev, REL_X, acc); + input_report_rel(dev, REL_Y, -acc); + break; + case KIND_LD: + input_report_rel(dev, REL_X, -acc); + input_report_rel(dev, REL_Y, acc); + break; + case KIND_RD: + input_report_rel(dev, REL_X, acc); + input_report_rel(dev, REL_Y, acc); + break; + default: + dev_dbg(&ati_remote->interface->dev, "ati_remote kind=%d\n", + ati_remote_tbl[index].kind); } + input_sync(dev); + + ati_remote->old_jiffies = jiffies; + ati_remote->old_data[0] = data[1]; + ati_remote->old_data[1] = data[2]; } /* diff --git a/trunk/drivers/usb/input/hid-input.c b/trunk/drivers/usb/input/hid-input.c index 7208839f2dbf..028e1ad89f5d 100644 --- a/trunk/drivers/usb/input/hid-input.c +++ b/trunk/drivers/usb/input/hid-input.c @@ -607,8 +607,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel } - if (usage->type == EV_ABS && - (usage->hat_min < usage->hat_max || usage->hat_dir)) { + if (usage->hat_min < usage->hat_max || usage->hat_dir) { int i; for (i = usage->code; i < usage->code + 2 && i <= max; i++) { input_set_abs_params(input, i, -1, 1, 0, 0); diff --git a/trunk/drivers/usb/input/hiddev.c b/trunk/drivers/usb/input/hiddev.c index f6b839c257a7..70477f02cc29 100644 --- a/trunk/drivers/usb/input/hiddev.c +++ b/trunk/drivers/usb/input/hiddev.c @@ -49,7 +49,7 @@ struct hiddev { int open; wait_queue_head_t wait; struct hid_device *hid; - struct list_head list; + struct hiddev_list *list; }; struct hiddev_list { @@ -59,7 +59,7 @@ struct hiddev_list { unsigned flags; struct fasync_struct *fasync; struct hiddev *hiddev; - struct list_head node; + struct hiddev_list *next; }; static struct hiddev *hiddev_table[HIDDEV_MINORS]; @@ -73,15 +73,12 @@ static struct hiddev *hiddev_table[HIDDEV_MINORS]; static struct hid_report * hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) { - unsigned int flags = rinfo->report_id & ~HID_REPORT_ID_MASK; - unsigned int rid = rinfo->report_id & HID_REPORT_ID_MASK; + unsigned flags = rinfo->report_id & ~HID_REPORT_ID_MASK; struct hid_report_enum *report_enum; - struct hid_report *report; struct list_head *list; if (rinfo->report_type < HID_REPORT_TYPE_MIN || - rinfo->report_type > HID_REPORT_TYPE_MAX) - return NULL; + rinfo->report_type > HID_REPORT_TYPE_MAX) return NULL; report_enum = hid->report_enum + (rinfo->report_type - HID_REPORT_TYPE_MIN); @@ -91,25 +88,21 @@ hiddev_lookup_report(struct hid_device *hid, struct hiddev_report_info *rinfo) break; case HID_REPORT_ID_FIRST: - if (list_empty(&report_enum->report_list)) - return NULL; - list = report_enum->report_list.next; - report = list_entry(list, struct hid_report, list); - rinfo->report_id = report->id; + if (list == &report_enum->report_list) + return NULL; + rinfo->report_id = ((struct hid_report *) list)->id; break; case HID_REPORT_ID_NEXT: - report = report_enum->report_id_hash[rid]; - if (!report) + list = (struct list_head *) + report_enum->report_id_hash[rinfo->report_id & HID_REPORT_ID_MASK]; + if (list == NULL) return NULL; - - list = report->list.next; + list = list->next; if (list == &report_enum->report_list) return NULL; - - report = list_entry(list, struct hid_report, list); - rinfo->report_id = report->id; + rinfo->report_id = ((struct hid_report *) list)->id; break; default: @@ -132,13 +125,12 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) struct hid_field *field; if (uref->report_type < HID_REPORT_TYPE_MIN || - uref->report_type > HID_REPORT_TYPE_MAX) - return NULL; + uref->report_type > HID_REPORT_TYPE_MAX) return NULL; report_enum = hid->report_enum + (uref->report_type - HID_REPORT_TYPE_MIN); - list_for_each_entry(report, &report_enum->report_list, list) { + list_for_each_entry(report, &report_enum->report_list, list) for (i = 0; i < report->maxfield; i++) { field = report->field[i]; for (j = 0; j < field->maxusage; j++) { @@ -150,7 +142,6 @@ hiddev_lookup_usage(struct hid_device *hid, struct hiddev_usage_ref *uref) } } } - } return NULL; } @@ -159,9 +150,9 @@ static void hiddev_send_event(struct hid_device *hid, struct hiddev_usage_ref *uref) { struct hiddev *hiddev = hid->hiddev; - struct hiddev_list *list; + struct hiddev_list *list = hiddev->list; - list_for_each_entry(list, &hiddev->list, node) { + while (list) { if (uref->field_index != HID_FIELD_INDEX_NONE || (list->flags & HIDDEV_FLAG_REPORT) != 0) { list->buffer[list->head] = *uref; @@ -169,6 +160,8 @@ static void hiddev_send_event(struct hid_device *hid, (HIDDEV_BUFFER_SIZE - 1); kill_fasync(&list->fasync, SIGIO, POLL_IN); } + + list = list->next; } wake_up_interruptible(&hiddev->wait); @@ -187,7 +180,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, uref.report_type = (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : - ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); + ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); uref.report_id = field->report->id; uref.field_index = field->index; uref.usage_index = (usage - field->usage); @@ -207,7 +200,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) uref.report_type = (type == HID_INPUT_REPORT) ? HID_REPORT_TYPE_INPUT : ((type == HID_OUTPUT_REPORT) ? HID_REPORT_TYPE_OUTPUT : - ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE : 0)); + ((type == HID_FEATURE_REPORT) ? HID_REPORT_TYPE_FEATURE:0)); uref.report_id = report->id; uref.field_index = HID_FIELD_INDEX_NONE; @@ -220,9 +213,7 @@ static int hiddev_fasync(int fd, struct file *file, int on) { int retval; struct hiddev_list *list = file->private_data; - retval = fasync_helper(fd, file, on, &list->fasync); - return retval < 0 ? retval : 0; } @@ -233,9 +224,14 @@ static int hiddev_fasync(int fd, struct file *file, int on) static int hiddev_release(struct inode * inode, struct file * file) { struct hiddev_list *list = file->private_data; + struct hiddev_list **listptr; + listptr = &list->hiddev->list; hiddev_fasync(-1, file, 0); - list_del(&list->node); + + while (*listptr && (*listptr != list)) + listptr = &((*listptr)->next); + *listptr = (*listptr)->next; if (!--list->hiddev->open) { if (list->hiddev->exist) @@ -252,8 +248,7 @@ static int hiddev_release(struct inode * inode, struct file * file) /* * open file op */ -static int hiddev_open(struct inode *inode, struct file *file) -{ +static int hiddev_open(struct inode * inode, struct file * file) { struct hiddev_list *list; int i = iminor(inode) - HIDDEV_MINOR_BASE; @@ -265,7 +260,9 @@ static int hiddev_open(struct inode *inode, struct file *file) return -ENOMEM; list->hiddev = hiddev_table[i]; - list_add_tail(&list->node, &hiddev_table[i]->list); + list->next = hiddev_table[i]->list; + hiddev_table[i]->list = list; + file->private_data = list; if (!list->hiddev->open++) @@ -365,7 +362,6 @@ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t coun static unsigned int hiddev_poll(struct file *file, poll_table *wait) { struct hiddev_list *list = file->private_data; - poll_wait(file, &list->hiddev->wait, wait); if (list->head != list->tail) return POLLIN | POLLRDNORM; @@ -386,7 +382,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; - struct hiddev_usage_ref_multi *uref_multi = NULL; + struct hiddev_usage_ref_multi *uref_multi=NULL; struct hiddev_usage_ref *uref; struct hiddev_devinfo dinfo; struct hid_report *report; @@ -768,15 +764,15 @@ int hiddev_connect(struct hid_device *hid) } init_waitqueue_head(&hiddev->wait); - INIT_LIST_HEAD(&hiddev->list); + + hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; + hiddev->hid = hid; hiddev->exist = 1; hid->minor = hid->intf->minor; hid->hiddev = hiddev; - hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; - return 0; } diff --git a/trunk/drivers/usb/misc/cypress_cy7c63.c b/trunk/drivers/usb/misc/cypress_cy7c63.c index a4062a6adbb8..e091d327bd9e 100644 --- a/trunk/drivers/usb/misc/cypress_cy7c63.c +++ b/trunk/drivers/usb/misc/cypress_cy7c63.c @@ -12,13 +12,8 @@ * the single I/O ports of the device. * * Supported vendors: AK Modul-Bus Computer GmbH -* (Firmware "Port-Chip") -* -* Supported devices: CY7C63001A-PC -* CY7C63001C-PXC -* CY7C63001C-SXC -* -* Supported functions: Read/Write Ports +* Supported devices: CY7C63001A-PC (to be continued...) +* Supported functions: Read/Write Ports (to be continued...) * * * This program is free software; you can redistribute it and/or diff --git a/trunk/drivers/usb/net/rtl8150.c b/trunk/drivers/usb/net/rtl8150.c index bd09232ce13c..e5e6e4f3ef87 100644 --- a/trunk/drivers/usb/net/rtl8150.c +++ b/trunk/drivers/usb/net/rtl8150.c @@ -175,8 +175,6 @@ static inline struct sk_buff *pull_skb(rtl8150_t *); static void rtl8150_disconnect(struct usb_interface *intf); static int rtl8150_probe(struct usb_interface *intf, const struct usb_device_id *id); -static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message); -static int rtl8150_resume(struct usb_interface *intf); static const char driver_name [] = "rtl8150"; @@ -185,8 +183,6 @@ static struct usb_driver rtl8150_driver = { .probe = rtl8150_probe, .disconnect = rtl8150_disconnect, .id_table = rtl8150_table, - .suspend = rtl8150_suspend, - .resume = rtl8150_resume }; /* @@ -242,11 +238,9 @@ static int async_set_registers(rtl8150_t * dev, u16 indx, u16 size) usb_fill_control_urb(dev->ctrl_urb, dev->udev, usb_sndctrlpipe(dev->udev, 0), (char *) &dev->dr, &dev->rx_creg, size, ctrl_callback, dev); - if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) { - if (ret == -ENODEV) - netif_device_detach(dev->netdev); + if ((ret = usb_submit_urb(dev->ctrl_urb, GFP_ATOMIC))) err("control request submission failed: %d", ret); - } else + else set_bit(RX_REG_SET, &dev->flags); return ret; @@ -422,7 +416,6 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) struct sk_buff *skb; struct net_device *netdev; u16 rx_stat; - int status; dev = urb->context; if (!dev) @@ -472,10 +465,7 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) goon: usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); - status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); - if (status == -ENODEV) - netif_device_detach(dev->netdev); - else if (status) { + if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { set_bit(RX_URB_FAIL, &dev->flags); goto resched; } else { @@ -491,7 +481,6 @@ static void rx_fixup(unsigned long data) { rtl8150_t *dev; struct sk_buff *skb; - int status; dev = (rtl8150_t *)data; @@ -510,13 +499,10 @@ static void rx_fixup(unsigned long data) usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); try_again: - status = usb_submit_urb(dev->rx_urb, GFP_ATOMIC); - if (status == -ENODEV) { - netif_device_detach(dev->netdev); - } else if (status) { + if (usb_submit_urb(dev->rx_urb, GFP_ATOMIC)) { set_bit(RX_URB_FAIL, &dev->flags); goto tlsched; - } else { + } else { clear_bit(RX_URB_FAIL, &dev->flags); } @@ -588,43 +574,12 @@ static void intr_callback(struct urb *urb, struct pt_regs *regs) resubmit: status = usb_submit_urb (urb, SLAB_ATOMIC); - if (status == -ENODEV) - netif_device_detach(dev->netdev); - else if (status) + if (status) err ("can't resubmit intr, %s-%s/input0, status %d", dev->udev->bus->bus_name, dev->udev->devpath, status); } -static int rtl8150_suspend(struct usb_interface *intf, pm_message_t message) -{ - rtl8150_t *dev = usb_get_intfdata(intf); - - netif_device_detach(dev->netdev); - - if (netif_running(dev->netdev)) { - usb_kill_urb(dev->rx_urb); - usb_kill_urb(dev->intr_urb); - } - return 0; -} - -static int rtl8150_resume(struct usb_interface *intf) -{ - rtl8150_t *dev = usb_get_intfdata(intf); - - netif_device_attach(dev->netdev); - if (netif_running(dev->netdev)) { - dev->rx_urb->status = 0; - dev->rx_urb->actual_length = 0; - read_bulk_callback(dev->rx_urb, NULL); - - dev->intr_urb->status = 0; - dev->intr_urb->actual_length = 0; - intr_callback(dev->intr_urb, NULL); - } - return 0; -} /* ** @@ -735,14 +690,9 @@ static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev) usb_fill_bulk_urb(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), skb->data, count, write_bulk_callback, dev); if ((res = usb_submit_urb(dev->tx_urb, GFP_ATOMIC))) { - /* Can we get/handle EPIPE here? */ - if (res == -ENODEV) - netif_device_detach(dev->netdev); - else { - warn("failed tx_urb %d\n", res); - dev->stats.tx_errors++; - netif_start_queue(netdev); - } + warn("failed tx_urb %d\n", res); + dev->stats.tx_errors++; + netif_start_queue(netdev); } else { dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; @@ -779,25 +729,16 @@ static int rtl8150_open(struct net_device *netdev) usb_fill_bulk_urb(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), dev->rx_skb->data, RTL8150_MTU, read_bulk_callback, dev); - if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) { - if (res == -ENODEV) - netif_device_detach(dev->netdev); + if ((res = usb_submit_urb(dev->rx_urb, GFP_KERNEL))) warn("%s: rx_urb submit failed: %d", __FUNCTION__, res); - return res; - } usb_fill_int_urb(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3), dev->intr_buff, INTBUFSIZE, intr_callback, dev, dev->intr_interval); - if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) { - if (res == -ENODEV) - netif_device_detach(dev->netdev); + if ((res = usb_submit_urb(dev->intr_urb, GFP_KERNEL))) warn("%s: intr_urb submit failed: %d", __FUNCTION__, res); - usb_kill_urb(dev->rx_urb); - return res; - } + netif_start_queue(netdev); enable_net_traffic(dev); set_carrier(netdev); - netif_start_queue(netdev); return res; } diff --git a/trunk/drivers/usb/serial/Kconfig b/trunk/drivers/usb/serial/Kconfig index f5b9438c94f0..ac33bd47cfce 100644 --- a/trunk/drivers/usb/serial/Kconfig +++ b/trunk/drivers/usb/serial/Kconfig @@ -62,6 +62,15 @@ config USB_SERIAL_AIRPRIME To compile this driver as a module, choose M here: the module will be called airprime. +config USB_SERIAL_ANYDATA + tristate "USB AnyData CDMA Wireless Driver" + depends on USB_SERIAL + help + Say Y here if you want to use a AnyData CDMA device. + + To compile this driver as a module, choose M here: the + module will be called anydata. + config USB_SERIAL_ARK3116 tristate "USB ARK Micro 3116 USB Serial Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL @@ -493,18 +502,15 @@ config USB_SERIAL_XIRCOM module will be called keyspan_pda. config USB_SERIAL_OPTION - tristate "USB driver for GSM and CDMA modems" + tristate "USB driver for GSM modems" depends on USB_SERIAL help - Say Y here if you have a GSM or CDMA modem that's connected to USB. - - This driver also supports several PCMCIA cards which have a - built-in OHCI-USB adapter and an internally-connected GSM modem. - The USB bus on these cards is not accessible externally. + Say Y here if you have an "Option" GSM PCMCIA card + (or an OEM version: branded Huawei, Audiovox, or Novatel). - Supported devices include (some of?) those made by: - Option, Huawei, Audiovox, Sierra Wireless, Novatel Wireless, or - Anydata. + These cards feature a built-in OHCI-USB adapter and an + internally-connected GSM modem. The USB bus is not + accessible externally. To compile this driver as a module, choose M here: the module will be called option. diff --git a/trunk/drivers/usb/serial/Makefile b/trunk/drivers/usb/serial/Makefile index 8efed2ce1ba3..35d4acc7f1d3 100644 --- a/trunk/drivers/usb/serial/Makefile +++ b/trunk/drivers/usb/serial/Makefile @@ -12,6 +12,7 @@ usbserial-obj-$(CONFIG_USB_EZUSB) += ezusb.o usbserial-objs := usb-serial.o generic.o bus.o $(usbserial-obj-y) obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o +obj-$(CONFIG_USB_SERIAL_ANYDATA) += anydata.o obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o diff --git a/trunk/drivers/usb/serial/anydata.c b/trunk/drivers/usb/serial/anydata.c new file mode 100644 index 000000000000..01843ef8c11e --- /dev/null +++ b/trunk/drivers/usb/serial/anydata.c @@ -0,0 +1,123 @@ +/* + * AnyData CDMA Serial USB driver + * + * Copyright (C) 2005 Greg Kroah-Hartman + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version + * 2 as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +static struct usb_device_id id_table [] = { + { USB_DEVICE(0x16d5, 0x6501) }, /* AirData CDMA device */ + { }, +}; +MODULE_DEVICE_TABLE(usb, id_table); + +/* if overridden by the user, then use their value for the size of the + * read and write urbs */ +static int buffer_size; +static int debug; + +static struct usb_driver anydata_driver = { + .name = "anydata", + .probe = usb_serial_probe, + .disconnect = usb_serial_disconnect, + .id_table = id_table, + .no_dynamic_id = 1, +}; + +static int anydata_open(struct usb_serial_port *port, struct file *filp) +{ + char *buffer; + int result = 0; + + dbg("%s - port %d", __FUNCTION__, port->number); + + if (buffer_size) { + /* override the default buffer sizes */ + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) { + dev_err(&port->dev, "%s - out of memory.\n", + __FUNCTION__); + return -ENOMEM; + } + kfree (port->read_urb->transfer_buffer); + port->read_urb->transfer_buffer = buffer; + port->read_urb->transfer_buffer_length = buffer_size; + + buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!buffer) { + dev_err(&port->dev, "%s - out of memory.\n", + __FUNCTION__); + return -ENOMEM; + } + kfree (port->write_urb->transfer_buffer); + port->write_urb->transfer_buffer = buffer; + port->write_urb->transfer_buffer_length = buffer_size; + port->bulk_out_size = buffer_size; + } + + /* Start reading from the device */ + usb_fill_bulk_urb(port->read_urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + usb_serial_generic_read_bulk_callback, port); + result = usb_submit_urb(port->read_urb, GFP_KERNEL); + if (result) + dev_err(&port->dev, + "%s - failed submitting read urb, error %d\n", + __FUNCTION__, result); + + return result; +} + +static struct usb_serial_driver anydata_device = { + .driver = { + .owner = THIS_MODULE, + .name = "anydata", + }, + .id_table = id_table, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 1, + .open = anydata_open, +}; + +static int __init anydata_init(void) +{ + int retval; + + retval = usb_serial_register(&anydata_device); + if (retval) + return retval; + retval = usb_register(&anydata_driver); + if (retval) + usb_serial_deregister(&anydata_device); + return retval; +} + +static void __exit anydata_exit(void) +{ + usb_deregister(&anydata_driver); + usb_serial_deregister(&anydata_device); +} + +module_init(anydata_init); +module_exit(anydata_exit); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug enabled or not"); +module_param(buffer_size, int, 0); +MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers"); diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index a20da8528a5f..b458aedc5fb6 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -337,7 +337,6 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, - { USB_DEVICE(FTDI_VID, FTDI_TNC_X_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2103_PID) }, diff --git a/trunk/drivers/usb/serial/ftdi_sio.h b/trunk/drivers/usb/serial/ftdi_sio.h index 9f7343a45424..04ef90fcb876 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.h +++ b/trunk/drivers/usb/serial/ftdi_sio.h @@ -182,10 +182,6 @@ /* http://home.earthlink.net/~jrhees/USBUIRT/index.htm */ #define FTDI_USB_UIRT_PID 0xF850 /* Product Id */ -/* TNC-X USB-to-packet-radio adapter, versions prior to 3.0 (DLP module) */ - -#define FTDI_TNC_X_PID 0xEBE0 - /* * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). * All of these devices use FTDI's vendor ID (0x0403). diff --git a/trunk/drivers/usb/serial/ipaq.c b/trunk/drivers/usb/serial/ipaq.c index 7e1bd5d6dfa0..59c5d999009a 100644 --- a/trunk/drivers/usb/serial/ipaq.c +++ b/trunk/drivers/usb/serial/ipaq.c @@ -250,7 +250,6 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */ { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */ - { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */ { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c index c856e6f40e22..f0530c1d7b7a 100644 --- a/trunk/drivers/usb/serial/option.c +++ b/trunk/drivers/usb/serial/option.c @@ -9,14 +9,40 @@ Portions copied from the Keyspan driver by Hugh Blemings - History: see the git log. + History: + + 2005-05-19 v0.1 Initial version, based on incomplete docs + and analysis of misbehavior with the standard driver + 2005-05-20 v0.2 Extended the input buffer to avoid losing + random 64-byte chunks of data + 2005-05-21 v0.3 implemented chars_in_buffer() + turned on low_latency + simplified the code somewhat + 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load + removed some dead code + added sponsor notice + coding style clean-up + 2005-06-20 v0.4.1 add missing braces :-/ + killed end-of-line whitespace + 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2 + 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard + 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes + wants to send >2000 bytes. + 2006-04-10 v0.5 fixed two array overrun errors :-/ + 2006-04-21 v0.5.1 added support for Sierra Wireless MC8755 + 2006-05-15 v0.6 re-enable multi-port support + 2006-06-01 v0.6.1 add COBRA + 2006-06-01 v0.6.2 add backwards-compatibility stuff + 2006-06-01 v0.6.3 add Novatel Wireless + 2006-06-01 v0.7 Option => GSM + 2006-06-01 v0.7.1 add COBRA2 Work sponsored by: Sigos GmbH, Germany This driver exists because the "normal" serial driver doesn't work too well with GSM modems. Issues: - data loss -- one single Receive URB is not nearly enough - - nonstandard flow (Option devices) control + - nonstandard flow (Option devices) and multiplex (Sierra) control - controlling the baud rate doesn't make sense This driver is named "option" because the most common device it's @@ -70,8 +96,8 @@ static int option_send_setup(struct usb_serial_port *port); #define OPTION_VENDOR_ID 0x0AF0 #define HUAWEI_VENDOR_ID 0x12D1 #define AUDIOVOX_VENDOR_ID 0x0F3D +#define SIERRAWIRELESS_VENDOR_ID 0x1199 #define NOVATELWIRELESS_VENDOR_ID 0x1410 -#define ANYDATA_VENDOR_ID 0x16d5 #define OPTION_PRODUCT_OLD 0x5000 #define OPTION_PRODUCT_FUSION 0x6000 @@ -80,8 +106,8 @@ static int option_send_setup(struct usb_serial_port *port); #define OPTION_PRODUCT_COBRA2 0x6600 #define HUAWEI_PRODUCT_E600 0x1001 #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 +#define SIERRAWIRELESS_PRODUCT_MC8755 0x6802 #define NOVATELWIRELESS_PRODUCT_U740 0x1400 -#define ANYDATA_PRODUCT_ID 0x6501 static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, @@ -91,8 +117,8 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, + { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, { } /* Terminating entry */ }; @@ -105,7 +131,10 @@ static struct usb_device_id option_ids1[] = { { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, - { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +static struct usb_device_id option_ids3[] = { + { USB_DEVICE(SIERRAWIRELESS_VENDOR_ID, SIERRAWIRELESS_PRODUCT_MC8755) }, { } /* Terminating entry */ }; @@ -122,11 +151,37 @@ static struct usb_driver option_driver = { /* The card has three separate interfaces, which the serial driver * recognizes separately, thus num_port=1. */ +static struct usb_serial_driver option_3port_device = { + .driver = { + .owner = THIS_MODULE, + .name = "option", + }, + .description = "GSM modem (3-port)", + .id_table = option_ids3, + .num_interrupt_in = NUM_DONT_CARE, + .num_bulk_in = NUM_DONT_CARE, + .num_bulk_out = NUM_DONT_CARE, + .num_ports = 3, + .open = option_open, + .close = option_close, + .write = option_write, + .write_room = option_write_room, + .chars_in_buffer = option_chars_in_buffer, + .throttle = option_rx_throttle, + .unthrottle = option_rx_unthrottle, + .set_termios = option_set_termios, + .break_ctl = option_break_ctl, + .tiocmget = option_tiocmget, + .tiocmset = option_tiocmset, + .attach = option_startup, + .shutdown = option_shutdown, + .read_int_callback = option_instat_callback, +}; static struct usb_serial_driver option_1port_device = { .driver = { .owner = THIS_MODULE, - .name = "option1", + .name = "option", }, .description = "GSM modem (1-port)", .id_table = option_ids1, @@ -190,6 +245,9 @@ static int __init option_init(void) retval = usb_serial_register(&option_1port_device); if (retval) goto failed_1port_device_register; + retval = usb_serial_register(&option_3port_device); + if (retval) + goto failed_3port_device_register; retval = usb_register(&option_driver); if (retval) goto failed_driver_register; @@ -199,6 +257,8 @@ static int __init option_init(void) return 0; failed_driver_register: + usb_serial_deregister (&option_3port_device); +failed_3port_device_register: usb_serial_deregister (&option_1port_device); failed_1port_device_register: return retval; @@ -207,6 +267,7 @@ static int __init option_init(void) static void __exit option_exit(void) { usb_deregister (&option_driver); + usb_serial_deregister (&option_3port_device); usb_serial_deregister (&option_1port_device); } @@ -595,6 +656,7 @@ static void option_setup_urbs(struct usb_serial *serial) dbg("%s", __FUNCTION__); + for (i = 0; i < serial->num_ports; i++) { port = serial->port[i]; portdata = usb_get_serial_port_data(port); diff --git a/trunk/drivers/usb/serial/pl2303.c b/trunk/drivers/usb/serial/pl2303.c index efbbc0adb89a..259db31b65c1 100644 --- a/trunk/drivers/usb/serial/pl2303.c +++ b/trunk/drivers/usb/serial/pl2303.c @@ -81,7 +81,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(SPEEDDRAGON_VENDOR_ID, SPEEDDRAGON_PRODUCT_ID) }, { USB_DEVICE(OTI_VENDOR_ID, OTI_PRODUCT_ID) }, { USB_DEVICE(DATAPILOT_U2_VENDOR_ID, DATAPILOT_U2_PRODUCT_ID) }, - { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/usb/serial/pl2303.h b/trunk/drivers/usb/serial/pl2303.h index a692ac66ca6c..d9c1e6e0b4b3 100644 --- a/trunk/drivers/usb/serial/pl2303.h +++ b/trunk/drivers/usb/serial/pl2303.h @@ -89,7 +89,3 @@ /* DATAPILOT Universal-2 Phone Cable */ #define DATAPILOT_U2_VENDOR_ID 0x0731 #define DATAPILOT_U2_PRODUCT_ID 0x2003 - -/* Belkin "F5U257" Serial Adapter */ -#define BELKIN_VENDOR_ID 0x050d -#define BELKIN_PRODUCT_ID 0x0257 diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 2793f9a912b4..a5ca449f6e64 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -145,13 +145,6 @@ UNUSUAL_DEV( 0x0420, 0x0001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), -/* Reported by Mario Rettig */ -UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, - "Nokia", - "Nokia 3250", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), - /* Reported by Sumedha Swamy and * Einar Th. Einarsson */ UNUSUAL_DEV( 0x0421, 0x0444, 0x0100, 0x0100, @@ -634,6 +627,18 @@ UNUSUAL_DEV( 0x0595, 0x4343, 0x0000, 0x2210, "Digital Camera EX-20 DSC", US_SC_8070, US_PR_DEVICE, NULL, 0 ), +/* The entry was here before I took over, and had US_SC_RBC. It turns + * out that isn't needed. Additionally, Torsten Eriksson + * is able to use his device fine + * without this entry at all - but I don't suspect that will be true + * for all users (the protocol is likely needed), so is staying at + * this time. - Phil Dibowitz + */ +UNUSUAL_DEV( 0x059f, 0xa601, 0x0200, 0x0200, + "LaCie", + "USB Hard Disk", + US_SC_DEVICE, US_PR_CB, NULL, 0 ), + /* Submitted by Joel Bourquard * Some versions of this device need the SubClass and Protocol overrides * while others don't. @@ -1101,15 +1106,7 @@ UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, "Optio S/S4", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), - -/* This is a virtual windows driver CD, which the zd1211rw driver automatically - * converts into a WLAN device. */ -UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, - "ZyXEL", - "G-220F USB-WLAN Install", - US_SC_DEVICE, US_PR_DEVICE, NULL, - US_FL_IGNORE_DEVICE ), - + #ifdef CONFIG_USB_STORAGE_ISD200 UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, "ATI", diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index 8d7bdcb5924d..5ee19be52f65 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -483,7 +483,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) } /* Get the unusual_devs entries and the string descriptors */ -static int get_device_info(struct us_data *us, const struct usb_device_id *id) +static void get_device_info(struct us_data *us, const struct usb_device_id *id) { struct usb_device *dev = us->pusb_dev; struct usb_interface_descriptor *idesc = @@ -500,11 +500,6 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) unusual_dev->useTransport; us->flags = USB_US_ORIG_FLAGS(id->driver_info); - if (us->flags & US_FL_IGNORE_DEVICE) { - printk(KERN_INFO USB_STORAGE "device ignored\n"); - return -ENODEV; - } - /* * This flag is only needed when we're in high-speed, so let's * disable it if we're in full-speed @@ -546,8 +541,6 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) msgs[msg], UTS_RELEASE); } - - return 0; } /* Get the transport settings */ @@ -976,9 +969,7 @@ static int storage_probe(struct usb_interface *intf, * of the match from the usb_device_id table, so we can find the * corresponding entry in the private table. */ - result = get_device_info(us, id); - if (result) - goto BadDevice; + get_device_info(us, id); /* Get the transport, protocol, and pipe settings */ result = get_transport(us); diff --git a/trunk/drivers/video/Kconfig b/trunk/drivers/video/Kconfig index c40b9b8b1e7e..6533b0f39231 100644 --- a/trunk/drivers/video/Kconfig +++ b/trunk/drivers/video/Kconfig @@ -86,11 +86,9 @@ config FB_MACMODES default n config FB_BACKLIGHT - bool - depends on FB - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default n + bool + depends on FB + default n config FB_MODE_HELPERS bool "Enable Video Mode Handling Helpers" @@ -422,7 +420,7 @@ config FB_OF config FB_CONTROL bool "Apple \"control\" display support" - depends on (FB = y) && PPC_PMAC && PPC32 + depends on (FB = y) && PPC_PMAC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -433,7 +431,7 @@ config FB_CONTROL config FB_PLATINUM bool "Apple \"platinum\" display support" - depends on (FB = y) && PPC_PMAC && PPC32 + depends on (FB = y) && PPC_PMAC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -444,7 +442,7 @@ config FB_PLATINUM config FB_VALKYRIE bool "Apple \"valkyrie\" display support" - depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) + depends on (FB = y) && (MAC || PPC_PMAC) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -455,7 +453,7 @@ config FB_VALKYRIE config FB_CT65550 bool "Chips 65550 display support" - depends on (FB = y) && PPC32 + depends on (FB = y) && PPC select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -723,8 +721,10 @@ config FB_NVIDIA_I2C config FB_NVIDIA_BACKLIGHT bool "Support for backlight control" - depends on FB_NVIDIA && PMAC_BACKLIGHT + depends on FB_NVIDIA && PPC_PMAC select FB_BACKLIGHT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -769,8 +769,10 @@ config FB_RIVA_DEBUG config FB_RIVA_BACKLIGHT bool "Support for backlight control" - depends on FB_RIVA && PMAC_BACKLIGHT + depends on FB_RIVA && PPC_PMAC select FB_BACKLIGHT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1023,8 +1025,10 @@ config FB_RADEON_I2C config FB_RADEON_BACKLIGHT bool "Support for backlight control" - depends on FB_RADEON && PMAC_BACKLIGHT + depends on FB_RADEON && PPC_PMAC select FB_BACKLIGHT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1055,8 +1059,10 @@ config FB_ATY128 config FB_ATY128_BACKLIGHT bool "Support for backlight control" - depends on FB_ATY128 && PMAC_BACKLIGHT + depends on FB_ATY128 && PPC_PMAC select FB_BACKLIGHT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1105,8 +1111,10 @@ config FB_ATY_GX config FB_ATY_BACKLIGHT bool "Support for backlight control" - depends on FB_ATY && PMAC_BACKLIGHT + depends on FB_ATY && PPC_PMAC select FB_BACKLIGHT + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1612,7 +1620,7 @@ if FB || SGI_NEWPORT_CONSOLE source "drivers/video/logo/Kconfig" endif -if SYSFS +if FB && SYSFS source "drivers/video/backlight/Kconfig" endif diff --git a/trunk/drivers/video/Makefile b/trunk/drivers/video/Makefile index 481c6c9695f8..95563c9c6b9c 100644 --- a/trunk/drivers/video/Makefile +++ b/trunk/drivers/video/Makefile @@ -4,7 +4,6 @@ # Each configuration option enables a list of files. -obj-y += fb_notify.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o diff --git a/trunk/drivers/video/aty/aty128fb.c b/trunk/drivers/video/aty/aty128fb.c index 3e827e04a2aa..c64a717e2d4b 100644 --- a/trunk/drivers/video/aty/aty128fb.c +++ b/trunk/drivers/video/aty/aty128fb.c @@ -455,10 +455,7 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par); static void wait_for_fifo(u16 entries, struct aty128fb_par *par); static void wait_for_idle(struct aty128fb_par *par); static u32 depth_to_dst(u32 depth); - -#ifdef CONFIG_FB_ATY128_BACKLIGHT static void aty128_bl_set_power(struct fb_info *info, int power); -#endif #define BIOS_IN8(v) (readb(bios + (v))) #define BIOS_IN16(v) (readb(bios + (v)) | \ @@ -1913,6 +1910,9 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i u8 chip_rev; u32 dac; + if (!par->vram_size) /* may have already been probed */ + par->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF; + /* Get the chip revision */ chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F; @@ -2025,6 +2025,9 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i aty128_init_engine(par); + if (register_framebuffer(info) < 0) + return 0; + par->pm_reg = pci_find_capability(pdev, PCI_CAP_ID_PM); par->pdev = pdev; par->asleep = 0; @@ -2034,9 +2037,6 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i aty128_bl_init(par); #endif - if (register_framebuffer(info) < 0) - return 0; - printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", info->node, info->fix.id, video_card); @@ -2086,6 +2086,7 @@ static int __devinit aty128_probe(struct pci_dev *pdev, const struct pci_device_ par = info->par; info->pseudo_palette = par->pseudo_palette; + info->fix = aty128fb_fix; /* Virtualize mmio region */ info->fix.mmio_start = reg_addr; diff --git a/trunk/drivers/video/aty/atyfb_base.c b/trunk/drivers/video/aty/atyfb_base.c index 053ff63365b7..1507d19f481f 100644 --- a/trunk/drivers/video/aty/atyfb_base.c +++ b/trunk/drivers/video/aty/atyfb_base.c @@ -2812,7 +2812,7 @@ static int atyfb_blank(int blank, struct fb_info *info) if (par->lock_blank || par->asleep) return 0; -#ifdef CONFIG_FB_ATY_BACKLIGHT +#ifdef CONFIG_PMAC_BACKLIGHT if (machine_is(powermac) && blank > FB_BLANK_NORMAL) aty_bl_set_power(info, FB_BLANK_POWERDOWN); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) @@ -2844,7 +2844,7 @@ static int atyfb_blank(int blank, struct fb_info *info) } aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); -#ifdef CONFIG_FB_ATY_BACKLIGHT +#ifdef CONFIG_PMAC_BACKLIGHT if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) aty_bl_set_power(info, FB_BLANK_UNBLANK); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) diff --git a/trunk/drivers/video/aty/radeon_base.c b/trunk/drivers/video/aty/radeon_base.c index 8e3400d5dd21..8d85fc58142e 100644 --- a/trunk/drivers/video/aty/radeon_base.c +++ b/trunk/drivers/video/aty/radeon_base.c @@ -266,8 +266,6 @@ static int force_measure_pll = 0; #ifdef CONFIG_MTRR static int nomtrr = 0; #endif -static int force_sleep; -static int ignore_devlist; /* * prototypes @@ -2329,9 +2327,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, /* -2 is special: means ON on mobility chips and do not * change on others */ - radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep); + radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); } else - radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep); + radeonfb_pm_init(rinfo, default_dynclk); pci_set_drvdata(pdev, info); @@ -2479,12 +2477,6 @@ static int __init radeonfb_setup (char *options) force_measure_pll = 1; } else if (!strncmp(this_opt, "ignore_edid", 11)) { ignore_edid = 1; -#if defined(CONFIG_PM) && defined(CONFIG_X86) - } else if (!strncmp(this_opt, "force_sleep", 11)) { - force_sleep = 1; - } else if (!strncmp(this_opt, "ignore_devlist", 14)) { - ignore_devlist = 1; -#endif } else mode_option = this_opt; } @@ -2540,9 +2532,3 @@ module_param(panel_yres, int, 0); MODULE_PARM_DESC(panel_yres, "int: set panel yres"); module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify resolution as \"x[-][@]\" "); -#if defined(CONFIG_PM) && defined(CONFIG_X86) -module_param(force_sleep, bool, 0); -MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware"); -module_param(ignore_devlist, bool, 0); -MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops"); -#endif diff --git a/trunk/drivers/video/aty/radeon_pm.c b/trunk/drivers/video/aty/radeon_pm.c index f31e606a2ded..c7091761cef4 100644 --- a/trunk/drivers/video/aty/radeon_pm.c +++ b/trunk/drivers/video/aty/radeon_pm.c @@ -27,99 +27,6 @@ #include "ati_ids.h" -static void radeon_reinitialize_M10(struct radeonfb_info *rinfo); - -/* - * Workarounds for bugs in PC laptops: - * - enable D2 sleep in some IBM Thinkpads - * - special case for Samsung P35 - * - * Whitelist by subsystem vendor/device because - * its the subsystem vendor's fault! - */ - -#if defined(CONFIG_PM) && defined(CONFIG_X86) -struct radeon_device_id { - const char *ident; /* (arbitrary) Name */ - const unsigned short subsystem_vendor; /* Subsystem Vendor ID */ - const unsigned short subsystem_device; /* Subsystem Device ID */ - const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */ - const reinit_function_ptr new_reinit_func; /* changed reinit_func */ -}; - -#define BUGFIX(model, sv, sd, pm, fn) { \ - .ident = model, \ - .subsystem_vendor = sv, \ - .subsystem_device = sd, \ - .pm_mode_modifier = pm, \ - .new_reinit_func = fn \ -} - -static struct radeon_device_id radeon_workaround_list[] = { - BUGFIX("IBM Thinkpad R32", - PCI_VENDOR_ID_IBM, 0x1905, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad R40", - PCI_VENDOR_ID_IBM, 0x0526, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad R40", - PCI_VENDOR_ID_IBM, 0x0527, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad R50/R51/T40/T41", - PCI_VENDOR_ID_IBM, 0x0531, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad R51/T40/T41/T42", - PCI_VENDOR_ID_IBM, 0x0530, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad T30", - PCI_VENDOR_ID_IBM, 0x0517, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad T40p", - PCI_VENDOR_ID_IBM, 0x054d, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad T42", - PCI_VENDOR_ID_IBM, 0x0550, - radeon_pm_d2, NULL), - BUGFIX("IBM Thinkpad X31/X32", - PCI_VENDOR_ID_IBM, 0x052f, - radeon_pm_d2, NULL), - BUGFIX("Samsung P35", - PCI_VENDOR_ID_SAMSUNG, 0xc00c, - radeon_pm_off, radeon_reinitialize_M10), - { .ident = NULL } -}; - -static int radeon_apply_workarounds(struct radeonfb_info *rinfo) -{ - struct radeon_device_id *id; - - for (id = radeon_workaround_list; id->ident != NULL; id++ ) - if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) && - (id->subsystem_device == rinfo->pdev->subsystem_device )) { - - /* we found a device that requires workaround */ - printk(KERN_DEBUG "radeonfb: %s detected" - ", enabling workaround\n", id->ident); - - rinfo->pm_mode |= id->pm_mode_modifier; - - if (id->new_reinit_func != NULL) - rinfo->reinit_func = id->new_reinit_func; - - return 1; - } - return 0; /* not found */ -} - -#else /* defined(CONFIG_PM) && defined(CONFIG_X86) */ -static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo) -{ - return 0; -} -#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */ - - - static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) { u32 tmp; @@ -945,26 +852,18 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) /* because both INPLL and OUTPLL take the same lock, that's why. */ tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; OUTPLL( pllMCLK_MISC, tmp); + + /* AGP PLL control */ + if (rinfo->family <= CHIP_FAMILY_RV280) { + OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); - /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset - * and radeon chip dependent. Thus we only enable it on Mac for - * now (until we get more info on how to compute the correct - * value for various X86 bridges). - */ -#ifdef CONFIG_PPC_PMAC - if (machine_is(powermac)) { - /* AGP PLL control */ - if (rinfo->family <= CHIP_FAMILY_RV280) { - OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); - OUTREG(BUS_CNTL1, - (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) - | (2<pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); @@ -2830,13 +2729,22 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis } #if defined(CONFIG_PM) -#if defined(CONFIG_PPC_PMAC) /* Check if we can power manage on suspend/resume. We can do * D2 on M6, M7 and M9, and we can resume from D3 cold a few other * "Mac" cards, but that's all. We need more infos about what the * BIOS does tho. Right now, all this PM stuff is pmac-only for that * reason. --BenH */ + /* Special case for Samsung P35 laptops + */ + if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) && + (rinfo->pdev->device == PCI_CHIP_RV350_NP) && + (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) && + (rinfo->pdev->subsystem_device == 0xc00c)) { + rinfo->reinit_func = radeon_reinitialize_M10; + rinfo->pm_mode |= radeon_pm_off; + } +#if defined(CONFIG_PPC_PMAC) if (machine_is(powermac) && rinfo->of_node) { if (rinfo->is_mobility && rinfo->pm_reg && rinfo->family <= CHIP_FAMILY_RV250) @@ -2882,18 +2790,6 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis } #endif /* defined(CONFIG_PPC_PMAC) */ #endif /* defined(CONFIG_PM) */ - - if (ignore_devlist) - printk(KERN_DEBUG - "radeonfb: skipping test for device workarounds\n"); - else - radeon_apply_workarounds(rinfo); - - if (force_sleep) { - printk(KERN_DEBUG - "radeonfb: forcefully enabling D2 sleep mode\n"); - rinfo->pm_mode |= radeon_pm_d2; - } } void radeonfb_pm_exit(struct radeonfb_info *rinfo) diff --git a/trunk/drivers/video/aty/radeonfb.h b/trunk/drivers/video/aty/radeonfb.h index d5ff224a6258..38657b2d10eb 100644 --- a/trunk/drivers/video/aty/radeonfb.h +++ b/trunk/drivers/video/aty/radeonfb.h @@ -273,8 +273,6 @@ enum radeon_pm_mode { radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ }; -typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo); - struct radeonfb_info { struct fb_info *info; @@ -340,7 +338,7 @@ struct radeonfb_info { int dynclk; int no_schedule; enum radeon_pm_mode pm_mode; - reinit_function_ptr reinit_func; + void (*reinit_func)(struct radeonfb_info *rinfo); /* Lock on register access */ spinlock_t reg_lock; @@ -602,7 +600,7 @@ extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 /* PM Functions */ extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state); extern int radeonfb_pci_resume(struct pci_dev *pdev); -extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep); +extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk); extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); /* Monitor probe functions */ diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index f25d5d648333..a92a91fef16f 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -156,7 +156,7 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) info->fix.visual = FB_VISUAL_TRUECOLOR; info->fix.line_length = info->var.xres_virtual << 1; /* depth=16 */ - } + } } else { /* mono */ info->fix.visual = FB_VISUAL_MONO10; @@ -164,16 +164,20 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) } info->screen_size = info->fix.line_length * info->var.yres_virtual; - info->var.rotate = ((fbdev->panel->control_base&LCD_CONTROL_SM_MASK) \ - >> LCD_CONTROL_SM_BIT) * 90; /* Determine BPP mode and format */ - fbdev->regs->lcd_control = fbdev->panel->control_base; + fbdev->regs->lcd_control = fbdev->panel->control_base | + ((info->var.rotate/90) << LCD_CONTROL_SM_BIT); + + fbdev->regs->lcd_intenable = 0; + fbdev->regs->lcd_intstatus = 0; + fbdev->regs->lcd_horztiming = fbdev->panel->horztiming; + fbdev->regs->lcd_verttiming = fbdev->panel->verttiming; + fbdev->regs->lcd_clkcontrol = fbdev->panel->clkcontrol_base; - fbdev->regs->lcd_intenable = 0; - fbdev->regs->lcd_intstatus = 0; + fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(fbdev->fb_phys); if (panel_is_dual(fbdev->panel)) { @@ -202,8 +206,6 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) /* Resume controller */ fbdev->regs->lcd_control |= LCD_CONTROL_GO; - mdelay(10); - au1100fb_fb_blank(VESA_NO_BLANKING, info); return 0; } diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 02f15297a021..022f9d3473f5 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of the LCD @@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT + depends on BACKLIGHT_LCD_SUPPORT && FB default m help This framework adds support for low-level control of LCD. diff --git a/trunk/drivers/video/console/mdacon.c b/trunk/drivers/video/console/mdacon.c index eb4d03fa5391..52ed12b12acc 100644 --- a/trunk/drivers/video/console/mdacon.c +++ b/trunk/drivers/video/console/mdacon.c @@ -197,7 +197,7 @@ static int __init mdacon_setup(char *str) __setup("mdacon=", mdacon_setup); #endif -static int mda_detect(void) +static int __init mda_detect(void) { int count=0; u16 *p, p_save; @@ -282,7 +282,7 @@ static int mda_detect(void) return 1; } -static void mda_initialize(void) +static void __init mda_initialize(void) { write_mda_b(97, 0x00); /* horizontal total */ write_mda_b(80, 0x01); /* horizontal displayed */ diff --git a/trunk/drivers/video/fb_notify.c b/trunk/drivers/video/fb_notify.c deleted file mode 100644 index 8c020389e4fa..000000000000 --- a/trunk/drivers/video/fb_notify.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * linux/drivers/video/fb_notify.c - * - * Copyright (C) 2006 Antonino Daplas - * - * 2001 - Documented with DocBook - * - Brad Douglas - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - */ -#include -#include - -static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); - -/** - * fb_register_client - register a client notifier - * @nb: notifier block to callback on events - */ -int fb_register_client(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&fb_notifier_list, nb); -} -EXPORT_SYMBOL(fb_register_client); - -/** - * fb_unregister_client - unregister a client notifier - * @nb: notifier block to callback on events - */ -int fb_unregister_client(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&fb_notifier_list, nb); -} -EXPORT_SYMBOL(fb_unregister_client); - -/** - * fb_notifier_call_chain - notify clients of fb_events - * - */ -int fb_notifier_call_chain(unsigned long val, void *v) -{ - return blocking_notifier_call_chain(&fb_notifier_list, val, v); -} -EXPORT_SYMBOL_GPL(fb_notifier_call_chain); diff --git a/trunk/drivers/video/fbmem.c b/trunk/drivers/video/fbmem.c index 17961e3ecaa0..4fc9df426c1a 100644 --- a/trunk/drivers/video/fbmem.c +++ b/trunk/drivers/video/fbmem.c @@ -52,6 +52,7 @@ #define FBPIXMAPSIZE (1024 * 8) +static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); struct fb_info *registered_fb[FB_MAX]; int num_registered_fb; @@ -790,7 +791,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) event.info = info; event.data = &mode1; - ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); + ret = blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_MODE_DELETE, &event); } if (!ret) @@ -835,7 +837,8 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; - fb_notifier_call_chain(evnt, &event); + blocking_notifier_call_chain(&fb_notifier_list, + evnt, &event); } } } @@ -858,7 +861,8 @@ fb_blank(struct fb_info *info, int blank) event.info = info; event.data = ␣ - fb_notifier_call_chain(FB_EVENT_BLANK, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_BLANK, &event); } return ret; @@ -929,7 +933,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, con2fb.framebuffer = -1; event.info = info; event.data = &con2fb; - fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_GET_CONSOLE_MAP, &event); return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; case FBIOPUT_CON2FBMAP: @@ -947,8 +952,9 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -EINVAL; event.info = info; event.data = &con2fb; - return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, - &event); + return blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_SET_CONSOLE_MAP, + &event); case FBIOBLANK: acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; @@ -1324,7 +1330,8 @@ register_framebuffer(struct fb_info *fb_info) registered_fb[i] = fb_info; event.info = fb_info; - fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_FB_REGISTERED, &event); return 0; } @@ -1358,10 +1365,29 @@ unregister_framebuffer(struct fb_info *fb_info) fb_cleanup_class_device(fb_info); class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; - fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_FB_UNREGISTERED, &event); return 0; } +/** + * fb_register_client - register a client notifier + * @nb: notifier block to callback on events + */ +int fb_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&fb_notifier_list, nb); +} + +/** + * fb_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + */ +int fb_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&fb_notifier_list, nb); +} + /** * fb_set_suspend - low level driver signals suspend * @info: framebuffer affected @@ -1377,11 +1403,13 @@ void fb_set_suspend(struct fb_info *info, int state) event.info = info; if (state) { - fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_SUSPEND, &event); info->state = FBINFO_STATE_SUSPENDED; } else { info->state = FBINFO_STATE_RUNNING; - fb_notifier_call_chain(FB_EVENT_RESUME, &event); + blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_RESUME, &event); } } @@ -1452,7 +1480,9 @@ int fb_new_modelist(struct fb_info *info) if (!list_empty(&info->modelist)) { event.info = info; - err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); + err = blocking_notifier_call_chain(&fb_notifier_list, + FB_EVENT_NEW_MODELIST, + &event); } return err; @@ -1564,6 +1594,8 @@ EXPORT_SYMBOL(fb_blank); EXPORT_SYMBOL(fb_pan_display); EXPORT_SYMBOL(fb_get_buffer_offset); EXPORT_SYMBOL(fb_set_suspend); +EXPORT_SYMBOL(fb_register_client); +EXPORT_SYMBOL(fb_unregister_client); EXPORT_SYMBOL(fb_get_options); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/nvidia/nvidia.c b/trunk/drivers/video/nvidia/nvidia.c index d4f850117874..9f2066f0745a 100644 --- a/trunk/drivers/video/nvidia/nvidia.c +++ b/trunk/drivers/video/nvidia/nvidia.c @@ -34,6 +34,10 @@ #include "nv_proto.h" #include "nv_dma.h" +#ifndef CONFIG_PCI /* sanity check */ +#error This driver requires PCI support. +#endif + #undef CONFIG_FB_NVIDIA_DEBUG #ifdef CONFIG_FB_NVIDIA_DEBUG #define NVTRACE printk @@ -1299,19 +1303,20 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, nvidia_save_vga(par, &par->SavedReg); - pci_set_drvdata(pd, info); - nvidia_bl_init(par); if (register_framebuffer(info) < 0) { printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); goto err_out_iounmap_fb; } + pci_set_drvdata(pd, info); printk(KERN_INFO PFX "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", info->fix.id, par->FbMapSize / (1024 * 1024), info->fix.smem_start); + nvidia_bl_init(par); + NVTRACE_LEAVE(); return 0; diff --git a/trunk/drivers/video/offb.c b/trunk/drivers/video/offb.c index 0013311e0564..ce5f3031b99b 100644 --- a/trunk/drivers/video/offb.c +++ b/trunk/drivers/video/offb.c @@ -62,6 +62,8 @@ struct offb_par default_par; * Interface used by the world */ +int offb_init(void); + static int offb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int transp, struct fb_info *info); static int offb_blank(int blank, struct fb_info *info); @@ -70,6 +72,11 @@ static int offb_blank(int blank, struct fb_info *info); extern boot_infos_t *boot_infos; #endif +static void offb_init_nodriver(struct device_node *); +static void offb_init_fb(const char *name, const char *full_name, + int width, int height, int depth, int pitch, + unsigned long address, struct device_node *dp); + static struct fb_ops offb_ops = { .owner = THIS_MODULE, .fb_setcolreg = offb_setcolreg, @@ -222,17 +229,123 @@ static int offb_blank(int blank, struct fb_info *info) return 0; } + /* + * Initialisation + */ -static void __iomem *offb_map_reg(struct device_node *np, int index, - unsigned long offset, unsigned long size) +int __init offb_init(void) { - struct resource r; + struct device_node *dp = NULL, *boot_disp = NULL; - if (of_address_to_resource(np, index, &r)) - return 0; - if ((r.start + offset + size) > r.end) - return 0; - return ioremap(r.start + offset, size); + if (fb_get_options("offb", NULL)) + return -ENODEV; + + for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { + if (get_property(dp, "linux,opened", NULL) && + get_property(dp, "linux,boot-display", NULL)) { + boot_disp = dp; + offb_init_nodriver(dp); + } + } + for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { + if (get_property(dp, "linux,opened", NULL) && + dp != boot_disp) + offb_init_nodriver(dp); + } + + return 0; +} + + +static void __init offb_init_nodriver(struct device_node *dp) +{ + unsigned int len; + int i, width = 640, height = 480, depth = 8, pitch = 640; + unsigned int flags, rsize, addr_prop = 0; + unsigned long max_size = 0; + u64 rstart, address = OF_BAD_ADDR; + u32 *pp, *addrp, *up; + u64 asize; + + pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "depth", &len); + if (pp && len == sizeof(u32)) + depth = *pp; + + pp = (u32 *)get_property(dp, "linux,bootx-width", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "width", &len); + if (pp && len == sizeof(u32)) + width = *pp; + + pp = (u32 *)get_property(dp, "linux,bootx-height", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "height", &len); + if (pp && len == sizeof(u32)) + height = *pp; + + pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); + if (pp == NULL) + pp = (u32 *)get_property(dp, "linebytes", &len); + if (pp && len == sizeof(u32)) + pitch = *pp; + else + pitch = width * ((depth + 7) / 8); + + rsize = (unsigned long)pitch * (unsigned long)height; + + /* Ok, now we try to figure out the address of the framebuffer. + * + * Unfortunately, Open Firmware doesn't provide a standard way to do + * so. All we can do is a dodgy heuristic that happens to work in + * practice. On most machines, the "address" property contains what + * we need, though not on Matrox cards found in IBM machines. What I've + * found that appears to give good results is to go through the PCI + * ranges and pick one that is both big enough and if possible encloses + * the "address" property. If none match, we pick the biggest + */ + up = (u32 *)get_property(dp, "linux,bootx-addr", &len); + if (up == NULL) + up = (u32 *)get_property(dp, "address", &len); + if (up && len == sizeof(u32)) + addr_prop = *up; + + for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) + != NULL; i++) { + int match_addrp = 0; + + if (!(flags & IORESOURCE_MEM)) + continue; + if (asize < rsize) + continue; + rstart = of_translate_address(dp, addrp); + if (rstart == OF_BAD_ADDR) + continue; + if (addr_prop && (rstart <= addr_prop) && + ((rstart + asize) >= (addr_prop + rsize))) + match_addrp = 1; + if (match_addrp) { + address = addr_prop; + break; + } + if (rsize > max_size) { + max_size = rsize; + address = OF_BAD_ADDR; + } + + if (address == OF_BAD_ADDR) + address = rstart; + } + if (address == OF_BAD_ADDR && addr_prop) + address = (u64)addr_prop; + if (address != OF_BAD_ADDR) { + /* kludge for valkyrie */ + if (strcmp(dp->name, "valkyrie") == 0) + address += 0x1000; + offb_init_fb(dp->name, dp->full_name, width, height, depth, + pitch, address, dp); + } } static void __init offb_init_fb(const char *name, const char *full_name, @@ -289,39 +402,45 @@ static void __init offb_init_fb(const char *name, const char *full_name, par->cmap_type = cmap_unknown; if (depth == 8) { + /* Palette hacks disabled for now */ +#if 0 if (dp && !strncmp(name, "ATY,Rage128", 11)) { - par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); - if (par->cmap_adr) - par->cmap_type = cmap_r128; + unsigned long regbase = dp->addrs[2].address; + par->cmap_adr = ioremap(regbase, 0x1FFF); + par->cmap_type = cmap_r128; } else if (dp && (!strncmp(name, "ATY,RageM3pA", 12) || !strncmp(name, "ATY,RageM3p12A", 14))) { - par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); - if (par->cmap_adr) - par->cmap_type = cmap_M3A; + unsigned long regbase = + dp->parent->addrs[2].address; + par->cmap_adr = ioremap(regbase, 0x1FFF); + par->cmap_type = cmap_M3A; } else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) { - par->cmap_adr = offb_map_reg(dp, 2, 0, 0x1fff); - if (par->cmap_adr) - par->cmap_type = cmap_M3B; + unsigned long regbase = + dp->parent->addrs[2].address; + par->cmap_adr = ioremap(regbase, 0x1FFF); + par->cmap_type = cmap_M3B; } else if (dp && !strncmp(name, "ATY,Rage6", 9)) { - par->cmap_adr = offb_map_reg(dp, 1, 0, 0x1fff); - if (par->cmap_adr) - par->cmap_type = cmap_radeon; + unsigned long regbase = dp->addrs[1].address; + par->cmap_adr = ioremap(regbase, 0x1FFF); + par->cmap_type = cmap_radeon; } else if (!strncmp(name, "ATY,", 4)) { unsigned long base = address & 0xff000000UL; par->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0; par->cmap_data = par->cmap_adr + 1; par->cmap_type = cmap_m64; - } else if (dp && device_is_compatible(dp, "pci1014,b7")) { - par->cmap_adr = offb_map_reg(dp, 0, 0x6000, 0x1000); - if (par->cmap_adr) - par->cmap_type = cmap_gxt2000; + } else if (device_is_compatible(dp, "pci1014,b7")) { + unsigned long regbase = dp->addrs[0].address; + par->cmap_adr = ioremap(regbase + 0x6000, 0x1000); + par->cmap_type = cmap_gxt2000; } - fix->visual = (par->cmap_type != cmap_unknown) ? - FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_STATIC_PSEUDOCOLOR; +#endif + fix->visual = par->cmap_adr ? FB_VISUAL_PSEUDOCOLOR + : FB_VISUAL_STATIC_PSEUDOCOLOR; } else - fix->visual = FB_VISUAL_TRUECOLOR; + fix->visual = /* par->cmap_adr ? FB_VISUAL_DIRECTCOLOR + : */ FB_VISUAL_TRUECOLOR; var->xoffset = var->yoffset = 0; switch (depth) { @@ -401,139 +520,5 @@ static void __init offb_init_fb(const char *name, const char *full_name, info->node, full_name); } - -static void __init offb_init_nodriver(struct device_node *dp, int no_real_node) -{ - unsigned int len; - int i, width = 640, height = 480, depth = 8, pitch = 640; - unsigned int flags, rsize, addr_prop = 0; - unsigned long max_size = 0; - u64 rstart, address = OF_BAD_ADDR; - u32 *pp, *addrp, *up; - u64 asize; - - pp = (u32 *)get_property(dp, "linux,bootx-depth", &len); - if (pp == NULL) - pp = (u32 *)get_property(dp, "depth", &len); - if (pp && len == sizeof(u32)) - depth = *pp; - - pp = (u32 *)get_property(dp, "linux,bootx-width", &len); - if (pp == NULL) - pp = (u32 *)get_property(dp, "width", &len); - if (pp && len == sizeof(u32)) - width = *pp; - - pp = (u32 *)get_property(dp, "linux,bootx-height", &len); - if (pp == NULL) - pp = (u32 *)get_property(dp, "height", &len); - if (pp && len == sizeof(u32)) - height = *pp; - - pp = (u32 *)get_property(dp, "linux,bootx-linebytes", &len); - if (pp == NULL) - pp = (u32 *)get_property(dp, "linebytes", &len); - if (pp && len == sizeof(u32)) - pitch = *pp; - else - pitch = width * ((depth + 7) / 8); - - rsize = (unsigned long)pitch * (unsigned long)height; - - /* Ok, now we try to figure out the address of the framebuffer. - * - * Unfortunately, Open Firmware doesn't provide a standard way to do - * so. All we can do is a dodgy heuristic that happens to work in - * practice. On most machines, the "address" property contains what - * we need, though not on Matrox cards found in IBM machines. What I've - * found that appears to give good results is to go through the PCI - * ranges and pick one that is both big enough and if possible encloses - * the "address" property. If none match, we pick the biggest - */ - up = (u32 *)get_property(dp, "linux,bootx-addr", &len); - if (up == NULL) - up = (u32 *)get_property(dp, "address", &len); - if (up && len == sizeof(u32)) - addr_prop = *up; - - /* Hack for when BootX is passing us */ - if (no_real_node) - goto skip_addr; - - for (i = 0; (addrp = of_get_address(dp, i, &asize, &flags)) - != NULL; i++) { - int match_addrp = 0; - - if (!(flags & IORESOURCE_MEM)) - continue; - if (asize < rsize) - continue; - rstart = of_translate_address(dp, addrp); - if (rstart == OF_BAD_ADDR) - continue; - if (addr_prop && (rstart <= addr_prop) && - ((rstart + asize) >= (addr_prop + rsize))) - match_addrp = 1; - if (match_addrp) { - address = addr_prop; - break; - } - if (rsize > max_size) { - max_size = rsize; - address = OF_BAD_ADDR; - } - - if (address == OF_BAD_ADDR) - address = rstart; - } - skip_addr: - if (address == OF_BAD_ADDR && addr_prop) - address = (u64)addr_prop; - if (address != OF_BAD_ADDR) { - /* kludge for valkyrie */ - if (strcmp(dp->name, "valkyrie") == 0) - address += 0x1000; - offb_init_fb(no_real_node ? "bootx" : dp->name, - no_real_node ? "display" : dp->full_name, - width, height, depth, pitch, address, - no_real_node ? dp : NULL); - } -} - -static int __init offb_init(void) -{ - struct device_node *dp = NULL, *boot_disp = NULL; - - if (fb_get_options("offb", NULL)) - return -ENODEV; - - /* Check if we have a MacOS display without a node spec */ - if (get_property(of_chosen, "linux,bootx-noscreen", NULL) != NULL) { - /* The old code tried to work out which node was the MacOS - * display based on the address. I'm dropping that since the - * lack of a node spec only happens with old BootX versions - * (users can update) and with this code, they'll still get - * a display (just not the palette hacks). - */ - offb_init_nodriver(of_chosen, 1); - } - - for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { - if (get_property(dp, "linux,opened", NULL) && - get_property(dp, "linux,boot-display", NULL)) { - boot_disp = dp; - offb_init_nodriver(dp, 0); - } - } - for (dp = NULL; (dp = of_find_node_by_type(dp, "display"));) { - if (get_property(dp, "linux,opened", NULL) && - dp != boot_disp) - offb_init_nodriver(dp, 0); - } - - return 0; -} - - module_init(offb_init); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/video/riva/fbdev.c b/trunk/drivers/video/riva/fbdev.c index 76fc9d355eb7..33dddbae5420 100644 --- a/trunk/drivers/video/riva/fbdev.c +++ b/trunk/drivers/video/riva/fbdev.c @@ -2132,9 +2132,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, fb_destroy_modedb(info->monspecs.modedb); info->monspecs.modedb = NULL; - - pci_set_drvdata(pd, info); - riva_bl_init(info->par); ret = register_framebuffer(info); if (ret < 0) { printk(KERN_ERR PFX @@ -2142,6 +2139,8 @@ static int __devinit rivafb_probe(struct pci_dev *pd, goto err_iounmap_screen_base; } + pci_set_drvdata(pd, info); + printk(KERN_INFO PFX "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", info->fix.id, @@ -2149,6 +2148,8 @@ static int __devinit rivafb_probe(struct pci_dev *pd, info->fix.smem_len / (1024 * 1024), info->fix.smem_start); + riva_bl_init(info->par); + NVTRACE_LEAVE(); return 0; diff --git a/trunk/fs/9p/conv.c b/trunk/fs/9p/conv.c index 56d88c1a09c5..1e898144eb7c 100644 --- a/trunk/fs/9p/conv.c +++ b/trunk/fs/9p/conv.c @@ -673,10 +673,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, struct cbuf *bufp = &buffer; size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ - if (extended) { - size += 2 + /* extension[s] */ - (extension == NULL ? 0 : strlen(extension)); - } + if (extended && extension!=NULL) + size += 2 + strlen(extension); /* extension[s] */ fc = v9fs_create_common(bufp, size, TCREATE); if (IS_ERR(fc)) diff --git a/trunk/fs/9p/vfs_inode.c b/trunk/fs/9p/vfs_inode.c index eae50c9d6dc4..2f580a197b8d 100644 --- a/trunk/fs/9p/vfs_inode.c +++ b/trunk/fs/9p/vfs_inode.c @@ -434,11 +434,11 @@ static int v9fs_remove(struct inode *dir, struct dentry *file, int rmdir) result = v9fs_t_remove(v9ses, fid, &fcall); if (result < 0) { PRINT_FCALL_ERROR("remove fails", fcall); + } else { + v9fs_put_idpool(fid, &v9ses->fidpool); + v9fs_fid_destroy(v9fid); } - v9fs_put_idpool(fid, &v9ses->fidpool); - v9fs_fid_destroy(v9fid); - kfree(fcall); return result; } diff --git a/trunk/fs/befs/linuxvfs.c b/trunk/fs/befs/linuxvfs.c index 50cfca5c7efd..fcaeead9696b 100644 --- a/trunk/fs/befs/linuxvfs.c +++ b/trunk/fs/befs/linuxvfs.c @@ -512,11 +512,7 @@ befs_utf2nls(struct super_block *sb, const char *in, wchar_t uni; int unilen, utflen; char *result; - /* The utf8->nls conversion won't make the final nls string bigger - * than the utf one, but if the string is pure ascii they'll have the - * same width and an extra char is needed to save the additional \0 - */ - int maxlen = in_len + 1; + int maxlen = in_len; /* The utf8->nls conversion can't make more chars */ befs_debug(sb, "---> utf2nls()"); @@ -592,10 +588,7 @@ befs_nls2utf(struct super_block *sb, const char *in, wchar_t uni; int unilen, utflen; char *result; - /* There're nls characters that will translate to 3-chars-wide UTF-8 - * characters, a additional byte is needed to save the final \0 - * in special cases */ - int maxlen = (3 * in_len) + 1; + int maxlen = 3 * in_len; befs_debug(sb, "---> nls2utf()\n"); diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 71649ef9b658..3660dcb97591 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -470,18 +470,13 @@ __find_get_block_slow(struct block_device *bdev, sector_t block) pass does the actual I/O. */ void invalidate_bdev(struct block_device *bdev, int destroy_dirty_buffers) { - struct address_space *mapping = bdev->bd_inode->i_mapping; - - if (mapping->nrpages == 0) - return; - invalidate_bh_lrus(); /* * FIXME: what about destroy_dirty_buffers? * We really want to use invalidate_inode_pages2() for * that, but not until that's cleaned up. */ - invalidate_inode_pages(mapping); + invalidate_inode_pages(bdev->bd_inode->i_mapping); } /* diff --git a/trunk/fs/coda/file.c b/trunk/fs/coda/file.c index dbfbcfa5b3c0..cc66c681bd11 100644 --- a/trunk/fs/coda/file.c +++ b/trunk/fs/coda/file.c @@ -136,8 +136,10 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) coda_vfs_stat.open++; cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL); - if (!cfi) + if (!cfi) { + unlock_kernel(); return -ENOMEM; + } lock_kernel(); diff --git a/trunk/fs/efs/symlink.c b/trunk/fs/efs/symlink.c index 1d30d2ff440f..e249cf733a6b 100644 --- a/trunk/fs/efs/symlink.c +++ b/trunk/fs/efs/symlink.c @@ -22,7 +22,7 @@ static int efs_symlink_readpage(struct file *file, struct page *page) err = -ENAMETOOLONG; if (size > 2 * EFS_BLOCKSIZE) - goto fail_notlocked; + goto fail; lock_kernel(); /* read first 512 bytes of link target */ @@ -47,7 +47,6 @@ static int efs_symlink_readpage(struct file *file, struct page *page) return 0; fail: unlock_kernel(); -fail_notlocked: SetPageError(page); kunmap(page); unlock_page(page); diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index c5ee9f0691e3..f804d5e9d60c 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -1158,7 +1158,7 @@ static int ext3_prepare_write(struct file *file, struct page *page, ret = PTR_ERR(handle); goto out; } - if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) + if (test_opt(inode->i_sb, NOBH)) ret = nobh_prepare_write(page, from, to, ext3_get_block); else ret = block_prepare_write(page, from, to, ext3_get_block); @@ -1244,7 +1244,7 @@ static int ext3_writeback_commit_write(struct file *file, struct page *page, if (new_i_size > EXT3_I(inode)->i_disksize) EXT3_I(inode)->i_disksize = new_i_size; - if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) + if (test_opt(inode->i_sb, NOBH)) ret = nobh_commit_write(file, page, from, to); else ret = generic_commit_write(file, page, from, to); @@ -1494,7 +1494,7 @@ static int ext3_writeback_writepage(struct page *page, goto out_fail; } - if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) + if (test_opt(inode->i_sb, NOBH)) ret = nobh_writepage(page, ext3_get_block, wbc); else ret = block_write_full_page(page, ext3_get_block, wbc); @@ -2402,15 +2402,14 @@ static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, struct buffer_head *bh; struct ext3_group_desc * gdp; - if (!ext3_valid_inum(sb, ino)) { - /* - * This error is already checked for in namei.c unless we are - * looking at an NFS filehandle, in which case no error - * report is needed - */ + + if ((ino != EXT3_ROOT_INO && ino != EXT3_JOURNAL_INO && + ino != EXT3_RESIZE_INO && ino < EXT3_FIRST_INO(sb)) || + ino > le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)) { + ext3_error(sb, "ext3_get_inode_block", + "bad inode number: %lu", ino); return 0; } - block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb); if (block_group >= EXT3_SB(sb)->s_groups_count) { ext3_error(sb,"ext3_get_inode_block","group >= groups count"); diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index 2aa7101b27cd..d9176dba3698 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -1000,12 +1000,7 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str if (bh) { unsigned long ino = le32_to_cpu(de->inode); brelse (bh); - if (!ext3_valid_inum(dir->i_sb, ino)) { - ext3_error(dir->i_sb, "ext3_lookup", - "bad inode number: %lu", ino); - inode = NULL; - } else - inode = iget(dir->i_sb, ino); + inode = iget(dir->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); @@ -1033,13 +1028,7 @@ struct dentry *ext3_get_parent(struct dentry *child) return ERR_PTR(-ENOENT); ino = le32_to_cpu(de->inode); brelse(bh); - - if (!ext3_valid_inum(child->d_inode->i_sb, ino)) { - ext3_error(child->d_inode->i_sb, "ext3_get_parent", - "bad inode number: %lu", ino); - inode = NULL; - } else - inode = iget(child->d_inode->i_sb, ino); + inode = iget(child->d_inode->i_sb, ino); if (!inode) return ERR_PTR(-EACCES); diff --git a/trunk/fs/freevxfs/vxfs_lookup.c b/trunk/fs/freevxfs/vxfs_lookup.c index 43886fa00a2a..29cce456c7ce 100644 --- a/trunk/fs/freevxfs/vxfs_lookup.c +++ b/trunk/fs/freevxfs/vxfs_lookup.c @@ -246,8 +246,6 @@ vxfs_readdir(struct file *fp, void *retp, filldir_t filler) u_long page, npages, block, pblocks, nblocks, offset; loff_t pos; - lock_kernel(); - switch ((long)fp->f_pos) { case 0: if (filler(retp, ".", 1, fp->f_pos, ip->i_ino, DT_DIR) < 0) diff --git a/trunk/fs/fuse/control.c b/trunk/fs/fuse/control.c index 46fe60b2da23..a3bce3a77253 100644 --- a/trunk/fs/fuse/control.c +++ b/trunk/fs/fuse/control.c @@ -105,7 +105,7 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, /* * Add a connection to the control filesystem (if it exists). Caller - * must hold fuse_mutex + * must host fuse_mutex */ int fuse_ctl_add_conn(struct fuse_conn *fc) { @@ -139,7 +139,7 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) /* * Remove a connection from the control filesystem (if it exists). - * Caller must hold fuse_mutex + * Caller must host fuse_mutex */ void fuse_ctl_remove_conn(struct fuse_conn *fc) { diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 409ce6a7cca4..72a74cde6de8 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -14,33 +14,6 @@ #include #include -#if BITS_PER_LONG >= 64 -static inline void fuse_dentry_settime(struct dentry *entry, u64 time) -{ - entry->d_time = time; -} - -static inline u64 fuse_dentry_time(struct dentry *entry) -{ - return entry->d_time; -} -#else -/* - * On 32 bit archs store the high 32 bits of time in d_fsdata - */ -static void fuse_dentry_settime(struct dentry *entry, u64 time) -{ - entry->d_time = time; - entry->d_fsdata = (void *) (unsigned long) (time >> 32); -} - -static u64 fuse_dentry_time(struct dentry *entry) -{ - return (u64) entry->d_time + - ((u64) (unsigned long) entry->d_fsdata << 32); -} -#endif - /* * FUSE caches dentries and attributes with separate timeout. The * time in jiffies until the dentry/attributes are valid is stored in @@ -50,13 +23,10 @@ static u64 fuse_dentry_time(struct dentry *entry) /* * Calculate the time in jiffies until a dentry/attributes are valid */ -static u64 time_to_jiffies(unsigned long sec, unsigned long nsec) +static unsigned long time_to_jiffies(unsigned long sec, unsigned long nsec) { - if (sec || nsec) { - struct timespec ts = {sec, nsec}; - return get_jiffies_64() + timespec_to_jiffies(&ts); - } else - return 0; + struct timespec ts = {sec, nsec}; + return jiffies + timespec_to_jiffies(&ts); } /* @@ -65,8 +35,7 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec) */ static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o) { - fuse_dentry_settime(entry, - time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); + entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec); if (entry->d_inode) get_fuse_inode(entry->d_inode)->i_time = time_to_jiffies(o->attr_valid, o->attr_valid_nsec); @@ -78,7 +47,7 @@ static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o) */ void fuse_invalidate_attr(struct inode *inode) { - get_fuse_inode(inode)->i_time = 0; + get_fuse_inode(inode)->i_time = jiffies - 1; } /* @@ -91,7 +60,7 @@ void fuse_invalidate_attr(struct inode *inode) */ static void fuse_invalidate_entry_cache(struct dentry *entry) { - fuse_dentry_settime(entry, 0); + entry->d_time = jiffies - 1; } /* @@ -133,7 +102,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (inode && is_bad_inode(inode)) return 0; - else if (fuse_dentry_time(entry) < get_jiffies_64()) { + else if (time_after(jiffies, entry->d_time)) { int err; struct fuse_entry_out outarg; struct fuse_conn *fc; @@ -697,7 +666,7 @@ static int fuse_revalidate(struct dentry *entry) if (!fuse_allow_task(fc, current)) return -EACCES; if (get_node_id(inode) != FUSE_ROOT_ID && - fi->i_time >= get_jiffies_64()) + time_before_eq(jiffies, fi->i_time)) return 0; return fuse_do_getattr(inode); diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index 69c7750d55b8..0dbf96621841 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -59,7 +59,7 @@ struct fuse_inode { struct fuse_req *forget_req; /** Time in jiffies until the file attributes are valid */ - u64 i_time; + unsigned long i_time; }; /** FUSE specific file data */ diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 7d25092262ae..dcaaabd3b9c4 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -51,7 +51,7 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) return NULL; fi = get_fuse_inode(inode); - fi->i_time = 0; + fi->i_time = jiffies - 1; fi->nodeid = 0; fi->nlookup = 0; fi->forget_req = fuse_request_alloc(); diff --git a/trunk/fs/inotify_user.c b/trunk/fs/inotify_user.c index 017cb0f134d6..f2386442adee 100644 --- a/trunk/fs/inotify_user.c +++ b/trunk/fs/inotify_user.c @@ -187,7 +187,7 @@ static struct inotify_kernel_event * kernel_event(s32 wd, u32 mask, u32 cookie, { struct inotify_kernel_event *kevent; - kevent = kmem_cache_alloc(event_cachep, GFP_NOFS); + kevent = kmem_cache_alloc(event_cachep, GFP_KERNEL); if (unlikely(!kevent)) return NULL; diff --git a/trunk/fs/lockd/svclock.c b/trunk/fs/lockd/svclock.c index c9d419703cf3..baf5ae513481 100644 --- a/trunk/fs/lockd/svclock.c +++ b/trunk/fs/lockd/svclock.c @@ -638,6 +638,9 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) if (task->tk_status < 0) { /* RPC error: Re-insert for retransmission */ timeout = 10 * HZ; + } else if (block->b_done) { + /* Block already removed, kill it for real */ + timeout = 0; } else { /* Call was successful, now wait for client callback */ timeout = 60 * HZ; @@ -706,10 +709,13 @@ nlmsvc_retry_blocked(void) break; if (time_after(block->b_when,jiffies)) break; - dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n", - block, block->b_when); + dprintk("nlmsvc_retry_blocked(%p, when=%ld, done=%d)\n", + block, block->b_when, block->b_done); kref_get(&block->b_count); - nlmsvc_grant_blocked(block); + if (block->b_done) + nlmsvc_unlink_block(block); + else + nlmsvc_grant_blocked(block); nlmsvc_release_block(block); } diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 55a131230f94..e01070d7bf58 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -159,7 +159,7 @@ char * getname(const char __user * filename) #ifdef CONFIG_AUDITSYSCALL void putname(const char *name) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) audit_putname(name); else __putname(name); @@ -1125,7 +1125,7 @@ static int fastcall do_path_lookup(int dfd, const char *name, retval = link_path_walk(name, nd); out: if (likely(retval == 0)) { - if (unlikely(!audit_dummy_context() && nd && nd->dentry && + if (unlikely(current->audit_context && nd && nd->dentry && nd->dentry->d_inode)) audit_inode(name, nd->dentry->d_inode); } @@ -1357,7 +1357,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) return -ENOENT; BUG_ON(victim->d_parent->d_inode != dir); - audit_inode_child(victim->d_name.name, victim->d_inode, dir); + audit_inode_child(victim->d_name.name, victim->d_inode, dir->i_ino); error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); if (error) @@ -1659,7 +1659,6 @@ int open_namei(int dfd, const char *pathname, int flag, * It already exists. */ mutex_unlock(&dir->d_inode->i_mutex); - audit_inode_update(path.dentry->d_inode); error = -EEXIST; if (flag & O_EXCL) @@ -1670,7 +1669,6 @@ int open_namei(int dfd, const char *pathname, int flag, if (flag & O_NOFOLLOW) goto exit_dput; } - error = -ENOENT; if (!path.dentry->d_inode) goto exit_dput; diff --git a/trunk/fs/nfs/namespace.c b/trunk/fs/nfs/namespace.c index 86b3169c8cac..19b98ca468eb 100644 --- a/trunk/fs/nfs/namespace.c +++ b/trunk/fs/nfs/namespace.c @@ -51,7 +51,7 @@ char *nfs_path(const char *base, const struct dentry *dentry, namelen = dentry->d_name.len; buflen -= namelen + 1; if (buflen < 0) - goto Elong_unlock; + goto Elong; end -= namelen; memcpy(end, dentry->d_name.name, namelen); *--end = '/'; @@ -68,8 +68,6 @@ char *nfs_path(const char *base, const struct dentry *dentry, end -= namelen; memcpy(end, base, namelen); return end; -Elong_unlock: - spin_unlock(&dcache_lock); Elong: return ERR_PTR(-ENAMETOOLONG); } diff --git a/trunk/fs/nfs/read.c b/trunk/fs/nfs/read.c index 65c0c5b32351..52bf634260a1 100644 --- a/trunk/fs/nfs/read.c +++ b/trunk/fs/nfs/read.c @@ -63,7 +63,7 @@ struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount) return p; } -static void nfs_readdata_free(struct nfs_read_data *p) +void nfs_readdata_free(struct nfs_read_data *p) { if (p && (p->pagevec != &p->page_array[0])) kfree(p->pagevec); diff --git a/trunk/fs/nfs/write.c b/trunk/fs/nfs/write.c index 50774991f8d5..86bac6a5008e 100644 --- a/trunk/fs/nfs/write.c +++ b/trunk/fs/nfs/write.c @@ -137,7 +137,7 @@ struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount) return p; } -static void nfs_writedata_free(struct nfs_write_data *p) +void nfs_writedata_free(struct nfs_write_data *p) { if (p && (p->pagevec != &p->page_array[0])) kfree(p->pagevec); diff --git a/trunk/fs/nfsd/nfsfh.c b/trunk/fs/nfsd/nfsfh.c index 501d83884530..ecc439d2565f 100644 --- a/trunk/fs/nfsd/nfsfh.c +++ b/trunk/fs/nfsd/nfsfh.c @@ -187,11 +187,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) goto out; } - /* Set user creds for this exportpoint */ - error = nfserrno(nfsd_setuser(rqstp, exp)); - if (error) - goto out; - /* * Look up the dentry using the NFS file handle. */ @@ -246,17 +241,16 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) dprintk("nfsd: fh_verify - just checking\n"); dentry = fhp->fh_dentry; exp = fhp->fh_export; - /* Set user creds for this exportpoint; necessary even - * in the "just checking" case because this may be a - * filehandle that was created by fh_compose, and that - * is about to be used in another nfsv4 compound - * operation */ - error = nfserrno(nfsd_setuser(rqstp, exp)); - if (error) - goto out; } cache_get(&exp->h); + /* Set user creds for this exportpoint; necessary even in the "just + * checking" case because this may be a filehandle that was created by + * fh_compose, and that is about to be used in another nfsv4 compound + * operation */ + error = nfserrno(nfsd_setuser(rqstp, exp)); + if (error) + goto out; error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); if (error) diff --git a/trunk/fs/partitions/Kconfig b/trunk/fs/partitions/Kconfig index e478f1941831..c9a478099281 100644 --- a/trunk/fs/partitions/Kconfig +++ b/trunk/fs/partitions/Kconfig @@ -99,7 +99,7 @@ config IBM_PARTITION config MAC_PARTITION bool "Macintosh partition map support" if PARTITION_ADVANCED - default y if (MAC || PPC_PMAC) + default y if MAC help Say Y here if you would like to use hard disks under Linux which were partitioned on a Macintosh. diff --git a/trunk/fs/reiserfs/file.c b/trunk/fs/reiserfs/file.c index 1627edd50810..f318b58510fd 100644 --- a/trunk/fs/reiserfs/file.c +++ b/trunk/fs/reiserfs/file.c @@ -48,8 +48,8 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp) return 0; } - mutex_lock(&inode->i_mutex); reiserfs_write_lock(inode->i_sb); + mutex_lock(&inode->i_mutex); /* freeing preallocation only involves relogging blocks that * are already in the current transaction. preallocation gets * freed at the end of each transaction, so it is impossible for diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index 52f1e2136546..12dfdcfbee3d 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -39,10 +39,14 @@ void reiserfs_delete_inode(struct inode *inode) /* The = 0 happens when we abort creating a new inode for some reason like lack of space.. */ if (!(inode->i_state & I_NEW) && INODE_PKEY(inode)->k_objectid != 0) { /* also handles bad_inode case */ + mutex_lock(&inode->i_mutex); + reiserfs_delete_xattrs(inode); - if (journal_begin(&th, inode->i_sb, jbegin_count)) + if (journal_begin(&th, inode->i_sb, jbegin_count)) { + mutex_unlock(&inode->i_mutex); goto out; + } reiserfs_update_inode_transaction(inode); err = reiserfs_delete_object(&th, inode); @@ -53,8 +57,12 @@ void reiserfs_delete_inode(struct inode *inode) if (!err) DQUOT_FREE_INODE(inode); - if (journal_end(&th, inode->i_sb, jbegin_count)) + if (journal_end(&th, inode->i_sb, jbegin_count)) { + mutex_unlock(&inode->i_mutex); goto out; + } + + mutex_unlock(&inode->i_mutex); /* check return value from reiserfs_delete_object after * ending the transaction @@ -2340,7 +2348,6 @@ static int reiserfs_write_full_page(struct page *page, unsigned long end_index = inode->i_size >> PAGE_CACHE_SHIFT; int error = 0; unsigned long block; - sector_t last_block; struct buffer_head *head, *bh; int partial = 0; int nr = 0; @@ -2388,19 +2395,10 @@ static int reiserfs_write_full_page(struct page *page, } bh = head; block = page->index << (PAGE_CACHE_SHIFT - s->s_blocksize_bits); - last_block = (i_size_read(inode) - 1) >> inode->i_blkbits; /* first map all the buffers, logging any direct items we find */ do { - if (block > last_block) { - /* - * This can happen when the block size is less than - * the page size. The corresponding bytes in the page - * were zero filled above - */ - clear_buffer_dirty(bh); - set_buffer_uptodate(bh); - } else if ((checked || buffer_dirty(bh)) && - (!buffer_mapped(bh) || (buffer_mapped(bh) + if ((checked || buffer_dirty(bh)) && (!buffer_mapped(bh) || + (buffer_mapped(bh) && bh->b_blocknr == 0))) { /* not mapped yet, or it points to a direct item, search diff --git a/trunk/fs/reiserfs/ioctl.c b/trunk/fs/reiserfs/ioctl.c index a986b5e1e288..745c88100895 100644 --- a/trunk/fs/reiserfs/ioctl.c +++ b/trunk/fs/reiserfs/ioctl.c @@ -116,12 +116,12 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp) if (REISERFS_I(inode)->i_flags & i_nopack_mask) { return 0; } + reiserfs_write_lock(inode->i_sb); /* we need to make sure nobody is changing the file size beneath ** us */ mutex_lock(&inode->i_mutex); - reiserfs_write_lock(inode->i_sb); write_from = inode->i_size & (blocksize - 1); /* if we are on a block boundary, we are already unpacked. */ diff --git a/trunk/fs/udf/ialloc.c b/trunk/fs/udf/ialloc.c index 33323473e3c4..3873c672cb4c 100644 --- a/trunk/fs/udf/ialloc.c +++ b/trunk/fs/udf/ialloc.c @@ -75,12 +75,6 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) } *err = -ENOSPC; - UDF_I_UNIQUE(inode) = 0; - UDF_I_LENEXTENTS(inode) = 0; - UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; - UDF_I_NEXT_ALLOC_GOAL(inode) = 0; - UDF_I_STRAT4096(inode) = 0; - block = udf_new_block(dir->i_sb, NULL, UDF_I_LOCATION(dir).partitionReferenceNum, start, err); if (*err) @@ -90,6 +84,11 @@ struct inode * udf_new_inode (struct inode *dir, int mode, int * err) } mutex_lock(&sbi->s_alloc_mutex); + UDF_I_UNIQUE(inode) = 0; + UDF_I_LENEXTENTS(inode) = 0; + UDF_I_NEXT_ALLOC_BLOCK(inode) = 0; + UDF_I_NEXT_ALLOC_GOAL(inode) = 0; + UDF_I_STRAT4096(inode) = 0; if (UDF_SB_LVIDBH(sb)) { struct logicalVolHeaderDesc *lvhd; diff --git a/trunk/fs/ufs/balloc.c b/trunk/fs/ufs/balloc.c index b82381475779..b01804baa120 100644 --- a/trunk/fs/ufs/balloc.c +++ b/trunk/fs/ufs/balloc.c @@ -248,7 +248,7 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk, if (likely(cur_index != index)) { page = ufs_get_locked_page(mapping, index); - if (!page || IS_ERR(page)) /* it was truncated or EIO */ + if (IS_ERR(page)) continue; } else page = locked_page; diff --git a/trunk/fs/ufs/namei.c b/trunk/fs/ufs/namei.c index d344b411e261..abd5f23a426d 100644 --- a/trunk/fs/ufs/namei.c +++ b/trunk/fs/ufs/namei.c @@ -129,7 +129,7 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, struct inode * inode; if (l > sb->s_blocksize) - goto out_notlocked; + goto out; lock_kernel(); inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO); @@ -155,7 +155,6 @@ static int ufs_symlink (struct inode * dir, struct dentry * dentry, err = ufs_add_nondir(dentry, inode); out: unlock_kernel(); -out_notlocked: return err; out_fail: diff --git a/trunk/fs/ufs/util.c b/trunk/fs/ufs/util.c index 22f820a9b15c..337cf2c46d10 100644 --- a/trunk/fs/ufs/util.c +++ b/trunk/fs/ufs/util.c @@ -251,12 +251,12 @@ struct page *ufs_get_locked_page(struct address_space *mapping, { struct page *page; +try_again: page = find_lock_page(mapping, index); if (!page) { page = read_cache_page(mapping, index, (filler_t*)mapping->a_ops->readpage, NULL); - if (IS_ERR(page)) { printk(KERN_ERR "ufs_change_blocknr: " "read_cache_page error: ino %lu, index: %lu\n", @@ -266,14 +266,6 @@ struct page *ufs_get_locked_page(struct address_space *mapping, lock_page(page); - if (unlikely(page->mapping == NULL)) { - /* Truncate got there first */ - unlock_page(page); - page_cache_release(page); - page = NULL; - goto out; - } - if (!PageUptodate(page) || PageError(page)) { unlock_page(page); page_cache_release(page); @@ -283,8 +275,15 @@ struct page *ufs_get_locked_page(struct address_space *mapping, mapping->host->i_ino, index); page = ERR_PTR(-EIO); + goto out; } } + + if (unlikely(!page->mapping || !page_has_buffers(page))) { + unlock_page(page); + page_cache_release(page); + goto try_again;/*we really need these buffers*/ + } out: return page; } diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.h b/trunk/fs/xfs/linux-2.6/xfs_buf.h index 7858703ed84c..ceda3a2859d2 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.h +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.h @@ -246,8 +246,8 @@ extern void xfs_buf_trace(xfs_buf_t *, char *, void *, void *); #define BUF_BUSY XBF_DONT_BLOCK #define XFS_BUF_BFLAGS(bp) ((bp)->b_flags) -#define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ - ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) +#define XFS_BUF_ZEROFLAGS(bp) \ + ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI)) #define XFS_BUF_STALE(bp) ((bp)->b_flags |= XFS_B_STALE) #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XFS_B_STALE) diff --git a/trunk/fs/xfs/linux-2.6/xfs_super.c b/trunk/fs/xfs/linux-2.6/xfs_super.c index 4754f342a5d3..9bdef9d51900 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_super.c +++ b/trunk/fs/xfs/linux-2.6/xfs_super.c @@ -314,13 +314,6 @@ xfs_mountfs_check_barriers(xfs_mount_t *mp) return; } - if (xfs_readonly_buftarg(mp->m_ddev_targp)) { - xfs_fs_cmn_err(CE_NOTE, mp, - "Disabling barriers, underlying device is readonly"); - mp->m_flags &= ~XFS_MOUNT_BARRIER; - return; - } - error = xfs_barrier_test(mp); if (error) { xfs_fs_cmn_err(CE_NOTE, mp, diff --git a/trunk/fs/xfs/quota/xfs_qm_bhv.c b/trunk/fs/xfs/quota/xfs_qm_bhv.c index f137856c3261..e95e99f7168f 100644 --- a/trunk/fs/xfs/quota/xfs_qm_bhv.c +++ b/trunk/fs/xfs/quota/xfs_qm_bhv.c @@ -217,24 +217,17 @@ xfs_qm_statvfs( return 0; dp = &dqp->q_core; - limit = dp->d_blk_softlimit ? - be64_to_cpu(dp->d_blk_softlimit) : - be64_to_cpu(dp->d_blk_hardlimit); + limit = dp->d_blk_softlimit ? dp->d_blk_softlimit : dp->d_blk_hardlimit; if (limit && statp->f_blocks > limit) { statp->f_blocks = limit; - statp->f_bfree = - (statp->f_blocks > be64_to_cpu(dp->d_bcount)) ? - (statp->f_blocks - be64_to_cpu(dp->d_bcount)) : 0; + statp->f_bfree = (statp->f_blocks > dp->d_bcount) ? + (statp->f_blocks - dp->d_bcount) : 0; } - - limit = dp->d_ino_softlimit ? - be64_to_cpu(dp->d_ino_softlimit) : - be64_to_cpu(dp->d_ino_hardlimit); + limit = dp->d_ino_softlimit ? dp->d_ino_softlimit : dp->d_ino_hardlimit; if (limit && statp->f_files > limit) { statp->f_files = limit; - statp->f_ffree = - (statp->f_files > be64_to_cpu(dp->d_icount)) ? - (statp->f_ffree - be64_to_cpu(dp->d_icount)) : 0; + statp->f_ffree = (statp->f_files > dp->d_icount) ? + (statp->f_ffree - dp->d_icount) : 0; } xfs_qm_dqput(dqp); diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 1f8ecff8553a..86c1bf0bba9e 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -334,9 +334,10 @@ xfs_itobp( #if !defined(__KERNEL__) ni = 0; #elif defined(DEBUG) - ni = BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog; + ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : + (BBTOB(imap.im_len) >> mp->m_sb.sb_inodelog); #else /* usual case */ - ni = 1; + ni = (imap_flags & XFS_IMAP_BULKSTAT) ? 0 : 1; #endif for (i = 0; i < ni; i++) { @@ -347,15 +348,11 @@ xfs_itobp( (i << mp->m_sb.sb_inodelog)); di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); - if (unlikely(XFS_TEST_ERROR(!di_ok, mp, - XFS_ERRTAG_ITOBP_INOTOBP, - XFS_RANDOM_ITOBP_INOTOBP))) { - if (imap_flags & XFS_IMAP_BULKSTAT) { - xfs_trans_brelse(tp, bp); - return XFS_ERROR(EINVAL); - } + if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, + XFS_RANDOM_ITOBP_INOTOBP))) { #ifdef DEBUG - cmn_err(CE_ALERT, + if (!(imap_flags & XFS_IMAP_BULKSTAT)) + cmn_err(CE_ALERT, "Device %s - bad inode magic/vsn " "daddr %lld #%d (magic=%x)", XFS_BUFTARG_NAME(mp->m_ddev_targp), diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 21ac1a67e3e0..e730328636c3 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -1413,7 +1413,7 @@ xlog_sync(xlog_t *log, ops = iclog->ic_header.h_num_logops; INT_SET(iclog->ic_header.h_num_logops, ARCH_CONVERT, ops); - bp = iclog->ic_bp; + bp = iclog->ic_bp; ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2); XFS_BUF_SET_ADDR(bp, BLOCK_LSN(INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT))); @@ -1430,14 +1430,15 @@ xlog_sync(xlog_t *log, } XFS_BUF_SET_PTR(bp, (xfs_caddr_t) &(iclog->ic_header), count); XFS_BUF_SET_FSPRIVATE(bp, iclog); /* save for later */ - XFS_BUF_ZEROFLAGS(bp); XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); /* * Do an ordered write for the log block. - * Its unnecessary to flush the first split block in the log wrap case. + * + * It may not be needed to flush the first split block in the log wrap + * case, but do it anyways to be safe -AK */ - if (!split && (log->l_mp->m_flags & XFS_MOUNT_BARRIER)) + if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) XFS_BUF_ORDERED(bp); ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); @@ -1459,7 +1460,7 @@ xlog_sync(xlog_t *log, return error; } if (split) { - bp = iclog->ic_log->l_xbuf; + bp = iclog->ic_log->l_xbuf; ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1); XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2); @@ -1467,7 +1468,6 @@ xlog_sync(xlog_t *log, XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+ (__psint_t)count), split); XFS_BUF_SET_FSPRIVATE(bp, iclog); - XFS_BUF_ZEROFLAGS(bp); XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) diff --git a/trunk/fs/xfs/xfs_vfsops.c b/trunk/fs/xfs/xfs_vfsops.c index b427d220a169..6c96391f3f1a 100644 --- a/trunk/fs/xfs/xfs_vfsops.c +++ b/trunk/fs/xfs/xfs_vfsops.c @@ -515,7 +515,7 @@ xfs_mount( if (error) goto error2; - if (mp->m_flags & XFS_MOUNT_BARRIER) + if ((mp->m_flags & XFS_MOUNT_BARRIER) && !(vfsp->vfs_flag & VFS_RDONLY)) xfs_mountfs_check_barriers(mp); error = XFS_IOINIT(vfsp, args, flags); diff --git a/trunk/include/asm-alpha/libata-portmap.h b/trunk/include/asm-alpha/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-alpha/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-arm/arch-iop3xx/iop331-irqs.h b/trunk/include/asm-arm/arch-iop3xx/iop331-irqs.h index 7135ad7e335e..8ff73d487222 100644 --- a/trunk/include/asm-arm/arch-iop3xx/iop331-irqs.h +++ b/trunk/include/asm-arm/arch-iop3xx/iop331-irqs.h @@ -91,6 +91,7 @@ #define NR_IRQS NR_IOP331_IRQS +#if defined(CONFIG_ARCH_IQ80331) /* * Interrupts available on the IQ80331 board */ @@ -110,6 +111,7 @@ #define IRQ_IQ80331_INTC IRQ_IOP331_XINT2 #define IRQ_IQ80331_INTD IRQ_IOP331_XINT3 +#elif defined(CONFIG_MACH_IQ80332) /* * Interrupts available on the IQ80332 board */ @@ -129,4 +131,6 @@ #define IRQ_IQ80332_INTC IRQ_IOP331_XINT2 #define IRQ_IQ80332_INTD IRQ_IOP331_XINT3 +#endif + #endif // _IOP331_IRQ_H_ diff --git a/trunk/include/asm-arm/arch-omap/clock.h b/trunk/include/asm-arm/arch-omap/clock.h index f83003f5287b..3c4eb9fbe48a 100644 --- a/trunk/include/asm-arm/arch-omap/clock.h +++ b/trunk/include/asm-arm/arch-omap/clock.h @@ -48,6 +48,8 @@ struct clk_functions { }; extern unsigned int mpurate; +extern struct list_head clocks; +extern spinlock_t clockfw_lock; extern int clk_init(struct clk_functions * custom_clocks); extern int clk_register(struct clk *clk); diff --git a/trunk/include/asm-generic/libata-portmap.h b/trunk/include/asm-generic/libata-portmap.h deleted file mode 100644 index 9202fd02d5be..000000000000 --- a/trunk/include/asm-generic/libata-portmap.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ASM_GENERIC_LIBATA_PORTMAP_H -#define __ASM_GENERIC_LIBATA_PORTMAP_H - -#define ATA_PRIMARY_CMD 0x1F0 -#define ATA_PRIMARY_CTL 0x3F6 -#define ATA_PRIMARY_IRQ 14 - -#define ATA_SECONDARY_CMD 0x170 -#define ATA_SECONDARY_CTL 0x376 -#define ATA_SECONDARY_IRQ 15 - -#endif diff --git a/trunk/include/asm-i386/kprobes.h b/trunk/include/asm-i386/kprobes.h index 8774d06689da..0730a20f6db8 100644 --- a/trunk/include/asm-i386/kprobes.h +++ b/trunk/include/asm-i386/kprobes.h @@ -45,7 +45,6 @@ typedef u8 kprobe_opcode_t; #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 0 -#define flush_insn_slot(p) do { } while (0) void arch_remove_kprobe(struct kprobe *p); void kretprobe_trampoline(void); diff --git a/trunk/include/asm-i386/libata-portmap.h b/trunk/include/asm-i386/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-i386/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-ia64/kprobes.h b/trunk/include/asm-ia64/kprobes.h index 938904910115..2418a787c405 100644 --- a/trunk/include/asm-ia64/kprobes.h +++ b/trunk/include/asm-ia64/kprobes.h @@ -125,6 +125,5 @@ static inline void jprobe_return(void) } extern void invalidate_stacked_regs(void); extern void flush_register_stack(void); -extern void flush_insn_slot(struct kprobe *p); #endif /* _ASM_KPROBES_H */ diff --git a/trunk/include/asm-ia64/libata-portmap.h b/trunk/include/asm-ia64/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-ia64/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-ia64/meminit.h b/trunk/include/asm-ia64/meminit.h index 6a33a07b3f1d..894bc4d89dc0 100644 --- a/trunk/include/asm-ia64/meminit.h +++ b/trunk/include/asm-ia64/meminit.h @@ -56,11 +56,6 @@ extern void efi_memmap_init(unsigned long *, unsigned long *); extern struct page *vmem_map; extern int find_largest_hole (u64 start, u64 end, void *arg); extern int create_mem_map_page_table (u64 start, u64 end, void *arg); - extern int vmemmap_find_next_valid_pfn(int, int); -#else -static inline int vmemmap_find_next_valid_pfn(int node, int i) -{ - return i + 1; -} #endif + #endif /* meminit_h */ diff --git a/trunk/include/asm-ia64/pal.h b/trunk/include/asm-ia64/pal.h index 20a8d618c845..37e52a2836b0 100644 --- a/trunk/include/asm-ia64/pal.h +++ b/trunk/include/asm-ia64/pal.h @@ -1433,12 +1433,7 @@ typedef union pal_version_u { } pal_version_u_t; -/* - * Return PAL version information. While the documentation states that - * PAL_VERSION can be called in either physical or virtual mode, some - * implementations only allow physical calls. We don't call it very often, - * so the overhead isn't worth eliminating. - */ +/* Return PAL version information */ static inline s64 ia64_pal_version (pal_version_u_t *pal_min_version, pal_version_u_t *pal_cur_version) { diff --git a/trunk/include/asm-ia64/sn/xpc.h b/trunk/include/asm-ia64/sn/xpc.h index b72af597878d..8406f1ef4caf 100644 --- a/trunk/include/asm-ia64/sn/xpc.h +++ b/trunk/include/asm-ia64/sn/xpc.h @@ -1124,8 +1124,8 @@ xpc_notify_IRQ_send_local(struct xpc_channel *ch, u8 ipi_flag, #define XPC_GET_IPI_FLAGS(_amo, _c) ((u8) (((_amo) >> ((_c) * 8)) & 0xff)) #define XPC_SET_IPI_FLAGS(_amo, _c, _f) (_amo) |= ((u64) (_f) << ((_c) * 8)) -#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x0f0f0f0f0f0f0f0f)) -#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & __IA64_UL_CONST(0x1010101010101010)) +#define XPC_ANY_OPENCLOSE_IPI_FLAGS_SET(_amo) ((_amo) & 0x0f0f0f0f0f0f0f0f) +#define XPC_ANY_MSG_IPI_FLAGS_SET(_amo) ((_amo) & 0x1010101010101010) static inline void diff --git a/trunk/include/asm-ia64/system.h b/trunk/include/asm-ia64/system.h index 384fbf7f2a0f..fc9677bc87ee 100644 --- a/trunk/include/asm-ia64/system.h +++ b/trunk/include/asm-ia64/system.h @@ -24,7 +24,7 @@ * 0xa000000000000000+2*PERCPU_PAGE_SIZE * - 0xa000000000000000+3*PERCPU_PAGE_SIZE remain unmapped (guard page) */ -#define KERNEL_START (GATE_ADDR+__IA64_UL_CONST(0x100000000)) +#define KERNEL_START (GATE_ADDR+0x100000000) #define PERCPU_ADDR (-PERCPU_PAGE_SIZE) #ifndef __ASSEMBLY__ diff --git a/trunk/include/asm-m68k/oplib.h b/trunk/include/asm-m68k/oplib.h index 06caa2d08451..c3594f473ef7 100644 --- a/trunk/include/asm-m68k/oplib.h +++ b/trunk/include/asm-m68k/oplib.h @@ -244,6 +244,11 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, char *name); +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/trunk/include/asm-powerpc/backlight.h b/trunk/include/asm-powerpc/backlight.h index 8cf5c37c3817..58d4b6f8d827 100644 --- a/trunk/include/asm-powerpc/backlight.h +++ b/trunk/include/asm-powerpc/backlight.h @@ -30,12 +30,8 @@ static inline void pmac_backlight_key_down(void) pmac_backlight_key(1); } -extern void pmac_backlight_set_legacy_brightness_pmu(int brightness); extern int pmac_backlight_set_legacy_brightness(int brightness); extern int pmac_backlight_get_legacy_brightness(void); -extern void pmac_backlight_enable(void); -extern void pmac_backlight_disable(void); - #endif /* __KERNEL__ */ #endif diff --git a/trunk/include/asm-powerpc/kprobes.h b/trunk/include/asm-powerpc/kprobes.h index 34e1f89a5fa0..2d0af52c823d 100644 --- a/trunk/include/asm-powerpc/kprobes.h +++ b/trunk/include/asm-powerpc/kprobes.h @@ -51,7 +51,6 @@ typedef unsigned int kprobe_opcode_t; #define ARCH_SUPPORTS_KRETPROBES #define ARCH_INACTIVE_KPROBE_COUNT 1 -#define flush_insn_slot(p) do { } while (0) void kretprobe_trampoline(void); extern void arch_remove_kprobe(struct kprobe *p); diff --git a/trunk/include/asm-powerpc/libata-portmap.h b/trunk/include/asm-powerpc/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-powerpc/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-s390/system.h b/trunk/include/asm-s390/system.h index 16040048cd1b..36a3a85d611a 100644 --- a/trunk/include/asm-s390/system.h +++ b/trunk/include/asm-s390/system.h @@ -128,13 +128,8 @@ extern void account_system_vtime(struct task_struct *); #define nop() __asm__ __volatile__ ("nop") -#define xchg(ptr,x) \ -({ \ - __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ - __ret; \ -}) +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(void *)(ptr),sizeof(*(ptr)))) static inline unsigned long __xchg(unsigned long x, void * ptr, int size) { diff --git a/trunk/include/asm-s390/timex.h b/trunk/include/asm-s390/timex.h index 5d0332a4c2bd..4848057dafe4 100644 --- a/trunk/include/asm-s390/timex.h +++ b/trunk/include/asm-s390/timex.h @@ -19,7 +19,7 @@ static inline cycles_t get_cycles(void) { cycles_t cycles; - __asm__ __volatile__ ("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); + __asm__("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); return cycles >> 2; } @@ -27,7 +27,7 @@ static inline unsigned long long get_clock (void) { unsigned long long clk; - __asm__ __volatile__ ("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); + __asm__("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); return clk; } diff --git a/trunk/include/asm-sparc/libata-portmap.h b/trunk/include/asm-sparc/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-sparc/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sparc/oplib.h b/trunk/include/asm-sparc/oplib.h index 91691e52c058..f283f8aaf6a9 100644 --- a/trunk/include/asm-sparc/oplib.h +++ b/trunk/include/asm-sparc/oplib.h @@ -267,6 +267,11 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, char *name); +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/trunk/include/asm-sparc/signal.h b/trunk/include/asm-sparc/signal.h index d03a21c97abb..0ae5084c427b 100644 --- a/trunk/include/asm-sparc/signal.h +++ b/trunk/include/asm-sparc/signal.h @@ -168,7 +168,7 @@ struct sigstack { * statically allocated data.. which is NOT GOOD. * */ -#define SA_STATIC_ALLOC 0x8000 +#define SA_STATIC_ALLOC 0x80 #endif #include diff --git a/trunk/include/asm-sparc64/kprobes.h b/trunk/include/asm-sparc64/kprobes.h index c9f5c34d318c..15065af566c2 100644 --- a/trunk/include/asm-sparc64/kprobes.h +++ b/trunk/include/asm-sparc64/kprobes.h @@ -13,7 +13,6 @@ typedef u32 kprobe_opcode_t; #define JPROBE_ENTRY(pentry) (kprobe_opcode_t *)pentry #define arch_remove_kprobe(p) do {} while (0) #define ARCH_INACTIVE_KPROBE_COUNT 0 -#define flush_insn_slot(p) do { } while (0) /* Architecture specific copy of original instruction*/ struct arch_specific_insn { diff --git a/trunk/include/asm-sparc64/libata-portmap.h b/trunk/include/asm-sparc64/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-sparc64/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-sparc64/openprom.h b/trunk/include/asm-sparc64/openprom.h index e01b80559c93..b4959d2b0d99 100644 --- a/trunk/include/asm-sparc64/openprom.h +++ b/trunk/include/asm-sparc64/openprom.h @@ -175,7 +175,7 @@ struct linux_nodeops { }; /* More fun PROM structures for device probing. */ -#define PROMREG_MAX 24 +#define PROMREG_MAX 16 #define PROMVADDR_MAX 16 #define PROMINTR_MAX 15 diff --git a/trunk/include/asm-sparc64/oplib.h b/trunk/include/asm-sparc64/oplib.h index 6a0da3b1695c..a68b0bb05958 100644 --- a/trunk/include/asm-sparc64/oplib.h +++ b/trunk/include/asm-sparc64/oplib.h @@ -287,6 +287,11 @@ extern void prom_getstring(int node, const char *prop, char *buf, int bufsize); /* Does the passed node have the given "name"? YES=1 NO=0 */ extern int prom_nodematch(int thisnode, const char *name); +/* Puts in buffer a prom name in the form name@x,y or name (x for which_io + * and y for first regs phys address + */ +extern int prom_getname(int node, char *buf, int buflen); + /* Search all siblings starting at the passed node for "name" matching * the given string. Returns the node on success, zero on failure. */ diff --git a/trunk/include/asm-sparc64/pgtable.h b/trunk/include/asm-sparc64/pgtable.h index 1ba19eb34ce3..03f5bc9b6bec 100644 --- a/trunk/include/asm-sparc64/pgtable.h +++ b/trunk/include/asm-sparc64/pgtable.h @@ -339,7 +339,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot) " .section .sun4v_2insn_patch, \"ax\"\n" " .word 661b\n" " andn %0, %4, %0\n" - " or %0, %5, %0\n" + " or %0, %3, %0\n" " .previous\n" : "=r" (val) : "0" (val), "i" (_PAGE_CP_4U | _PAGE_CV_4U), "i" (_PAGE_E_4U), diff --git a/trunk/include/asm-sparc64/sfp-machine.h b/trunk/include/asm-sparc64/sfp-machine.h index 89d42431efb5..5015bb8d6c32 100644 --- a/trunk/include/asm-sparc64/sfp-machine.h +++ b/trunk/include/asm-sparc64/sfp-machine.h @@ -34,7 +34,7 @@ #define _FP_MUL_MEAT_D(R,X,Y) \ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) #define _FP_MUL_MEAT_Q(R,X,Y) \ - _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) + _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm) #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv_norm(D,R,X,Y) diff --git a/trunk/include/asm-x86_64/calgary.h b/trunk/include/asm-x86_64/calgary.h index 4e3919524240..fbfb50136edb 100644 --- a/trunk/include/asm-x86_64/calgary.h +++ b/trunk/include/asm-x86_64/calgary.h @@ -60,4 +60,9 @@ static inline int calgary_iommu_init(void) { return 1; } static inline void detect_calgary(void) { return; } #endif +static inline unsigned int bus_to_phb(unsigned char busno) +{ + return ((busno % 15 == 0) ? 0 : busno / 2 + 1); +} + #endif /* _ASM_X86_64_CALGARY_H */ diff --git a/trunk/include/asm-x86_64/kprobes.h b/trunk/include/asm-x86_64/kprobes.h index cf5317898fb0..d36febd9bb18 100644 --- a/trunk/include/asm-x86_64/kprobes.h +++ b/trunk/include/asm-x86_64/kprobes.h @@ -47,7 +47,6 @@ typedef u8 kprobe_opcode_t; void kretprobe_trampoline(void); extern void arch_remove_kprobe(struct kprobe *p); -#define flush_insn_slot(p) do { } while (0) /* Architecture specific copy of original instruction*/ struct arch_specific_insn { diff --git a/trunk/include/asm-x86_64/libata-portmap.h b/trunk/include/asm-x86_64/libata-portmap.h deleted file mode 100644 index 75484ef0c743..000000000000 --- a/trunk/include/asm-x86_64/libata-portmap.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/trunk/include/asm-x86_64/page.h b/trunk/include/asm-x86_64/page.h index 10f346165cab..f7bf875aae40 100644 --- a/trunk/include/asm-x86_64/page.h +++ b/trunk/include/asm-x86_64/page.h @@ -19,7 +19,7 @@ #define EXCEPTION_STACK_ORDER 0 #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER) -#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) +#define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) #define IRQSTACK_ORDER 2 diff --git a/trunk/include/asm-x86_64/swiotlb.h b/trunk/include/asm-x86_64/swiotlb.h index ba94ab3d2673..5f9a01805821 100644 --- a/trunk/include/asm-x86_64/swiotlb.h +++ b/trunk/include/asm-x86_64/swiotlb.h @@ -42,8 +42,6 @@ extern void swiotlb_free_coherent (struct device *hwdev, size_t size, extern int swiotlb_dma_supported(struct device *hwdev, u64 mask); extern void swiotlb_init(void); -extern int swiotlb_force; - #ifdef CONFIG_SWIOTLB extern int swiotlb; #else diff --git a/trunk/include/linux/audit.h b/trunk/include/linux/audit.h index 64f9f9e56ac5..b27d7debc5a1 100644 --- a/trunk/include/linux/audit.h +++ b/trunk/include/linux/audit.h @@ -327,31 +327,21 @@ extern void __audit_getname(const char *name); extern void audit_putname(const char *name); extern void __audit_inode(const char *name, const struct inode *inode); extern void __audit_inode_child(const char *dname, const struct inode *inode, - const struct inode *parent); -extern void __audit_inode_update(const struct inode *inode); -static inline int audit_dummy_context(void) -{ - void *p = current->audit_context; - return !p || *(int *)p; -} + unsigned long pino); static inline void audit_getname(const char *name) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) __audit_getname(name); } static inline void audit_inode(const char *name, const struct inode *inode) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) __audit_inode(name, inode); } static inline void audit_inode_child(const char *dname, - const struct inode *inode, - const struct inode *parent) { - if (unlikely(!audit_dummy_context())) - __audit_inode_child(dname, inode, parent); -} -static inline void audit_inode_update(const struct inode *inode) { - if (unlikely(!audit_dummy_context())) - __audit_inode_update(inode); + const struct inode *inode, + unsigned long pino) { + if (unlikely(current->audit_context)) + __audit_inode_child(dname, inode, pino); } /* Private API (for audit.c only) */ @@ -375,61 +365,57 @@ extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat); static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_ipc_obj(ipcp); return 0; } static inline int audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_ipc_set_perm(qbytes, uid, gid, mode); return 0; } static inline int audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_mq_open(oflag, mode, u_attr); return 0; } static inline int audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec __user *u_abs_timeout) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_mq_timedsend(mqdes, msg_len, msg_prio, u_abs_timeout); return 0; } static inline int audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __user *u_msg_prio, const struct timespec __user *u_abs_timeout) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_mq_timedreceive(mqdes, msg_len, u_msg_prio, u_abs_timeout); return 0; } static inline int audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_mq_notify(mqdes, u_notification); return 0; } static inline int audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat) { - if (unlikely(!audit_dummy_context())) + if (unlikely(current->audit_context)) return __audit_mq_getsetattr(mqdes, mqstat); return 0; } -extern int audit_n_rules; #else #define audit_alloc(t) ({ 0; }) #define audit_free(t) do { ; } while (0) #define audit_syscall_entry(ta,a,b,c,d,e) do { ; } while (0) #define audit_syscall_exit(f,r) do { ; } while (0) -#define audit_dummy_context() 1 #define audit_getname(n) do { ; } while (0) #define audit_putname(n) do { ; } while (0) #define __audit_inode(n,i) do { ; } while (0) #define __audit_inode_child(d,i,p) do { ; } while (0) -#define __audit_inode_update(i) do { ; } while (0) #define audit_inode(n,i) do { ; } while (0) #define audit_inode_child(d,i,p) do { ; } while (0) -#define audit_inode_update(i) do { ; } while (0) #define auditsc_get_stamp(c,t,s) do { BUG(); } while (0) #define audit_get_loginuid(c) ({ -1; }) #define audit_ipc_obj(i) ({ 0; }) @@ -444,7 +430,6 @@ extern int audit_n_rules; #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) #define audit_mq_notify(d,n) ({ 0; }) #define audit_mq_getsetattr(d,s) ({ 0; }) -#define audit_n_rules 0 #endif #ifdef CONFIG_AUDIT diff --git a/trunk/include/linux/cn_proc.h b/trunk/include/linux/cn_proc.h index 1c86d65bc4b9..dbb7769009be 100644 --- a/trunk/include/linux/cn_proc.h +++ b/trunk/include/linux/cn_proc.h @@ -57,8 +57,7 @@ struct proc_event { PROC_EVENT_EXIT = 0x80000000 } what; __u32 cpu; - __u64 __attribute__((aligned(8))) timestamp_ns; - /* Number of nano seconds since system boot */ + struct timespec timestamp; union { /* must be last field of proc_event struct */ struct { __u32 err; diff --git a/trunk/include/linux/cpu.h b/trunk/include/linux/cpu.h index 8fb344a9abd8..44a11f1ccaf2 100644 --- a/trunk/include/linux/cpu.h +++ b/trunk/include/linux/cpu.h @@ -48,6 +48,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) { } #endif +extern int current_in_cpu_hotplug(void); int cpu_up(unsigned int cpu); @@ -60,6 +61,10 @@ static inline int register_cpu_notifier(struct notifier_block *nb) static inline void unregister_cpu_notifier(struct notifier_block *nb) { } +static inline int current_in_cpu_hotplug(void) +{ + return 0; +} #endif /* CONFIG_SMP */ extern struct sysdev_class cpu_sysdev_class; @@ -68,6 +73,7 @@ extern struct sysdev_class cpu_sysdev_class; /* Stop CPUs going up and down. */ extern void lock_cpu_hotplug(void); extern void unlock_cpu_hotplug(void); +extern int lock_cpu_hotplug_interruptible(void); #define hotcpu_notifier(fn, pri) { \ static struct notifier_block fn##_nb = \ { .notifier_call = fn, .priority = pri }; \ diff --git a/trunk/include/linux/cpufreq.h b/trunk/include/linux/cpufreq.h index 4ea39fee99c7..35e137636b0b 100644 --- a/trunk/include/linux/cpufreq.h +++ b/trunk/include/linux/cpufreq.h @@ -172,6 +172,9 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int relation); +/* pass an event to the cpufreq governor */ +int cpufreq_governor(unsigned int cpu, unsigned int event); + int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); diff --git a/trunk/include/linux/debug_locks.h b/trunk/include/linux/debug_locks.h index 88dafa246d87..6a7047851e48 100644 --- a/trunk/include/linux/debug_locks.h +++ b/trunk/include/linux/debug_locks.h @@ -1,8 +1,6 @@ #ifndef __LINUX_DEBUG_LOCKING_H #define __LINUX_DEBUG_LOCKING_H -struct task_struct; - extern int debug_locks; extern int debug_locks_silent; diff --git a/trunk/include/linux/delayacct.h b/trunk/include/linux/delayacct.h index 11487b6e7127..7e8b6011b8f3 100644 --- a/trunk/include/linux/delayacct.h +++ b/trunk/include/linux/delayacct.h @@ -55,7 +55,7 @@ static inline void delayacct_tsk_init(struct task_struct *tsk) { /* reinitialize in case parent's non-null pointer was dup'ed*/ tsk->delays = NULL; - if (delayacct_on) + if (unlikely(delayacct_on)) __delayacct_tsk_init(tsk); } @@ -80,7 +80,9 @@ static inline void delayacct_blkio_end(void) static inline int delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) { - if (!delayacct_on || !tsk->delays) + if (likely(!delayacct_on)) + return -EINVAL; + if (!tsk->delays) return 0; return __delayacct_add_tsk(d, tsk); } diff --git a/trunk/include/linux/ext3_fs.h b/trunk/include/linux/ext3_fs.h index 9f9cce7bd86d..5607e6457a65 100644 --- a/trunk/include/linux/ext3_fs.h +++ b/trunk/include/linux/ext3_fs.h @@ -492,15 +492,6 @@ static inline struct ext3_inode_info *EXT3_I(struct inode *inode) { return container_of(inode, struct ext3_inode_info, vfs_inode); } - -static inline int ext3_valid_inum(struct super_block *sb, unsigned long ino) -{ - return ino == EXT3_ROOT_INO || - ino == EXT3_JOURNAL_INO || - ino == EXT3_RESIZE_INO || - (ino >= EXT3_FIRST_INO(sb) && - ino <= le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count)); -} #else /* Assume that user mode programs are passing in an ext3fs superblock, not * a kernel struct super_block. This will allow us to call the feature-test diff --git a/trunk/include/linux/fb.h b/trunk/include/linux/fb.h index 4ad0673b1995..405f44e44e5d 100644 --- a/trunk/include/linux/fb.h +++ b/trunk/include/linux/fb.h @@ -524,7 +524,7 @@ struct fb_event { extern int fb_register_client(struct notifier_block *nb); extern int fb_unregister_client(struct notifier_block *nb); -extern int fb_notifier_call_chain(unsigned long val, void *v); + /* * Pixmap structure definition * diff --git a/trunk/include/linux/fsnotify.h b/trunk/include/linux/fsnotify.h index d4f219ffaa5d..cc5dec70c32c 100644 --- a/trunk/include/linux/fsnotify.h +++ b/trunk/include/linux/fsnotify.h @@ -67,7 +67,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, if (source) { inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL, NULL); } - audit_inode_child(new_name, source, new_dir); + audit_inode_child(new_name, source, new_dir->i_ino); } /* @@ -98,7 +98,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) inode_dir_notify(inode, DN_CREATE); inotify_inode_queue_event(inode, IN_CREATE, 0, dentry->d_name.name, dentry->d_inode); - audit_inode_child(dentry->d_name.name, dentry->d_inode, inode); + audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); } /* @@ -109,7 +109,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) inode_dir_notify(inode, DN_CREATE); inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, dentry->d_name.name, dentry->d_inode); - audit_inode_child(dentry->d_name.name, dentry->d_inode, inode); + audit_inode_child(dentry->d_name.name, dentry->d_inode, inode->i_ino); } /* diff --git a/trunk/include/linux/futex.h b/trunk/include/linux/futex.h index d097b5b72bc6..34c3a215f2cd 100644 --- a/trunk/include/linux/futex.h +++ b/trunk/include/linux/futex.h @@ -96,8 +96,7 @@ struct robust_list_head { long do_futex(u32 __user *uaddr, int op, u32 val, unsigned long timeout, u32 __user *uaddr2, u32 val2, u32 val3); -extern int -handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi); +extern int handle_futex_death(u32 __user *uaddr, struct task_struct *curr); #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 99620451d958..dc7abef10965 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -571,7 +571,6 @@ typedef struct ide_drive_s { u8 waiting_for_dma; /* dma currently in progress */ u8 unmask; /* okay to unmask other irqs */ u8 bswap; /* byte swap data */ - u8 noflush; /* don't attempt flushes */ u8 dsc_overlap; /* DSC overlap */ u8 nice1; /* give potential excess bandwidth */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index b3253ab72ff7..56f1e0e1e598 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -893,6 +893,7 @@ struct input_dev { int (*open)(struct input_dev *dev); void (*close)(struct input_dev *dev); + int (*accept)(struct input_dev *dev, struct file *file); int (*flush)(struct input_dev *dev, struct file *file); int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); int (*upload_effect)(struct input_dev *dev, struct ff_effect *effect); @@ -960,26 +961,6 @@ struct input_dev { struct input_handle; -/** - * struct input_handler - implements one of interfaces for input devices - * @private: driver-specific data - * @event: event handler - * @connect: called when attaching a handler to an input device - * @disconnect: disconnects a handler from input device - * @start: starts handler for given handle. This function is called by - * input core right after connect() method and also when a process - * that "grabbed" a device releases it - * @fops: file operations this driver implements - * @minor: beginning of range of 32 minors for devices this driver - * can provide - * @name: name of the handler, to be shown in /proc/bus/input/handlers - * @id_table: pointer to a table of input_device_ids this driver can - * handle - * @blacklist: prointer to a table of input_device_ids this driver should - * ignore even if they match @id_table - * @h_list: list of input handles associated with the handler - * @node: for placing the driver onto input_handler_list - */ struct input_handler { void *private; @@ -987,7 +968,6 @@ struct input_handler { void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); struct input_handle* (*connect)(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id); void (*disconnect)(struct input_handle *handle); - void (*start)(struct input_handle *handle); const struct file_operations *fops; int minor; @@ -1050,10 +1030,10 @@ void input_release_device(struct input_handle *); int input_open_device(struct input_handle *); void input_close_device(struct input_handle *); +int input_accept_process(struct input_handle *handle, struct file *file); int input_flush_device(struct input_handle* handle, struct file* file); void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); -void input_inject_event(struct input_handle *handle, unsigned int type, unsigned int code, int value); static inline void input_report_key(struct input_dev *dev, unsigned int code, int value) { diff --git a/trunk/include/linux/irq.h b/trunk/include/linux/irq.h index fbf6d901e9c2..b48eae32dc61 100644 --- a/trunk/include/linux/irq.h +++ b/trunk/include/linux/irq.h @@ -47,8 +47,8 @@ #define IRQ_WAITING 0x00200000 /* IRQ not yet seen - for autodetection */ #define IRQ_LEVEL 0x00400000 /* IRQ level triggered */ #define IRQ_MASKED 0x00800000 /* IRQ masked - shouldn't be seen again */ -#define IRQ_PER_CPU 0x01000000 /* IRQ is per CPU */ #ifdef CONFIG_IRQ_PER_CPU +# define IRQ_PER_CPU 0x01000000 /* IRQ is per CPU */ # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) #else # define CHECK_IRQ_PER_CPU(var) 0 @@ -58,7 +58,6 @@ #define IRQ_NOREQUEST 0x04000000 /* IRQ cannot be requested */ #define IRQ_NOAUTOEN 0x08000000 /* IRQ will not be enabled on request irq */ #define IRQ_DELAYED_DISABLE 0x10000000 /* IRQ disable (masking) happens delayed. */ -#define IRQ_WAKEUP 0x20000000 /* IRQ triggers system wakeup */ struct proc_dir_entry; @@ -125,7 +124,6 @@ struct irq_chip { * @action: the irq action chain * @status: status information * @depth: disable-depth, for nested irq_disable() calls - * @wake_depth: enable depth, for multiple set_irq_wake() callers * @irq_count: stats field to detect stalled irqs * @irqs_unhandled: stats field for spurious unhandled interrupts * @lock: locking for SMP @@ -149,7 +147,6 @@ struct irq_desc { unsigned int status; /* IRQ status */ unsigned int depth; /* nested irq disables */ - unsigned int wake_depth; /* nested wake enables */ unsigned int irq_count; /* For detecting broken IRQs */ unsigned int irqs_unhandled; spinlock_t lock; diff --git a/trunk/include/linux/jiffies.h b/trunk/include/linux/jiffies.h index 329ebcffa106..043376920f51 100644 --- a/trunk/include/linux/jiffies.h +++ b/trunk/include/linux/jiffies.h @@ -47,8 +47,8 @@ * - (NOM / DEN) fits in (32 - LSH) bits. * - (NOM % DEN) fits in (32 - LSH) bits. */ -#define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \ - + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN)) +#define SH_DIV(NOM,DEN,LSH) ( ((NOM / DEN) << LSH) \ + + (((NOM % DEN) << LSH) + DEN / 2) / DEN) /* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */ #define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8)) diff --git a/trunk/include/linux/kobject.h b/trunk/include/linux/kobject.h index 2d229327959e..0503b2ed8bae 100644 --- a/trunk/include/linux/kobject.h +++ b/trunk/include/linux/kobject.h @@ -46,6 +46,8 @@ enum kobject_action { KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ + KOBJ_UNDOCK = (__force kobject_action_t) 0x08, /* undocking */ + KOBJ_DOCK = (__force kobject_action_t) 0x09, /* dock */ }; struct kobject { diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index ed749f778697..6cc497a2b6da 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -36,8 +36,6 @@ #include #include -#include - /* * compile-time options: to be removed as soon as all the drivers are * converted to the new debugging mechanism @@ -267,14 +265,12 @@ enum { /* ata_eh_info->flags */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ - ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */ + ATA_EHI_RESUME_LINK = (1 << 1), /* need to resume link */ ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ ATA_EHI_QUIET = (1 << 3), /* be quiet */ ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ - ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, - /* max repeat if error condition is still set after ->error_handler */ ATA_EH_MAX_REPEAT = 5, @@ -352,12 +348,12 @@ struct ata_probe_ent { struct scsi_host_template *sht; struct ata_ioports port[ATA_MAX_PORTS]; unsigned int n_ports; - unsigned int dummy_port_mask; + unsigned int hard_port_no; unsigned int pio_mask; unsigned int mwdma_mask; unsigned int udma_mask; + unsigned int legacy_mode; unsigned long irq; - unsigned long irq2; unsigned int irq_flags; unsigned long host_flags; unsigned long host_set_flags; @@ -369,7 +365,6 @@ struct ata_host_set { spinlock_t lock; struct device *dev; unsigned long irq; - unsigned long irq2; void __iomem *mmio_base; unsigned int n_ports; void *private_data; @@ -377,6 +372,7 @@ struct ata_host_set { unsigned long flags; int simplex_claimed; /* Keep seperate in case we ever need to do this locked */ + struct ata_host_set *next; /* for legacy mode */ struct ata_port *ports[0]; }; @@ -507,6 +503,7 @@ struct ata_port { unsigned int pflags; /* ATA_PFLAG_xxx */ unsigned int id; /* unique id req'd by scsi midlyr */ unsigned int port_no; /* unique port #; from zero */ + unsigned int hard_port_no; /* hardware port #; from zero */ struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ @@ -650,8 +647,6 @@ extern const unsigned long sata_deb_timing_normal[]; extern const unsigned long sata_deb_timing_hotplug[]; extern const unsigned long sata_deb_timing_long[]; -extern const struct ata_port_operations ata_dummy_port_ops; - static inline const unsigned long * sata_ehc_deb_timing(struct ata_eh_context *ehc) { @@ -661,11 +656,6 @@ sata_ehc_deb_timing(struct ata_eh_context *ehc) return sata_deb_timing_normal; } -static inline int ata_port_is_dummy(struct ata_port *ap) -{ - return ap->ops == &ata_dummy_port_ops; -} - extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); @@ -684,30 +674,19 @@ extern void ata_std_ports(struct ata_ioports *ioaddr); extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info, unsigned int n_ports); extern void ata_pci_remove_one (struct pci_dev *pdev); -extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); +extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t state); extern void ata_pci_device_do_resume(struct pci_dev *pdev); -extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); +extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t state); extern int ata_pci_device_resume(struct pci_dev *pdev); extern int ata_pci_clear_simplex(struct pci_dev *pdev); #endif /* CONFIG_PCI */ extern int ata_device_add(const struct ata_probe_ent *ent); extern void ata_port_detach(struct ata_port *ap); -extern void ata_host_set_init(struct ata_host_set *, struct device *, - unsigned long, const struct ata_port_operations *); extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_scsi_release(struct Scsi_Host *host); -extern void ata_sas_port_destroy(struct ata_port *); -extern struct ata_port *ata_sas_port_alloc(struct ata_host_set *, - struct ata_port_info *, struct Scsi_Host *); -extern int ata_sas_port_init(struct ata_port *); -extern int ata_sas_port_start(struct ata_port *ap); -extern void ata_sas_port_stop(struct ata_port *ap); -extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); -extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), - struct ata_port *ap); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int sata_scr_valid(struct ata_port *ap); extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val); @@ -716,7 +695,7 @@ extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val); extern int ata_port_online(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap); extern int ata_scsi_device_resume(struct scsi_device *); -extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg); +extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); extern int ata_host_set_suspend(struct ata_host_set *host_set, pm_message_t mesg); extern void ata_host_set_resume(struct ata_host_set *host_set); diff --git a/trunk/include/linux/lockd/lockd.h b/trunk/include/linux/lockd/lockd.h index 0d92c468d55a..aa4fe905bb4d 100644 --- a/trunk/include/linux/lockd/lockd.h +++ b/trunk/include/linux/lockd/lockd.h @@ -123,6 +123,7 @@ struct nlm_block { unsigned int b_id; /* block id */ unsigned char b_queued; /* re-queued */ unsigned char b_granted; /* VFS granted lock */ + unsigned char b_done; /* callback complete */ struct nlm_file * b_file; /* file in question */ }; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 75f02d8c6ed3..76cc099c8580 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -924,10 +924,10 @@ static inline void netif_tx_lock_bh(struct net_device *dev) static inline int netif_tx_trylock(struct net_device *dev) { - int ok = spin_trylock(&dev->_xmit_lock); - if (likely(ok)) + int err = spin_trylock(&dev->_xmit_lock); + if (!err) dev->xmit_lock_owner = smp_processor_id(); - return ok; + return err; } static inline void netif_tx_unlock(struct net_device *dev) diff --git a/trunk/include/linux/netfilter_bridge.h b/trunk/include/linux/netfilter_bridge.h index 10c13dc4665b..87764022cc67 100644 --- a/trunk/include/linux/netfilter_bridge.h +++ b/trunk/include/linux/netfilter_bridge.h @@ -6,6 +6,7 @@ #include #if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER) +#include #include #endif @@ -78,8 +79,6 @@ struct bridge_skb_cb { __u32 ipv4; } daddr; }; - -extern int brnf_deferred_hooks; #endif /* CONFIG_BRIDGE_NETFILTER */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/nfs_fs.h b/trunk/include/linux/nfs_fs.h index 247434553ae8..55ea853d57bc 100644 --- a/trunk/include/linux/nfs_fs.h +++ b/trunk/include/linux/nfs_fs.h @@ -476,9 +476,10 @@ static inline int nfs_wb_page(struct inode *inode, struct page* page) } /* - * Allocate nfs_write_data structures + * Allocate and free nfs_write_data structures */ extern struct nfs_write_data *nfs_writedata_alloc(unsigned int pagecount); +extern void nfs_writedata_free(struct nfs_write_data *p); /* * linux/fs/nfs/read.c @@ -490,9 +491,10 @@ extern int nfs_readpage_result(struct rpc_task *, struct nfs_read_data *); extern void nfs_readdata_release(void *data); /* - * Allocate nfs_read_data structures + * Allocate and free nfs_read_data structures */ extern struct nfs_read_data *nfs_readdata_alloc(unsigned int pagecount); +extern void nfs_readdata_free(struct nfs_read_data *p); /* * linux/fs/nfs3proc.c diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 4eae06b08cf2..c09396d2c77b 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2142,7 +2142,6 @@ #define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501 #define PCI_DEVICE_ID_INTEL_82850_HB 0x2530 #define PCI_DEVICE_ID_INTEL_82860_HB 0x2531 -#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c #define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560 #define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562 #define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 diff --git a/trunk/include/linux/pmu.h b/trunk/include/linux/pmu.h index 783177387ac6..2ed807ddc08c 100644 --- a/trunk/include/linux/pmu.h +++ b/trunk/include/linux/pmu.h @@ -231,6 +231,7 @@ extern struct pmu_battery_info pmu_batteries[PMU_MAX_BATTERIES]; extern unsigned int pmu_power_flags; /* Backlight */ -extern void pmu_backlight_init(void); +extern int disable_kernel_backlight; +extern void pmu_backlight_init(struct device_node*); #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 6674fc1e51bf..6afa72e080cb 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1557,14 +1557,6 @@ static inline void freeze(struct task_struct *p) p->flags |= PF_FREEZE; } -/* - * Sometimes we may need to cancel the previous 'freeze' request - */ -static inline void do_not_freeze(struct task_struct *p) -{ - p->flags &= ~PF_FREEZE; -} - /* * Wake up a frozen process */ diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index 6bc2aad494ff..f75303831d09 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -1109,16 +1109,6 @@ struct swap_info_struct; * @name contains the name of the security module being unstacked. * @ops contains a pointer to the struct security_operations of the module to unstack. * - * @secid_to_secctx: - * Convert secid to security context. - * @secid contains the security ID. - * @secdata contains the pointer that stores the converted security context. - * - * @release_secctx: - * Release the security context. - * @secdata contains the security context. - * @seclen contains the length of the security context. - * * This is the main security structure. */ struct security_operations { @@ -1299,8 +1289,6 @@ struct security_operations { int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); - int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); - void (*release_secctx)(char *secdata, u32 seclen); #ifdef CONFIG_SECURITY_NETWORK int (*unix_stream_connect) (struct socket * sock, @@ -1329,7 +1317,7 @@ struct security_operations { int (*socket_shutdown) (struct socket * sock, int how); int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb); int (*socket_getpeersec_stream) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len); - int (*socket_getpeersec_dgram) (struct socket *sock, struct sk_buff *skb, u32 *secid); + int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen); int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority); void (*sk_free_security) (struct sock *sk); unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir); @@ -2071,16 +2059,6 @@ static inline int security_netlink_recv(struct sk_buff * skb, int cap) return security_ops->netlink_recv(skb, cap); } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) -{ - return security_ops->secid_to_secctx(secid, secdata, seclen); -} - -static inline void security_release_secctx(char *secdata, u32 seclen) -{ - return security_ops->release_secctx(secdata, seclen); -} - /* prototypes */ extern int security_init (void); extern int register_security (struct security_operations *ops); @@ -2747,14 +2725,6 @@ static inline void securityfs_remove(struct dentry *dentry) { } -static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) -{ - return -EOPNOTSUPP; -} - -static inline void security_release_secctx(char *secdata, u32 seclen) -{ -} #endif /* CONFIG_SECURITY */ #ifdef CONFIG_SECURITY_NETWORK @@ -2870,9 +2840,10 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __ return security_ops->socket_getpeersec_stream(sock, optval, optlen, len); } -static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, + u32 *seclen) { - return security_ops->socket_getpeersec_dgram(sock, skb, secid); + return security_ops->socket_getpeersec_dgram(skb, secdata, seclen); } static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority) @@ -2997,7 +2968,8 @@ static inline int security_socket_getpeersec_stream(struct socket *sock, char __ return -ENOPROTOOPT; } -static inline int security_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, + u32 *seclen) { return -ENOPROTOOPT; } diff --git a/trunk/include/linux/skbuff.h b/trunk/include/linux/skbuff.h index 19c96d498e20..0bf31b83578c 100644 --- a/trunk/include/linux/skbuff.h +++ b/trunk/include/linux/skbuff.h @@ -604,17 +604,12 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) return list_->qlen; } -/* - * This function creates a split out lock class for each invocation; - * this is needed for now since a whole lot of users of the skb-queue - * infrastructure in drivers have different locking usage (in hardirq) - * than the networking core (in softirq only). In the long run either the - * network layer or drivers should need annotation to consolidate the - * main types of usage into 3 classes. - */ +extern struct lock_class_key skb_queue_lock_key; + static inline void skb_queue_head_init(struct sk_buff_head *list) { spin_lock_init(&list->lock); + lockdep_set_class(&list->lock, &skb_queue_lock_key); list->prev = list->next = (struct sk_buff *)list; list->qlen = 0; } @@ -1071,8 +1066,9 @@ static inline void __skb_queue_purge(struct sk_buff_head *list) kfree_skb(skb); } +#ifndef CONFIG_HAVE_ARCH_DEV_ALLOC_SKB /** - * __dev_alloc_skb - allocate an skbuff for receiving + * __dev_alloc_skb - allocate an skbuff for sending * @length: length to allocate * @gfp_mask: get_free_pages mask, passed to alloc_skb * @@ -1091,9 +1087,12 @@ static inline struct sk_buff *__dev_alloc_skb(unsigned int length, skb_reserve(skb, NET_SKB_PAD); return skb; } +#else +extern struct sk_buff *__dev_alloc_skb(unsigned int length, int gfp_mask); +#endif /** - * dev_alloc_skb - allocate an skbuff for receiving + * dev_alloc_skb - allocate an skbuff for sending * @length: length to allocate * * Allocate a new &sk_buff and assign it a usage count of one. The @@ -1109,28 +1108,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length) return __dev_alloc_skb(length, GFP_ATOMIC); } -extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, gfp_t gfp_mask); - -/** - * netdev_alloc_skb - allocate an skbuff for rx on a specific device - * @dev: network device to receive on - * @length: length to allocate - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned if there is no free memory. Although this function - * allocates memory it can be called from an interrupt. - */ -static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, - unsigned int length) -{ - return __netdev_alloc_skb(dev, length, GFP_ATOMIC); -} - /** * skb_cow - copy header of skb when it is required * @skb: buffer to cow diff --git a/trunk/include/linux/sunrpc/xprt.h b/trunk/include/linux/sunrpc/xprt.h index 840e47a4ccc5..e8bbe8118de8 100644 --- a/trunk/include/linux/sunrpc/xprt.h +++ b/trunk/include/linux/sunrpc/xprt.h @@ -229,7 +229,7 @@ int xprt_reserve_xprt(struct rpc_task *task); int xprt_reserve_xprt_cong(struct rpc_task *task); int xprt_prepare_transmit(struct rpc_task *task); void xprt_transmit(struct rpc_task *task); -void xprt_end_transmit(struct rpc_task *task); +void xprt_abort_transmit(struct rpc_task *task); int xprt_adjust_timeout(struct rpc_rqst *req); void xprt_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task); void xprt_release_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task); diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index d2bd0c8e0154..c944e8f06a4a 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -103,7 +103,8 @@ enum usb_interface_condition { * @condition: binding state of the interface: not bound, binding * (in probe()), bound to a driver, or unbinding (in disconnect()) * @dev: driver model's view of this device - * @class_dev: driver model's class view of this device. + * @usb_dev: if an interface is bound to the USB major, this will point + * to the sysfs representation for that device. * * USB device drivers attach to interfaces on a physical device. Each * interface encapsulates a single high level function, such as feeding @@ -143,7 +144,7 @@ struct usb_interface { * bound to */ enum usb_interface_condition condition; /* state of binding */ struct device dev; /* interface specific device info */ - struct class_device *class_dev; + struct device *usb_dev; /* pointer to the usb class's device, if any */ }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) #define interface_to_usbdev(intf) \ @@ -360,7 +361,7 @@ struct usb_device { char *serial; /* iSerialNumber string, if present */ struct list_head filelist; - struct class_device *class_dev; + struct device *usbfs_dev; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ /* diff --git a/trunk/include/linux/usb_usual.h b/trunk/include/linux/usb_usual.h index e7fc5fed5b98..f38f43f20fae 100644 --- a/trunk/include/linux/usb_usual.h +++ b/trunk/include/linux/usb_usual.h @@ -44,9 +44,7 @@ US_FLAG(NO_WP_DETECT, 0x00000200) \ /* Don't check for write-protect */ \ US_FLAG(MAX_SECTORS_64, 0x00000400) \ - /* Sets max_sectors to 64 */ \ - US_FLAG(IGNORE_DEVICE, 0x00000800) \ - /* Don't claim device */ + /* Sets max_sectors to 64 */ #define US_FLAG(name, value) US_FL_##name = value , enum { US_DO_ALL_FLAGS }; diff --git a/trunk/include/linux/videodev.h b/trunk/include/linux/videodev.h index 518c7a32175e..41bc7e9603cd 100644 --- a/trunk/include/linux/videodev.h +++ b/trunk/include/linux/videodev.h @@ -12,11 +12,10 @@ #ifndef __LINUX_VIDEODEV_H #define __LINUX_VIDEODEV_H -#include - -#ifdef CONFIG_VIDEO_V4L1_COMPAT #define HAVE_V4L1 1 +#include + struct video_capability { char name[32]; @@ -337,8 +336,6 @@ struct video_code #define VID_HARDWARE_SN9C102 38 #define VID_HARDWARE_ARV 39 -#endif /* CONFIG_VIDEO_V4L1_COMPAT */ - #endif /* __LINUX_VIDEODEV_H */ /* diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index b7146956a929..a62673dad76e 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -716,7 +716,7 @@ struct v4l2_ext_control __s64 value64; void *reserved; }; -} __attribute__ ((packed)); +}; struct v4l2_ext_controls { diff --git a/trunk/include/linux/vmstat.h b/trunk/include/linux/vmstat.h index 2d9b1b60798a..1ab806c47514 100644 --- a/trunk/include/linux/vmstat.h +++ b/trunk/include/linux/vmstat.h @@ -41,23 +41,23 @@ DECLARE_PER_CPU(struct vm_event_state, vm_event_states); static inline void __count_vm_event(enum vm_event_item item) { - __get_cpu_var(vm_event_states).event[item]++; + __get_cpu_var(vm_event_states.event[item])++; } static inline void count_vm_event(enum vm_event_item item) { - get_cpu_var(vm_event_states).event[item]++; + get_cpu_var(vm_event_states.event[item])++; put_cpu(); } static inline void __count_vm_events(enum vm_event_item item, long delta) { - __get_cpu_var(vm_event_states).event[item] += delta; + __get_cpu_var(vm_event_states.event[item]) += delta; } static inline void count_vm_events(enum vm_event_item item, long delta) { - get_cpu_var(vm_event_states).event[item] += delta; + get_cpu_var(vm_event_states.event[item]) += delta; put_cpu(); } diff --git a/trunk/include/media/v4l2-dev.h b/trunk/include/media/v4l2-dev.h index f8665326ed9f..62dae1a8c441 100644 --- a/trunk/include/media/v4l2-dev.h +++ b/trunk/include/media/v4l2-dev.h @@ -341,14 +341,11 @@ extern int video_usercopy(struct inode *inode, struct file *file, extern struct video_device* video_devdata(struct file*); #define to_video_device(cd) container_of(cd, struct video_device, class_dev) -static inline int +static inline void video_device_create_file(struct video_device *vfd, struct class_device_attribute *attr) { - int ret = class_device_create_file(&vfd->class_dev, attr); - if (ret < 0) - printk(KERN_WARNING "%s error: %d\n", __FUNCTION__, ret); - return ret; + class_device_create_file(&vfd->class_dev, attr); } static inline void video_device_remove_file(struct video_device *vfd, diff --git a/trunk/include/net/af_unix.h b/trunk/include/net/af_unix.h index c0398f5a8cb9..2fec827c8801 100644 --- a/trunk/include/net/af_unix.h +++ b/trunk/include/net/af_unix.h @@ -54,13 +54,15 @@ struct unix_skb_parms { struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Security ID */ + char *secdata; /* Security context */ + u32 seclen; /* Security length */ #endif }; #define UNIXCB(skb) (*(struct unix_skb_parms*)&((skb)->cb)) #define UNIXCREDS(skb) (&UNIXCB((skb)).creds) -#define UNIXSID(skb) (&UNIXCB((skb)).secid) +#define UNIXSECDATA(skb) (&UNIXCB((skb)).secdata) +#define UNIXSECLEN(skb) (&UNIXCB((skb)).seclen) #define unix_state_rlock(s) spin_lock(&unix_sk(s)->lock) #define unix_state_runlock(s) spin_unlock(&unix_sk(s)->lock) diff --git a/trunk/include/net/ip6_route.h b/trunk/include/net/ip6_route.h index 96b0e66406ec..ab29dafb1a6a 100644 --- a/trunk/include/net/ip6_route.h +++ b/trunk/include/net/ip6_route.h @@ -139,22 +139,16 @@ extern rwlock_t rt6_lock; /* * Store a destination cache entry in a socket */ -static inline void __ip6_dst_store(struct sock *sk, struct dst_entry *dst, - struct in6_addr *daddr) +static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, + struct in6_addr *daddr) { struct ipv6_pinfo *np = inet6_sk(sk); struct rt6_info *rt = (struct rt6_info *) dst; + write_lock(&sk->sk_dst_lock); sk_setup_caps(sk, dst); np->daddr_cache = daddr; np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; -} - -static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst, - struct in6_addr *daddr) -{ - write_lock(&sk->sk_dst_lock); - __ip6_dst_store(sk, dst, daddr); write_unlock(&sk->sk_dst_lock); } diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index ece7e8a84ffd..a8fdf7970b37 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -468,9 +468,6 @@ extern void ip6_flush_pending_frames(struct sock *sk); extern int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl); -extern int ip6_sk_dst_lookup(struct sock *sk, - struct dst_entry **dst, - struct flowi *fl); /* * skb processing functions diff --git a/trunk/include/net/netdma.h b/trunk/include/net/netdma.h index 7f53cd1d8b1e..19760eb131aa 100644 --- a/trunk/include/net/netdma.h +++ b/trunk/include/net/netdma.h @@ -29,7 +29,7 @@ static inline struct dma_chan *get_softnet_dma(void) { struct dma_chan *chan; rcu_read_lock(); - chan = rcu_dereference(__get_cpu_var(softnet_data).net_dma); + chan = rcu_dereference(__get_cpu_var(softnet_data.net_dma)); if (chan) dma_chan_get(chan); rcu_read_unlock(); @@ -37,7 +37,7 @@ static inline struct dma_chan *get_softnet_dma(void) } int dma_skb_copy_datagram_iovec(struct dma_chan* chan, - struct sk_buff *skb, int offset, struct iovec *to, + const struct sk_buff *skb, int offset, struct iovec *to, size_t len, struct dma_pinned_list *pinned_list); #endif /* CONFIG_NET_DMA */ diff --git a/trunk/include/net/netevent.h b/trunk/include/net/netevent.h deleted file mode 100644 index e5d216241423..000000000000 --- a/trunk/include/net/netevent.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _NET_EVENT_H -#define _NET_EVENT_H - -/* - * Generic netevent notifiers - * - * Authors: - * Tom Tucker - * Steve Wise - * - * Changes: - */ -#ifdef __KERNEL__ - -#include - -struct netevent_redirect { - struct dst_entry *old; - struct dst_entry *new; -}; - -enum netevent_notif_type { - NETEVENT_NEIGH_UPDATE = 1, /* arg is struct neighbour ptr */ - NETEVENT_PMTU_UPDATE, /* arg is struct dst_entry ptr */ - NETEVENT_REDIRECT, /* arg is struct netevent_redirect ptr */ -}; - -extern int register_netevent_notifier(struct notifier_block *nb); -extern int unregister_netevent_notifier(struct notifier_block *nb); -extern int call_netevent_notifiers(unsigned long val, void *v); - -#endif -#endif diff --git a/trunk/include/net/pkt_sched.h b/trunk/include/net/pkt_sched.h index f6afee73235d..1925c65e617b 100644 --- a/trunk/include/net/pkt_sched.h +++ b/trunk/include/net/pkt_sched.h @@ -169,17 +169,23 @@ psched_tod_diff(int delta_sec, int bound) #define PSCHED_TADD2(tv, delta, tv_res) \ ({ \ - int __delta = (tv).tv_usec + (delta); \ - (tv_res).tv_sec = (tv).tv_sec; \ - while (__delta >= USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \ + int __delta = (delta); \ + (tv_res) = (tv); \ + while(__delta >= USEC_PER_SEC){ \ + (tv_res).tv_sec++; \ + __delta -= USEC_PER_SEC; \ + } \ (tv_res).tv_usec = __delta; \ }) #define PSCHED_TADD(tv, delta) \ ({ \ - (tv).tv_usec += (delta); \ - while ((tv).tv_usec >= USEC_PER_SEC) { (tv).tv_sec++; \ - (tv).tv_usec -= USEC_PER_SEC; } \ + int __delta = (delta); \ + while(__delta >= USEC_PER_SEC){ \ + (tv).tv_sec++; \ + __delta -= USEC_PER_SEC; \ + } \ + (tv).tv_usec = __delta; \ }) /* Set/check that time is in the "past perfect"; diff --git a/trunk/include/net/red.h b/trunk/include/net/red.h index a4eb37946f2c..5ccdbb3d4722 100644 --- a/trunk/include/net/red.h +++ b/trunk/include/net/red.h @@ -212,7 +212,7 @@ static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p) * Seems, it is the best solution to * problem of too coarse exponent tabulation. */ - us_idle = (p->qavg * (u64)us_idle) >> p->Scell_log; + us_idle = (p->qavg * us_idle) >> p->Scell_log; if (us_idle < (p->qavg >> 1)) return p->qavg - us_idle; diff --git a/trunk/include/net/scm.h b/trunk/include/net/scm.h index 5637d5e22d5f..02daa097cdcd 100644 --- a/trunk/include/net/scm.h +++ b/trunk/include/net/scm.h @@ -3,7 +3,6 @@ #include #include -#include /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -21,7 +20,8 @@ struct scm_cookie struct ucred creds; /* Skb credentials */ struct scm_fp_list *fp; /* Passed files */ #ifdef CONFIG_SECURITY_NETWORK - u32 secid; /* Passed security ID */ + char *secdata; /* Security context */ + u32 seclen; /* Security length */ #endif unsigned long seq; /* Connection seqno */ }; @@ -32,16 +32,6 @@ extern int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie extern void __scm_destroy(struct scm_cookie *scm); extern struct scm_fp_list * scm_fp_dup(struct scm_fp_list *fpl); -#ifdef CONFIG_SECURITY_NETWORK -static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) -{ - security_socket_getpeersec_dgram(sock, NULL, &scm->secid); -} -#else -static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_cookie *scm) -{ } -#endif /* CONFIG_SECURITY_NETWORK */ - static __inline__ void scm_destroy(struct scm_cookie *scm) { if (scm && scm->fp) @@ -57,7 +47,6 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, scm->creds.pid = p->tgid; scm->fp = NULL; scm->seq = 0; - unix_get_peersec_dgram(sock, scm); if (msg->msg_controllen <= 0) return 0; return __scm_send(sock, msg, scm); @@ -66,18 +55,8 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, #ifdef CONFIG_SECURITY_NETWORK static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) { - char *secdata; - u32 seclen; - int err; - - if (test_bit(SOCK_PASSSEC, &sock->flags)) { - err = security_secid_to_secctx(scm->secid, &secdata, &seclen); - - if (!err) { - put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); - } - } + if (test_bit(SOCK_PASSSEC, &sock->flags) && scm->secdata != NULL) + put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, scm->seclen, scm->secdata); } #else static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm) diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index e5aa7ff1f5b5..5f69158c1006 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -445,7 +445,6 @@ typedef struct sctp_sender_hb_info { struct sctp_paramhdr param_hdr; union sctp_addr daddr; unsigned long sent_at; - __u64 hb_nonce; } __attribute__((packed)) sctp_sender_hb_info_t; /* @@ -731,10 +730,13 @@ void sctp_init_addrs(struct sctp_chunk *, union sctp_addr *, const union sctp_addr *sctp_source(const struct sctp_chunk *chunk); /* This is a structure for holding either an IPv6 or an IPv4 address. */ +/* sin_family -- AF_INET or AF_INET6 + * sin_port -- ordinary port number + * sin_addr -- cast to either (struct in_addr) or (struct in6_addr) + */ struct sctp_sockaddr_entry { struct list_head list; union sctp_addr a; - __u8 use_as_src; }; typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); @@ -982,9 +984,6 @@ struct sctp_transport { */ char cacc_saw_newack; } cacc; - - /* 64-bit random number sent with heartbeat. */ - __u64 hb_nonce; }; struct sctp_transport *sctp_transport_new(const union sctp_addr *, @@ -1139,7 +1138,7 @@ int sctp_bind_addr_copy(struct sctp_bind_addr *dest, sctp_scope_t scope, gfp_t gfp, int flags); int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, - __u8 use_as_src, gfp_t gfp); + gfp_t gfp); int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *); int sctp_bind_addr_match(struct sctp_bind_addr *, const union sctp_addr *, struct sctp_sock *); diff --git a/trunk/include/net/sctp/user.h b/trunk/include/net/sctp/user.h index 1b7aae6cdd82..8a6bef6f91eb 100644 --- a/trunk/include/net/sctp/user.h +++ b/trunk/include/net/sctp/user.h @@ -560,18 +560,9 @@ struct sctp_paddrinfo { } __attribute__((packed, aligned(4))); /* Peer addresses's state. */ -/* UNKNOWN: Peer address passed by the upper layer in sendmsg or connect[x] - * calls. - * UNCONFIRMED: Peer address received in INIT/INIT-ACK address parameters. - * Not yet confirmed by a heartbeat and not available for data - * transfers. - * ACTIVE : Peer address confirmed, active and available for data transfers. - * INACTIVE: Peer address inactive and not available for data transfers. - */ enum sctp_spinfo_state { SCTP_INACTIVE, SCTP_ACTIVE, - SCTP_UNCONFIRMED, SCTP_UNKNOWN = 0xffff /* Value used for transport state unknown */ }; diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 7a093d0aa0fe..0720bddff1e9 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -914,9 +914,6 @@ static inline void tcp_set_state(struct sock *sk, int state) static inline void tcp_done(struct sock *sk) { - if(sk->sk_state == TCP_SYN_SENT || sk->sk_state == TCP_SYN_RECV) - TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); - tcp_set_state(sk, TCP_CLOSE); tcp_clear_xmit_timers(sk); diff --git a/trunk/include/rdma/ib_mad.h b/trunk/include/rdma/ib_mad.h index 585d28e960dd..5ff77558013b 100644 --- a/trunk/include/rdma/ib_mad.h +++ b/trunk/include/rdma/ib_mad.h @@ -75,7 +75,6 @@ #define IB_MGMT_METHOD_TRAP_REPRESS 0x07 #define IB_MGMT_METHOD_RESP 0x80 -#define IB_BM_ATTR_MOD_RESP cpu_to_be32(1) #define IB_MGMT_MAX_METHODS 128 @@ -247,12 +246,6 @@ struct ib_mad_send_buf { int retries; }; -/** - * ib_response_mad - Returns if the specified MAD has been generated in - * response to a sent request or trap. - */ -int ib_response_mad(struct ib_mad *mad); - /** * ib_get_rmpp_resptime - Returns the RMPP response time. * @rmpp_hdr: An RMPP header. diff --git a/trunk/include/scsi/scsi_cmnd.h b/trunk/include/scsi/scsi_cmnd.h index 58e6444eebee..371f70d9aa92 100644 --- a/trunk/include/scsi/scsi_cmnd.h +++ b/trunk/include/scsi/scsi_cmnd.h @@ -58,7 +58,9 @@ struct scsi_cmnd { int timeout_per_command; unsigned char cmd_len; + unsigned char old_cmd_len; enum dma_data_direction sc_data_direction; + enum dma_data_direction sc_old_data_direction; /* These elements define the operation we are about to perform */ #define MAX_COMMAND_SIZE 16 @@ -69,11 +71,18 @@ struct scsi_cmnd { void *request_buffer; /* Actual requested buffer */ /* These elements define the operation we ultimately want to perform */ + unsigned char data_cmnd[MAX_COMMAND_SIZE]; + unsigned short old_use_sg; /* We save use_sg here when requesting + * sense info */ unsigned short use_sg; /* Number of pieces of scatter-gather */ unsigned short sglist_len; /* size of malloc'd scatter-gather list */ + unsigned bufflen; /* Size of data buffer */ + void *buffer; /* Data buffer */ unsigned underflow; /* Return error if less than this amount is transferred */ + unsigned old_underflow; /* save underflow here when reusing the + * command for error handling */ unsigned transfersize; /* How much we are guaranteed to transfer with each SCSI transfer diff --git a/trunk/include/scsi/scsi_transport_sas.h b/trunk/include/scsi/scsi_transport_sas.h index 6cc2314098cf..e3c503cd175e 100644 --- a/trunk/include/scsi/scsi_transport_sas.h +++ b/trunk/include/scsi/scsi_transport_sas.h @@ -106,7 +106,6 @@ struct sas_end_device { struct sas_expander_device { int level; - int next_port_id; #define SAS_EXPANDER_VENDOR_ID_LEN 8 char vendor_id[SAS_EXPANDER_VENDOR_ID_LEN+1]; @@ -128,10 +127,8 @@ struct sas_expander_device { struct sas_port { struct device dev; - int port_identifier; + u8 port_identifier; int num_phys; - /* port flags */ - unsigned int is_backlink:1; /* the other end of the link */ struct sas_rphy *rphy; @@ -171,13 +168,11 @@ extern void sas_rphy_delete(struct sas_rphy *); extern int scsi_is_sas_rphy(const struct device *); struct sas_port *sas_port_alloc(struct device *, int); -struct sas_port *sas_port_alloc_num(struct device *); int sas_port_add(struct sas_port *); void sas_port_free(struct sas_port *); void sas_port_delete(struct sas_port *); void sas_port_add_phy(struct sas_port *, struct sas_phy *); void sas_port_delete_phy(struct sas_port *, struct sas_phy *); -void sas_port_mark_backlink(struct sas_port *); int scsi_is_sas_port(const struct device *); extern struct scsi_transport_template * diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index 2b4fccf8ea55..cd92d342953e 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -1,6 +1,6 @@ /* * linux/ipc/msg.c - * Copyright (C) 1992 Krishna Balasubramanian + * Copyright (C) 1992 Krishna Balasubramanian * * Removed all the remaining kerneld mess * Catch the -EFAULT stuff properly @@ -41,24 +41,22 @@ int msg_ctlmax = MSGMAX; int msg_ctlmnb = MSGMNB; int msg_ctlmni = MSGMNI; -/* - * one msg_receiver structure for each sleeping receiver: - */ +/* one msg_receiver structure for each sleeping receiver */ struct msg_receiver { - struct list_head r_list; - struct task_struct *r_tsk; + struct list_head r_list; + struct task_struct* r_tsk; - int r_mode; - long r_msgtype; - long r_maxsize; + int r_mode; + long r_msgtype; + long r_maxsize; - volatile struct msg_msg *r_msg; + struct msg_msg* volatile r_msg; }; /* one msg_sender for each sleeping sender */ struct msg_sender { - struct list_head list; - struct task_struct *tsk; + struct list_head list; + struct task_struct* tsk; }; #define SEARCH_ANY 1 @@ -66,42 +64,45 @@ struct msg_sender { #define SEARCH_NOTEQUAL 3 #define SEARCH_LESSEQUAL 4 -static atomic_t msg_bytes = ATOMIC_INIT(0); -static atomic_t msg_hdrs = ATOMIC_INIT(0); +static atomic_t msg_bytes = ATOMIC_INIT(0); +static atomic_t msg_hdrs = ATOMIC_INIT(0); static struct ipc_ids msg_ids; -#define msg_lock(id) ((struct msg_queue *)ipc_lock(&msg_ids, id)) -#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) -#define msg_rmid(id) ((struct msg_queue *)ipc_rmid(&msg_ids, id)) -#define msg_checkid(msq, msgid) ipc_checkid(&msg_ids, &msq->q_perm, msgid) -#define msg_buildid(id, seq) ipc_buildid(&msg_ids, id, seq) +#define msg_lock(id) ((struct msg_queue*)ipc_lock(&msg_ids,id)) +#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) +#define msg_rmid(id) ((struct msg_queue*)ipc_rmid(&msg_ids,id)) +#define msg_checkid(msq, msgid) \ + ipc_checkid(&msg_ids,&msq->q_perm,msgid) +#define msg_buildid(id, seq) \ + ipc_buildid(&msg_ids, id, seq) -static void freeque(struct msg_queue *msq, int id); -static int newque(key_t key, int msgflg); +static void freeque (struct msg_queue *msq, int id); +static int newque (key_t key, int msgflg); #ifdef CONFIG_PROC_FS static int sysvipc_msg_proc_show(struct seq_file *s, void *it); #endif -void __init msg_init(void) +void __init msg_init (void) { - ipc_init_ids(&msg_ids, msg_ctlmni); + ipc_init_ids(&msg_ids,msg_ctlmni); ipc_init_proc_interface("sysvipc/msg", " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", &msg_ids, sysvipc_msg_proc_show); } -static int newque(key_t key, int msgflg) +static int newque (key_t key, int msgflg) { + int id; + int retval; struct msg_queue *msq; - int id, retval; - msq = ipc_rcu_alloc(sizeof(*msq)); - if (!msq) + msq = ipc_rcu_alloc(sizeof(*msq)); + if (!msq) return -ENOMEM; - msq->q_perm.mode = msgflg & S_IRWXUGO; + msq->q_perm.mode = (msgflg & S_IRWXUGO); msq->q_perm.key = key; msq->q_perm.security = NULL; @@ -112,13 +113,13 @@ static int newque(key_t key, int msgflg) } id = ipc_addid(&msg_ids, &msq->q_perm, msg_ctlmni); - if (id == -1) { + if(id == -1) { security_msg_queue_free(msq); ipc_rcu_putref(msq); return -ENOSPC; } - msq->q_id = msg_buildid(id, msq->q_perm.seq); + msq->q_id = msg_buildid(id,msq->q_perm.seq); msq->q_stime = msq->q_rtime = 0; msq->q_ctime = get_seconds(); msq->q_cbytes = msq->q_qnum = 0; @@ -132,44 +133,44 @@ static int newque(key_t key, int msgflg) return msq->q_id; } -static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss) +static inline void ss_add(struct msg_queue* msq, struct msg_sender* mss) { - mss->tsk = current; - current->state = TASK_INTERRUPTIBLE; - list_add_tail(&mss->list, &msq->q_senders); + mss->tsk=current; + current->state=TASK_INTERRUPTIBLE; + list_add_tail(&mss->list,&msq->q_senders); } -static inline void ss_del(struct msg_sender *mss) +static inline void ss_del(struct msg_sender* mss) { - if (mss->list.next != NULL) + if(mss->list.next != NULL) list_del(&mss->list); } -static void ss_wakeup(struct list_head *h, int kill) +static void ss_wakeup(struct list_head* h, int kill) { struct list_head *tmp; tmp = h->next; while (tmp != h) { - struct msg_sender *mss; - - mss = list_entry(tmp, struct msg_sender, list); + struct msg_sender* mss; + + mss = list_entry(tmp,struct msg_sender,list); tmp = tmp->next; - if (kill) - mss->list.next = NULL; + if(kill) + mss->list.next=NULL; wake_up_process(mss->tsk); } } -static void expunge_all(struct msg_queue *msq, int res) +static void expunge_all(struct msg_queue* msq, int res) { struct list_head *tmp; tmp = msq->q_receivers.next; while (tmp != &msq->q_receivers) { - struct msg_receiver *msr; - - msr = list_entry(tmp, struct msg_receiver, r_list); + struct msg_receiver* msr; + + msr = list_entry(tmp,struct msg_receiver,r_list); tmp = tmp->next; msr->r_msg = NULL; wake_up_process(msr->r_tsk); @@ -177,28 +178,26 @@ static void expunge_all(struct msg_queue *msq, int res) msr->r_msg = ERR_PTR(res); } } - -/* - * freeque() wakes up waiters on the sender and receiver waiting queue, - * removes the message queue from message queue ID +/* + * freeque() wakes up waiters on the sender and receiver waiting queue, + * removes the message queue from message queue ID * array, and cleans up all the messages associated with this queue. * * msg_ids.mutex and the spinlock for this message queue is hold * before freeque() is called. msg_ids.mutex remains locked on exit. */ -static void freeque(struct msg_queue *msq, int id) +static void freeque (struct msg_queue *msq, int id) { struct list_head *tmp; - expunge_all(msq, -EIDRM); - ss_wakeup(&msq->q_senders, 1); + expunge_all(msq,-EIDRM); + ss_wakeup(&msq->q_senders,1); msq = msg_rmid(id); msg_unlock(msq); - + tmp = msq->q_messages.next; - while (tmp != &msq->q_messages) { - struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list); - + while(tmp != &msq->q_messages) { + struct msg_msg* msg = list_entry(tmp,struct msg_msg,m_list); tmp = tmp->next; atomic_dec(&msg_hdrs); free_msg(msg); @@ -208,10 +207,10 @@ static void freeque(struct msg_queue *msq, int id) ipc_rcu_putref(msq); } -asmlinkage long sys_msgget(key_t key, int msgflg) +asmlinkage long sys_msgget (key_t key, int msgflg) { - struct msg_queue *msq; int id, ret = -EPERM; + struct msg_queue *msq; mutex_lock(&msg_ids.mutex); if (key == IPC_PRIVATE) @@ -225,34 +224,31 @@ asmlinkage long sys_msgget(key_t key, int msgflg) ret = -EEXIST; } else { msq = msg_lock(id); - BUG_ON(msq == NULL); + BUG_ON(msq==NULL); if (ipcperms(&msq->q_perm, msgflg)) ret = -EACCES; else { int qid = msg_buildid(id, msq->q_perm.seq); - - ret = security_msg_queue_associate(msq, msgflg); + ret = security_msg_queue_associate(msq, msgflg); if (!ret) ret = qid; } msg_unlock(msq); } mutex_unlock(&msg_ids.mutex); - return ret; } -static inline unsigned long -copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) +static inline unsigned long copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) { switch(version) { case IPC_64: - return copy_to_user(buf, in, sizeof(*in)); + return copy_to_user (buf, in, sizeof(*in)); case IPC_OLD: - { + { struct msqid_ds out; - memset(&out, 0, sizeof(out)); + memset(&out,0,sizeof(out)); ipc64_perm_to_ipc_perm(&in->msg_perm, &out.msg_perm); @@ -260,18 +256,18 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) out.msg_rtime = in->msg_rtime; out.msg_ctime = in->msg_ctime; - if (in->msg_cbytes > USHRT_MAX) + if(in->msg_cbytes > USHRT_MAX) out.msg_cbytes = USHRT_MAX; else out.msg_cbytes = in->msg_cbytes; out.msg_lcbytes = in->msg_cbytes; - if (in->msg_qnum > USHRT_MAX) + if(in->msg_qnum > USHRT_MAX) out.msg_qnum = USHRT_MAX; else out.msg_qnum = in->msg_qnum; - if (in->msg_qbytes > USHRT_MAX) + if(in->msg_qbytes > USHRT_MAX) out.msg_qbytes = USHRT_MAX; else out.msg_qbytes = in->msg_qbytes; @@ -280,8 +276,8 @@ copy_msqid_to_user(void __user *buf, struct msqid64_ds *in, int version) out.msg_lspid = in->msg_lspid; out.msg_lrpid = in->msg_lrpid; - return copy_to_user(buf, &out, sizeof(out)); - } + return copy_to_user (buf, &out, sizeof(out)); + } default: return -EINVAL; } @@ -294,15 +290,14 @@ struct msq_setbuf { mode_t mode; }; -static inline unsigned long -copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version) +static inline unsigned long copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version) { switch(version) { case IPC_64: - { + { struct msqid64_ds tbuf; - if (copy_from_user(&tbuf, buf, sizeof(tbuf))) + if (copy_from_user (&tbuf, buf, sizeof (tbuf))) return -EFAULT; out->qbytes = tbuf.msg_qbytes; @@ -311,61 +306,60 @@ copy_msqid_from_user(struct msq_setbuf *out, void __user *buf, int version) out->mode = tbuf.msg_perm.mode; return 0; - } + } case IPC_OLD: - { + { struct msqid_ds tbuf_old; - if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old))) + if (copy_from_user (&tbuf_old, buf, sizeof (tbuf_old))) return -EFAULT; out->uid = tbuf_old.msg_perm.uid; out->gid = tbuf_old.msg_perm.gid; out->mode = tbuf_old.msg_perm.mode; - if (tbuf_old.msg_qbytes == 0) + if(tbuf_old.msg_qbytes == 0) out->qbytes = tbuf_old.msg_lqbytes; else out->qbytes = tbuf_old.msg_qbytes; return 0; - } + } default: return -EINVAL; } } -asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) +asmlinkage long sys_msgctl (int msqid, int cmd, struct msqid_ds __user *buf) { - struct kern_ipc_perm *ipcp; - struct msq_setbuf setbuf; - struct msg_queue *msq; int err, version; - + struct msg_queue *msq; + struct msq_setbuf setbuf; + struct kern_ipc_perm *ipcp; + if (msqid < 0 || cmd < 0) return -EINVAL; version = ipc_parse_version(&cmd); switch (cmd) { - case IPC_INFO: - case MSG_INFO: - { + case IPC_INFO: + case MSG_INFO: + { struct msginfo msginfo; int max_id; - if (!buf) return -EFAULT; - /* - * We must not return kernel stack data. + /* We must not return kernel stack data. * due to padding, it's not enough * to set all member fields. */ + err = security_msg_queue_msgctl(NULL, cmd); if (err) return err; - memset(&msginfo, 0, sizeof(msginfo)); + memset(&msginfo,0,sizeof(msginfo)); msginfo.msgmni = msg_ctlmni; msginfo.msgmax = msg_ctlmax; msginfo.msgmnb = msg_ctlmnb; @@ -383,37 +377,36 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) } max_id = msg_ids.max_id; mutex_unlock(&msg_ids.mutex); - if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) + if (copy_to_user (buf, &msginfo, sizeof(struct msginfo))) return -EFAULT; - return (max_id < 0) ? 0 : max_id; + return (max_id < 0) ? 0: max_id; } case MSG_STAT: case IPC_STAT: { struct msqid64_ds tbuf; int success_return; - if (!buf) return -EFAULT; - if (cmd == MSG_STAT && msqid >= msg_ids.entries->size) + if(cmd == MSG_STAT && msqid >= msg_ids.entries->size) return -EINVAL; - memset(&tbuf, 0, sizeof(tbuf)); + memset(&tbuf,0,sizeof(tbuf)); msq = msg_lock(msqid); if (msq == NULL) return -EINVAL; - if (cmd == MSG_STAT) { + if(cmd == MSG_STAT) { success_return = msg_buildid(msqid, msq->q_perm.seq); } else { err = -EIDRM; - if (msg_checkid(msq, msqid)) + if (msg_checkid(msq,msqid)) goto out_unlock; success_return = 0; } err = -EACCES; - if (ipcperms(&msq->q_perm, S_IRUGO)) + if (ipcperms (&msq->q_perm, S_IRUGO)) goto out_unlock; err = security_msg_queue_msgctl(msq, cmd); @@ -437,7 +430,7 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) case IPC_SET: if (!buf) return -EFAULT; - if (copy_msqid_from_user(&setbuf, buf, version)) + if (copy_msqid_from_user (&setbuf, buf, version)) return -EFAULT; break; case IPC_RMID: @@ -448,12 +441,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) mutex_lock(&msg_ids.mutex); msq = msg_lock(msqid); - err = -EINVAL; + err=-EINVAL; if (msq == NULL) goto out_up; err = -EIDRM; - if (msg_checkid(msq, msqid)) + if (msg_checkid(msq,msqid)) goto out_unlock_up; ipcp = &msq->q_perm; @@ -461,16 +454,15 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) if (err) goto out_unlock_up; if (cmd==IPC_SET) { - err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, - setbuf.mode); + err = audit_ipc_set_perm(setbuf.qbytes, setbuf.uid, setbuf.gid, setbuf.mode); if (err) goto out_unlock_up; } err = -EPERM; - if (current->euid != ipcp->cuid && + if (current->euid != ipcp->cuid && current->euid != ipcp->uid && !capable(CAP_SYS_ADMIN)) - /* We _could_ check for CAP_CHOWN above, but we don't */ + /* We _could_ check for CAP_CHOWN above, but we don't */ goto out_unlock_up; err = security_msg_queue_msgctl(msq, cmd); @@ -488,22 +480,22 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) ipcp->uid = setbuf.uid; ipcp->gid = setbuf.gid; - ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | - (S_IRWXUGO & setbuf.mode); + ipcp->mode = (ipcp->mode & ~S_IRWXUGO) | + (S_IRWXUGO & setbuf.mode); msq->q_ctime = get_seconds(); /* sleeping receivers might be excluded by * stricter permissions. */ - expunge_all(msq, -EAGAIN); + expunge_all(msq,-EAGAIN); /* sleeping senders might be able to send * due to a larger queue size. */ - ss_wakeup(&msq->q_senders, 0); + ss_wakeup(&msq->q_senders,0); msg_unlock(msq); break; } case IPC_RMID: - freeque(msq, msqid); + freeque (msq, msqid); break; } err = 0; @@ -518,44 +510,41 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) return err; } -static int testmsg(struct msg_msg *msg, long type, int mode) +static int testmsg(struct msg_msg* msg,long type,int mode) { switch(mode) { case SEARCH_ANY: return 1; case SEARCH_LESSEQUAL: - if (msg->m_type <=type) + if(msg->m_type <=type) return 1; break; case SEARCH_EQUAL: - if (msg->m_type == type) + if(msg->m_type == type) return 1; break; case SEARCH_NOTEQUAL: - if (msg->m_type != type) + if(msg->m_type != type) return 1; break; } return 0; } -static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) +static inline int pipelined_send(struct msg_queue* msq, struct msg_msg* msg) { - struct list_head *tmp; + struct list_head* tmp; tmp = msq->q_receivers.next; while (tmp != &msq->q_receivers) { - struct msg_receiver *msr; - - msr = list_entry(tmp, struct msg_receiver, r_list); + struct msg_receiver* msr; + msr = list_entry(tmp,struct msg_receiver,r_list); tmp = tmp->next; - if (testmsg(msg, msr->r_msgtype, msr->r_mode) && - !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, - msr->r_msgtype, msr->r_mode)) { - + if(testmsg(msg,msr->r_msgtype,msr->r_mode) && + !security_msg_queue_msgrcv(msq, msg, msr->r_tsk, msr->r_msgtype, msr->r_mode)) { list_del(&msr->r_list); - if (msr->r_maxsize < msg->m_ts) { + if(msr->r_maxsize < msg->m_ts) { msr->r_msg = NULL; wake_up_process(msr->r_tsk); smp_mb(); @@ -567,7 +556,6 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) wake_up_process(msr->r_tsk); smp_mb(); msr->r_msg = msg; - return 1; } } @@ -575,41 +563,40 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) return 0; } -asmlinkage long -sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) +asmlinkage long sys_msgsnd (int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) { struct msg_queue *msq; struct msg_msg *msg; long mtype; int err; - + if (msgsz > msg_ctlmax || (long) msgsz < 0 || msqid < 0) return -EINVAL; if (get_user(mtype, &msgp->mtype)) - return -EFAULT; + return -EFAULT; if (mtype < 1) return -EINVAL; msg = load_msg(msgp->mtext, msgsz); - if (IS_ERR(msg)) + if(IS_ERR(msg)) return PTR_ERR(msg); msg->m_type = mtype; msg->m_ts = msgsz; msq = msg_lock(msqid); - err = -EINVAL; - if (msq == NULL) + err=-EINVAL; + if(msq==NULL) goto out_free; err= -EIDRM; - if (msg_checkid(msq, msqid)) + if (msg_checkid(msq,msqid)) goto out_unlock_free; for (;;) { struct msg_sender s; - err = -EACCES; + err=-EACCES; if (ipcperms(&msq->q_perm, S_IWUGO)) goto out_unlock_free; @@ -617,14 +604,14 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) if (err) goto out_unlock_free; - if (msgsz + msq->q_cbytes <= msq->q_qbytes && + if(msgsz + msq->q_cbytes <= msq->q_qbytes && 1 + msq->q_qnum <= msq->q_qbytes) { break; } /* queue full, wait: */ - if (msgflg & IPC_NOWAIT) { - err = -EAGAIN; + if(msgflg&IPC_NOWAIT) { + err=-EAGAIN; goto out_unlock_free; } ss_add(msq, &s); @@ -639,9 +626,9 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) goto out_unlock_free; } ss_del(&s); - + if (signal_pending(current)) { - err = -ERESTARTNOHAND; + err=-ERESTARTNOHAND; goto out_unlock_free; } } @@ -649,47 +636,47 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) msq->q_lspid = current->tgid; msq->q_stime = get_seconds(); - if (!pipelined_send(msq, msg)) { + if(!pipelined_send(msq,msg)) { /* noone is waiting for this message, enqueue it */ - list_add_tail(&msg->m_list, &msq->q_messages); + list_add_tail(&msg->m_list,&msq->q_messages); msq->q_cbytes += msgsz; msq->q_qnum++; - atomic_add(msgsz, &msg_bytes); + atomic_add(msgsz,&msg_bytes); atomic_inc(&msg_hdrs); } - + err = 0; msg = NULL; out_unlock_free: msg_unlock(msq); out_free: - if (msg != NULL) + if(msg!=NULL) free_msg(msg); return err; } -static inline int convert_mode(long *msgtyp, int msgflg) +static inline int convert_mode(long* msgtyp, int msgflg) { - /* + /* * find message of correct type. * msgtyp = 0 => get first. * msgtyp > 0 => get first message of matching type. - * msgtyp < 0 => get message with least type must be < abs(msgtype). + * msgtyp < 0 => get message with least type must be < abs(msgtype). */ - if (*msgtyp == 0) + if(*msgtyp==0) return SEARCH_ANY; - if (*msgtyp < 0) { - *msgtyp = -*msgtyp; + if(*msgtyp<0) { + *msgtyp=-(*msgtyp); return SEARCH_LESSEQUAL; } - if (msgflg & MSG_EXCEPT) + if(msgflg & MSG_EXCEPT) return SEARCH_NOTEQUAL; return SEARCH_EQUAL; } -asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, - long msgtyp, int msgflg) +asmlinkage long sys_msgrcv (int msqid, struct msgbuf __user *msgp, size_t msgsz, + long msgtyp, int msgflg) { struct msg_queue *msq; struct msg_msg *msg; @@ -697,51 +684,44 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, if (msqid < 0 || (long) msgsz < 0) return -EINVAL; - mode = convert_mode(&msgtyp, msgflg); + mode = convert_mode(&msgtyp,msgflg); msq = msg_lock(msqid); - if (msq == NULL) + if(msq==NULL) return -EINVAL; msg = ERR_PTR(-EIDRM); - if (msg_checkid(msq, msqid)) + if (msg_checkid(msq,msqid)) goto out_unlock; for (;;) { struct msg_receiver msr_d; - struct list_head *tmp; + struct list_head* tmp; msg = ERR_PTR(-EACCES); - if (ipcperms(&msq->q_perm, S_IRUGO)) + if (ipcperms (&msq->q_perm, S_IRUGO)) goto out_unlock; msg = ERR_PTR(-EAGAIN); tmp = msq->q_messages.next; while (tmp != &msq->q_messages) { struct msg_msg *walk_msg; - - walk_msg = list_entry(tmp, struct msg_msg, m_list); - if (testmsg(walk_msg, msgtyp, mode) && - !security_msg_queue_msgrcv(msq, walk_msg, current, - msgtyp, mode)) { - + walk_msg = list_entry(tmp,struct msg_msg,m_list); + if(testmsg(walk_msg,msgtyp,mode) && + !security_msg_queue_msgrcv(msq, walk_msg, current, msgtyp, mode)) { msg = walk_msg; - if (mode == SEARCH_LESSEQUAL && - walk_msg->m_type != 1) { - msg = walk_msg; - msgtyp = walk_msg->m_type - 1; + if(mode == SEARCH_LESSEQUAL && walk_msg->m_type != 1) { + msg=walk_msg; + msgtyp=walk_msg->m_type-1; } else { - msg = walk_msg; + msg=walk_msg; break; } } tmp = tmp->next; } - if (!IS_ERR(msg)) { - /* - * Found a suitable message. - * Unlink it from the queue. - */ + if(!IS_ERR(msg)) { + /* Found a suitable message. Unlink it from the queue. */ if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { msg = ERR_PTR(-E2BIG); goto out_unlock; @@ -751,9 +731,9 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, msq->q_rtime = get_seconds(); msq->q_lrpid = current->tgid; msq->q_cbytes -= msg->m_ts; - atomic_sub(msg->m_ts, &msg_bytes); + atomic_sub(msg->m_ts,&msg_bytes); atomic_dec(&msg_hdrs); - ss_wakeup(&msq->q_senders, 0); + ss_wakeup(&msq->q_senders,0); msg_unlock(msq); break; } @@ -762,13 +742,13 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, msg = ERR_PTR(-ENOMSG); goto out_unlock; } - list_add_tail(&msr_d.r_list, &msq->q_receivers); + list_add_tail(&msr_d.r_list,&msq->q_receivers); msr_d.r_tsk = current; msr_d.r_msgtype = msgtyp; msr_d.r_mode = mode; - if (msgflg & MSG_NOERROR) + if(msgflg & MSG_NOERROR) msr_d.r_maxsize = INT_MAX; - else + else msr_d.r_maxsize = msgsz; msr_d.r_msg = ERR_PTR(-EAGAIN); current->state = TASK_INTERRUPTIBLE; @@ -793,17 +773,17 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, * wake_up_process(). There is a race with exit(), see * ipc/mqueue.c for the details. */ - msg = (struct msg_msg*)msr_d.r_msg; + msg = (struct msg_msg*) msr_d.r_msg; while (msg == NULL) { cpu_relax(); - msg = (struct msg_msg *)msr_d.r_msg; + msg = (struct msg_msg*) msr_d.r_msg; } /* Lockless receive, part 3: * If there is a message or an error then accept it without * locking. */ - if (msg != ERR_PTR(-EAGAIN)) { + if(msg != ERR_PTR(-EAGAIN)) { rcu_read_unlock(); break; } @@ -818,7 +798,7 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, * Repeat test after acquiring the spinlock. */ msg = (struct msg_msg*)msr_d.r_msg; - if (msg != ERR_PTR(-EAGAIN)) + if(msg != ERR_PTR(-EAGAIN)) goto out_unlock; list_del(&msr_d.r_list); @@ -830,15 +810,14 @@ asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, } } if (IS_ERR(msg)) - return PTR_ERR(msg); + return PTR_ERR(msg); msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; if (put_user (msg->m_type, &msgp->mtype) || store_msg(msgp->mtext, msg, msgsz)) { - msgsz = -EFAULT; + msgsz = -EFAULT; } free_msg(msg); - return msgsz; } @@ -848,20 +827,20 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) struct msg_queue *msq = it; return seq_printf(s, - "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", - msq->q_perm.key, - msq->q_id, - msq->q_perm.mode, - msq->q_cbytes, - msq->q_qnum, - msq->q_lspid, - msq->q_lrpid, - msq->q_perm.uid, - msq->q_perm.gid, - msq->q_perm.cuid, - msq->q_perm.cgid, - msq->q_stime, - msq->q_rtime, - msq->q_ctime); + "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", + msq->q_perm.key, + msq->q_id, + msq->q_perm.mode, + msq->q_cbytes, + msq->q_qnum, + msq->q_lspid, + msq->q_lrpid, + msq->q_perm.uid, + msq->q_perm.gid, + msq->q_perm.cuid, + msq->q_perm.cgid, + msq->q_stime, + msq->q_rtime, + msq->q_ctime); } #endif diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 0a36091ed712..d417ca1db79b 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -690,7 +690,9 @@ static const struct inotify_operations audit_inotify_ops = { /* Initialize audit support at boot time. */ static int __init audit_init(void) { +#ifdef CONFIG_AUDITSYSCALL int i; +#endif printk(KERN_INFO "audit: initializing netlink socket (%s)\n", audit_default ? "enabled" : "disabled"); @@ -715,10 +717,10 @@ static int __init audit_init(void) audit_ih = inotify_init(&audit_inotify_ops); if (IS_ERR(audit_ih)) audit_panic("cannot initialize inotify handle"); -#endif for (i = 0; i < AUDIT_INODE_BUCKETS; i++) INIT_LIST_HEAD(&audit_inode_hash[i]); +#endif return 0; } diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index 6a9a5c5a4e7d..5b4e16276ca0 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -442,7 +442,6 @@ static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule) case AUDIT_EQUAL: break; default: - err = -EINVAL; goto exit_free; } } @@ -580,7 +579,6 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, case AUDIT_EQUAL: break; default: - err = -EINVAL; goto exit_free; } } @@ -1136,14 +1134,6 @@ static inline int audit_add_rule(struct audit_entry *entry, struct audit_watch *watch = entry->rule.watch; struct nameidata *ndp, *ndw; int h, err, putnd_needed = 0; -#ifdef CONFIG_AUDITSYSCALL - int dont_count = 0; - - /* If either of these, don't count towards total */ - if (entry->rule.listnr == AUDIT_FILTER_USER || - entry->rule.listnr == AUDIT_FILTER_TYPE) - dont_count = 1; -#endif if (inode_f) { h = audit_hash_ino(inode_f->val); @@ -1184,10 +1174,6 @@ static inline int audit_add_rule(struct audit_entry *entry, } else { list_add_tail_rcu(&entry->list, list); } -#ifdef CONFIG_AUDITSYSCALL - if (!dont_count) - audit_n_rules++; -#endif mutex_unlock(&audit_filter_mutex); if (putnd_needed) @@ -1212,14 +1198,6 @@ static inline int audit_del_rule(struct audit_entry *entry, struct audit_watch *watch, *tmp_watch = entry->rule.watch; LIST_HEAD(inotify_list); int h, ret = 0; -#ifdef CONFIG_AUDITSYSCALL - int dont_count = 0; - - /* If either of these, don't count towards total */ - if (entry->rule.listnr == AUDIT_FILTER_USER || - entry->rule.listnr == AUDIT_FILTER_TYPE) - dont_count = 1; -#endif if (inode_f) { h = audit_hash_ino(inode_f->val); @@ -1257,10 +1235,6 @@ static inline int audit_del_rule(struct audit_entry *entry, list_del_rcu(&e->list); call_rcu(&e->rcu, audit_free_rule_rcu); -#ifdef CONFIG_AUDITSYSCALL - if (!dont_count) - audit_n_rules--; -#endif mutex_unlock(&audit_filter_mutex); if (!list_empty(&inotify_list)) diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index efc1b74bebf3..ae40ac8c39e7 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -85,9 +85,6 @@ extern int audit_enabled; /* Indicates that audit should log the full pathname. */ #define AUDIT_NAME_FULL -1 -/* number of audit rules */ -int audit_n_rules; - /* When fs/namei.c:getname() is called, we store the pointer in name and * we don't let putname() free it (instead we free all of the saved * pointers at syscall exit time). @@ -177,7 +174,6 @@ struct audit_aux_data_path { /* The per-task audit context. */ struct audit_context { - int dummy; /* must be the first element */ int in_syscall; /* 1 if task is in a syscall */ enum audit_state state; unsigned int serial; /* serial number for record */ @@ -518,7 +514,7 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, context->return_valid = return_valid; context->return_code = return_code; - if (context->in_syscall && !context->dummy && !context->auditable) { + if (context->in_syscall && !context->auditable) { enum audit_state state; state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); @@ -534,7 +530,17 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, } get_context: - + context->pid = tsk->pid; + context->ppid = sys_getppid(); /* sic. tsk == current in all cases */ + context->uid = tsk->uid; + context->gid = tsk->gid; + context->euid = tsk->euid; + context->suid = tsk->suid; + context->fsuid = tsk->fsuid; + context->egid = tsk->egid; + context->sgid = tsk->sgid; + context->fsgid = tsk->fsgid; + context->personality = tsk->personality; tsk->audit_context = NULL; return context; } @@ -743,17 +749,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts const char *tty; /* tsk == current */ - context->pid = tsk->pid; - context->ppid = sys_getppid(); /* sic. tsk == current in all cases */ - context->uid = tsk->uid; - context->gid = tsk->gid; - context->euid = tsk->euid; - context->suid = tsk->suid; - context->fsuid = tsk->fsuid; - context->egid = tsk->egid; - context->sgid = tsk->sgid; - context->fsgid = tsk->fsgid; - context->personality = tsk->personality; ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); if (!ab) @@ -1071,8 +1066,7 @@ void audit_syscall_entry(int arch, int major, context->argv[3] = a4; state = context->state; - context->dummy = !audit_n_rules; - if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT)) + if (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT) state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]); if (likely(state == AUDIT_DISABLED)) return; @@ -1205,18 +1199,14 @@ void audit_putname(const char *name) #endif } -/* Copy inode data into an audit_names. */ -static void audit_copy_inode(struct audit_names *name, const struct inode *inode) +static void audit_inode_context(int idx, const struct inode *inode) { - name->ino = inode->i_ino; - name->dev = inode->i_sb->s_dev; - name->mode = inode->i_mode; - name->uid = inode->i_uid; - name->gid = inode->i_gid; - name->rdev = inode->i_rdev; - selinux_get_inode_sid(inode, &name->osid); + struct audit_context *context = current->audit_context; + + selinux_get_inode_sid(inode, &context->names[idx].osid); } + /** * audit_inode - store the inode and device from a lookup * @name: name being audited @@ -1250,14 +1240,20 @@ void __audit_inode(const char *name, const struct inode *inode) ++context->ino_count; #endif } - audit_copy_inode(&context->names[idx], inode); + context->names[idx].ino = inode->i_ino; + context->names[idx].dev = inode->i_sb->s_dev; + context->names[idx].mode = inode->i_mode; + context->names[idx].uid = inode->i_uid; + context->names[idx].gid = inode->i_gid; + context->names[idx].rdev = inode->i_rdev; + audit_inode_context(idx, inode); } /** * audit_inode_child - collect inode info for created/removed objects * @dname: inode's dentry name * @inode: inode being audited - * @parent: inode of dentry parent + * @pino: inode number of dentry parent * * For syscalls that create or remove filesystem objects, audit_inode * can only collect information for the filesystem object's parent. @@ -1268,7 +1264,7 @@ void __audit_inode(const char *name, const struct inode *inode) * unsuccessful attempts. */ void __audit_inode_child(const char *dname, const struct inode *inode, - const struct inode *parent) + unsigned long pino) { int idx; struct audit_context *context = current->audit_context; @@ -1282,7 +1278,7 @@ void __audit_inode_child(const char *dname, const struct inode *inode, if (!dname) goto update_context; for (idx = 0; idx < context->name_count; idx++) - if (context->names[idx].ino == parent->i_ino) { + if (context->names[idx].ino == pino) { const char *name = context->names[idx].name; if (!name) @@ -1306,47 +1302,16 @@ void __audit_inode_child(const char *dname, const struct inode *inode, context->names[idx].name_len = AUDIT_NAME_FULL; context->names[idx].name_put = 0; /* don't call __putname() */ - if (!inode) - context->names[idx].ino = (unsigned long)-1; - else - audit_copy_inode(&context->names[idx], inode); - - /* A parent was not found in audit_names, so copy the inode data for the - * provided parent. */ - if (!found_name) { - idx = context->name_count++; -#if AUDIT_DEBUG - context->ino_count++; -#endif - audit_copy_inode(&context->names[idx], parent); - } -} - -/** - * audit_inode_update - update inode info for last collected name - * @inode: inode being audited - * - * When open() is called on an existing object with the O_CREAT flag, the inode - * data audit initially collects is incorrect. This additional hook ensures - * audit has the inode data for the actual object to be opened. - */ -void __audit_inode_update(const struct inode *inode) -{ - struct audit_context *context = current->audit_context; - int idx; - - if (!context->in_syscall || !inode) - return; - - if (context->name_count == 0) { - context->name_count++; -#if AUDIT_DEBUG - context->ino_count++; -#endif - } - idx = context->name_count - 1; - - audit_copy_inode(&context->names[idx], inode); + if (inode) { + context->names[idx].ino = inode->i_ino; + context->names[idx].dev = inode->i_sb->s_dev; + context->names[idx].mode = inode->i_mode; + context->names[idx].uid = inode->i_uid; + context->names[idx].gid = inode->i_gid; + context->names[idx].rdev = inode->i_rdev; + audit_inode_context(idx, inode); + } else + context->names[idx].ino = (unsigned long)-1; } /** @@ -1677,7 +1642,7 @@ int audit_bprm(struct linux_binprm *bprm) unsigned long p, next; void *to; - if (likely(!audit_enabled || !context || context->dummy)) + if (likely(!audit_enabled || !context)) return 0; ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p, @@ -1715,7 +1680,7 @@ int audit_socketcall(int nargs, unsigned long *args) struct audit_aux_data_socketcall *ax; struct audit_context *context = current->audit_context; - if (likely(!context || context->dummy)) + if (likely(!context)) return 0; ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); @@ -1743,7 +1708,7 @@ int audit_sockaddr(int len, void *a) struct audit_aux_data_sockaddr *ax; struct audit_context *context = current->audit_context; - if (likely(!context || context->dummy)) + if (likely(!context)) return 0; ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); diff --git a/trunk/kernel/cpu.c b/trunk/kernel/cpu.c index f230f9ae01c2..70fbf2e83766 100644 --- a/trunk/kernel/cpu.c +++ b/trunk/kernel/cpu.c @@ -16,48 +16,56 @@ #include /* This protects CPUs going up and down... */ -static DEFINE_MUTEX(cpu_add_remove_lock); -static DEFINE_MUTEX(cpu_bitmask_lock); +static DEFINE_MUTEX(cpucontrol); static __cpuinitdata BLOCKING_NOTIFIER_HEAD(cpu_chain); #ifdef CONFIG_HOTPLUG_CPU +static struct task_struct *lock_cpu_hotplug_owner; +static int lock_cpu_hotplug_depth; -/* Crappy recursive lock-takers in cpufreq! Complain loudly about idiots */ -static struct task_struct *recursive; -static int recursive_depth; +static int __lock_cpu_hotplug(int interruptible) +{ + int ret = 0; + + if (lock_cpu_hotplug_owner != current) { + if (interruptible) + ret = mutex_lock_interruptible(&cpucontrol); + else + mutex_lock(&cpucontrol); + } + + /* + * Set only if we succeed in locking + */ + if (!ret) { + lock_cpu_hotplug_depth++; + lock_cpu_hotplug_owner = current; + } + + return ret; +} void lock_cpu_hotplug(void) { - struct task_struct *tsk = current; - - if (tsk == recursive) { - static int warnings = 10; - if (warnings) { - printk(KERN_ERR "Lukewarm IQ detected in hotplug locking\n"); - WARN_ON(1); - warnings--; - } - recursive_depth++; - return; - } - mutex_lock(&cpu_bitmask_lock); - recursive = tsk; + __lock_cpu_hotplug(0); } EXPORT_SYMBOL_GPL(lock_cpu_hotplug); void unlock_cpu_hotplug(void) { - WARN_ON(recursive != current); - if (recursive_depth) { - recursive_depth--; - return; + if (--lock_cpu_hotplug_depth == 0) { + lock_cpu_hotplug_owner = NULL; + mutex_unlock(&cpucontrol); } - mutex_unlock(&cpu_bitmask_lock); - recursive = NULL; } EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); +int lock_cpu_hotplug_interruptible(void) +{ + return __lock_cpu_hotplug(1); +} +EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible); #endif /* CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ @@ -114,7 +122,9 @@ int cpu_down(unsigned int cpu) struct task_struct *p; cpumask_t old_allowed, tmp; - mutex_lock(&cpu_add_remove_lock); + if ((err = lock_cpu_hotplug_interruptible()) != 0) + return err; + if (num_online_cpus() == 1) { err = -EBUSY; goto out; @@ -140,10 +150,7 @@ int cpu_down(unsigned int cpu) cpu_clear(cpu, tmp); set_cpus_allowed(current, tmp); - mutex_lock(&cpu_bitmask_lock); p = __stop_machine_run(take_cpu_down, NULL, cpu); - mutex_unlock(&cpu_bitmask_lock); - if (IS_ERR(p)) { /* CPU didn't die: tell everyone. Can't complain. */ if (blocking_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, @@ -180,7 +187,7 @@ int cpu_down(unsigned int cpu) out_allowed: set_cpus_allowed(current, old_allowed); out: - mutex_unlock(&cpu_add_remove_lock); + unlock_cpu_hotplug(); return err; } #endif /*CONFIG_HOTPLUG_CPU*/ @@ -190,7 +197,9 @@ int __devinit cpu_up(unsigned int cpu) int ret; void *hcpu = (void *)(long)cpu; - mutex_lock(&cpu_add_remove_lock); + if ((ret = lock_cpu_hotplug_interruptible()) != 0) + return ret; + if (cpu_online(cpu) || !cpu_present(cpu)) { ret = -EINVAL; goto out; @@ -205,9 +214,7 @@ int __devinit cpu_up(unsigned int cpu) } /* Arch-specific enabling code. */ - mutex_lock(&cpu_bitmask_lock); ret = __cpu_up(cpu); - mutex_unlock(&cpu_bitmask_lock); if (ret != 0) goto out_notify; BUG_ON(!cpu_online(cpu)); @@ -220,6 +227,6 @@ int __devinit cpu_up(unsigned int cpu) blocking_notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); out: - mutex_unlock(&cpu_add_remove_lock); + unlock_cpu_hotplug(); return ret; } diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 1a649f2bb9bb..c232dc077438 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -762,8 +762,6 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) * * Call with manage_mutex held. May nest a call to the * lock_cpu_hotplug()/unlock_cpu_hotplug() pair. - * Must not be called holding callback_mutex, because we must - * not call lock_cpu_hotplug() while holding callback_mutex. */ static void update_cpu_domains(struct cpuset *cur) @@ -783,7 +781,7 @@ static void update_cpu_domains(struct cpuset *cur) if (is_cpu_exclusive(c)) cpus_andnot(pspan, pspan, c->cpus_allowed); } - if (!is_cpu_exclusive(cur)) { + if (is_removed(cur) || !is_cpu_exclusive(cur)) { cpus_or(pspan, pspan, cur->cpus_allowed); if (cpus_equal(pspan, cur->cpus_allowed)) return; @@ -1919,17 +1917,6 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode) return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); } -/* - * Locking note on the strange update_flag() call below: - * - * If the cpuset being removed is marked cpu_exclusive, then simulate - * turning cpu_exclusive off, which will call update_cpu_domains(). - * The lock_cpu_hotplug() call in update_cpu_domains() must not be - * made while holding callback_mutex. Elsewhere the kernel nests - * callback_mutex inside lock_cpu_hotplug() calls. So the reverse - * nesting would risk an ABBA deadlock. - */ - static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) { struct cpuset *cs = dentry->d_fsdata; @@ -1949,16 +1936,11 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) mutex_unlock(&manage_mutex); return -EBUSY; } - if (is_cpu_exclusive(cs)) { - int retval = update_flag(CS_CPU_EXCLUSIVE, cs, "0"); - if (retval < 0) { - mutex_unlock(&manage_mutex); - return retval; - } - } parent = cs->parent; mutex_lock(&callback_mutex); set_bit(CS_REMOVED, &cs->flags); + if (is_cpu_exclusive(cs)) + update_cpu_domains(cs); list_del(&cs->sibling); /* delete my sibling from parent->children */ spin_lock(&cs->dentry->d_lock); d = dget(cs->dentry); diff --git a/trunk/kernel/delayacct.c b/trunk/kernel/delayacct.c index 57ca3730205d..f05392d64267 100644 --- a/trunk/kernel/delayacct.c +++ b/trunk/kernel/delayacct.c @@ -19,15 +19,15 @@ #include #include -int delayacct_on __read_mostly = 1; /* Delay accounting turned on/off */ +int delayacct_on __read_mostly; /* Delay accounting turned on/off */ kmem_cache_t *delayacct_cache; -static int __init delayacct_setup_disable(char *str) +static int __init delayacct_setup_enable(char *str) { - delayacct_on = 0; + delayacct_on = 1; return 1; } -__setup("nodelayacct", delayacct_setup_disable); +__setup("delayacct", delayacct_setup_enable); void delayacct_init(void) { diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index aa36c43783cc..1b0f7b1e0881 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -1387,10 +1387,8 @@ long do_fork(unsigned long clone_flags, if (clone_flags & CLONE_VFORK) { wait_for_completion(&vfork); - if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) { - current->ptrace_message = nr; + if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP); - } } } else { free_pid(pid); diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index c2b2e0b83abf..cf0c8e21d1ab 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -415,15 +415,15 @@ static struct task_struct * futex_find_get_task(pid_t pid) */ void exit_pi_state_list(struct task_struct *curr) { + struct futex_hash_bucket *hb; struct list_head *next, *head = &curr->pi_state_list; struct futex_pi_state *pi_state; - struct futex_hash_bucket *hb; union futex_key key; /* * We are a ZOMBIE and nobody can enqueue itself on * pi_state_list anymore, but we have to be careful - * versus waiters unqueueing themselves: + * versus waiters unqueueing themselfs */ spin_lock_irq(&curr->pi_lock); while (!list_empty(head)) { @@ -431,24 +431,21 @@ void exit_pi_state_list(struct task_struct *curr) next = head->next; pi_state = list_entry(next, struct futex_pi_state, list); key = pi_state->key; - hb = hash_futex(&key); spin_unlock_irq(&curr->pi_lock); + hb = hash_futex(&key); spin_lock(&hb->lock); spin_lock_irq(&curr->pi_lock); - /* - * We dropped the pi-lock, so re-check whether this - * task still owns the PI-state: - */ if (head->next != next) { spin_unlock(&hb->lock); continue; } - WARN_ON(pi_state->owner != curr); - WARN_ON(list_empty(&pi_state->list)); list_del_init(&pi_state->list); + + WARN_ON(pi_state->owner != curr); + pi_state->owner = NULL; spin_unlock_irq(&curr->pi_lock); @@ -473,7 +470,7 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me) head = &hb->chain; list_for_each_entry_safe(this, next, head, list) { - if (match_futex(&this->key, &me->key)) { + if (match_futex (&this->key, &me->key)) { /* * Another waiter already exists - bump up * the refcount and return its pi_state: @@ -485,8 +482,6 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me) if (unlikely(!pi_state)) return -EINVAL; - WARN_ON(!atomic_read(&pi_state->refcount)); - atomic_inc(&pi_state->refcount); me->pi_state = pi_state; @@ -495,13 +490,10 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me) } /* - * We are the first waiter - try to look up the real owner and attach - * the new pi_state to it, but bail out when the owner died bit is set - * and TID = 0: + * We are the first waiter - try to look up the real owner and + * attach the new pi_state to it: */ pid = uval & FUTEX_TID_MASK; - if (!pid && (uval & FUTEX_OWNER_DIED)) - return -ESRCH; p = futex_find_get_task(pid); if (!p) return -ESRCH; @@ -518,7 +510,6 @@ lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, struct futex_q *me) pi_state->key = me->key; spin_lock_irq(&p->pi_lock); - WARN_ON(!list_empty(&pi_state->list)); list_add(&pi_state->list, &p->pi_state_list); pi_state->owner = p; spin_unlock_irq(&p->pi_lock); @@ -582,29 +573,20 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) * kept enabled while there is PI state around. We must also * preserve the owner died bit.) */ - if (!(uval & FUTEX_OWNER_DIED)) { - newval = FUTEX_WAITERS | new_owner->pid; + newval = (uval & FUTEX_OWNER_DIED) | FUTEX_WAITERS | new_owner->pid; - inc_preempt_count(); - curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - dec_preempt_count(); - if (curval == -EFAULT) - return -EFAULT; - if (curval != uval) - return -EINVAL; - } + inc_preempt_count(); + curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); + dec_preempt_count(); - spin_lock_irq(&pi_state->owner->pi_lock); - WARN_ON(list_empty(&pi_state->list)); - list_del_init(&pi_state->list); - spin_unlock_irq(&pi_state->owner->pi_lock); + if (curval == -EFAULT) + return -EFAULT; + if (curval != uval) + return -EINVAL; - spin_lock_irq(&new_owner->pi_lock); - WARN_ON(!list_empty(&pi_state->list)); + list_del_init(&pi_state->owner->pi_state_list); list_add(&pi_state->list, &new_owner->pi_state_list); pi_state->owner = new_owner; - spin_unlock_irq(&new_owner->pi_lock); - rt_mutex_unlock(&pi_state->pi_mutex); return 0; @@ -948,7 +930,6 @@ static int unqueue_me(struct futex_q *q) /* In the common case we don't take the spinlock, which is nice. */ retry: lock_ptr = q->lock_ptr; - barrier(); if (lock_ptr != 0) { spin_lock(lock_ptr); /* @@ -1255,7 +1236,6 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock, /* Owner died? */ if (q.pi_state->owner != NULL) { spin_lock_irq(&q.pi_state->owner->pi_lock); - WARN_ON(list_empty(&q.pi_state->list)); list_del_init(&q.pi_state->list); spin_unlock_irq(&q.pi_state->owner->pi_lock); } else @@ -1264,7 +1244,6 @@ static int do_futex_lock_pi(u32 __user *uaddr, int detect, int trylock, q.pi_state->owner = current; spin_lock_irq(¤t->pi_lock); - WARN_ON(!list_empty(&q.pi_state->list)); list_add(&q.pi_state->list, ¤t->pi_state_list); spin_unlock_irq(¤t->pi_lock); @@ -1448,11 +1427,9 @@ static int futex_unlock_pi(u32 __user *uaddr) * again. If it succeeds then we can return without waking * anyone else up: */ - if (!(uval & FUTEX_OWNER_DIED)) { - inc_preempt_count(); - uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); - dec_preempt_count(); - } + inc_preempt_count(); + uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); + dec_preempt_count(); if (unlikely(uval == -EFAULT)) goto pi_faulted; @@ -1485,11 +1462,9 @@ static int futex_unlock_pi(u32 __user *uaddr) /* * No waiters - kernel unlocks the futex: */ - if (!(uval & FUTEX_OWNER_DIED)) { - ret = unlock_futex_pi(uaddr, uval); - if (ret == -EFAULT) - goto pi_faulted; - } + ret = unlock_futex_pi(uaddr, uval); + if (ret == -EFAULT) + goto pi_faulted; out_unlock: spin_unlock(&hb->lock); @@ -1708,9 +1683,9 @@ sys_get_robust_list(int pid, struct robust_list_head __user **head_ptr, * Process a futex-list entry, check whether it's owned by the * dying task, and do notification if so: */ -int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) +int handle_futex_death(u32 __user *uaddr, struct task_struct *curr) { - u32 uval, nval, mval; + u32 uval, nval; retry: if (get_user(uval, uaddr)) @@ -1727,44 +1702,20 @@ int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) * thread-death.) The rest of the cleanup is done in * userspace. */ - mval = (uval & FUTEX_WAITERS) | FUTEX_OWNER_DIED; - nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, mval); - + nval = futex_atomic_cmpxchg_inatomic(uaddr, uval, + uval | FUTEX_OWNER_DIED); if (nval == -EFAULT) return -1; if (nval != uval) goto retry; - /* - * Wake robust non-PI futexes here. The wakeup of - * PI futexes happens in exit_pi_state(): - */ - if (!pi) { - if (uval & FUTEX_WAITERS) - futex_wake(uaddr, 1); - } + if (uval & FUTEX_WAITERS) + futex_wake(uaddr, 1); } return 0; } -/* - * Fetch a robust-list pointer. Bit 0 signals PI futexes: - */ -static inline int fetch_robust_entry(struct robust_list __user **entry, - struct robust_list __user **head, int *pi) -{ - unsigned long uentry; - - if (get_user(uentry, (unsigned long *)head)) - return -EFAULT; - - *entry = (void *)(uentry & ~1UL); - *pi = uentry & 1; - - return 0; -} - /* * Walk curr->robust_list (very carefully, it's a userspace list!) * and mark any locks found there dead, and notify any waiters. @@ -1775,14 +1726,14 @@ void exit_robust_list(struct task_struct *curr) { struct robust_list_head __user *head = curr->robust_list; struct robust_list __user *entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; + unsigned int limit = ROBUST_LIST_LIMIT; unsigned long futex_offset; /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): */ - if (fetch_robust_entry(&entry, &head->list.next, &pi)) + if (get_user(entry, &head->list.next)) return; /* * Fetch the relative futex offset: @@ -1793,11 +1744,10 @@ void exit_robust_list(struct task_struct *curr) * Fetch any possibly pending lock-add first, and handle it * if it exists: */ - if (fetch_robust_entry(&pending, &head->list_op_pending, &pip)) + if (get_user(pending, &head->list_op_pending)) return; - if (pending) - handle_futex_death((void *)pending + futex_offset, curr, pip); + handle_futex_death((void *)pending + futex_offset, curr); while (entry != &head->list) { /* @@ -1806,12 +1756,12 @@ void exit_robust_list(struct task_struct *curr) */ if (entry != pending) if (handle_futex_death((void *)entry + futex_offset, - curr, pi)) + curr)) return; /* * Fetch the next entry in the list: */ - if (fetch_robust_entry(&entry, &entry->next, &pi)) + if (get_user(entry, &entry->next)) return; /* * Avoid excessively long or circular lists: diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index c5cca3f65cb7..d1d92b441fb7 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -12,23 +12,6 @@ #include - -/* - * Fetch a robust-list pointer. Bit 0 signals PI futexes: - */ -static inline int -fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry, - compat_uptr_t *head, int *pi) -{ - if (get_user(*uentry, head)) - return -EFAULT; - - *entry = compat_ptr((*uentry) & ~1); - *pi = (unsigned int)(*uentry) & 1; - - return 0; -} - /* * Walk curr->robust_list (very carefully, it's a userspace list!) * and mark any locks found there dead, and notify any waiters. @@ -39,16 +22,17 @@ void compat_exit_robust_list(struct task_struct *curr) { struct compat_robust_list_head __user *head = curr->compat_robust_list; struct robust_list __user *entry, *pending; - unsigned int limit = ROBUST_LIST_LIMIT, pi, pip; compat_uptr_t uentry, upending; + unsigned int limit = ROBUST_LIST_LIMIT; compat_long_t futex_offset; /* * Fetch the list head (which was registered earlier, via * sys_set_robust_list()): */ - if (fetch_robust_entry(&uentry, &entry, &head->list.next, &pi)) + if (get_user(uentry, &head->list.next)) return; + entry = compat_ptr(uentry); /* * Fetch the relative futex offset: */ @@ -58,11 +42,11 @@ void compat_exit_robust_list(struct task_struct *curr) * Fetch any possibly pending lock-add first, and handle it * if it exists: */ - if (fetch_robust_entry(&upending, &pending, - &head->list_op_pending, &pip)) + if (get_user(upending, &head->list_op_pending)) return; + pending = compat_ptr(upending); if (upending) - handle_futex_death((void *)pending + futex_offset, curr, pip); + handle_futex_death((void *)pending + futex_offset, curr); while (compat_ptr(uentry) != &head->list) { /* @@ -71,15 +55,15 @@ void compat_exit_robust_list(struct task_struct *curr) */ if (entry != pending) if (handle_futex_death((void *)entry + futex_offset, - curr, pi)) + curr)) return; /* * Fetch the next entry in the list: */ - if (fetch_robust_entry(&uentry, &entry, - (compat_uptr_t *)&entry->next, &pi)) + if (get_user(uentry, (compat_uptr_t *)&entry->next)) return; + entry = compat_ptr(uentry); /* * Avoid excessively long or circular lists: */ diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index be989efc7856..d17766d40dab 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -835,7 +835,7 @@ static void migrate_hrtimers(int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, +static int __devinit hrtimer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { long cpu = (long)hcpu; @@ -859,7 +859,7 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata hrtimers_nb = { +static struct notifier_block __devinitdata hrtimers_nb = { .notifier_call = hrtimer_cpu_notify, }; diff --git a/trunk/kernel/irq/manage.c b/trunk/kernel/irq/manage.c index 92be519eff26..4e461438e48b 100644 --- a/trunk/kernel/irq/manage.c +++ b/trunk/kernel/irq/manage.c @@ -137,40 +137,16 @@ EXPORT_SYMBOL(enable_irq); * @irq: interrupt to control * @on: enable/disable power management wakeup * - * Enable/disable power management wakeup mode, which is - * disabled by default. Enables and disables must match, - * just as they match for non-wakeup mode support. - * - * Wakeup mode lets this IRQ wake the system from sleep - * states like "suspend to RAM". + * Enable/disable power management wakeup mode */ int set_irq_wake(unsigned int irq, unsigned int on) { struct irq_desc *desc = irq_desc + irq; unsigned long flags; int ret = -ENXIO; - int (*set_wake)(unsigned, unsigned) = desc->chip->set_wake; - /* wakeup-capable irqs can be shared between drivers that - * don't need to have the same sleep mode behaviors. - */ spin_lock_irqsave(&desc->lock, flags); - if (on) { - if (desc->wake_depth++ == 0) - desc->status |= IRQ_WAKEUP; - else - set_wake = NULL; - } else { - if (desc->wake_depth == 0) { - printk(KERN_WARNING "Unbalanced IRQ %d " - "wake disable\n", irq); - WARN_ON(1); - } else if (--desc->wake_depth == 0) - desc->status &= ~IRQ_WAKEUP; - else - set_wake = NULL; - } - if (set_wake) + if (desc->chip->set_wake) ret = desc->chip->set_wake(irq, on); spin_unlock_irqrestore(&desc->lock, flags); return ret; diff --git a/trunk/kernel/kprobes.c b/trunk/kernel/kprobes.c index 3f57dfdc8f92..64aab081153b 100644 --- a/trunk/kernel/kprobes.c +++ b/trunk/kernel/kprobes.c @@ -393,7 +393,6 @@ static int __kprobes add_new_kprobe(struct kprobe *old_p, struct kprobe *p) static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p) { copy_kprobe(p, ap); - flush_insn_slot(ap); ap->addr = p->addr; ap->pre_handler = aggr_pre_handler; ap->fault_handler = aggr_fault_handler; diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index 72e72d2c61e6..b2a5f671d6cd 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -66,25 +66,13 @@ static inline void freeze_process(struct task_struct *p) } } -static void cancel_freezing(struct task_struct *p) -{ - unsigned long flags; - - if (freezing(p)) { - pr_debug(" clean up: %s\n", p->comm); - do_not_freeze(p); - spin_lock_irqsave(&p->sighand->siglock, flags); - recalc_sigpending_tsk(p); - spin_unlock_irqrestore(&p->sighand->siglock, flags); - } -} - /* 0 = success, else # of processes that we failed to stop */ int freeze_processes(void) { int todo, nr_user, user_frozen; unsigned long start_time; struct task_struct *g, *p; + unsigned long flags; printk( "Stopping tasks: " ); start_time = jiffies; @@ -97,10 +85,6 @@ int freeze_processes(void) continue; if (frozen(p)) continue; - if (p->state == TASK_TRACED && frozen(p->parent)) { - cancel_freezing(p); - continue; - } if (p->mm && !(p->flags & PF_BORROWED_MM)) { /* The task is a user-space one. * Freeze it unless there's a vfork completion @@ -142,7 +126,13 @@ int freeze_processes(void) do_each_thread(g, p) { if (freezeable(p) && !frozen(p)) printk(KERN_ERR " %s\n", p->comm); - cancel_freezing(p); + if (freezing(p)) { + pr_debug(" clean up: %s\n", p->comm); + p->flags &= ~PF_FREEZE; + spin_lock_irqsave(&p->sighand->siglock, flags); + recalc_sigpending_tsk(p); + spin_unlock_irqrestore(&p->sighand->siglock, flags); + } } while_each_thread(g, p); read_unlock(&tasklist_lock); return todo; diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 1149365e989e..65ca0688f86f 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -799,9 +799,6 @@ void release_console_sem(void) up(&secondary_console_sem); return; } - - console_may_schedule = 0; - for ( ; ; ) { spin_lock_irqsave(&logbuf_lock, flags); wake_klogd |= log_start - log_end; @@ -815,6 +812,7 @@ void release_console_sem(void) local_irq_restore(flags); } console_locked = 0; + console_may_schedule = 0; up(&console_sem); spin_unlock_irqrestore(&logbuf_lock, flags); if (wake_klogd && !oops_in_progress && waitqueue_active(&log_wait)) { diff --git a/trunk/kernel/rcupdate.c b/trunk/kernel/rcupdate.c index 436ab35f6fa7..759805c9859a 100644 --- a/trunk/kernel/rcupdate.c +++ b/trunk/kernel/rcupdate.c @@ -548,7 +548,7 @@ static void __devinit rcu_online_cpu(int cpu) tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL); } -static int __cpuinit rcu_cpu_notify(struct notifier_block *self, +static int __devinit rcu_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { long cpu = (long)hcpu; @@ -565,7 +565,7 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata rcu_nb = { +static struct notifier_block __devinitdata rcu_nb = { .notifier_call = rcu_cpu_notify, }; diff --git a/trunk/kernel/resource.c b/trunk/kernel/resource.c index 46286434af80..0dd3a857579e 100644 --- a/trunk/kernel/resource.c +++ b/trunk/kernel/resource.c @@ -244,7 +244,6 @@ int find_next_system_ram(struct resource *res) start = res->start; end = res->end; - BUG_ON(start >= end); read_lock(&resource_lock); for (p = iomem_resource.child; p ; p = p->sibling) { @@ -255,17 +254,15 @@ int find_next_system_ram(struct resource *res) p = NULL; break; } - if ((p->end >= start) && (p->start < end)) + if (p->start >= start) break; } read_unlock(&resource_lock); if (!p) return -1; /* copy data */ - if (res->start < p->start) - res->start = p->start; - if (res->end > p->end) - res->end = p->end; + res->start = p->start; + res->end = p->end; return 0; } #endif diff --git a/trunk/kernel/rtmutex.c b/trunk/kernel/rtmutex.c index 3e13a1e5856f..d2ef13b485e7 100644 --- a/trunk/kernel/rtmutex.c +++ b/trunk/kernel/rtmutex.c @@ -7,8 +7,6 @@ * Copyright (C) 2005-2006 Timesys Corp., Thomas Gleixner * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt * Copyright (C) 2006 Esben Nielsen - * - * See Documentation/rt-mutex-design.txt for details. */ #include #include diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index a2be2d055299..b44b9a43b0fc 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -4456,9 +4456,9 @@ asmlinkage long sys_sched_yield(void) return 0; } -static inline int __resched_legal(int expected_preempt_count) +static inline int __resched_legal(void) { - if (unlikely(preempt_count() != expected_preempt_count)) + if (unlikely(preempt_count())) return 0; if (unlikely(system_state != SYSTEM_RUNNING)) return 0; @@ -4484,7 +4484,7 @@ static void __cond_resched(void) int __sched cond_resched(void) { - if (need_resched() && __resched_legal(0)) { + if (need_resched() && __resched_legal()) { __cond_resched(); return 1; } @@ -4510,7 +4510,7 @@ int cond_resched_lock(spinlock_t *lock) ret = 1; spin_lock(lock); } - if (need_resched() && __resched_legal(1)) { + if (need_resched() && __resched_legal()) { spin_release(&lock->dep_map, 1, _THIS_IP_); _raw_spin_unlock(lock); preempt_enable_no_resched(); @@ -4526,7 +4526,7 @@ int __sched cond_resched_softirq(void) { BUG_ON(!in_softirq()); - if (need_resched() && __resched_legal(0)) { + if (need_resched() && __resched_legal()) { raw_local_irq_disable(); _local_bh_enable(); raw_local_irq_enable(); @@ -6494,12 +6494,7 @@ static int build_sched_domains(const cpumask_t *cpu_map) for (i = 0; i < MAX_NUMNODES; i++) init_numa_sched_groups_power(sched_group_nodes[i]); - if (sched_group_allnodes) { - int group = cpu_to_allnodes_group(first_cpu(*cpu_map)); - struct sched_group *sg = &sched_group_allnodes[group]; - - init_numa_sched_groups_power(sg); - } + init_numa_sched_groups_power(sched_group_allnodes); #endif /* Attach the domains */ @@ -6766,11 +6761,6 @@ void __init sched_init(void) } set_load_weight(&init_task); - -#ifdef CONFIG_RT_MUTEXES - plist_head_init(&init_task.pi_waiters, &init_task.pi_lock); -#endif - /* * The boot idle thread does lazy MMU switching as well: */ diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index bfdb5686fa3e..7fe874d12fae 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -791,31 +791,22 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t) /* * Force a signal that the process can't ignore: if necessary * we unblock the signal and change any SIG_IGN to SIG_DFL. - * - * Note: If we unblock the signal, we always reset it to SIG_DFL, - * since we do not want to have a signal handler that was blocked - * be invoked when user space had explicitly blocked it. - * - * We don't want to have recursive SIGSEGV's etc, for example. */ + int force_sig_info(int sig, struct siginfo *info, struct task_struct *t) { unsigned long int flags; - int ret, blocked, ignored; - struct k_sigaction *action; + int ret; spin_lock_irqsave(&t->sighand->siglock, flags); - action = &t->sighand->action[sig-1]; - ignored = action->sa.sa_handler == SIG_IGN; - blocked = sigismember(&t->blocked, sig); - if (blocked || ignored) { - action->sa.sa_handler = SIG_DFL; - if (blocked) { - sigdelset(&t->blocked, sig); - recalc_sigpending_tsk(t); - } + if (t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) { + t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; + } + if (sigismember(&t->blocked, sig)) { + sigdelset(&t->blocked, sig); } + recalc_sigpending_tsk(t); ret = specific_send_sig_info(sig, info, t); spin_unlock_irqrestore(&t->sighand->siglock, flags); diff --git a/trunk/kernel/softirq.c b/trunk/kernel/softirq.c index 3789ca98197c..0f08a84ae307 100644 --- a/trunk/kernel/softirq.c +++ b/trunk/kernel/softirq.c @@ -65,7 +65,6 @@ static inline void wakeup_softirqd(void) * This one is for softirq.c-internal use, * where hardirqs are disabled legitimately: */ -#ifdef CONFIG_TRACE_IRQFLAGS static void __local_bh_disable(unsigned long ip) { unsigned long flags; @@ -81,13 +80,6 @@ static void __local_bh_disable(unsigned long ip) trace_softirqs_off(ip); raw_local_irq_restore(flags); } -#else /* !CONFIG_TRACE_IRQFLAGS */ -static inline void __local_bh_disable(unsigned long ip) -{ - add_preempt_count(SOFTIRQ_OFFSET); - barrier(); -} -#endif /* CONFIG_TRACE_IRQFLAGS */ void local_bh_disable(void) { @@ -129,16 +121,12 @@ EXPORT_SYMBOL(_local_bh_enable); void local_bh_enable(void) { -#ifdef CONFIG_TRACE_IRQFLAGS unsigned long flags; WARN_ON_ONCE(in_irq()); -#endif WARN_ON_ONCE(irqs_disabled()); -#ifdef CONFIG_TRACE_IRQFLAGS local_irq_save(flags); -#endif /* * Are softirqs going to be turned on now: */ @@ -154,22 +142,18 @@ void local_bh_enable(void) do_softirq(); dec_preempt_count(); -#ifdef CONFIG_TRACE_IRQFLAGS local_irq_restore(flags); -#endif preempt_check_resched(); } EXPORT_SYMBOL(local_bh_enable); void local_bh_enable_ip(unsigned long ip) { -#ifdef CONFIG_TRACE_IRQFLAGS unsigned long flags; WARN_ON_ONCE(in_irq()); local_irq_save(flags); -#endif /* * Are softirqs going to be turned on now: */ @@ -185,9 +169,7 @@ void local_bh_enable_ip(unsigned long ip) do_softirq(); dec_preempt_count(); -#ifdef CONFIG_TRACE_IRQFLAGS local_irq_restore(flags); -#endif preempt_check_resched(); } EXPORT_SYMBOL(local_bh_enable_ip); @@ -565,7 +547,7 @@ static void takeover_tasklets(unsigned int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __cpuinit cpu_callback(struct notifier_block *nfb, +static int __devinit cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { @@ -605,7 +587,7 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpu_nfb = { +static struct notifier_block __devinitdata cpu_nfb = { .notifier_call = cpu_callback }; diff --git a/trunk/kernel/softlockup.c b/trunk/kernel/softlockup.c index 03e6a2b0b787..6b76caa22981 100644 --- a/trunk/kernel/softlockup.c +++ b/trunk/kernel/softlockup.c @@ -104,7 +104,7 @@ static int watchdog(void * __bind_cpu) /* * Create/destroy watchdog threads as CPUs come and go: */ -static int __cpuinit +static int __devinit cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { int hotcpu = (unsigned long)hcpu; @@ -142,7 +142,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) return NOTIFY_OK; } -static struct notifier_block __cpuinitdata cpu_nfb = { +static struct notifier_block __devinitdata cpu_nfb = { .notifier_call = cpu_callback }; diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index e78187657330..f45179ce028e 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -121,45 +121,46 @@ static int send_reply(struct sk_buff *skb, pid_t pid) /* * Send taskstats data in @skb to listeners registered for @cpu's exit data */ -static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) +static int send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) { struct genlmsghdr *genlhdr = nlmsg_data((struct nlmsghdr *)skb->data); struct listener_list *listeners; struct listener *s, *tmp; struct sk_buff *skb_next, *skb_cur = skb; void *reply = genlmsg_data(genlhdr); - int rc, delcount = 0; + int rc, ret, delcount = 0; rc = genlmsg_end(skb, reply); if (rc < 0) { nlmsg_free(skb); - return; + return rc; } rc = 0; listeners = &per_cpu(listener_array, cpu); down_read(&listeners->sem); - list_for_each_entry(s, &listeners->list, list) { + list_for_each_entry_safe(s, tmp, &listeners->list, list) { skb_next = NULL; if (!list_is_last(&s->list, &listeners->list)) { skb_next = skb_clone(skb_cur, GFP_KERNEL); - if (!skb_next) + if (!skb_next) { + nlmsg_free(skb_cur); + rc = -ENOMEM; break; + } } - rc = genlmsg_unicast(skb_cur, s->pid); - if (rc == -ECONNREFUSED) { + ret = genlmsg_unicast(skb_cur, s->pid); + if (ret == -ECONNREFUSED) { s->valid = 0; delcount++; + rc = ret; } skb_cur = skb_next; } up_read(&listeners->sem); - if (skb_cur) - nlmsg_free(skb_cur); - if (!delcount) - return; + return rc; /* Delete invalidated entries */ down_write(&listeners->sem); @@ -170,12 +171,13 @@ static void send_cpu_listeners(struct sk_buff *skb, unsigned int cpu) } } up_write(&listeners->sem); + return rc; } static int fill_pid(pid_t pid, struct task_struct *pidtsk, struct taskstats *stats) { - int rc = 0; + int rc; struct task_struct *tsk = pidtsk; if (!pidtsk) { @@ -194,10 +196,12 @@ static int fill_pid(pid_t pid, struct task_struct *pidtsk, * Each accounting subsystem adds calls to its functions to * fill in relevant parts of struct taskstsats as follows * - * per-task-foo(stats, tsk); + * rc = per-task-foo(stats, tsk); + * if (rc) + * goto err; */ - delayacct_add_tsk(stats, tsk); + rc = delayacct_add_tsk(stats, tsk); stats->version = TASKSTATS_VERSION; /* Define err: label here if needed */ diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index b650f04888ed..05809c2e2fd6 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -84,7 +84,7 @@ typedef struct tvec_t_base_s tvec_base_t; tvec_base_t boot_tvec_bases; EXPORT_SYMBOL(boot_tvec_bases); -static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases; +static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = { &boot_tvec_bases }; static inline void set_running_timer(tvec_base_t *base, struct timer_list *timer) @@ -408,7 +408,7 @@ static int cascade(tvec_base_t *base, tvec_t *tv, int index) * This function cascades all vectors and executes all expired timer * vectors. */ -#define INDEX(N) ((base->timer_jiffies >> (TVR_BITS + (N) * TVN_BITS)) & TVN_MASK) +#define INDEX(N) (base->timer_jiffies >> (TVR_BITS + N * TVN_BITS)) & TVN_MASK static inline void __run_timers(tvec_base_t *base) { @@ -1688,7 +1688,7 @@ static void __devinit migrate_timers(int cpu) } #endif /* CONFIG_HOTPLUG_CPU */ -static int __cpuinit timer_cpu_notify(struct notifier_block *self, +static int __devinit timer_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { long cpu = (long)hcpu; @@ -1708,7 +1708,7 @@ static int __cpuinit timer_cpu_notify(struct notifier_block *self, return NOTIFY_OK; } -static struct notifier_block __cpuinitdata timers_nb = { +static struct notifier_block __devinitdata timers_nb = { .notifier_call = timer_cpu_notify, }; diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 448e8f7b342d..eebb1d839235 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -93,12 +93,9 @@ static void __queue_work(struct cpu_workqueue_struct *cwq, spin_unlock_irqrestore(&cwq->lock, flags); } -/** - * queue_work - queue work on a workqueue - * @wq: workqueue to use - * @work: work to queue - * - * Returns non-zero if it was successfully added. +/* + * Queue work on a workqueue. Return non-zero if it was successfully + * added. * * We queue the work to the CPU it was submitted, but there is no * guarantee that it will be processed by that CPU. @@ -131,14 +128,6 @@ static void delayed_work_timer_fn(unsigned long __data) __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); } -/** - * queue_delayed_work - queue work on a workqueue after delay - * @wq: workqueue to use - * @work: work to queue - * @delay: number of jiffies to wait before queueing - * - * Returns non-zero if it was successfully added. - */ int fastcall queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay) { @@ -161,15 +150,6 @@ int fastcall queue_delayed_work(struct workqueue_struct *wq, } EXPORT_SYMBOL_GPL(queue_delayed_work); -/** - * queue_delayed_work_on - queue work on specific CPU after delay - * @cpu: CPU number to execute work on - * @wq: workqueue to use - * @work: work to queue - * @delay: number of jiffies to wait before queueing - * - * Returns non-zero if it was successfully added. - */ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, struct work_struct *work, unsigned long delay) { @@ -295,9 +275,8 @@ static void flush_cpu_workqueue(struct cpu_workqueue_struct *cwq) } } -/** +/* * flush_workqueue - ensure that any scheduled work has run to completion. - * @wq: workqueue to flush * * Forces execution of the workqueue and blocks until its completion. * This is typically used in driver shutdown handlers. @@ -421,12 +400,6 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu) kthread_stop(p); } -/** - * destroy_workqueue - safely terminate a workqueue - * @wq: target workqueue - * - * Safely destroy a workqueue. All work currently pending will be done first. - */ void destroy_workqueue(struct workqueue_struct *wq) { int cpu; @@ -452,41 +425,18 @@ EXPORT_SYMBOL_GPL(destroy_workqueue); static struct workqueue_struct *keventd_wq; -/** - * schedule_work - put work task in global workqueue - * @work: job to be done - * - * This puts a job in the kernel-global workqueue. - */ int fastcall schedule_work(struct work_struct *work) { return queue_work(keventd_wq, work); } EXPORT_SYMBOL(schedule_work); -/** - * schedule_delayed_work - put work task in global workqueue after delay - * @work: job to be done - * @delay: number of jiffies to wait - * - * After waiting for a given time this puts a job in the kernel-global - * workqueue. - */ int fastcall schedule_delayed_work(struct work_struct *work, unsigned long delay) { return queue_delayed_work(keventd_wq, work, delay); } EXPORT_SYMBOL(schedule_delayed_work); -/** - * schedule_delayed_work_on - queue work in global workqueue on CPU after delay - * @cpu: cpu to use - * @work: job to be done - * @delay: number of jiffies to wait - * - * After waiting for a given time this puts a job in the kernel-global - * workqueue on the specified CPU. - */ int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay) { diff --git a/trunk/lib/kobject_uevent.c b/trunk/lib/kobject_uevent.c index 7f20e7b857cb..2b1530fc573b 100644 --- a/trunk/lib/kobject_uevent.c +++ b/trunk/lib/kobject_uevent.c @@ -50,6 +50,10 @@ static char *action_to_string(enum kobject_action action) return "offline"; case KOBJ_ONLINE: return "online"; + case KOBJ_DOCK: + return "dock"; + case KOBJ_UNDOCK: + return "undock"; default: return NULL; } diff --git a/trunk/lib/spinlock_debug.c b/trunk/lib/spinlock_debug.c index 58c577dd82e5..3d9c4dc965ed 100644 --- a/trunk/lib/spinlock_debug.c +++ b/trunk/lib/spinlock_debug.c @@ -162,7 +162,6 @@ static void rwlock_bug(rwlock_t *lock, const char *msg) #define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) -#if 0 /* __write_lock_debug() can lock up - maybe this can too? */ static void __read_lock_debug(rwlock_t *lock) { int print_once = 1; @@ -185,12 +184,12 @@ static void __read_lock_debug(rwlock_t *lock) } } } -#endif void _raw_read_lock(rwlock_t *lock) { RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); - __raw_read_lock(&lock->raw_lock); + if (unlikely(!__raw_read_trylock(&lock->raw_lock))) + __read_lock_debug(lock); } int _raw_read_trylock(rwlock_t *lock) @@ -236,7 +235,6 @@ static inline void debug_write_unlock(rwlock_t *lock) lock->owner_cpu = -1; } -#if 0 /* This can cause lockups */ static void __write_lock_debug(rwlock_t *lock) { int print_once = 1; @@ -259,12 +257,12 @@ static void __write_lock_debug(rwlock_t *lock) } } } -#endif void _raw_write_lock(rwlock_t *lock) { debug_write_lock_before(lock); - __raw_write_lock(&lock->raw_lock); + if (unlikely(!__raw_write_trylock(&lock->raw_lock))) + __write_lock_debug(lock); debug_write_lock_after(lock); } diff --git a/trunk/lib/zlib_inflate/inflate.c b/trunk/lib/zlib_inflate/inflate.c index fceb97c3aff7..7f922dccf1a5 100644 --- a/trunk/lib/zlib_inflate/inflate.c +++ b/trunk/lib/zlib_inflate/inflate.c @@ -347,10 +347,7 @@ int zlib_inflate(z_streamp strm, int flush) static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - /* Do not check for strm->next_out == NULL here as ppc zImage - inflates to strm->next_out = 0 */ - - if (strm == NULL || strm->state == NULL || + if (strm == NULL || strm->state == NULL || strm->next_out == NULL || (strm->next_in == NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; diff --git a/trunk/mm/fadvise.c b/trunk/mm/fadvise.c index 168c78a121bb..60a5d55e51d9 100644 --- a/trunk/mm/fadvise.c +++ b/trunk/mm/fadvise.c @@ -73,6 +73,7 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) file->f_ra.ra_pages = bdi->ra_pages * 2; break; case POSIX_FADV_WILLNEED: + case POSIX_FADV_NOREUSE: if (!mapping->a_ops->readpage) { ret = -EINVAL; break; @@ -93,8 +94,6 @@ asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice) if (ret > 0) ret = 0; break; - case POSIX_FADV_NOREUSE: - break; case POSIX_FADV_DONTNEED: if (!bdi_write_congested(mapping->backing_dev_info)) filemap_flush(mapping); diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index b9a60c43b61a..d087fc3d3281 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -849,6 +849,8 @@ static void shrink_readahead_size_eio(struct file *filp, return; ra->ra_pages /= 4; + printk(KERN_WARNING "Reducing readahead size to %luK\n", + ra->ra_pages << (PAGE_CACHE_SHIFT - 10)); } /** diff --git a/trunk/mm/memory_hotplug.c b/trunk/mm/memory_hotplug.c index c37319542b70..01c9fb97c619 100644 --- a/trunk/mm/memory_hotplug.c +++ b/trunk/mm/memory_hotplug.c @@ -52,9 +52,6 @@ static int __add_section(struct zone *zone, unsigned long phys_start_pfn) int nr_pages = PAGES_PER_SECTION; int ret; - if (pfn_valid(phys_start_pfn)) - return -EEXIST; - ret = sparse_add_one_section(zone, phys_start_pfn, nr_pages); if (ret < 0) @@ -79,22 +76,15 @@ int __add_pages(struct zone *zone, unsigned long phys_start_pfn, { unsigned long i; int err = 0; - int start_sec, end_sec; - /* during initialize mem_map, align hot-added range to section */ - start_sec = pfn_to_section_nr(phys_start_pfn); - end_sec = pfn_to_section_nr(phys_start_pfn + nr_pages - 1); - for (i = start_sec; i <= end_sec; i++) { - err = __add_section(zone, i << PFN_SECTION_SHIFT); + for (i = 0; i < nr_pages; i += PAGES_PER_SECTION) { + err = __add_section(zone, phys_start_pfn + i); - /* - * EEXIST is finally dealed with by ioresource collision - * check. see add_memory() => register_memory_resource() - * Warning will be printed if there is collision. + /* We want to keep adding the rest of the + * sections if the first ones already exist */ if (err && (err != -EEXIST)) break; - err = 0; } return err; @@ -166,7 +156,7 @@ int online_pages(unsigned long pfn, unsigned long nr_pages) res.flags = IORESOURCE_MEM; /* we just need system ram */ section_end = res.end; - while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) { + while (find_next_system_ram(&res) >= 0) { start_pfn = (unsigned long)(res.start >> PAGE_SHIFT); nr_pages = (unsigned long) ((res.end + 1 - res.start) >> PAGE_SHIFT); @@ -223,9 +213,10 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat) } /* add this memory to iomem resource */ -static struct resource *register_memory_resource(u64 start, u64 size) +static void register_memory_resource(u64 start, u64 size) { struct resource *res; + res = kzalloc(sizeof(struct resource), GFP_KERNEL); BUG_ON(!res); @@ -237,18 +228,7 @@ static struct resource *register_memory_resource(u64 start, u64 size) printk("System RAM resource %llx - %llx cannot be added\n", (unsigned long long)res->start, (unsigned long long)res->end); kfree(res); - res = NULL; } - return res; -} - -static void release_memory_resource(struct resource *res) -{ - if (!res) - return; - release_resource(res); - kfree(res); - return; } @@ -257,13 +237,8 @@ int add_memory(int nid, u64 start, u64 size) { pg_data_t *pgdat = NULL; int new_pgdat = 0; - struct resource *res; int ret; - res = register_memory_resource(start, size); - if (!res) - return -EEXIST; - if (!node_online(nid)) { pgdat = hotadd_new_pgdat(nid, start); if (!pgdat) @@ -293,13 +268,14 @@ int add_memory(int nid, u64 start, u64 size) BUG_ON(ret); } + /* register this memory as resource */ + register_memory_resource(start, size); + return ret; error: /* rollback pgdat allocation and others */ if (new_pgdat) rollback_node_hotadd(nid, pgdat); - if (res) - release_memory_resource(res); return ret; } diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 21ba06035700..0f20843beffd 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -1106,7 +1106,7 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) #endif -static int __cpuinit cpuup_callback(struct notifier_block *nfb, +static int __devinit cpuup_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { long cpu = (long)hcpu; @@ -3224,7 +3224,7 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) EXPORT_SYMBOL(kmem_cache_alloc); /** - * kmem_cache_zalloc - Allocate an object. The memory is set to zero. + * kmem_cache_alloc - Allocate an object. The memory is set to zero. * @cache: The cache to allocate from. * @flags: See kmalloc(). * diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index 18fcb9fa518d..458031bfff55 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -67,6 +67,10 @@ static struct packet_type vlan_packet_type = { .func = vlan_skb_recv, /* VLAN receive method */ }; +/* Bits of netdev state that are propagated from real device to virtual */ +#define VLAN_LINK_STATE_MASK \ + ((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)|(1<<__LINK_STATE_DORMANT)) + /* End of global variables definitions. */ /* @@ -475,9 +479,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, new_dev->flags = real_dev->flags; new_dev->flags &= ~IFF_UP; - new_dev->state = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) | - (1<<__LINK_STATE_DORMANT))) | - (1<<__LINK_STATE_PRESENT); + new_dev->state = real_dev->state & ~(1<<__LINK_STATE_START); /* need 4 bytes for extra VLAN header info, * hope the underlying device can handle it. @@ -540,11 +542,12 @@ static struct net_device *register_vlan_device(const char *eth_IF_name, * so it cannot "appear" on us. */ if (!grp) { /* need to add a new group */ - grp = kzalloc(sizeof(struct vlan_group), GFP_KERNEL); + grp = kmalloc(sizeof(struct vlan_group), GFP_KERNEL); if (!grp) goto out_free_unregister; /* printk(KERN_ALERT "VLAN REGISTER: Allocated new group.\n"); */ + memset(grp, 0, sizeof(struct vlan_group)); grp->real_dev_ifindex = real_dev->ifindex; hlist_add_head_rcu(&grp->hlist, diff --git a/trunk/net/appletalk/ddp.c b/trunk/net/appletalk/ddp.c index 96dc6bb52d14..5ee96d4b40e9 100644 --- a/trunk/net/appletalk/ddp.c +++ b/trunk/net/appletalk/ddp.c @@ -227,11 +227,12 @@ static void atif_drop_device(struct net_device *dev) static struct atalk_iface *atif_add_device(struct net_device *dev, struct atalk_addr *sa) { - struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); + struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL); if (!iface) goto out; + memset(iface, 0, sizeof(*iface)); dev_hold(dev); iface->dev = dev; dev->atalk_ptr = iface; @@ -558,11 +559,12 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) } if (!rt) { - rt = kzalloc(sizeof(*rt), GFP_ATOMIC); + rt = kmalloc(sizeof(*rt), GFP_ATOMIC); retval = -ENOBUFS; if (!rt) goto out_unlock; + memset(rt, 0, sizeof(*rt)); rt->next = atalk_routes; atalk_routes = rt; diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index d00cca97eb33..a487233dc466 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -508,9 +508,10 @@ Note: we do not have explicit unassign, but look at _push() if (copy_from_user(&be, arg, sizeof be)) return -EFAULT; - brvcc = kzalloc(sizeof(struct br2684_vcc), GFP_KERNEL); + brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL); if (!brvcc) return -ENOMEM; + memset(brvcc, 0, sizeof(struct br2684_vcc)); write_lock_irq(&devs_lock); net_dev = br2684_find_dev(&be.ifspec); if (net_dev == NULL) { diff --git a/trunk/net/atm/clip.c b/trunk/net/atm/clip.c index 7ce7bfe3fbad..2e62105d91bd 100644 --- a/trunk/net/atm/clip.c +++ b/trunk/net/atm/clip.c @@ -929,11 +929,12 @@ static int arp_seq_open(struct inode *inode, struct file *file) struct seq_file *seq; int rc = -EAGAIN; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc(sizeof(*state), GFP_KERNEL); if (!state) { rc = -ENOMEM; goto out_kfree; } + memset(state, 0, sizeof(*state)); state->ns.neigh_sub_iter = clip_seq_sub_iter; rc = seq_open(file, &arp_seq_ops); diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index b4aa489849df..4b68a18171cf 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -1811,11 +1811,12 @@ make_entry(struct lec_priv *priv, unsigned char *mac_addr) { struct lec_arp_table *to_return; - to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); + to_return = kmalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); if (!to_return) { printk("LEC: Arp entry kmalloc failed\n"); return NULL; } + memset(to_return, 0, sizeof(struct lec_arp_table)); memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); init_timer(&to_return->timer); to_return->timer.function = lec_arp_expire_arp; diff --git a/trunk/net/atm/mpc.c b/trunk/net/atm/mpc.c index 00704661e83f..9aafe1e2f048 100644 --- a/trunk/net/atm/mpc.c +++ b/trunk/net/atm/mpc.c @@ -258,9 +258,10 @@ static struct mpoa_client *alloc_mpc(void) { struct mpoa_client *mpc; - mpc = kzalloc(sizeof (struct mpoa_client), GFP_KERNEL); + mpc = kmalloc(sizeof (struct mpoa_client), GFP_KERNEL); if (mpc == NULL) return NULL; + memset(mpc, 0, sizeof(struct mpoa_client)); rwlock_init(&mpc->ingress_lock); rwlock_init(&mpc->egress_lock); mpc->next = mpcs; diff --git a/trunk/net/atm/pppoatm.c b/trunk/net/atm/pppoatm.c index 19d5dfc0702f..76a7d8ff6c0e 100644 --- a/trunk/net/atm/pppoatm.c +++ b/trunk/net/atm/pppoatm.c @@ -287,9 +287,10 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg) if (be.encaps != PPPOATM_ENCAPS_AUTODETECT && be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC) return -EINVAL; - pvcc = kzalloc(sizeof(*pvcc), GFP_KERNEL); + pvcc = kmalloc(sizeof(*pvcc), GFP_KERNEL); if (pvcc == NULL) return -ENOMEM; + memset(pvcc, 0, sizeof(*pvcc)); pvcc->atmvcc = atmvcc; pvcc->old_push = atmvcc->push; pvcc->old_pop = atmvcc->pop; diff --git a/trunk/net/atm/resources.c b/trunk/net/atm/resources.c index 529f7e64aa2c..de25c6408b04 100644 --- a/trunk/net/atm/resources.c +++ b/trunk/net/atm/resources.c @@ -33,9 +33,10 @@ static struct atm_dev *__alloc_atm_dev(const char *type) { struct atm_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return NULL; + memset(dev, 0, sizeof(*dev)); dev->type = type; dev->signal = ATM_PHY_SIG_UNKNOWN; dev->link_rate = ATM_OC3_PCR; diff --git a/trunk/net/ax25/sysctl_net_ax25.c b/trunk/net/ax25/sysctl_net_ax25.c index 867d42537979..369a75b160f2 100644 --- a/trunk/net/ax25/sysctl_net_ax25.c +++ b/trunk/net/ax25/sysctl_net_ax25.c @@ -203,11 +203,13 @@ void ax25_register_sysctl(void) for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) ax25_table_size += sizeof(ctl_table); - if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) { + if ((ax25_table = kmalloc(ax25_table_size, GFP_ATOMIC)) == NULL) { spin_unlock_bh(&ax25_dev_lock); return; } + memset(ax25_table, 0x00, ax25_table_size); + for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { ctl_table *child = kmalloc(sizeof(ax25_param_table), GFP_ATOMIC); if (!child) { diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index 332dd8f436ea..77eab8f4c7fd 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -55,7 +55,6 @@ #define VERSION "1.8" static int disable_cfc = 0; -static int channel_mtu = -1; static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU; static struct task_struct *rfcomm_thread; @@ -813,10 +812,7 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d pn->credits = 0; } - if (cr && channel_mtu >= 0) - pn->mtu = htobs(channel_mtu); - else - pn->mtu = htobs(d->mtu); + pn->mtu = htobs(d->mtu); *ptr = __fcs(buf); ptr++; @@ -1247,10 +1243,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn) d->priority = pn->priority; - d->mtu = btohs(pn->mtu); - - if (cr && d->mtu > s->mtu) - d->mtu = s->mtu; + d->mtu = s->mtu = btohs(pn->mtu); return 0; } @@ -1777,11 +1770,6 @@ static inline void rfcomm_accept_connection(struct rfcomm_session *s) s = rfcomm_session_add(nsock, BT_OPEN); if (s) { rfcomm_session_hold(s); - - /* We should adjust MTU on incoming sessions. - * L2CAP MTU minus UIH header and FCS. */ - s->mtu = min(l2cap_pi(nsock->sk)->omtu, l2cap_pi(nsock->sk)->imtu) - 5; - rfcomm_schedule(RFCOMM_SCHED_RX); } else sock_release(nsock); @@ -2099,9 +2087,6 @@ module_exit(rfcomm_exit); module_param(disable_cfc, bool, 0644); MODULE_PARM_DESC(disable_cfc, "Disable credit based flow control"); -module_param(channel_mtu, int, 0644); -MODULE_PARM_DESC(channel_mtu, "Default MTU for the RFCOMM channel"); - module_param(l2cap_mtu, uint, 0644); MODULE_PARM_DESC(l2cap_mtu, "Default MTU for the L2CAP connection"); diff --git a/trunk/net/bridge/br_ioctl.c b/trunk/net/bridge/br_ioctl.c index 4e4119a12139..159fb8409824 100644 --- a/trunk/net/bridge/br_ioctl.c +++ b/trunk/net/bridge/br_ioctl.c @@ -162,10 +162,12 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (num > BR_MAX_PORTS) num = BR_MAX_PORTS; - indices = kcalloc(num, sizeof(int), GFP_KERNEL); + indices = kmalloc(num*sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; + memset(indices, 0, num*sizeof(int)); + get_port_ifindices(br, indices, num); if (copy_to_user((void __user *)args[1], indices, num*sizeof(int))) num = -EFAULT; @@ -325,10 +327,11 @@ static int old_deviceless(void __user *uarg) if (args[2] >= 2048) return -ENOMEM; - indices = kcalloc(args[2], sizeof(int), GFP_KERNEL); + indices = kmalloc(args[2]*sizeof(int), GFP_KERNEL); if (indices == NULL) return -ENOMEM; + memset(indices, 0, args[2]*sizeof(int)); args[2] = get_bridge_ifindices(indices, args[2]); ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) diff --git a/trunk/net/bridge/br_netfilter.c b/trunk/net/bridge/br_netfilter.c index 05b3de888243..cbc8a389a0a8 100644 --- a/trunk/net/bridge/br_netfilter.c +++ b/trunk/net/bridge/br_netfilter.c @@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged = 1; #define brnf_filter_vlan_tagged 1 #endif -int brnf_deferred_hooks; -EXPORT_SYMBOL_GPL(brnf_deferred_hooks); - static __be16 inline vlan_proto(const struct sk_buff *skb) { return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; @@ -893,8 +890,6 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, return NF_ACCEPT; else if (ip->version == 6 && !brnf_call_ip6tables) return NF_ACCEPT; - else if (!brnf_deferred_hooks) - return NF_ACCEPT; #endif if (hook == NF_IP_POST_ROUTING) return NF_ACCEPT; diff --git a/trunk/net/bridge/br_netlink.c b/trunk/net/bridge/br_netlink.c index 53086fb75089..06abb6634f5b 100644 --- a/trunk/net/bridge/br_netlink.c +++ b/trunk/net/bridge/br_netlink.c @@ -85,7 +85,7 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port) goto err_out; err = br_fill_ifinfo(skb, port, current->pid, 0, event, 0); - if (err < 0) + if (err) goto err_kfree; NETLINK_CB(skb).dst_group = RTNLGRP_LINK; diff --git a/trunk/net/core/Makefile b/trunk/net/core/Makefile index 2645ba428d48..e9bd2467d5a9 100644 --- a/trunk/net/core/Makefile +++ b/trunk/net/core/Makefile @@ -7,7 +7,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ obj-$(CONFIG_SYSCTL) += sysctl_net_core.o -obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ +obj-y += dev.o ethtool.o dev_mcast.o dst.o \ neighbour.o rtnetlink.o utils.o link_watch.o filter.o obj-$(CONFIG_XFRM) += flow.o diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index d95e2626d944..4d2b5167d7f5 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1166,6 +1166,11 @@ int skb_checksum_help(struct sk_buff *skb, int inward) goto out_set_summed; if (unlikely(skb_shinfo(skb)->gso_size)) { + static int warned; + + WARN_ON(!warned); + warned = 1; + /* Let GSO fix up the checksum. */ goto out_set_summed; } @@ -1215,6 +1220,11 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features) __skb_pull(skb, skb->mac_len); if (unlikely(skb->ip_summed != CHECKSUM_HW)) { + static int warned; + + WARN_ON(!warned); + warned = 1; + if (skb_header_cloned(skb) && (err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) return ERR_PTR(err); @@ -3419,9 +3429,12 @@ static void net_dma_rebalance(void) unsigned int cpu, i, n; struct dma_chan *chan; + lock_cpu_hotplug(); + if (net_dma_count == 0) { for_each_online_cpu(cpu) - rcu_assign_pointer(per_cpu(softnet_data, cpu).net_dma, NULL); + rcu_assign_pointer(per_cpu(softnet_data.net_dma, cpu), NULL); + unlock_cpu_hotplug(); return; } @@ -3434,13 +3447,15 @@ static void net_dma_rebalance(void) + (i < (num_online_cpus() % net_dma_count) ? 1 : 0)); while(n) { - per_cpu(softnet_data, cpu).net_dma = chan; + per_cpu(softnet_data.net_dma, cpu) = chan; cpu = next_cpu(cpu, cpu_online_map); n--; } i++; } rcu_read_unlock(); + + unlock_cpu_hotplug(); } /** diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index 2797e2815418..27ce1683caf5 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -437,7 +437,7 @@ static int ethtool_set_pauseparam(struct net_device *dev, void __user *useraddr) { struct ethtool_pauseparam pauseparam; - if (!dev->ethtool_ops->set_pauseparam) + if (!dev->ethtool_ops->get_pauseparam) return -EOPNOTSUPP; if (copy_from_user(&pauseparam, useraddr, sizeof(pauseparam))) diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 5130d2efdbbe..7ad681f5e712 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -755,7 +754,6 @@ static void neigh_timer_handler(unsigned long arg) neigh->nud_state = NUD_STALE; neigh->updated = jiffies; neigh_suspect(neigh); - notify = 1; } } else if (state & NUD_DELAY) { if (time_before_eq(now, @@ -764,7 +762,6 @@ static void neigh_timer_handler(unsigned long arg) neigh->nud_state = NUD_REACHABLE; neigh->updated = jiffies; neigh_connect(neigh); - notify = 1; next = neigh->confirmed + neigh->parms->reachable_time; } else { NEIGH_PRINTK2("neigh %p is probed.\n", neigh); @@ -822,8 +819,6 @@ static void neigh_timer_handler(unsigned long arg) out: write_unlock(&neigh->lock); } - if (notify) - call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh); #ifdef CONFIG_ARPD if (notify && neigh->parms->app_probes) @@ -931,7 +926,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, { u8 old; int err; +#ifdef CONFIG_ARPD int notify = 0; +#endif struct net_device *dev; int update_isrouter = 0; @@ -951,7 +948,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, neigh_suspect(neigh); neigh->nud_state = new; err = 0; +#ifdef CONFIG_ARPD notify = old & NUD_VALID; +#endif goto out; } @@ -1023,7 +1022,9 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, if (!(new & NUD_CONNECTED)) neigh->confirmed = jiffies - (neigh->parms->base_reachable_time << 1); +#ifdef CONFIG_ARPD notify = 1; +#endif } if (new == old) goto out; @@ -1055,9 +1056,6 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, (neigh->flags & ~NTF_ROUTER); } write_unlock_bh(&neigh->lock); - - if (notify) - call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh); #ifdef CONFIG_ARPD if (notify && neigh->parms->app_probes) neigh_app_notify(neigh); diff --git a/trunk/net/core/netevent.c b/trunk/net/core/netevent.c deleted file mode 100644 index 35d02c38554e..000000000000 --- a/trunk/net/core/netevent.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Network event notifiers - * - * Authors: - * Tom Tucker - * Steve Wise - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Fixes: - */ - -#include -#include - -static ATOMIC_NOTIFIER_HEAD(netevent_notif_chain); - -/** - * register_netevent_notifier - register a netevent notifier block - * @nb: notifier - * - * Register a notifier to be called when a netevent occurs. - * The notifier passed is linked into the kernel structures and must - * not be reused until it has been unregistered. A negative errno code - * is returned on a failure. - */ -int register_netevent_notifier(struct notifier_block *nb) -{ - int err; - - err = atomic_notifier_chain_register(&netevent_notif_chain, nb); - return err; -} - -/** - * netevent_unregister_notifier - unregister a netevent notifier block - * @nb: notifier - * - * Unregister a notifier previously registered by - * register_neigh_notifier(). The notifier is unlinked into the - * kernel structures and may then be reused. A negative errno code - * is returned on a failure. - */ - -int unregister_netevent_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&netevent_notif_chain, nb); -} - -/** - * call_netevent_notifiers - call all netevent notifier blocks - * @val: value passed unmodified to notifier function - * @v: pointer passed unmodified to notifier function - * - * Call all neighbour notifier blocks. Parameters and return value - * are as for notifier_call_chain(). - */ - -int call_netevent_notifiers(unsigned long val, void *v) -{ - return atomic_notifier_call_chain(&netevent_notif_chain, val, v); -} - -EXPORT_SYMBOL_GPL(register_netevent_notifier); -EXPORT_SYMBOL_GPL(unregister_netevent_notifier); -EXPORT_SYMBOL_GPL(call_netevent_notifiers); diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 022d8894c11d..476aa3978504 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -70,6 +70,13 @@ static kmem_cache_t *skbuff_head_cache __read_mostly; static kmem_cache_t *skbuff_fclone_cache __read_mostly; +/* + * lockdep: lock class key used by skb_queue_head_init(): + */ +struct lock_class_key skb_queue_lock_key; + +EXPORT_SYMBOL(skb_queue_lock_key); + /* * Keep out-of-line to prevent kernel bloat. * __builtin_return_address is not used because it is not always @@ -249,29 +256,6 @@ struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, goto out; } -/** - * __netdev_alloc_skb - allocate an skbuff for rx on a specific device - * @dev: network device to receive on - * @length: length to allocate - * @gfp_mask: get_free_pages mask, passed to alloc_skb - * - * Allocate a new &sk_buff and assign it a usage count of one. The - * buffer has unspecified headroom built in. Users should allocate - * the headroom they think they need without accounting for the - * built in space. The built in space is used for optimisations. - * - * %NULL is returned if there is no free memory. - */ -struct sk_buff *__netdev_alloc_skb(struct net_device *dev, - unsigned int length, gfp_t gfp_mask) -{ - struct sk_buff *skb; - - skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); - if (likely(skb)) - skb_reserve(skb, NET_SKB_PAD); - return skb; -} static void skb_drop_list(struct sk_buff **listp) { @@ -862,11 +846,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) unlikely((err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))) return err; - i = 0; - if (offset >= len) - goto drop_pages; - - for (; i < nfrags; i++) { + for (i = 0; i < nfrags; i++) { int end = offset + skb_shinfo(skb)->frags[i].size; if (end < len) { @@ -874,9 +854,9 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) continue; } - skb_shinfo(skb)->frags[i++].size = len - offset; + if (len > offset) + skb_shinfo(skb)->frags[i++].size = len - offset; -drop_pages: skb_shinfo(skb)->nr_frags = i; for (; i < nfrags; i++) @@ -884,7 +864,7 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); - goto done; + break; } for (fragp = &skb_shinfo(skb)->frag_list; (frag = *fragp); @@ -899,7 +879,6 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) return -ENOMEM; nfrag->next = frag->next; - kfree_skb(frag); frag = nfrag; *fragp = frag; } @@ -918,7 +897,6 @@ int ___pskb_trim(struct sk_buff *skb, unsigned int len) break; } -done: if (len > skb_headlen(skb)) { skb->data_len -= skb->len - len; skb->len = len; @@ -2064,7 +2042,6 @@ EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(kfree_skb); EXPORT_SYMBOL(__pskb_pull_tail); EXPORT_SYMBOL(__alloc_skb); -EXPORT_SYMBOL(__netdev_alloc_skb); EXPORT_SYMBOL(pskb_copy); EXPORT_SYMBOL(pskb_expand_head); EXPORT_SYMBOL(skb_checksum); diff --git a/trunk/net/core/user_dma.c b/trunk/net/core/user_dma.c index 248a6b666aff..b7c98dbcdb81 100644 --- a/trunk/net/core/user_dma.c +++ b/trunk/net/core/user_dma.c @@ -29,7 +29,6 @@ #include #include /* for BUG_TRAP */ #include -#include #define NET_DMA_DEFAULT_COPYBREAK 4096 diff --git a/trunk/net/dccp/feat.h b/trunk/net/dccp/feat.h index b44c45504fb6..6048373c7186 100644 --- a/trunk/net/dccp/feat.h +++ b/trunk/net/dccp/feat.h @@ -26,6 +26,4 @@ extern void dccp_feat_clean(struct dccp_minisock *dmsk); extern int dccp_feat_clone(struct sock *oldsk, struct sock *newsk); extern int dccp_feat_init(struct dccp_minisock *dmsk); -extern int dccp_feat_default_sequence_window; - #endif /* _DCCP_FEAT_H */ diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 7f56f7e8f571..c3073e7e81d3 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -504,7 +504,8 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) ireq = inet_rsk(req); ireq->loc_addr = daddr; ireq->rmt_addr = saddr; - req->rcv_wnd = dccp_feat_default_sequence_window; + req->rcv_wnd = 100; /* Fake, option parsing will get the + right value */ ireq->opt = NULL; /* diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index 610c722ac27f..ff42bc43263d 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -31,7 +31,6 @@ #include "dccp.h" #include "ipv6.h" -#include "feat.h" /* Socket used for sending RSTs and ACKs */ static struct socket *dccp_v6_ctl_socket; @@ -230,7 +229,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, ipv6_addr_copy(&np->saddr, saddr); inet->rcv_saddr = LOOPBACK4_IPV6; - __ip6_dst_store(sk, dst, NULL); + ip6_dst_store(sk, dst, NULL); icsk->icsk_ext_hdr_len = 0; if (np->opt != NULL) @@ -708,7 +707,8 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) ireq = inet_rsk(req); ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); - req->rcv_wnd = dccp_feat_default_sequence_window; + req->rcv_wnd = 100; /* Fake, option parsing will get the + right value */ ireq6->pktopts = NULL; if (ipv6_opt_accepted(sk, skb) || @@ -863,7 +863,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, * comment in that function for the gory details. -acme */ - __ip6_dst_store(newsk, dst, NULL); + ip6_dst_store(newsk, dst, NULL); newsk->sk_route_caps = dst->dev->features & ~(NETIF_F_IP_CSUM | NETIF_F_TSO); newdp6 = (struct dccp6_sock *)newsk; diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index daf72bb671f0..c3cda1e39aa8 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -29,8 +29,6 @@ int dccp_feat_default_ack_ratio = DCCPF_INITIAL_ACK_RATIO; int dccp_feat_default_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR; int dccp_feat_default_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT; -EXPORT_SYMBOL_GPL(dccp_feat_default_sequence_window); - void dccp_minisock_init(struct dccp_minisock *dmsk) { dmsk->dccpms_sequence_window = dccp_feat_default_sequence_window; diff --git a/trunk/net/decnet/dn_dev.c b/trunk/net/decnet/dn_dev.c index 476455fbdb03..98a25208440d 100644 --- a/trunk/net/decnet/dn_dev.c +++ b/trunk/net/decnet/dn_dev.c @@ -413,7 +413,11 @@ static struct dn_ifaddr *dn_dev_alloc_ifa(void) { struct dn_ifaddr *ifa; - ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); + ifa = kmalloc(sizeof(*ifa), GFP_KERNEL); + + if (ifa) { + memset(ifa, 0, sizeof(*ifa)); + } return ifa; } @@ -1101,9 +1105,10 @@ struct dn_dev *dn_dev_create(struct net_device *dev, int *err) return NULL; *err = -ENOBUFS; - if ((dn_db = kzalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) + if ((dn_db = kmalloc(sizeof(struct dn_dev), GFP_ATOMIC)) == NULL) return NULL; + memset(dn_db, 0, sizeof(struct dn_dev)); memcpy(&dn_db->parms, p, sizeof(struct dn_dev_parms)); smp_wmb(); dev->dn_ptr = dn_db; diff --git a/trunk/net/decnet/dn_fib.c b/trunk/net/decnet/dn_fib.c index fa20e2efcfc1..0375077391b7 100644 --- a/trunk/net/decnet/dn_fib.c +++ b/trunk/net/decnet/dn_fib.c @@ -283,10 +283,11 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta goto err_inval; } - fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); + fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); err = -ENOBUFS; if (fi == NULL) goto failure; + memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct dn_fib_nh)); fi->fib_protocol = r->rtm_protocol; fi->fib_nhs = nhs; diff --git a/trunk/net/decnet/dn_neigh.c b/trunk/net/decnet/dn_neigh.c index ff0ebe99137d..5ce9c9e0565c 100644 --- a/trunk/net/decnet/dn_neigh.c +++ b/trunk/net/decnet/dn_neigh.c @@ -580,11 +580,12 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; + memset(s, 0, sizeof(*s)); rc = seq_open(file, &dn_neigh_seq_ops); if (rc) goto out_kfree; diff --git a/trunk/net/decnet/dn_route.c b/trunk/net/decnet/dn_route.c index 743e9fcf7c5a..1355614ec11b 100644 --- a/trunk/net/decnet/dn_route.c +++ b/trunk/net/decnet/dn_route.c @@ -925,13 +925,8 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old for(dev_out = dev_base; dev_out; dev_out = dev_out->next) { if (!dev_out->dn_ptr) continue; - if (!dn_dev_islocal(dev_out, oldflp->fld_src)) - continue; - if ((dev_out->flags & IFF_LOOPBACK) && - oldflp->fld_dst && - !dn_dev_islocal(dev_out, oldflp->fld_dst)) - continue; - break; + if (dn_dev_islocal(dev_out, oldflp->fld_src)) + break; } read_unlock(&dev_base_lock); if (dev_out == NULL) diff --git a/trunk/net/decnet/dn_rules.c b/trunk/net/decnet/dn_rules.c index 6986be754ef2..22f321d9bf9d 100644 --- a/trunk/net/decnet/dn_rules.c +++ b/trunk/net/decnet/dn_rules.c @@ -151,9 +151,10 @@ int dn_fib_rtm_newrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) } } - new_r = kzalloc(sizeof(*new_r), GFP_KERNEL); + new_r = kmalloc(sizeof(*new_r), GFP_KERNEL); if (!new_r) return -ENOMEM; + memset(new_r, 0, sizeof(*new_r)); if (rta[RTA_SRC-1]) memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 2); diff --git a/trunk/net/decnet/dn_table.c b/trunk/net/decnet/dn_table.c index e926c952e363..37d9d0a1ac8c 100644 --- a/trunk/net/decnet/dn_table.c +++ b/trunk/net/decnet/dn_table.c @@ -158,10 +158,12 @@ static void dn_rehash_zone(struct dn_zone *dz) break; } - ht = kcalloc(new_divisor, sizeof(struct dn_fib_node*), GFP_KERNEL); + ht = kmalloc(new_divisor*sizeof(struct dn_fib_node*), GFP_KERNEL); + if (ht == NULL) return; + memset(ht, 0, new_divisor*sizeof(struct dn_fib_node *)); write_lock_bh(&dn_fib_tables_lock); old_ht = dz->dz_hash; dz->dz_hash = ht; @@ -182,10 +184,11 @@ static void dn_free_node(struct dn_fib_node *f) static struct dn_zone *dn_new_zone(struct dn_hash *table, int z) { int i; - struct dn_zone *dz = kzalloc(sizeof(struct dn_zone), GFP_KERNEL); + struct dn_zone *dz = kmalloc(sizeof(struct dn_zone), GFP_KERNEL); if (!dz) return NULL; + memset(dz, 0, sizeof(struct dn_zone)); if (z) { dz->dz_divisor = 16; dz->dz_hashmask = 0x0F; @@ -194,12 +197,14 @@ static struct dn_zone *dn_new_zone(struct dn_hash *table, int z) dz->dz_hashmask = 0; } - dz->dz_hash = kcalloc(dz->dz_divisor, sizeof(struct dn_fib_node *), GFP_KERNEL); + dz->dz_hash = kmalloc(dz->dz_divisor*sizeof(struct dn_fib_node *), GFP_KERNEL); + if (!dz->dz_hash) { kfree(dz); return NULL; } + memset(dz->dz_hash, 0, dz->dz_divisor*sizeof(struct dn_fib_node*)); dz->dz_order = z; dz->dz_mask = dnet_make_mask(z); diff --git a/trunk/net/econet/af_econet.c b/trunk/net/econet/af_econet.c index 4d66aac13483..309ae4c6549a 100644 --- a/trunk/net/econet/af_econet.c +++ b/trunk/net/econet/af_econet.c @@ -673,11 +673,12 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) edev = dev->ec_ptr; if (edev == NULL) { /* Magic up a new one. */ - edev = kzalloc(sizeof(struct ec_device), GFP_KERNEL); + edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL); if (edev == NULL) { err = -ENOMEM; break; } + memset(edev, 0, sizeof(struct ec_device)); dev->ec_ptr = edev; } else net2dev_map[edev->net] = NULL; diff --git a/trunk/net/ieee80211/Kconfig b/trunk/net/ieee80211/Kconfig index f7e84e9d13ad..dbb08528ddf5 100644 --- a/trunk/net/ieee80211/Kconfig +++ b/trunk/net/ieee80211/Kconfig @@ -58,7 +58,6 @@ config IEEE80211_CRYPT_TKIP depends on IEEE80211 && NET_RADIO select CRYPTO select CRYPTO_MICHAEL_MIC - select CRC32 ---help--- Include software based cipher suites in support of IEEE 802.11i (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled diff --git a/trunk/net/ieee80211/ieee80211_crypt.c b/trunk/net/ieee80211/ieee80211_crypt.c index 5ed0a98b2d76..cb71d794a7d1 100644 --- a/trunk/net/ieee80211/ieee80211_crypt.c +++ b/trunk/net/ieee80211/ieee80211_crypt.c @@ -110,10 +110,11 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) unsigned long flags; struct ieee80211_crypto_alg *alg; - alg = kzalloc(sizeof(*alg), GFP_KERNEL); + alg = kmalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; + memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&ieee80211_crypto_lock, flags); diff --git a/trunk/net/ieee80211/ieee80211_crypt_ccmp.c b/trunk/net/ieee80211/ieee80211_crypt_ccmp.c index ed90a8af1444..492647382ad0 100644 --- a/trunk/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/trunk/net/ieee80211/ieee80211_crypt_ccmp.c @@ -76,9 +76,10 @@ static void *ieee80211_ccmp_init(int key_idx) { struct ieee80211_ccmp_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; + memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tfm = crypto_alloc_tfm("aes", 0); diff --git a/trunk/net/ieee80211/ieee80211_crypt_wep.c b/trunk/net/ieee80211/ieee80211_crypt_wep.c index 0ebf235f6939..c5a87724aabe 100644 --- a/trunk/net/ieee80211/ieee80211_crypt_wep.c +++ b/trunk/net/ieee80211/ieee80211_crypt_wep.c @@ -39,9 +39,10 @@ static void *prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; + memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tfm = crypto_alloc_tfm("arc4", 0); diff --git a/trunk/net/ieee80211/ieee80211_wx.c b/trunk/net/ieee80211/ieee80211_wx.c index 5cb9cfd35397..a78c4f845f66 100644 --- a/trunk/net/ieee80211/ieee80211_wx.c +++ b/trunk/net/ieee80211/ieee80211_wx.c @@ -369,10 +369,11 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee, struct ieee80211_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); if (new_crypt == NULL) return -ENOMEM; + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ieee80211_get_crypto_ops("WEP"); if (!new_crypt->ops) { request_module("ieee80211_crypt_wep"); @@ -615,11 +616,13 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee, ieee80211_crypt_delayed_deinit(ieee, crypt); - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = (struct ieee80211_crypt_data *) + kmalloc(sizeof(*new_crypt), GFP_KERNEL); if (new_crypt == NULL) { ret = -ENOMEM; goto done; } + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); new_crypt->ops = ops; if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) new_crypt->priv = new_crypt->ops->init(idx); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c index 4cef39e171d0..ebc33ca6e692 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_auth.c @@ -116,16 +116,6 @@ ieee80211softmac_auth_queue(void *data) kfree(auth); } -/* Sends a response to an auth challenge (for shared key auth). */ -static void -ieee80211softmac_auth_challenge_response(void *_aq) -{ - struct ieee80211softmac_auth_queue_item *aq = _aq; - - /* Send our response */ - ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); -} - /* Handle the auth response from the AP * This should be registered with ieee80211 as handle_auth */ @@ -207,30 +197,24 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth) case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE: /* Check to make sure we have a challenge IE */ data = (u8 *)auth->info_element; - if (*data++ != MFIE_TYPE_CHALLENGE) { + if(*data++ != MFIE_TYPE_CHALLENGE){ printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n"); break; } /* Save the challenge */ spin_lock_irqsave(&mac->lock, flags); net->challenge_len = *data++; - if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN) + if(net->challenge_len > WLAN_AUTH_CHALLENGE_LEN) net->challenge_len = WLAN_AUTH_CHALLENGE_LEN; - if (net->challenge != NULL) + if(net->challenge != NULL) kfree(net->challenge); net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC); memcpy(net->challenge, data, net->challenge_len); aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; - - /* We reuse the work struct from the auth request here. - * It is safe to do so as each one is per-request, and - * at this point (dealing with authentication response) - * we have obviously already sent the initial auth - * request. */ - cancel_delayed_work(&aq->work); - INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq); - schedule_work(&aq->work); spin_unlock_irqrestore(&mac->lock, flags); + + /* Send our response */ + ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); return 0; case IEEE80211SOFTMAC_AUTH_SHARED_PASS: kfree(net->challenge); diff --git a/trunk/net/ieee80211/softmac/ieee80211softmac_io.c b/trunk/net/ieee80211/softmac/ieee80211softmac_io.c index 6ae5a1dc7956..8cc8b20f5cda 100644 --- a/trunk/net/ieee80211/softmac/ieee80211softmac_io.c +++ b/trunk/net/ieee80211/softmac/ieee80211softmac_io.c @@ -96,7 +96,8 @@ ieee80211softmac_alloc_mgt(u32 size) if(size > IEEE80211_DATA_LEN) return NULL; /* Allocate the frame */ - data = kzalloc(size, GFP_ATOMIC); + data = kmalloc(size, GFP_ATOMIC); + memset(data, 0, size); return data; } diff --git a/trunk/net/ipv4/ah4.c b/trunk/net/ipv4/ah4.c index 1366bc6ce6a5..8e748be36c5a 100644 --- a/trunk/net/ipv4/ah4.c +++ b/trunk/net/ipv4/ah4.c @@ -215,10 +215,12 @@ static int ah_init_state(struct xfrm_state *x) if (x->encap) goto error; - ahp = kzalloc(sizeof(*ahp), GFP_KERNEL); + ahp = kmalloc(sizeof(*ahp), GFP_KERNEL); if (ahp == NULL) return -ENOMEM; + memset(ahp, 0, sizeof(*ahp)); + ahp->key = x->aalg->alg_key; ahp->key_len = (x->aalg->alg_key_len+7)/8; ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); diff --git a/trunk/net/ipv4/arp.c b/trunk/net/ipv4/arp.c index c8a3723bc001..7b51b3bdb548 100644 --- a/trunk/net/ipv4/arp.c +++ b/trunk/net/ipv4/arp.c @@ -1372,11 +1372,12 @@ static int arp_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct neigh_seq_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct neigh_seq_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; + memset(s, 0, sizeof(*s)); rc = seq_open(file, &arp_seq_ops); if (rc) goto out_kfree; diff --git a/trunk/net/ipv4/devinet.c b/trunk/net/ipv4/devinet.c index a6cc31d911eb..a7c65e9e5ec9 100644 --- a/trunk/net/ipv4/devinet.c +++ b/trunk/net/ipv4/devinet.c @@ -93,9 +93,10 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p); static struct in_ifaddr *inet_alloc_ifa(void) { - struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL); + struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL); if (ifa) { + memset(ifa, 0, sizeof(*ifa)); INIT_RCU_HEAD(&ifa->rcu_head); } @@ -139,9 +140,10 @@ struct in_device *inetdev_init(struct net_device *dev) ASSERT_RTNL(); - in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL); + in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL); if (!in_dev) goto out; + memset(in_dev, 0, sizeof(*in_dev)); INIT_RCU_HEAD(&in_dev->rcu_head); memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf)); in_dev->cnf.sysctl = NULL; diff --git a/trunk/net/ipv4/esp4.c b/trunk/net/ipv4/esp4.c index fc2f8ce441de..4e112738b3fa 100644 --- a/trunk/net/ipv4/esp4.c +++ b/trunk/net/ipv4/esp4.c @@ -316,10 +316,12 @@ static int esp_init_state(struct xfrm_state *x) if (x->ealg == NULL) goto error; - esp = kzalloc(sizeof(*esp), GFP_KERNEL); + esp = kmalloc(sizeof(*esp), GFP_KERNEL); if (esp == NULL) return -ENOMEM; + memset(esp, 0, sizeof(*esp)); + if (x->aalg) { struct xfrm_algo_desc *aalg_desc; diff --git a/trunk/net/ipv4/fib_hash.c b/trunk/net/ipv4/fib_hash.c index 72c633b357cf..3c1d32ad35f2 100644 --- a/trunk/net/ipv4/fib_hash.c +++ b/trunk/net/ipv4/fib_hash.c @@ -204,10 +204,11 @@ static struct fn_zone * fn_new_zone(struct fn_hash *table, int z) { int i; - struct fn_zone *fz = kzalloc(sizeof(struct fn_zone), GFP_KERNEL); + struct fn_zone *fz = kmalloc(sizeof(struct fn_zone), GFP_KERNEL); if (!fz) return NULL; + memset(fz, 0, sizeof(struct fn_zone)); if (z) { fz->fz_divisor = 16; } else { @@ -1045,7 +1046,7 @@ static int fib_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct fib_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct fib_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1056,6 +1057,7 @@ static int fib_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/trunk/net/ipv4/fib_rules.c b/trunk/net/ipv4/fib_rules.c index 79b04718bdfd..773b12ba4e3c 100644 --- a/trunk/net/ipv4/fib_rules.c +++ b/trunk/net/ipv4/fib_rules.c @@ -196,9 +196,10 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) } } - new_r = kzalloc(sizeof(*new_r), GFP_KERNEL); + new_r = kmalloc(sizeof(*new_r), GFP_KERNEL); if (!new_r) return -ENOMEM; + memset(new_r, 0, sizeof(*new_r)); if (rta[RTA_SRC-1]) memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 4); diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index 9be53a8e72c3..5f87533684d5 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -709,10 +709,11 @@ fib_create_info(const struct rtmsg *r, struct kern_rta *rta, goto failure; } - fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); + fi = kmalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); if (fi == NULL) goto failure; fib_info_cnt++; + memset(fi, 0, sizeof(*fi)+nhs*sizeof(struct fib_nh)); fi->fib_protocol = r->rtm_protocol; @@ -961,6 +962,10 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, rtm->rtm_protocol = fi->fib_protocol; if (fi->fib_priority) RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); +#ifdef CONFIG_NET_CLS_ROUTE + if (fi->fib_nh[0].nh_tclassid) + RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid); +#endif if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) goto rtattr_failure; if (fi->fib_prefsrc) @@ -970,10 +975,6 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, RTA_PUT(skb, RTA_GATEWAY, 4, &fi->fib_nh->nh_gw); if (fi->fib_nh->nh_oif) RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); -#ifdef CONFIG_NET_CLS_ROUTE - if (fi->fib_nh[0].nh_tclassid) - RTA_PUT(skb, RTA_FLOW, 4, &fi->fib_nh[0].nh_tclassid); -#endif } #ifdef CONFIG_IP_ROUTE_MULTIPATH if (fi->fib_nhs > 1) { @@ -992,10 +993,6 @@ fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, nhp->rtnh_ifindex = nh->nh_oif; if (nh->nh_gw) RTA_PUT(skb, RTA_GATEWAY, 4, &nh->nh_gw); -#ifdef CONFIG_NET_CLS_ROUTE - if (nh->nh_tclassid) - RTA_PUT(skb, RTA_FLOW, 4, &nh->nh_tclassid); -#endif nhp->rtnh_len = skb->tail - (unsigned char*)nhp; } endfor_nexthops(fi); mp_head->rta_type = RTA_MULTIPATH; diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 9f4b752f5a33..d299c8e547d6 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -1028,9 +1028,10 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im) * for deleted items allows change reports to use common code with * non-deleted or query-response MCA's. */ - pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); + pmc = kmalloc(sizeof(*pmc), GFP_KERNEL); if (!pmc) return; + memset(pmc, 0, sizeof(*pmc)); spin_lock_bh(&im->lock); pmc->interface = im->interface; in_dev_hold(in_dev); @@ -1528,9 +1529,10 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, psf_prev = psf; } if (!psf) { - psf = kzalloc(sizeof(*psf), GFP_ATOMIC); + psf = kmalloc(sizeof(*psf), GFP_ATOMIC); if (!psf) return -ENOBUFS; + memset(psf, 0, sizeof(*psf)); psf->sf_inaddr = *psfsrc; if (psf_prev) { psf_prev->sf_next = psf; @@ -2378,7 +2380,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct igmp_mc_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct igmp_mc_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -2388,6 +2390,7 @@ static int igmp_mc_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: @@ -2552,7 +2555,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct igmp_mcf_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct igmp_mcf_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -2562,6 +2565,7 @@ static int igmp_mcf_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/trunk/net/ipv4/inet_diag.c b/trunk/net/ipv4/inet_diag.c index 492858e6faf0..8e7e41b66c79 100644 --- a/trunk/net/ipv4/inet_diag.c +++ b/trunk/net/ipv4/inet_diag.c @@ -909,10 +909,11 @@ static int __init inet_diag_init(void) sizeof(struct inet_diag_handler *)); int err = -ENOMEM; - inet_diag_table = kzalloc(inet_diag_table_size, GFP_KERNEL); + inet_diag_table = kmalloc(inet_diag_table_size, GFP_KERNEL); if (!inet_diag_table) goto out; + memset(inet_diag_table, 0, inet_diag_table_size); idiagnl = netlink_kernel_create(NETLINK_INET_DIAG, 0, inet_diag_rcv, THIS_MODULE); if (idiagnl == NULL) diff --git a/trunk/net/ipv4/ip_gre.c b/trunk/net/ipv4/ip_gre.c index 0f9b3a31997b..6ff9b10d9563 100644 --- a/trunk/net/ipv4/ip_gre.c +++ b/trunk/net/ipv4/ip_gre.c @@ -617,6 +617,7 @@ static int ipgre_rcv(struct sk_buff *skb) skb->mac.raw = skb->nh.raw; skb->nh.raw = __pskb_pull(skb, offset); skb_postpull_rcsum(skb, skb->h.raw, offset); + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->pkt_type = PACKET_HOST; #ifdef CONFIG_NET_IPGRE_BROADCAST if (MULTICAST(iph->daddr)) { diff --git a/trunk/net/ipv4/ip_input.c b/trunk/net/ipv4/ip_input.c index 212734ca238f..184c78ca79e6 100644 --- a/trunk/net/ipv4/ip_input.c +++ b/trunk/net/ipv4/ip_input.c @@ -429,7 +429,7 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, } /* Remove any debris in the socket control block */ - memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish); diff --git a/trunk/net/ipv4/ip_options.c b/trunk/net/ipv4/ip_options.c index 406056edc02b..cbcae6544622 100644 --- a/trunk/net/ipv4/ip_options.c +++ b/trunk/net/ipv4/ip_options.c @@ -256,6 +256,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) if (!opt) { opt = &(IPCB(skb)->opt); + memset(opt, 0, sizeof(struct ip_options)); iph = skb->nh.raw; opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr); optptr = iph + sizeof(struct iphdr); diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 9bf307a29783..7c9f9a6421b8 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -526,8 +526,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) err = output(skb); - if (!err) - IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); if (err || !frag) break; @@ -651,6 +649,9 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) /* * Put this fragment into the sending queue. */ + + IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); + iph->tot_len = htons(len + hlen); ip_send_check(iph); @@ -658,8 +659,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) err = output(skb2); if (err) goto fail; - - IP_INC_STATS(IPSTATS_MIB_FRAGCREATES); } kfree_skb(skb); IP_INC_STATS(IPSTATS_MIB_FRAGOKS); diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index 2d05c4133d3e..84f43a3c9098 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -112,19 +112,14 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb) static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb) { char *secdata; - u32 seclen, secid; + u32 seclen; int err; - err = security_socket_getpeersec_dgram(NULL, skb, &secid); - if (err) - return; - - err = security_secid_to_secctx(secid, &secdata, &seclen); + err = security_socket_getpeersec_dgram(skb, &secdata, &seclen); if (err) return; put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata); - security_release_secctx(secdata, seclen); } diff --git a/trunk/net/ipv4/ipcomp.c b/trunk/net/ipv4/ipcomp.c index a0c28b2b756e..8a8b5cf2f7fe 100644 --- a/trunk/net/ipv4/ipcomp.c +++ b/trunk/net/ipv4/ipcomp.c @@ -410,10 +410,11 @@ static int ipcomp_init_state(struct xfrm_state *x) goto out; err = -ENOMEM; - ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); + ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL); if (!ipcd) goto out; + memset(ipcd, 0, sizeof(*ipcd)); x->props.header_len = 0; if (x->props.mode) x->props.header_len += sizeof(struct iphdr); diff --git a/trunk/net/ipv4/ipip.c b/trunk/net/ipv4/ipip.c index 76ab50b0d6ef..3291d5192aad 100644 --- a/trunk/net/ipv4/ipip.c +++ b/trunk/net/ipv4/ipip.c @@ -487,6 +487,7 @@ static int ipip_rcv(struct sk_buff *skb) skb->mac.raw = skb->nh.raw; skb->nh.raw = skb->data; + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->pkt_type = PACKET_HOST; diff --git a/trunk/net/ipv4/ipmr.c b/trunk/net/ipv4/ipmr.c index 85893eef6b16..ba33f8621c67 100644 --- a/trunk/net/ipv4/ipmr.c +++ b/trunk/net/ipv4/ipmr.c @@ -1461,6 +1461,7 @@ int pim_rcv_v1(struct sk_buff * skb) skb_pull(skb, (u8*)encap - skb->data); skb->nh.iph = (struct iphdr *)skb->data; skb->dev = reg_dev; + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; @@ -1516,6 +1517,7 @@ static int pim_rcv(struct sk_buff * skb) skb_pull(skb, (u8*)encap - skb->data); skb->nh.iph = (struct iphdr *)skb->data; skb->dev = reg_dev; + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); skb->protocol = htons(ETH_P_IP); skb->ip_summed = 0; skb->pkt_type = PACKET_HOST; @@ -1578,7 +1580,6 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) cache = ipmr_cache_find(rt->rt_src, rt->rt_dst); if (cache==NULL) { - struct sk_buff *skb2; struct net_device *dev; int vif; @@ -1592,18 +1593,12 @@ int ipmr_get_route(struct sk_buff *skb, struct rtmsg *rtm, int nowait) read_unlock(&mrt_lock); return -ENODEV; } - skb2 = skb_clone(skb, GFP_ATOMIC); - if (!skb2) { - read_unlock(&mrt_lock); - return -ENOMEM; - } - - skb2->nh.raw = skb_push(skb2, sizeof(struct iphdr)); - skb2->nh.iph->ihl = sizeof(struct iphdr)>>2; - skb2->nh.iph->saddr = rt->rt_src; - skb2->nh.iph->daddr = rt->rt_dst; - skb2->nh.iph->version = 0; - err = ipmr_cache_unresolved(vif, skb2); + skb->nh.raw = skb_push(skb, sizeof(struct iphdr)); + skb->nh.iph->ihl = sizeof(struct iphdr)>>2; + skb->nh.iph->saddr = rt->rt_src; + skb->nh.iph->daddr = rt->rt_dst; + skb->nh.iph->version = 0; + err = ipmr_cache_unresolved(vif, skb); read_unlock(&mrt_lock); return err; } diff --git a/trunk/net/ipv4/ipvs/ip_vs_ctl.c b/trunk/net/ipv4/ipvs/ip_vs_ctl.c index 6a28fafe910c..f28ec6882162 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_ctl.c +++ b/trunk/net/ipv4/ipvs/ip_vs_ctl.c @@ -735,11 +735,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, if (atype != RTN_LOCAL && atype != RTN_UNICAST) return -EINVAL; - dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); + dest = kmalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); if (dest == NULL) { IP_VS_ERR("ip_vs_new_dest: kmalloc failed.\n"); return -ENOMEM; } + memset(dest, 0, sizeof(struct ip_vs_dest)); dest->protocol = svc->protocol; dest->vaddr = svc->addr; @@ -1049,12 +1050,14 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) goto out_mod_dec; } - svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); + svc = (struct ip_vs_service *) + kmalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); if (svc == NULL) { IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n"); ret = -ENOMEM; goto out_err; } + memset(svc, 0, sizeof(struct ip_vs_service)); /* I'm the first user of the service */ atomic_set(&svc->usecnt, 1); @@ -1794,7 +1797,7 @@ static int ip_vs_info_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct ip_vs_iter *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct ip_vs_iter *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1805,6 +1808,7 @@ static int ip_vs_info_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/trunk/net/ipv4/ipvs/ip_vs_est.c b/trunk/net/ipv4/ipvs/ip_vs_est.c index 7d68b80c4c19..4c1940381ba0 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_est.c +++ b/trunk/net/ipv4/ipvs/ip_vs_est.c @@ -123,10 +123,11 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats) { struct ip_vs_estimator *est; - est = kzalloc(sizeof(*est), GFP_KERNEL); + est = kmalloc(sizeof(*est), GFP_KERNEL); if (est == NULL) return -ENOMEM; + memset(est, 0, sizeof(*est)); est->stats = stats; est->last_conns = stats->conns; est->cps = stats->cps<<10; diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c index 9a39e2969712..af35235672d5 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_helper_h323.c @@ -1200,7 +1200,7 @@ static struct ip_conntrack_expect *find_expect(struct ip_conntrack *ct, tuple.dst.protonum = IPPROTO_TCP; exp = __ip_conntrack_expect_find(&tuple); - if (exp && exp->master == ct) + if (exp->master == ct) return exp; return NULL; } diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_sip.c b/trunk/net/ipv4/netfilter/ip_conntrack_sip.c index 4f222d6be009..fc87ce0da40d 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_sip.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_sip.c @@ -442,7 +442,7 @@ static int __init init(void) sip[i].tuple.src.u.udp.port = htons(ports[i]); sip[i].mask.src.u.udp.port = 0xFFFF; sip[i].mask.dst.protonum = 0xFF; - sip[i].max_expected = 2; + sip[i].max_expected = 1; sip[i].timeout = 3 * 60; /* 3 minutes */ sip[i].me = THIS_MODULE; sip[i].help = sip_help; diff --git a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c index 7a9fa04a467a..7bd3c22003a2 100644 --- a/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/trunk/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -534,8 +534,6 @@ static struct nf_hook_ops ip_conntrack_ops[] = { /* Sysctl support */ -int ip_conntrack_checksum = 1; - #ifdef CONFIG_SYSCTL /* From ip_conntrack_core.c */ @@ -570,6 +568,8 @@ extern unsigned int ip_ct_generic_timeout; static int log_invalid_proto_min = 0; static int log_invalid_proto_max = 255; +int ip_conntrack_checksum = 1; + static struct ctl_table_header *ip_ct_sysctl_header; static ctl_table ip_ct_sysctl_table[] = { diff --git a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c index 18b7fbdccb61..0b1b416759cc 100644 --- a/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/trunk/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1255,9 +1255,9 @@ static int help(struct sk_buff **pskb, struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl); /* SNMP replies and originating SNMP traps get mangled */ - if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY) + if (udph->source == ntohs(SNMP_PORT) && dir != IP_CT_DIR_REPLY) return NF_ACCEPT; - if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) + if (udph->dest == ntohs(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL) return NF_ACCEPT; /* No NAT? */ diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c index d994c5f5744c..cbffeae3f565 100644 --- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -172,10 +172,11 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, u_int32_t ip, struct clusterip_config *c; char buffer[16]; - c = kzalloc(sizeof(*c), GFP_ATOMIC); + c = kmalloc(sizeof(*c), GFP_ATOMIC); if (!c) return NULL; + memset(c, 0, sizeof(*c)); c->dev = dev; c->clusterip = ip; memcpy(&c->clustermac, &i->clustermac, ETH_ALEN); diff --git a/trunk/net/ipv4/netfilter/ipt_hashlimit.c b/trunk/net/ipv4/netfilter/ipt_hashlimit.c index 6b662449e825..92980ab8ce48 100644 --- a/trunk/net/ipv4/netfilter/ipt_hashlimit.c +++ b/trunk/net/ipv4/netfilter/ipt_hashlimit.c @@ -508,9 +508,6 @@ hashlimit_checkentry(const char *tablename, if (!r->cfg.expire) return 0; - if (r->name[sizeof(r->name) - 1] != '\0') - return 0; - /* This is the best we've got: We cannot release and re-grab lock, * since checkentry() is called before ip_tables.c grabs ipt_mutex. * We also cannot grab the hashtable spinlock, since htable_create will diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 62b2762a2420..bd221ec3f81e 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -609,7 +609,6 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if (sin) { sin->sin_family = AF_INET; sin->sin_addr.s_addr = skb->nh.iph->saddr; - sin->sin_port = 0; memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); } if (inet->cmsg_flags) diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 19bd49d69d9f..2dc6dbb28467 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -104,7 +104,6 @@ #include #include #include -#include #ifdef CONFIG_SYSCTL #include #endif @@ -1126,7 +1125,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, struct rtable *rth, **rthp; u32 skeys[2] = { saddr, 0 }; int ikeys[2] = { dev->ifindex, 0 }; - struct netevent_redirect netevent; if (!in_dev) return; @@ -1218,11 +1216,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, rt_drop(rt); goto do_next; } - - netevent.old = &rth->u.dst; - netevent.new = &rt->u.dst; - call_netevent_notifiers(NETEVENT_REDIRECT, - &netevent); rt_del(hash, rth); if (!rt_intern_hash(hash, rt, &rt)) @@ -1459,7 +1452,6 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) } dst->metrics[RTAX_MTU-1] = mtu; dst_set_expires(dst, ip_rt_mtu_expires); - call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } } diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 934396bb1376..f6a2d9223d07 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -1132,7 +1132,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, tp->ucopy.dma_chan = NULL; preempt_disable(); if ((len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) && - !sysctl_tcp_low_latency && __get_cpu_var(softnet_data).net_dma) { + !sysctl_tcp_low_latency && __get_cpu_var(softnet_data.net_dma)) { preempt_enable_no_resched(); tp->ucopy.pinned_list = dma_pin_iovec_pages(msg->msg_iov, len); } else @@ -1659,8 +1659,7 @@ void tcp_close(struct sock *sk, long timeout) const int tmo = tcp_fin_time(sk); if (tmo > TCP_TIMEWAIT_LEN) { - inet_csk_reset_keepalive_timer(sk, - tmo - TCP_TIMEWAIT_LEN); + inet_csk_reset_keepalive_timer(sk, tcp_fin_time(sk)); } else { tcp_time_wait(sk, TCP_FIN_WAIT2, tmo); goto out; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 104af5d5bcbc..738dad9f7d49 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -3541,8 +3541,7 @@ void tcp_cwnd_application_limited(struct sock *sk) if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open && sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { /* Limited by application or receiver window. */ - u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk)); - u32 win_used = max(tp->snd_cwnd_used, init_win); + u32 win_used = max(tp->snd_cwnd_used, 2U); if (win_used < tp->snd_cwnd) { tp->snd_ssthresh = tcp_current_ssthresh(sk); tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1; diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 4b04c3edd4a9..a891133f00e4 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -438,6 +438,7 @@ void tcp_v4_err(struct sk_buff *skb, u32 info) It can f.e. if SYNs crossed. */ if (!sock_owned_by_user(sk)) { + TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); sk->sk_err = err; sk->sk_error_report(sk); @@ -873,6 +874,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) drop_and_free: reqsk_free(req); drop: + TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); return 0; } @@ -1638,9 +1640,10 @@ static int tcp_seq_open(struct inode *inode, struct file *file) if (unlikely(afinfo == NULL)) return -EINVAL; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) return -ENOMEM; + memset(s, 0, sizeof(*s)); s->family = afinfo->family; s->seq_ops.start = tcp_seq_start; s->seq_ops.next = tcp_seq_next; diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index 624e2b2c7f53..0ccb7cb22b15 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -589,10 +589,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, /* RFC793: "second check the RST bit" and * "fourth, check the SYN bit" */ - if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) { - TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); + if (flg & (TCP_FLAG_RST|TCP_FLAG_SYN)) goto embryonic_reset; - } /* ACK sequence verified above, just make sure ACK is * set. If ACK not set, just silently drop the packet. diff --git a/trunk/net/ipv4/tcp_probe.c b/trunk/net/ipv4/tcp_probe.c index b3435324b573..d7d517a3a238 100644 --- a/trunk/net/ipv4/tcp_probe.c +++ b/trunk/net/ipv4/tcp_probe.c @@ -114,7 +114,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file) static ssize_t tcpprobe_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) { - int error = 0, cnt = 0; + int error = 0, cnt; unsigned char *tbuf; if (!buf || len < 0) diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index f136cec96d95..9bfcddad695b 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -1468,10 +1468,11 @@ static int udp_seq_open(struct inode *inode, struct file *file) struct udp_seq_afinfo *afinfo = PDE(inode)->data; struct seq_file *seq; int rc = -ENOMEM; - struct udp_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; + memset(s, 0, sizeof(*s)); s->family = afinfo->family; s->seq_ops.start = udp_seq_start; s->seq_ops.next = udp_seq_next; diff --git a/trunk/net/ipv4/xfrm4_mode_tunnel.c b/trunk/net/ipv4/xfrm4_mode_tunnel.c index 13cafbe56ce3..f8d880beb12f 100644 --- a/trunk/net/ipv4/xfrm4_mode_tunnel.c +++ b/trunk/net/ipv4/xfrm4_mode_tunnel.c @@ -92,6 +92,7 @@ static int xfrm4_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) skb->mac.raw = memmove(skb->data - skb->mac_len, skb->mac.raw, skb->mac_len); skb->nh.raw = skb->data; + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); err = 0; out: diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 8ea1e36bf8eb..2316a4315a18 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -1869,21 +1869,15 @@ int addrconf_set_dstaddr(void __user *arg) /* * Manual configuration of address on an interface */ -static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, - __u32 prefered_lft, __u32 valid_lft) +static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen) { struct inet6_ifaddr *ifp; struct inet6_dev *idev; struct net_device *dev; - __u8 ifa_flags = 0; int scope; ASSERT_RTNL(); - /* check the lifetime */ - if (!valid_lft || prefered_lft > valid_lft) - return -EINVAL; - if ((dev = __dev_get_by_index(ifindex)) == NULL) return -ENODEV; @@ -1895,29 +1889,10 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, scope = ipv6_addr_scope(pfx); - if (valid_lft == INFINITY_LIFE_TIME) - ifa_flags |= IFA_F_PERMANENT; - else if (valid_lft >= 0x7FFFFFFF/HZ) - valid_lft = 0x7FFFFFFF/HZ; - - if (prefered_lft == 0) - ifa_flags |= IFA_F_DEPRECATED; - else if ((prefered_lft >= 0x7FFFFFFF/HZ) && - (prefered_lft != INFINITY_LIFE_TIME)) - prefered_lft = 0x7FFFFFFF/HZ; - - ifp = ipv6_add_addr(idev, pfx, plen, scope, ifa_flags); - + ifp = ipv6_add_addr(idev, pfx, plen, scope, IFA_F_PERMANENT); if (!IS_ERR(ifp)) { - spin_lock(&ifp->lock); - ifp->valid_lft = valid_lft; - ifp->prefered_lft = prefered_lft; - ifp->tstamp = jiffies; - spin_unlock(&ifp->lock); - addrconf_dad_start(ifp, 0); in6_ifa_put(ifp); - addrconf_verify(0); return 0; } @@ -1970,8 +1945,7 @@ int addrconf_add_ifaddr(void __user *arg) return -EFAULT; rtnl_lock(); - err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, - INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); + err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); rtnl_unlock(); return err; } @@ -2797,16 +2771,12 @@ static void addrconf_verify(unsigned long foo) ifp->idev->nd_parms->retrans_time / HZ; #endif - if (ifp->valid_lft != INFINITY_LIFE_TIME && - age >= ifp->valid_lft) { + if (age >= ifp->valid_lft) { spin_unlock(&ifp->lock); in6_ifa_hold(ifp); read_unlock(&addrconf_hash_lock); ipv6_del_addr(ifp); goto restart; - } else if (ifp->prefered_lft == INFINITY_LIFE_TIME) { - spin_unlock(&ifp->lock); - continue; } else if (age >= ifp->prefered_lft) { /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ int deprecate = 0; @@ -2883,8 +2853,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) pfx = RTA_DATA(rta[IFA_ADDRESS-1]); } if (rta[IFA_LOCAL-1]) { - if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || - (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) + if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))) return -EINVAL; pfx = RTA_DATA(rta[IFA_LOCAL-1]); } @@ -2894,62 +2863,12 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); } -static int -inet6_addr_modify(int ifindex, struct in6_addr *pfx, - __u32 prefered_lft, __u32 valid_lft) -{ - struct inet6_ifaddr *ifp = NULL; - struct net_device *dev; - int ifa_flags = 0; - - if ((dev = __dev_get_by_index(ifindex)) == NULL) - return -ENODEV; - - if (!(dev->flags&IFF_UP)) - return -ENETDOWN; - - if (!valid_lft || (prefered_lft > valid_lft)) - return -EINVAL; - - ifp = ipv6_get_ifaddr(pfx, dev, 1); - if (ifp == NULL) - return -ENOENT; - - if (valid_lft == INFINITY_LIFE_TIME) - ifa_flags = IFA_F_PERMANENT; - else if (valid_lft >= 0x7FFFFFFF/HZ) - valid_lft = 0x7FFFFFFF/HZ; - - if (prefered_lft == 0) - ifa_flags = IFA_F_DEPRECATED; - else if ((prefered_lft >= 0x7FFFFFFF/HZ) && - (prefered_lft != INFINITY_LIFE_TIME)) - prefered_lft = 0x7FFFFFFF/HZ; - - spin_lock_bh(&ifp->lock); - ifp->flags = (ifp->flags & ~(IFA_F_DEPRECATED|IFA_F_PERMANENT)) | ifa_flags; - - ifp->tstamp = jiffies; - ifp->valid_lft = valid_lft; - ifp->prefered_lft = prefered_lft; - - spin_unlock_bh(&ifp->lock); - if (!(ifp->flags&IFA_F_TENTATIVE)) - ipv6_ifa_notify(0, ifp); - in6_ifa_put(ifp); - - addrconf_verify(0); - - return 0; -} - static int inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct rtattr **rta = arg; struct ifaddrmsg *ifm = NLMSG_DATA(nlh); struct in6_addr *pfx; - __u32 valid_lft = INFINITY_LIFE_TIME, prefered_lft = INFINITY_LIFE_TIME; pfx = NULL; if (rta[IFA_ADDRESS-1]) { @@ -2958,34 +2877,14 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) pfx = RTA_DATA(rta[IFA_ADDRESS-1]); } if (rta[IFA_LOCAL-1]) { - if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*pfx) || - (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))) + if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx))) return -EINVAL; pfx = RTA_DATA(rta[IFA_LOCAL-1]); } if (pfx == NULL) return -EINVAL; - if (rta[IFA_CACHEINFO-1]) { - struct ifa_cacheinfo *ci; - if (RTA_PAYLOAD(rta[IFA_CACHEINFO-1]) < sizeof(*ci)) - return -EINVAL; - ci = RTA_DATA(rta[IFA_CACHEINFO-1]); - valid_lft = ci->ifa_valid; - prefered_lft = ci->ifa_prefered; - } - - if (nlh->nlmsg_flags & NLM_F_REPLACE) { - int ret; - ret = inet6_addr_modify(ifm->ifa_index, pfx, - prefered_lft, valid_lft); - if (ret == 0 || !(nlh->nlmsg_flags & NLM_F_CREATE)) - return ret; - } - - return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, - prefered_lft, valid_lft); - + return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen); } /* Maximum length of ifa_cacheinfo attributes */ @@ -3222,62 +3121,6 @@ static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb) return inet6_dump_addr(skb, cb, type); } -static int inet6_rtm_getaddr(struct sk_buff *in_skb, - struct nlmsghdr* nlh, void *arg) -{ - struct rtattr **rta = arg; - struct ifaddrmsg *ifm = NLMSG_DATA(nlh); - struct in6_addr *addr = NULL; - struct net_device *dev = NULL; - struct inet6_ifaddr *ifa; - struct sk_buff *skb; - int size = NLMSG_SPACE(sizeof(struct ifaddrmsg) + INET6_IFADDR_RTA_SPACE); - int err; - - if (rta[IFA_ADDRESS-1]) { - if (RTA_PAYLOAD(rta[IFA_ADDRESS-1]) < sizeof(*addr)) - return -EINVAL; - addr = RTA_DATA(rta[IFA_ADDRESS-1]); - } - if (rta[IFA_LOCAL-1]) { - if (RTA_PAYLOAD(rta[IFA_LOCAL-1]) < sizeof(*addr) || - (addr && memcmp(addr, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*addr)))) - return -EINVAL; - addr = RTA_DATA(rta[IFA_LOCAL-1]); - } - if (addr == NULL) - return -EINVAL; - - if (ifm->ifa_index) - dev = __dev_get_by_index(ifm->ifa_index); - - if ((ifa = ipv6_get_ifaddr(addr, dev, 1)) == NULL) - return -EADDRNOTAVAIL; - - if ((skb = alloc_skb(size, GFP_KERNEL)) == NULL) { - err = -ENOBUFS; - goto out; - } - - NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; - err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, - nlh->nlmsg_seq, RTM_NEWADDR, 0); - if (err < 0) { - err = -EMSGSIZE; - goto out_free; - } - - err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); - if (err > 0) - err = 0; -out: - in6_ifa_put(ifa); - return err; -out_free: - kfree_skb(skb); - goto out; -} - static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa) { struct sk_buff *skb; @@ -3520,8 +3363,7 @@ static struct rtnetlink_link inet6_rtnetlink_table[RTM_NR_MSGTYPES] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, [RTM_DELADDR - RTM_BASE] = { .doit = inet6_rtm_deladdr, }, - [RTM_GETADDR - RTM_BASE] = { .doit = inet6_rtm_getaddr, - .dumpit = inet6_dump_ifaddr, }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = inet6_dump_ifaddr, }, [RTM_GETMULTICAST - RTM_BASE] = { .dumpit = inet6_dump_ifmcaddr, }, [RTM_GETANYCAST - RTM_BASE] = { .dumpit = inet6_dump_ifacaddr, }, [RTM_NEWROUTE - RTM_BASE] = { .doit = inet6_rtm_newroute, }, diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index ac85e9c532c2..5a0ba58b86cc 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -658,7 +658,7 @@ int inet6_sk_rebuild_header(struct sock *sk) return err; } - __ip6_dst_store(sk, dst, NULL); + ip6_dst_store(sk, dst, NULL); } return 0; diff --git a/trunk/net/ipv6/inet6_connection_sock.c b/trunk/net/ipv6/inet6_connection_sock.c index bf491077b822..5c950cc79d80 100644 --- a/trunk/net/ipv6/inet6_connection_sock.c +++ b/trunk/net/ipv6/inet6_connection_sock.c @@ -185,7 +185,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) return err; } - __ip6_dst_store(sk, dst, NULL); + ip6_dst_store(sk, dst, NULL); } skb->dst = dst_clone(dst); diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 25c2a9e03895..df8f051c0fce 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -71,8 +71,6 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt goto out; } - memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); - /* * Store incoming device index. When the packet will * be queued, we cannot refer to skb->dev anymore. diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 69451af6abe7..3bc74ce78800 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -356,7 +356,6 @@ int ip6_forward(struct sk_buff *skb) skb->dev = dst->dev; icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0, skb->dev); - IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); kfree_skb(skb); return -ETIMEDOUT; @@ -596,9 +595,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) } err = output(skb); - if(!err) - IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); - if (err || !frag) break; @@ -710,11 +706,12 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) /* * Put this fragment into the sending queue. */ + + IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); + err = output(frag); if (err) goto fail; - - IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); } kfree_skb(skb); IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); @@ -726,51 +723,48 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) return err; } -static struct dst_entry *ip6_sk_dst_check(struct sock *sk, - struct dst_entry *dst, - struct flowi *fl) +int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) { - struct ipv6_pinfo *np = inet6_sk(sk); - struct rt6_info *rt = (struct rt6_info *)dst; - - if (!dst) - goto out; + int err = 0; - /* Yes, checking route validity in not connected - * case is not very simple. Take into account, - * that we do not support routing by source, TOS, - * and MSG_DONTROUTE --ANK (980726) - * - * 1. If route was host route, check that - * cached destination is current. - * If it is network route, we still may - * check its validity using saved pointer - * to the last used address: daddr_cache. - * We do not want to save whole address now, - * (because main consumer of this service - * is tcp, which has not this problem), - * so that the last trick works only on connected - * sockets. - * 2. oif also should be the same. - */ - if (((rt->rt6i_dst.plen != 128 || - !ipv6_addr_equal(&fl->fl6_dst, &rt->rt6i_dst.addr)) - && (np->daddr_cache == NULL || - !ipv6_addr_equal(&fl->fl6_dst, np->daddr_cache))) - || (fl->oif && fl->oif != dst->dev->ifindex)) { - dst_release(dst); - dst = NULL; + *dst = NULL; + if (sk) { + struct ipv6_pinfo *np = inet6_sk(sk); + + *dst = sk_dst_check(sk, np->dst_cookie); + if (*dst) { + struct rt6_info *rt = (struct rt6_info*)*dst; + + /* Yes, checking route validity in not connected + * case is not very simple. Take into account, + * that we do not support routing by source, TOS, + * and MSG_DONTROUTE --ANK (980726) + * + * 1. If route was host route, check that + * cached destination is current. + * If it is network route, we still may + * check its validity using saved pointer + * to the last used address: daddr_cache. + * We do not want to save whole address now, + * (because main consumer of this service + * is tcp, which has not this problem), + * so that the last trick works only on connected + * sockets. + * 2. oif also should be the same. + */ + if (((rt->rt6i_dst.plen != 128 || + !ipv6_addr_equal(&fl->fl6_dst, + &rt->rt6i_dst.addr)) + && (np->daddr_cache == NULL || + !ipv6_addr_equal(&fl->fl6_dst, + np->daddr_cache))) + || (fl->oif && fl->oif != (*dst)->dev->ifindex)) { + dst_release(*dst); + *dst = NULL; + } + } } -out: - return dst; -} - -static int ip6_dst_lookup_tail(struct sock *sk, - struct dst_entry **dst, struct flowi *fl) -{ - int err; - if (*dst == NULL) *dst = ip6_route_output(sk, fl); @@ -779,6 +773,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, if (ipv6_addr_any(&fl->fl6_src)) { err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); + if (err) goto out_err_release; } @@ -791,48 +786,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, return err; } -/** - * ip6_dst_lookup - perform route lookup on flow - * @sk: socket which provides route info - * @dst: pointer to dst_entry * for result - * @fl: flow to lookup - * - * This function performs a route lookup on the given flow. - * - * It returns zero on success, or a standard errno code on error. - */ -int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) -{ - *dst = NULL; - return ip6_dst_lookup_tail(sk, dst, fl); -} EXPORT_SYMBOL_GPL(ip6_dst_lookup); -/** - * ip6_sk_dst_lookup - perform socket cached route lookup on flow - * @sk: socket which provides the dst cache and route info - * @dst: pointer to dst_entry * for result - * @fl: flow to lookup - * - * This function performs a route lookup on the given flow with the - * possibility of using the cached route in the socket if it is valid. - * It will take the socket dst lock when operating on the dst cache. - * As a result, this function can only be used in process context. - * - * It returns zero on success, or a standard errno code on error. - */ -int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) -{ - *dst = NULL; - if (sk) { - *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); - *dst = ip6_sk_dst_check(sk, *dst, fl); - } - - return ip6_dst_lookup_tail(sk, dst, fl); -} -EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup); - static inline int ip6_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), diff --git a/trunk/net/ipv6/ip6_tunnel.c b/trunk/net/ipv6/ip6_tunnel.c index 84d7ebdb9d21..bc77c0e1a943 100644 --- a/trunk/net/ipv6/ip6_tunnel.c +++ b/trunk/net/ipv6/ip6_tunnel.c @@ -567,9 +567,10 @@ static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) int opt_len = sizeof(*opt) + 8; - if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) { + if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) { return NULL; } + memset(opt, 0, opt_len); opt->tot_len = opt_len; opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1); opt->opt_nflen = 8; diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index d57e61ce4a7d..fa1ce0ae123e 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -411,7 +411,6 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk, /* Copy the address. */ if (sin6) { sin6->sin6_family = AF_INET6; - sin6->sin6_port = 0; ipv6_addr_copy(&sin6->sin6_addr, &skb->nh.ipv6h->saddr); sin6->sin6_flowinfo = 0; sin6->sin6_scope_id = 0; diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 4b163711f3a8..87c39c978cd0 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -53,7 +53,6 @@ #include #include #include -#include #include @@ -743,7 +742,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu) dst->metrics[RTAX_FEATURES-1] |= RTAX_FEATURE_ALLFRAG; } dst->metrics[RTAX_MTU-1] = mtu; - call_netevent_notifiers(NETEVENT_PMTU_UPDATE, dst); } } @@ -1157,7 +1155,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, struct rt6_info *rt, *nrt = NULL; int strict; struct fib6_node *fn; - struct netevent_redirect netevent; /* * Get the "current" route for this destination and @@ -1255,10 +1252,6 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, if (ip6_ins_rt(nrt, NULL, NULL, NULL)) goto out; - netevent.old = &rt->u.dst; - netevent.new = &nrt->u.dst; - call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); - if (rt->rt6i_flags&RTF_CACHE) { ip6_del_rt(rt, NULL, NULL, NULL); return; diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index 836eecd7e62b..c56aeece2bf5 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -380,6 +380,7 @@ static int ipip6_rcv(struct sk_buff *skb) secpath_reset(skb); skb->mac.raw = skb->nh.raw; skb->nh.raw = skb->data; + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); IPCB(skb)->flags = 0; skb->protocol = htons(ETH_P_IPV6); skb->pkt_type = PACKET_HOST; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index b843a650be71..923989d0520d 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -270,7 +270,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, inet->rcv_saddr = LOOPBACK4_IPV6; sk->sk_gso_type = SKB_GSO_TCPV6; - __ip6_dst_store(sk, dst, NULL); + ip6_dst_store(sk, dst, NULL); icsk->icsk_ext_hdr_len = 0; if (np->opt) @@ -427,6 +427,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, case TCP_SYN_RECV: /* Cannot happen. It can, it SYNs are crossed. --ANK */ if (!sock_owned_by_user(sk)) { + TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); sk->sk_err = err; sk->sk_error_report(sk); /* Wake people up to see the error (see connect in sock.c) */ @@ -830,6 +831,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) if (req) reqsk_free(req); + TCP_INC_STATS_BH(TCP_MIB_ATTEMPTFAILS); return 0; /* don't send reset */ } @@ -945,7 +947,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, */ sk->sk_gso_type = SKB_GSO_TCPV6; - __ip6_dst_store(newsk, dst, NULL); + ip6_dst_store(newsk, dst, NULL); newtcp6sk = (struct tcp6_sock *)newsk; inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index 3d54f246411e..ccc57f434cd3 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -782,7 +782,7 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, connected = 0; } - err = ip6_sk_dst_lookup(sk, &dst, fl); + err = ip6_dst_lookup(sk, &dst, fl); if (err) goto out; if (final_p) diff --git a/trunk/net/ipv6/xfrm6_output.c b/trunk/net/ipv6/xfrm6_output.c index c8c8b44a0f58..0eea60ea9ebc 100644 --- a/trunk/net/ipv6/xfrm6_output.c +++ b/trunk/net/ipv6/xfrm6_output.c @@ -125,7 +125,7 @@ static int xfrm6_output_finish(struct sk_buff *skb) if (!skb_is_gso(skb)) return xfrm6_output_finish2(skb); - skb->protocol = htons(ETH_P_IPV6); + skb->protocol = htons(ETH_P_IP); segs = skb_gso_segment(skb, 0); kfree_skb(skb); if (unlikely(IS_ERR(segs))) diff --git a/trunk/net/ipv6/xfrm6_tunnel.c b/trunk/net/ipv6/xfrm6_tunnel.c index c8f9369c2a87..6b44fe8516c3 100644 --- a/trunk/net/ipv6/xfrm6_tunnel.c +++ b/trunk/net/ipv6/xfrm6_tunnel.c @@ -31,6 +31,27 @@ #include #include +#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG +# define X6TDEBUG 3 +#else +# define X6TDEBUG 1 +#endif + +#define X6TPRINTK(fmt, args...) printk(fmt, ## args) +#define X6TNOPRINTK(fmt, args...) do { ; } while(0) + +#if X6TDEBUG >= 1 +# define X6TPRINTK1 X6TPRINTK +#else +# define X6TPRINTK1 X6TNOPRINTK +#endif + +#if X6TDEBUG >= 3 +# define X6TPRINTK3 X6TPRINTK +#else +# define X6TPRINTK3 X6TNOPRINTK +#endif + /* * xfrm_tunnel_spi things are for allocating unique id ("spi") * per xfrm_address_t. @@ -41,8 +62,15 @@ struct xfrm6_tunnel_spi { xfrm_address_t addr; u32 spi; atomic_t refcnt; +#ifdef XFRM6_TUNNEL_SPI_MAGIC + u32 magic; +#endif }; +#ifdef CONFIG_IPV6_XFRM6_TUNNEL_DEBUG +# define XFRM6_TUNNEL_SPI_MAGIC 0xdeadbeef +#endif + static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock); static u32 xfrm6_tunnel_spi; @@ -58,15 +86,43 @@ static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly; static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE]; static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE]; +#ifdef XFRM6_TUNNEL_SPI_MAGIC +static int x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi, + const char *name) +{ + if (unlikely(x6spi->magic != XFRM6_TUNNEL_SPI_MAGIC)) { + X6TPRINTK3(KERN_DEBUG "%s(): x6spi object " + "at %p has corrupted magic %08x " + "(should be %08x)\n", + name, x6spi, x6spi->magic, XFRM6_TUNNEL_SPI_MAGIC); + return -1; + } + return 0; +} +#else +static int inline x6spi_check_magic(const struct xfrm6_tunnel_spi *x6spi, + const char *name) +{ + return 0; +} +#endif + +#define X6SPI_CHECK_MAGIC(x6spi) x6spi_check_magic((x6spi), __FUNCTION__) + + static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) { unsigned h; + X6TPRINTK3(KERN_DEBUG "%s(addr=%p)\n", __FUNCTION__, addr); + h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]; h ^= h >> 16; h ^= h >> 8; h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1; + X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, h); + return h; } @@ -80,13 +136,19 @@ static int xfrm6_tunnel_spi_init(void) { int i; + X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); + xfrm6_tunnel_spi = 0; xfrm6_tunnel_spi_kmem = kmem_cache_create("xfrm6_tunnel_spi", sizeof(struct xfrm6_tunnel_spi), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if (!xfrm6_tunnel_spi_kmem) + if (!xfrm6_tunnel_spi_kmem) { + X6TPRINTK1(KERN_ERR + "%s(): failed to allocate xfrm6_tunnel_spi_kmem\n", + __FUNCTION__); return -ENOMEM; + } for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) INIT_HLIST_HEAD(&xfrm6_tunnel_spi_byaddr[i]); @@ -99,16 +161,22 @@ static void xfrm6_tunnel_spi_fini(void) { int i; + X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); + for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) { if (!hlist_empty(&xfrm6_tunnel_spi_byaddr[i])) - return; + goto err; } for (i = 0; i < XFRM6_TUNNEL_SPI_BYSPI_HSIZE; i++) { if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i])) - return; + goto err; } kmem_cache_destroy(xfrm6_tunnel_spi_kmem); xfrm6_tunnel_spi_kmem = NULL; + return; +err: + X6TPRINTK1(KERN_ERR "%s(): table is not empty\n", __FUNCTION__); + return; } static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) @@ -116,13 +184,19 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) struct xfrm6_tunnel_spi *x6spi; struct hlist_node *pos; + X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr); + hlist_for_each_entry(x6spi, pos, &xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)], list_byaddr) { - if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) + if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { + X6SPI_CHECK_MAGIC(x6spi); + X6TPRINTK3(KERN_DEBUG "%s() = %p(%u)\n", __FUNCTION__, x6spi, x6spi->spi); return x6spi; + } } + X6TPRINTK3(KERN_DEBUG "%s() = NULL(0)\n", __FUNCTION__); return NULL; } @@ -131,6 +205,8 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) struct xfrm6_tunnel_spi *x6spi; u32 spi; + X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr); + read_lock_bh(&xfrm6_tunnel_spi_lock); x6spi = __xfrm6_tunnel_spi_lookup(saddr); spi = x6spi ? x6spi->spi : 0; @@ -147,6 +223,8 @@ static u32 __xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) struct hlist_node *pos; unsigned index; + X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr); + if (xfrm6_tunnel_spi < XFRM6_TUNNEL_SPI_MIN || xfrm6_tunnel_spi >= XFRM6_TUNNEL_SPI_MAX) xfrm6_tunnel_spi = XFRM6_TUNNEL_SPI_MIN; @@ -180,10 +258,18 @@ try_next_2:; spi = 0; goto out; alloc_spi: + X6TPRINTK3(KERN_DEBUG "%s(): allocate new spi for " NIP6_FMT "\n", + __FUNCTION__, + NIP6(*(struct in6_addr *)saddr)); x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC); - if (!x6spi) + if (!x6spi) { + X6TPRINTK1(KERN_ERR "%s(): kmem_cache_alloc() failed\n", + __FUNCTION__); goto out; - + } +#ifdef XFRM6_TUNNEL_SPI_MAGIC + x6spi->magic = XFRM6_TUNNEL_SPI_MAGIC; +#endif memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr)); x6spi->spi = spi; atomic_set(&x6spi->refcnt, 1); @@ -192,7 +278,9 @@ try_next_2:; index = xfrm6_tunnel_spi_hash_byaddr(saddr); hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]); + X6SPI_CHECK_MAGIC(x6spi); out: + X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi); return spi; } @@ -201,6 +289,8 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) struct xfrm6_tunnel_spi *x6spi; u32 spi; + X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr); + write_lock_bh(&xfrm6_tunnel_spi_lock); x6spi = __xfrm6_tunnel_spi_lookup(saddr); if (x6spi) { @@ -210,6 +300,8 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) spi = __xfrm6_tunnel_alloc_spi(saddr); write_unlock_bh(&xfrm6_tunnel_spi_lock); + X6TPRINTK3(KERN_DEBUG "%s() = %u\n", __FUNCTION__, spi); + return spi; } @@ -220,6 +312,8 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) struct xfrm6_tunnel_spi *x6spi; struct hlist_node *pos, *n; + X6TPRINTK3(KERN_DEBUG "%s(saddr=%p)\n", __FUNCTION__, saddr); + write_lock_bh(&xfrm6_tunnel_spi_lock); hlist_for_each_entry_safe(x6spi, pos, n, @@ -227,6 +321,12 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr) list_byaddr) { if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) { + X6TPRINTK3(KERN_DEBUG "%s(): x6spi object for " NIP6_FMT + " found at %p\n", + __FUNCTION__, + NIP6(*(struct in6_addr *)saddr), + x6spi); + X6SPI_CHECK_MAGIC(x6spi); if (atomic_dec_and_test(&x6spi->refcnt)) { hlist_del(&x6spi->list_byaddr); hlist_del(&x6spi->list_byspi); @@ -277,14 +377,20 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, case ICMPV6_ADDR_UNREACH: case ICMPV6_PORT_UNREACH: default: + X6TPRINTK3(KERN_DEBUG + "xfrm6_tunnel: Destination Unreach.\n"); break; } break; case ICMPV6_PKT_TOOBIG: + X6TPRINTK3(KERN_DEBUG + "xfrm6_tunnel: Packet Too Big.\n"); break; case ICMPV6_TIME_EXCEED: switch (code) { case ICMPV6_EXC_HOPLIMIT: + X6TPRINTK3(KERN_DEBUG + "xfrm6_tunnel: Too small Hoplimit.\n"); break; case ICMPV6_EXC_FRAGTIME: default: @@ -341,14 +447,22 @@ static struct xfrm6_tunnel xfrm6_tunnel_handler = { static int __init xfrm6_tunnel_init(void) { - if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) - return -EAGAIN; + X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); + if (xfrm_register_type(&xfrm6_tunnel_type, AF_INET6) < 0) { + X6TPRINTK1(KERN_ERR + "xfrm6_tunnel init: can't add xfrm type\n"); + return -EAGAIN; + } if (xfrm6_tunnel_register(&xfrm6_tunnel_handler)) { + X6TPRINTK1(KERN_ERR + "xfrm6_tunnel init(): can't add handler\n"); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; } if (xfrm6_tunnel_spi_init() < 0) { + X6TPRINTK1(KERN_ERR + "xfrm6_tunnel init: failed to initialize spi\n"); xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); return -EAGAIN; @@ -358,9 +472,15 @@ static int __init xfrm6_tunnel_init(void) static void __exit xfrm6_tunnel_fini(void) { + X6TPRINTK3(KERN_DEBUG "%s()\n", __FUNCTION__); + xfrm6_tunnel_spi_fini(); - xfrm6_tunnel_deregister(&xfrm6_tunnel_handler); - xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); + if (xfrm6_tunnel_deregister(&xfrm6_tunnel_handler)) + X6TPRINTK1(KERN_ERR + "xfrm6_tunnel close: can't remove handler\n"); + if (xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6) < 0) + X6TPRINTK1(KERN_ERR + "xfrm6_tunnel close: can't remove xfrm type\n"); } module_init(xfrm6_tunnel_init); diff --git a/trunk/net/irda/af_irda.c b/trunk/net/irda/af_irda.c index 17699eeb64d7..7fae48a53bff 100644 --- a/trunk/net/irda/af_irda.c +++ b/trunk/net/irda/af_irda.c @@ -308,7 +308,7 @@ static void irda_connect_response(struct irda_sock *self) IRDA_ASSERT(self != NULL, return;); - skb = alloc_skb(64, GFP_ATOMIC); + skb = dev_alloc_skb(64); if (skb == NULL) { IRDA_DEBUG(0, "%s() Unable to allocate sk_buff!\n", __FUNCTION__); diff --git a/trunk/net/irda/ircomm/ircomm_core.c b/trunk/net/irda/ircomm/ircomm_core.c index ad6b6af3dd97..9c4a902a9dba 100644 --- a/trunk/net/irda/ircomm/ircomm_core.c +++ b/trunk/net/irda/ircomm/ircomm_core.c @@ -115,10 +115,12 @@ struct ircomm_cb *ircomm_open(notify_t *notify, __u8 service_type, int line) IRDA_ASSERT(ircomm != NULL, return NULL;); - self = kzalloc(sizeof(struct ircomm_cb), GFP_ATOMIC); + self = kmalloc(sizeof(struct ircomm_cb), GFP_ATOMIC); if (self == NULL) return NULL; + memset(self, 0, sizeof(struct ircomm_cb)); + self->notify = *notify; self->magic = IRCOMM_MAGIC; diff --git a/trunk/net/irda/ircomm/ircomm_lmp.c b/trunk/net/irda/ircomm/ircomm_lmp.c index 959874b6451f..d9097207aed3 100644 --- a/trunk/net/irda/ircomm/ircomm_lmp.c +++ b/trunk/net/irda/ircomm/ircomm_lmp.c @@ -81,7 +81,7 @@ static int ircomm_lmp_connect_response(struct ircomm_cb *self, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; @@ -115,7 +115,7 @@ static int ircomm_lmp_disconnect_request(struct ircomm_cb *self, IRDA_DEBUG(0, "%s()\n", __FUNCTION__ ); if (!userdata) { - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; diff --git a/trunk/net/irda/ircomm/ircomm_param.c b/trunk/net/irda/ircomm/ircomm_param.c index a39f5735a90b..6009bab05091 100644 --- a/trunk/net/irda/ircomm/ircomm_param.c +++ b/trunk/net/irda/ircomm/ircomm_param.c @@ -121,7 +121,7 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush) skb = self->ctrl_skb; if (!skb) { - skb = alloc_skb(256, GFP_ATOMIC); + skb = dev_alloc_skb(256); if (!skb) { spin_unlock_irqrestore(&self->spinlock, flags); return -ENOMEM; diff --git a/trunk/net/irda/ircomm/ircomm_tty.c b/trunk/net/irda/ircomm/ircomm_tty.c index 3bcdb467efc5..b400f27851fc 100644 --- a/trunk/net/irda/ircomm/ircomm_tty.c +++ b/trunk/net/irda/ircomm/ircomm_tty.c @@ -379,11 +379,12 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp) self = hashbin_lock_find(ircomm_tty, line, NULL); if (!self) { /* No, so make new instance */ - self = kzalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); + self = kmalloc(sizeof(struct ircomm_tty_cb), GFP_KERNEL); if (self == NULL) { IRDA_ERROR("%s(), kmalloc failed!\n", __FUNCTION__); return -ENOMEM; } + memset(self, 0, sizeof(struct ircomm_tty_cb)); self->magic = IRCOMM_TTY_MAGIC; self->flow = FLOW_STOP; @@ -758,9 +759,8 @@ static int ircomm_tty_write(struct tty_struct *tty, } } else { /* Prepare a full sized frame */ - skb = alloc_skb(self->max_data_size+ - self->max_header_size, - GFP_ATOMIC); + skb = dev_alloc_skb(self->max_data_size+ + self->max_header_size); if (!skb) { spin_unlock_irqrestore(&self->spinlock, flags); return -ENOBUFS; diff --git a/trunk/net/irda/irda_device.c b/trunk/net/irda/irda_device.c index 7e7a31798d8d..ba40e5495f58 100644 --- a/trunk/net/irda/irda_device.c +++ b/trunk/net/irda/irda_device.c @@ -401,10 +401,12 @@ dongle_t *irda_device_dongle_init(struct net_device *dev, int type) } /* Allocate dongle info for this instance */ - dongle = kzalloc(sizeof(dongle_t), GFP_KERNEL); + dongle = kmalloc(sizeof(dongle_t), GFP_KERNEL); if (!dongle) goto out; + memset(dongle, 0, sizeof(dongle_t)); + /* Bind the registration info to this particular instance */ dongle->issue = reg; dongle->dev = dev; diff --git a/trunk/net/irda/iriap.c b/trunk/net/irda/iriap.c index 61128aa05b40..a0472652a44e 100644 --- a/trunk/net/irda/iriap.c +++ b/trunk/net/irda/iriap.c @@ -345,7 +345,7 @@ static void iriap_disconnect_request(struct iriap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IAS_MAGIC, return;); - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (tx_skb == NULL) { IRDA_DEBUG(0, "%s(), Could not allocate an sk_buff of length %d\n", __FUNCTION__, 64); @@ -396,7 +396,7 @@ int iriap_getvaluebyclass_request(struct iriap_cb *self, attr_len = strlen(attr); /* Up to IAS_MAX_ATTRIBNAME = 60 */ skb_len = self->max_header_size+2+name_len+1+attr_len+4; - tx_skb = alloc_skb(skb_len, GFP_ATOMIC); + tx_skb = dev_alloc_skb(skb_len); if (!tx_skb) return -ENOMEM; @@ -562,8 +562,7 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self, * value. We add 32 bytes because of the 6 bytes for the frame and * max 5 bytes for the value coding. */ - tx_skb = alloc_skb(value->len + self->max_header_size + 32, - GFP_ATOMIC); + tx_skb = dev_alloc_skb(value->len + self->max_header_size + 32); if (!tx_skb) return; @@ -701,7 +700,7 @@ void iriap_send_ack(struct iriap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IAS_MAGIC, return;); - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return; diff --git a/trunk/net/irda/iriap_event.c b/trunk/net/irda/iriap_event.c index da17395df05a..a73607450de1 100644 --- a/trunk/net/irda/iriap_event.c +++ b/trunk/net/irda/iriap_event.c @@ -365,7 +365,7 @@ static void state_r_disconnect(struct iriap_cb *self, IRIAP_EVENT event, switch (event) { case IAP_LM_CONNECT_INDICATION: - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (tx_skb == NULL) { IRDA_WARNING("%s: unable to malloc!\n", __FUNCTION__); return; diff --git a/trunk/net/irda/irias_object.c b/trunk/net/irda/irias_object.c index a154b1d71c0f..82e665c79991 100644 --- a/trunk/net/irda/irias_object.c +++ b/trunk/net/irda/irias_object.c @@ -82,12 +82,13 @@ struct ias_object *irias_new_object( char *name, int id) IRDA_DEBUG( 4, "%s()\n", __FUNCTION__); - obj = kzalloc(sizeof(struct ias_object), GFP_ATOMIC); + obj = kmalloc(sizeof(struct ias_object), GFP_ATOMIC); if (obj == NULL) { IRDA_WARNING("%s(), Unable to allocate object!\n", __FUNCTION__); return NULL; } + memset(obj, 0, sizeof( struct ias_object)); obj->magic = IAS_OBJECT_MAGIC; obj->name = strndup(name, IAS_MAX_CLASSNAME); @@ -345,12 +346,13 @@ void irias_add_integer_attrib(struct ias_object *obj, char *name, int value, IRDA_ASSERT(obj->magic == IAS_OBJECT_MAGIC, return;); IRDA_ASSERT(name != NULL, return;); - attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); + attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -380,12 +382,13 @@ void irias_add_octseq_attrib(struct ias_object *obj, char *name, __u8 *octets, IRDA_ASSERT(name != NULL, return;); IRDA_ASSERT(octets != NULL, return;); - attrib = kzalloc(sizeof(struct ias_attrib), GFP_ATOMIC); + attrib = kmalloc(sizeof(struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -413,12 +416,13 @@ void irias_add_string_attrib(struct ias_object *obj, char *name, char *value, IRDA_ASSERT(name != NULL, return;); IRDA_ASSERT(value != NULL, return;); - attrib = kzalloc(sizeof( struct ias_attrib), GFP_ATOMIC); + attrib = kmalloc(sizeof( struct ias_attrib), GFP_ATOMIC); if (attrib == NULL) { IRDA_WARNING("%s: Unable to allocate attribute!\n", __FUNCTION__); return; } + memset(attrib, 0, sizeof( struct ias_attrib)); attrib->magic = IAS_ATTRIB_MAGIC; attrib->name = strndup(name, IAS_MAX_ATTRIBNAME); @@ -439,11 +443,12 @@ struct ias_value *irias_new_integer_value(int integer) { struct ias_value *value; - value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } + memset(value, 0, sizeof(struct ias_value)); value->type = IAS_INTEGER; value->len = 4; @@ -464,11 +469,12 @@ struct ias_value *irias_new_string_value(char *string) { struct ias_value *value; - value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } + memset( value, 0, sizeof( struct ias_value)); value->type = IAS_STRING; value->charset = CS_ASCII; @@ -489,11 +495,12 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len) { struct ias_value *value; - value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } + memset(value, 0, sizeof(struct ias_value)); value->type = IAS_OCT_SEQ; /* Check length */ @@ -515,11 +522,12 @@ struct ias_value *irias_new_missing_value(void) { struct ias_value *value; - value = kzalloc(sizeof(struct ias_value), GFP_ATOMIC); + value = kmalloc(sizeof(struct ias_value), GFP_ATOMIC); if (value == NULL) { IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); return NULL; } + memset(value, 0, sizeof(struct ias_value)); value->type = IAS_MISSING; value->len = 0; diff --git a/trunk/net/irda/irlan/irlan_common.c b/trunk/net/irda/irlan/irlan_common.c index 7dd0a2fe1d20..bd659dd545ac 100644 --- a/trunk/net/irda/irlan/irlan_common.c +++ b/trunk/net/irda/irlan/irlan_common.c @@ -636,7 +636,7 @@ void irlan_get_provider_info(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(64, GFP_ATOMIC); + skb = dev_alloc_skb(64); if (!skb) return; @@ -668,7 +668,7 @@ void irlan_open_data_channel(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(64, GFP_ATOMIC); + skb = dev_alloc_skb(64); if (!skb) return; @@ -704,7 +704,7 @@ void irlan_close_data_channel(struct irlan_cb *self) if (self->client.tsap_ctrl == NULL) return; - skb = alloc_skb(64, GFP_ATOMIC); + skb = dev_alloc_skb(64); if (!skb) return; @@ -739,7 +739,7 @@ static void irlan_open_unicast_addr(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(128, GFP_ATOMIC); + skb = dev_alloc_skb(128); if (!skb) return; @@ -777,7 +777,7 @@ void irlan_set_broadcast_filter(struct irlan_cb *self, int status) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(128, GFP_ATOMIC); + skb = dev_alloc_skb(128); if (!skb) return; @@ -816,7 +816,7 @@ void irlan_set_multicast_filter(struct irlan_cb *self, int status) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(128, GFP_ATOMIC); + skb = dev_alloc_skb(128); if (!skb) return; @@ -856,7 +856,7 @@ static void irlan_get_unicast_addr(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(128, GFP_ATOMIC); + skb = dev_alloc_skb(128); if (!skb) return; @@ -891,7 +891,7 @@ void irlan_get_media_char(struct irlan_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(64, GFP_ATOMIC); + skb = dev_alloc_skb(64); if (!skb) return; diff --git a/trunk/net/irda/irlan/irlan_provider.c b/trunk/net/irda/irlan/irlan_provider.c index 9c0df86044d7..39c202d1c374 100644 --- a/trunk/net/irda/irlan/irlan_provider.c +++ b/trunk/net/irda/irlan/irlan_provider.c @@ -296,7 +296,7 @@ void irlan_provider_send_reply(struct irlan_cb *self, int command, IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;); - skb = alloc_skb(128, GFP_ATOMIC); + skb = dev_alloc_skb(128); if (!skb) return; diff --git a/trunk/net/irda/irlap.c b/trunk/net/irda/irlap.c index e7852a07495e..cade355ac8af 100644 --- a/trunk/net/irda/irlap.c +++ b/trunk/net/irda/irlap.c @@ -116,10 +116,11 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, IRDA_DEBUG(4, "%s()\n", __FUNCTION__); /* Initialize the irlap structure. */ - self = kzalloc(sizeof(struct irlap_cb), GFP_KERNEL); + self = kmalloc(sizeof(struct irlap_cb), GFP_KERNEL); if (self == NULL) return NULL; + memset(self, 0, sizeof(struct irlap_cb)); self->magic = LAP_MAGIC; /* Make a binding between the layers */ @@ -881,7 +882,7 @@ static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now) /* Change speed now, or just piggyback speed on frames */ if (now) { /* Send down empty frame to trigger speed change */ - skb = alloc_skb(0, GFP_ATOMIC); + skb = dev_alloc_skb(0); if (skb) irlap_queue_xmit(self, skb); } @@ -1221,7 +1222,7 @@ static int irlap_seq_open(struct inode *inode, struct file *file) { struct seq_file *seq; int rc = -ENOMEM; - struct irlap_iter_state *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct irlap_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1237,6 +1238,7 @@ static int irlap_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/trunk/net/irda/irlap_frame.c b/trunk/net/irda/irlap_frame.c index ccb983bf0f4a..3e9a06abbdd0 100644 --- a/trunk/net/irda/irlap_frame.c +++ b/trunk/net/irda/irlap_frame.c @@ -117,7 +117,7 @@ void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos) IRDA_ASSERT(self->magic == LAP_MAGIC, return;); /* Allocate frame */ - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return; @@ -210,7 +210,7 @@ void irlap_send_ua_response_frame(struct irlap_cb *self, struct qos_info *qos) IRDA_ASSERT(self->magic == LAP_MAGIC, return;); /* Allocate frame */ - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return; @@ -250,7 +250,7 @@ void irlap_send_dm_frame( struct irlap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LAP_MAGIC, return;); - tx_skb = alloc_skb(32, GFP_ATOMIC); + tx_skb = dev_alloc_skb(32); if (!tx_skb) return; @@ -282,7 +282,7 @@ void irlap_send_disc_frame(struct irlap_cb *self) IRDA_ASSERT(self != NULL, return;); IRDA_ASSERT(self->magic == LAP_MAGIC, return;); - tx_skb = alloc_skb(16, GFP_ATOMIC); + tx_skb = dev_alloc_skb(16); if (!tx_skb) return; @@ -315,7 +315,7 @@ void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s, IRDA_ASSERT(self->magic == LAP_MAGIC, return;); IRDA_ASSERT(discovery != NULL, return;); - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return; @@ -422,10 +422,11 @@ static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self, return; } - if ((discovery = kzalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { + if ((discovery = kmalloc(sizeof(discovery_t), GFP_ATOMIC)) == NULL) { IRDA_WARNING("%s: kmalloc failed!\n", __FUNCTION__); return; } + memset(discovery, 0, sizeof(discovery_t)); discovery->data.daddr = info->daddr; discovery->data.saddr = self->saddr; @@ -575,7 +576,7 @@ void irlap_send_rr_frame(struct irlap_cb *self, int command) struct sk_buff *tx_skb; __u8 *frame; - tx_skb = alloc_skb(16, GFP_ATOMIC); + tx_skb = dev_alloc_skb(16); if (!tx_skb) return; @@ -600,7 +601,7 @@ void irlap_send_rd_frame(struct irlap_cb *self) struct sk_buff *tx_skb; __u8 *frame; - tx_skb = alloc_skb(16, GFP_ATOMIC); + tx_skb = dev_alloc_skb(16); if (!tx_skb) return; @@ -1214,7 +1215,7 @@ void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr, struct test_frame *frame; __u8 *info; - tx_skb = alloc_skb(cmd->len+sizeof(struct test_frame), GFP_ATOMIC); + tx_skb = dev_alloc_skb(cmd->len+sizeof(struct test_frame)); if (!tx_skb) return; diff --git a/trunk/net/irda/irlmp.c b/trunk/net/irda/irlmp.c index c440913dee14..129ad64c15bb 100644 --- a/trunk/net/irda/irlmp.c +++ b/trunk/net/irda/irlmp.c @@ -78,9 +78,10 @@ int __init irlmp_init(void) { IRDA_DEBUG(1, "%s()\n", __FUNCTION__); /* Initialize the irlmp structure. */ - irlmp = kzalloc( sizeof(struct irlmp_cb), GFP_KERNEL); + irlmp = kmalloc( sizeof(struct irlmp_cb), GFP_KERNEL); if (irlmp == NULL) return -ENOMEM; + memset(irlmp, 0, sizeof(struct irlmp_cb)); irlmp->magic = LMP_MAGIC; @@ -159,11 +160,12 @@ struct lsap_cb *irlmp_open_lsap(__u8 slsap_sel, notify_t *notify, __u8 pid) return NULL; /* Allocate new instance of a LSAP connection */ - self = kzalloc(sizeof(struct lsap_cb), GFP_ATOMIC); + self = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC); if (self == NULL) { IRDA_ERROR("%s: can't allocate memory\n", __FUNCTION__); return NULL; } + memset(self, 0, sizeof(struct lsap_cb)); self->magic = LMP_LSAP_MAGIC; self->slsap_sel = slsap_sel; @@ -286,11 +288,12 @@ void irlmp_register_link(struct irlap_cb *irlap, __u32 saddr, notify_t *notify) /* * Allocate new instance of a LSAP connection */ - lap = kzalloc(sizeof(struct lap_cb), GFP_KERNEL); + lap = kmalloc(sizeof(struct lap_cb), GFP_KERNEL); if (lap == NULL) { IRDA_ERROR("%s: unable to kmalloc\n", __FUNCTION__); return; } + memset(lap, 0, sizeof(struct lap_cb)); lap->irlap = irlap; lap->magic = LMP_LAP_MAGIC; @@ -392,7 +395,7 @@ int irlmp_connect_request(struct lsap_cb *self, __u8 dlsap_sel, /* Any userdata? */ if (tx_skb == NULL) { - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; diff --git a/trunk/net/irda/irnet/irnet_ppp.c b/trunk/net/irda/irnet/irnet_ppp.c index a1e502ff9070..e53bf9e0053e 100644 --- a/trunk/net/irda/irnet/irnet_ppp.c +++ b/trunk/net/irda/irnet/irnet_ppp.c @@ -476,10 +476,11 @@ dev_irnet_open(struct inode * inode, #endif /* SECURE_DEVIRNET */ /* Allocate a private structure for this IrNET instance */ - ap = kzalloc(sizeof(*ap), GFP_KERNEL); + ap = kmalloc(sizeof(*ap), GFP_KERNEL); DABORT(ap == NULL, -ENOMEM, FS_ERROR, "Can't allocate struct irnet...\n"); /* initialize the irnet structure */ + memset(ap, 0, sizeof(*ap)); ap->file = file; /* PPP channel setup */ diff --git a/trunk/net/irda/irttp.c b/trunk/net/irda/irttp.c index 42acf1cde737..49c51c5f1a86 100644 --- a/trunk/net/irda/irttp.c +++ b/trunk/net/irda/irttp.c @@ -85,9 +85,10 @@ static pi_param_info_t param_info = { pi_major_call_table, 1, 0x0f, 4 }; */ int __init irttp_init(void) { - irttp = kzalloc(sizeof(struct irttp_cb), GFP_KERNEL); + irttp = kmalloc(sizeof(struct irttp_cb), GFP_KERNEL); if (irttp == NULL) return -ENOMEM; + memset(irttp, 0, sizeof(struct irttp_cb)); irttp->magic = TTP_MAGIC; @@ -305,8 +306,7 @@ static inline void irttp_fragment_skb(struct tsap_cb *self, IRDA_DEBUG(2, "%s(), fragmenting ...\n", __FUNCTION__); /* Make new segment */ - frag = alloc_skb(self->max_seg_size+self->max_header_size, - GFP_ATOMIC); + frag = dev_alloc_skb(self->max_seg_size+self->max_header_size); if (!frag) return; @@ -389,11 +389,12 @@ struct tsap_cb *irttp_open_tsap(__u8 stsap_sel, int credit, notify_t *notify) return NULL; } - self = kzalloc(sizeof(struct tsap_cb), GFP_ATOMIC); + self = kmalloc(sizeof(struct tsap_cb), GFP_ATOMIC); if (self == NULL) { IRDA_DEBUG(0, "%s(), unable to kmalloc!\n", __FUNCTION__); return NULL; } + memset(self, 0, sizeof(struct tsap_cb)); spin_lock_init(&self->lock); /* Initialise todo timer */ @@ -804,7 +805,7 @@ static inline void irttp_give_credit(struct tsap_cb *self) self->send_credit, self->avail_credit, self->remote_credit); /* Give credit to peer */ - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return; @@ -1093,7 +1094,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; @@ -1341,7 +1342,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size, /* Any userdata supplied? */ if (userdata == NULL) { - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; @@ -1540,7 +1541,7 @@ int irttp_disconnect_request(struct tsap_cb *self, struct sk_buff *userdata, if (!userdata) { struct sk_buff *tx_skb; - tx_skb = alloc_skb(64, GFP_ATOMIC); + tx_skb = dev_alloc_skb(64); if (!tx_skb) return -ENOMEM; @@ -1875,7 +1876,7 @@ static int irttp_seq_open(struct inode *inode, struct file *file) int rc = -ENOMEM; struct irttp_iter_state *s; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) goto out; @@ -1885,6 +1886,7 @@ static int irttp_seq_open(struct inode *inode, struct file *file) seq = file->private_data; seq->private = s; + memset(s, 0, sizeof(*s)); out: return rc; out_kfree: diff --git a/trunk/net/lapb/lapb_iface.c b/trunk/net/lapb/lapb_iface.c index 7e6bc41eeb21..aea6616cea3d 100644 --- a/trunk/net/lapb/lapb_iface.c +++ b/trunk/net/lapb/lapb_iface.c @@ -115,12 +115,14 @@ static struct lapb_cb *lapb_devtostruct(struct net_device *dev) */ static struct lapb_cb *lapb_create_cb(void) { - struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC); + struct lapb_cb *lapb = kmalloc(sizeof(*lapb), GFP_ATOMIC); if (!lapb) goto out; + memset(lapb, 0x00, sizeof(*lapb)); + skb_queue_head_init(&lapb->write_queue); skb_queue_head_init(&lapb->ack_queue); @@ -238,13 +240,11 @@ int lapb_setparms(struct net_device *dev, struct lapb_parms_struct *parms) goto out_put; if (lapb->state == LAPB_STATE_0) { - if (parms->mode & LAPB_EXTENDED) { - if (parms->window < 1 || parms->window > 127) - goto out_put; - } else { - if (parms->window < 1 || parms->window > 7) - goto out_put; - } + if (((parms->mode & LAPB_EXTENDED) && + (parms->window < 1 || parms->window > 127)) || + (parms->window < 1 || parms->window > 7)) + goto out_put; + lapb->mode = parms->mode; lapb->window = parms->window; } diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 2652ead96c64..d6cfe84d521b 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -784,20 +784,24 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, copied += used; len -= used; + if (used + offset < skb->len) + continue; + if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, 0); *seq = 0; } - - /* For non stream protcols we get one packet per recvmsg call */ - if (sk->sk_type != SOCK_STREAM) - goto copy_uaddr; - - /* Partial read */ - if (used + offset < skb->len) - continue; } while (len > 0); + /* + * According to UNIX98, msg_name/msg_namelen are ignored + * on connected socket. -ANK + * But... af_llc still doesn't have separate sets of methods for + * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will + * eventually fix this tho :-) -acme + */ + if (sk->sk_type == SOCK_DGRAM) + goto copy_uaddr; out: release_sock(sk); return copied; diff --git a/trunk/net/llc/llc_core.c b/trunk/net/llc/llc_core.c index d12413cff5bd..bd242a49514a 100644 --- a/trunk/net/llc/llc_core.c +++ b/trunk/net/llc/llc_core.c @@ -33,9 +33,10 @@ unsigned char llc_station_mac_sa[ETH_ALEN]; */ static struct llc_sap *llc_sap_alloc(void) { - struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); + struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC); if (sap) { + memset(sap, 0, sizeof(*sap)); sap->state = LLC_SAP_STATE_ACTIVE; memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); rwlock_init(&sap->sk_list.lock); diff --git a/trunk/net/llc/llc_sap.c b/trunk/net/llc/llc_sap.c index 42eb0c3a9780..20c4eb5c1ac6 100644 --- a/trunk/net/llc/llc_sap.c +++ b/trunk/net/llc/llc_sap.c @@ -51,10 +51,10 @@ void llc_save_primitive(struct sock *sk, struct sk_buff* skb, u8 prim) { struct sockaddr_llc *addr; + if (skb->sk->sk_type == SOCK_STREAM) /* See UNIX98 */ + return; /* save primitive for use by the user. */ addr = llc_ui_skb_cb(skb); - - memset(addr, 0, sizeof(*addr)); addr->sllc_family = sk->sk_family; addr->sllc_arphrd = skb->dev->type; addr->sllc_test = prim == LLC_TEST_PRIM; diff --git a/trunk/net/netfilter/Kconfig b/trunk/net/netfilter/Kconfig index a9894ddfd72a..42a178aa30f9 100644 --- a/trunk/net/netfilter/Kconfig +++ b/trunk/net/netfilter/Kconfig @@ -386,8 +386,8 @@ config NETFILTER_XT_MATCH_REALM . If unsure, say `N'. config NETFILTER_XT_MATCH_SCTP - tristate '"sctp" protocol match support (EXPERIMENTAL)' - depends on NETFILTER_XTABLES && EXPERIMENTAL + tristate '"sctp" protocol match support' + depends on NETFILTER_XTABLES help With this option enabled, you will be able to use the `sctp' match in order to match on SCTP source/destination ports diff --git a/trunk/net/netfilter/nf_conntrack_standalone.c b/trunk/net/netfilter/nf_conntrack_standalone.c index 4ef836699962..5fcab2ef231f 100644 --- a/trunk/net/netfilter/nf_conntrack_standalone.c +++ b/trunk/net/netfilter/nf_conntrack_standalone.c @@ -428,8 +428,6 @@ static struct file_operations ct_cpu_seq_fops = { /* Sysctl support */ -int nf_conntrack_checksum = 1; - #ifdef CONFIG_SYSCTL /* From nf_conntrack_core.c */ @@ -461,6 +459,8 @@ extern unsigned int nf_ct_generic_timeout; static int log_invalid_proto_min = 0; static int log_invalid_proto_max = 255; +int nf_conntrack_checksum = 1; + static struct ctl_table_header *nf_ct_sysctl_header; static ctl_table nf_ct_sysctl_table[] = { diff --git a/trunk/net/netfilter/nf_queue.c b/trunk/net/netfilter/nf_queue.c index 662a869593bf..bb6fcee452ca 100644 --- a/trunk/net/netfilter/nf_queue.c +++ b/trunk/net/netfilter/nf_queue.c @@ -219,20 +219,21 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, switch (verdict & NF_VERDICT_MASK) { case NF_ACCEPT: - case NF_STOP: info->okfn(skb); - case NF_STOLEN: break; + case NF_QUEUE: if (!nf_queue(&skb, elem, info->pf, info->hook, info->indev, info->outdev, info->okfn, verdict >> NF_VERDICT_BITS)) goto next_hook; break; - default: - kfree_skb(skb); } rcu_read_unlock(); + + if (verdict == NF_DROP) + kfree_skb(skb); + kfree(info); return; } diff --git a/trunk/net/netfilter/xt_SECMARK.c b/trunk/net/netfilter/xt_SECMARK.c index de9537ad9a7c..c2ce9c4011cc 100644 --- a/trunk/net/netfilter/xt_SECMARK.c +++ b/trunk/net/netfilter/xt_SECMARK.c @@ -57,8 +57,6 @@ static int checkentry_selinux(struct xt_secmark_target_info *info) { int err; struct xt_secmark_target_selinux_info *sel = &info->u.sel; - - sel->selctx[SECMARK_SELCTX_MAX - 1] = '\0'; err = selinux_string_to_sid(sel->selctx, &sel->selsid); if (err) { diff --git a/trunk/net/netfilter/xt_physdev.c b/trunk/net/netfilter/xt_physdev.c index a9f4f6f3c628..5fe4c9df17f5 100644 --- a/trunk/net/netfilter/xt_physdev.c +++ b/trunk/net/netfilter/xt_physdev.c @@ -113,21 +113,6 @@ checkentry(const char *tablename, if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || info->bitmask & ~XT_PHYSDEV_OP_MASK) return 0; - if (brnf_deferred_hooks == 0 && - info->bitmask & XT_PHYSDEV_OP_OUT && - (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || - info->invert & XT_PHYSDEV_OP_BRIDGED) && - hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | - (1 << NF_IP_POST_ROUTING))) { - printk(KERN_WARNING "physdev match: using --physdev-out in the " - "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " - "traffic is deprecated and breaks other things, it will " - "be removed in January 2007. See Documentation/" - "feature-removal-schedule.txt for details. This doesn't " - "affect you in case you're using it for purely bridged " - "traffic.\n"); - brnf_deferred_hooks = 1; - } return 1; } diff --git a/trunk/net/netfilter/xt_pkttype.c b/trunk/net/netfilter/xt_pkttype.c index d2f5320a80bf..3ac703b5cb8f 100644 --- a/trunk/net/netfilter/xt_pkttype.c +++ b/trunk/net/netfilter/xt_pkttype.c @@ -9,8 +9,6 @@ #include #include #include -#include -#include #include #include @@ -30,17 +28,9 @@ static int match(const struct sk_buff *skb, unsigned int protoff, int *hotdrop) { - u_int8_t type; const struct xt_pkttype_info *info = matchinfo; - if (skb->pkt_type == PACKET_LOOPBACK) - type = (MULTICAST(skb->nh.iph->daddr) - ? PACKET_MULTICAST - : PACKET_BROADCAST); - else - type = skb->pkt_type; - - return (type == info->pkttype) ^ info->invert; + return (skb->pkt_type == info->pkttype) ^ info->invert; } static struct xt_match pkttype_match = { diff --git a/trunk/net/netfilter/xt_string.c b/trunk/net/netfilter/xt_string.c index d8e3891b5f8b..0ebb6ac2c8c7 100644 --- a/trunk/net/netfilter/xt_string.c +++ b/trunk/net/netfilter/xt_string.c @@ -55,10 +55,7 @@ static int checkentry(const char *tablename, /* Damn, can't handle this case properly with iptables... */ if (conf->from_offset > conf->to_offset) return 0; - if (conf->algo[XT_STRING_MAX_ALGO_NAME_SIZE - 1] != '\0') - return 0; - if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) - return 0; + ts_conf = textsearch_prepare(conf->algo, conf->pattern, conf->patlen, GFP_KERNEL, TS_AUTOLOAD); if (IS_ERR(ts_conf)) diff --git a/trunk/net/netlink/af_netlink.c b/trunk/net/netlink/af_netlink.c index b85c1f9f1288..55c0adc8f115 100644 --- a/trunk/net/netlink/af_netlink.c +++ b/trunk/net/netlink/af_netlink.c @@ -562,9 +562,10 @@ static int netlink_alloc_groups(struct sock *sk) if (err) return err; - nlk->groups = kzalloc(NLGRPSZ(groups), GFP_KERNEL); + nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL); if (nlk->groups == NULL) return -ENOMEM; + memset(nlk->groups, 0, NLGRPSZ(groups)); nlk->ngroups = groups; return 0; } @@ -1392,10 +1393,11 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, struct sock *sk; struct netlink_sock *nlk; - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kmalloc(sizeof(*cb), GFP_KERNEL); if (cb == NULL) return -ENOBUFS; + memset(cb, 0, sizeof(*cb)); cb->dump = dump; cb->done = done; cb->nlh = nlh; @@ -1666,7 +1668,7 @@ static int netlink_seq_open(struct inode *inode, struct file *file) struct nl_seq_iter *iter; int err; - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc(sizeof(*iter), GFP_KERNEL); if (!iter) return -ENOMEM; @@ -1676,6 +1678,7 @@ static int netlink_seq_open(struct inode *inode, struct file *file) return err; } + memset(iter, 0, sizeof(*iter)); seq = file->private_data; seq->private = iter; return 0; @@ -1744,13 +1747,15 @@ static int __init netlink_proto_init(void) if (sizeof(struct netlink_skb_parms) > sizeof(dummy_skb->cb)) netlink_skb_parms_too_large(); - nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL); + nl_table = kmalloc(sizeof(*nl_table) * MAX_LINKS, GFP_KERNEL); if (!nl_table) { enomem: printk(KERN_CRIT "netlink_init: Cannot allocate nl_table\n"); return -ENOMEM; } + memset(nl_table, 0, sizeof(*nl_table) * MAX_LINKS); + if (num_physpages >= (128 * 1024)) max = num_physpages >> (21 - PAGE_SHIFT); else diff --git a/trunk/net/rxrpc/connection.c b/trunk/net/rxrpc/connection.c index 93d2c55ad2d5..573b572f8f91 100644 --- a/trunk/net/rxrpc/connection.c +++ b/trunk/net/rxrpc/connection.c @@ -58,12 +58,13 @@ static inline int __rxrpc_create_connection(struct rxrpc_peer *peer, _enter("%p",peer); /* allocate and initialise a connection record */ - conn = kzalloc(sizeof(struct rxrpc_connection), GFP_KERNEL); + conn = kmalloc(sizeof(struct rxrpc_connection), GFP_KERNEL); if (!conn) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(conn, 0, sizeof(struct rxrpc_connection)); atomic_set(&conn->usage, 1); INIT_LIST_HEAD(&conn->link); @@ -534,12 +535,13 @@ int rxrpc_conn_newmsg(struct rxrpc_connection *conn, return -EINVAL; } - msg = kzalloc(sizeof(struct rxrpc_message), alloc_flags); + msg = kmalloc(sizeof(struct rxrpc_message), alloc_flags); if (!msg) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(msg, 0, sizeof(*msg)); atomic_set(&msg->usage, 1); INIT_LIST_HEAD(&msg->link); diff --git a/trunk/net/rxrpc/peer.c b/trunk/net/rxrpc/peer.c index 8a275157a3bb..ed38f5b17c1b 100644 --- a/trunk/net/rxrpc/peer.c +++ b/trunk/net/rxrpc/peer.c @@ -58,12 +58,13 @@ static int __rxrpc_create_peer(struct rxrpc_transport *trans, __be32 addr, _enter("%p,%08x", trans, ntohl(addr)); /* allocate and initialise a peer record */ - peer = kzalloc(sizeof(struct rxrpc_peer), GFP_KERNEL); + peer = kmalloc(sizeof(struct rxrpc_peer), GFP_KERNEL); if (!peer) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(peer, 0, sizeof(struct rxrpc_peer)); atomic_set(&peer->usage, 1); INIT_LIST_HEAD(&peer->link); diff --git a/trunk/net/rxrpc/transport.c b/trunk/net/rxrpc/transport.c index 465efc86fccf..dbe6105e83a5 100644 --- a/trunk/net/rxrpc/transport.c +++ b/trunk/net/rxrpc/transport.c @@ -68,10 +68,11 @@ int rxrpc_create_transport(unsigned short port, _enter("%hu", port); - trans = kzalloc(sizeof(struct rxrpc_transport), GFP_KERNEL); + trans = kmalloc(sizeof(struct rxrpc_transport), GFP_KERNEL); if (!trans) return -ENOMEM; + memset(trans, 0, sizeof(struct rxrpc_transport)); atomic_set(&trans->usage, 1); INIT_LIST_HEAD(&trans->services); INIT_LIST_HEAD(&trans->link); @@ -311,12 +312,13 @@ static int rxrpc_incoming_msg(struct rxrpc_transport *trans, _enter(""); - msg = kzalloc(sizeof(struct rxrpc_message), GFP_KERNEL); + msg = kmalloc(sizeof(struct rxrpc_message), GFP_KERNEL); if (!msg) { _leave(" = -ENOMEM"); return -ENOMEM; } + memset(msg, 0, sizeof(*msg)); atomic_set(&msg->usage, 1); list_add_tail(&msg->link,msgq); diff --git a/trunk/net/sched/act_api.c b/trunk/net/sched/act_api.c index a2587b52e531..9affeeedf107 100644 --- a/trunk/net/sched/act_api.c +++ b/trunk/net/sched/act_api.c @@ -312,9 +312,10 @@ struct tc_action *tcf_action_init_1(struct rtattr *rta, struct rtattr *est, } *err = -ENOMEM; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kmalloc(sizeof(*a), GFP_KERNEL); if (a == NULL) goto err_mod; + memset(a, 0, sizeof(*a)); /* backward compatibility for policer */ if (name == NULL) @@ -491,9 +492,10 @@ tcf_action_get_1(struct rtattr *rta, struct nlmsghdr *n, u32 pid, int *err) index = *(int *)RTA_DATA(tb[TCA_ACT_INDEX - 1]); *err = -ENOMEM; - a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); + a = kmalloc(sizeof(struct tc_action), GFP_KERNEL); if (a == NULL) return NULL; + memset(a, 0, sizeof(struct tc_action)); *err = -EINVAL; a->ops = tc_lookup_action(tb[TCA_ACT_KIND - 1]); @@ -529,11 +531,12 @@ static struct tc_action *create_a(int i) { struct tc_action *act; - act = kzalloc(sizeof(*act), GFP_KERNEL); + act = kmalloc(sizeof(*act), GFP_KERNEL); if (act == NULL) { printk("create_a: failed to alloc!\n"); return NULL; } + memset(act, 0, sizeof(*act)); act->order = i; return act; } diff --git a/trunk/net/sched/act_pedit.c b/trunk/net/sched/act_pedit.c index f257475e0e0c..58b3a8652042 100644 --- a/trunk/net/sched/act_pedit.c +++ b/trunk/net/sched/act_pedit.c @@ -209,9 +209,10 @@ tcf_pedit_dump(struct sk_buff *skb, struct tc_action *a,int bind, int ref) s = sizeof(*opt) + p->nkeys * sizeof(struct tc_pedit_key); /* netlink spinlocks held above us - must use ATOMIC */ - opt = kzalloc(s, GFP_ATOMIC); + opt = kmalloc(s, GFP_ATOMIC); if (opt == NULL) return -ENOBUFS; + memset(opt, 0, s); memcpy(opt->keys, p->keys, p->nkeys * sizeof(struct tc_pedit_key)); opt->index = p->index; diff --git a/trunk/net/sched/act_police.c b/trunk/net/sched/act_police.c index da905d7b4b40..47e00bd9625e 100644 --- a/trunk/net/sched/act_police.c +++ b/trunk/net/sched/act_police.c @@ -196,9 +196,10 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est, return ret; } - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return -ENOMEM; + memset(p, 0, sizeof(*p)); ret = ACT_P_CREATED; p->refcnt = 1; @@ -428,10 +429,11 @@ struct tcf_police * tcf_police_locate(struct rtattr *rta, struct rtattr *est) return p; } - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) return NULL; + memset(p, 0, sizeof(*p)); p->refcnt = 1; spin_lock_init(&p->lock); p->stats_lock = &p->lock; diff --git a/trunk/net/sched/cls_basic.c b/trunk/net/sched/cls_basic.c index 86cac49a0531..61507f006b11 100644 --- a/trunk/net/sched/cls_basic.c +++ b/trunk/net/sched/cls_basic.c @@ -178,17 +178,19 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, err = -ENOBUFS; if (head == NULL) { - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kmalloc(sizeof(*head), GFP_KERNEL); if (head == NULL) goto errout; + memset(head, 0, sizeof(*head)); INIT_LIST_HEAD(&head->flist); tp->root = head; } - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc(sizeof(*f), GFP_KERNEL); if (f == NULL) goto errout; + memset(f, 0, sizeof(*f)); err = -EINVAL; if (handle) diff --git a/trunk/net/sched/cls_fw.c b/trunk/net/sched/cls_fw.c index e6973d9b686d..d41de91fc4f6 100644 --- a/trunk/net/sched/cls_fw.c +++ b/trunk/net/sched/cls_fw.c @@ -267,18 +267,20 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, return -EINVAL; if (head == NULL) { - head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); + head = kmalloc(sizeof(struct fw_head), GFP_KERNEL); if (head == NULL) return -ENOBUFS; + memset(head, 0, sizeof(*head)); tcf_tree_lock(tp); tp->root = head; tcf_tree_unlock(tp); } - f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); + f = kmalloc(sizeof(struct fw_filter), GFP_KERNEL); if (f == NULL) return -ENOBUFS; + memset(f, 0, sizeof(*f)); f->id = handle; diff --git a/trunk/net/sched/cls_route.c b/trunk/net/sched/cls_route.c index d3aea730d4c8..c2e71900f7bd 100644 --- a/trunk/net/sched/cls_route.c +++ b/trunk/net/sched/cls_route.c @@ -396,9 +396,10 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, h1 = to_hash(nhandle); if ((b = head->table[h1]) == NULL) { err = -ENOBUFS; - b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL); + b = kmalloc(sizeof(struct route4_bucket), GFP_KERNEL); if (b == NULL) goto errout; + memset(b, 0, sizeof(*b)); tcf_tree_lock(tp); head->table[h1] = b; @@ -474,18 +475,20 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, err = -ENOBUFS; if (head == NULL) { - head = kzalloc(sizeof(struct route4_head), GFP_KERNEL); + head = kmalloc(sizeof(struct route4_head), GFP_KERNEL); if (head == NULL) goto errout; + memset(head, 0, sizeof(struct route4_head)); tcf_tree_lock(tp); tp->root = head; tcf_tree_unlock(tp); } - f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL); + f = kmalloc(sizeof(struct route4_filter), GFP_KERNEL); if (f == NULL) goto errout; + memset(f, 0, sizeof(*f)); err = route4_set_parms(tp, base, f, handle, head, tb, tca[TCA_RATE-1], 1); diff --git a/trunk/net/sched/cls_rsvp.h b/trunk/net/sched/cls_rsvp.h index 6e230ecfba05..ba8741971629 100644 --- a/trunk/net/sched/cls_rsvp.h +++ b/trunk/net/sched/cls_rsvp.h @@ -240,8 +240,9 @@ static int rsvp_init(struct tcf_proto *tp) { struct rsvp_head *data; - data = kzalloc(sizeof(struct rsvp_head), GFP_KERNEL); + data = kmalloc(sizeof(struct rsvp_head), GFP_KERNEL); if (data) { + memset(data, 0, sizeof(struct rsvp_head)); tp->root = data; return 0; } @@ -445,10 +446,11 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, goto errout2; err = -ENOBUFS; - f = kzalloc(sizeof(struct rsvp_filter), GFP_KERNEL); + f = kmalloc(sizeof(struct rsvp_filter), GFP_KERNEL); if (f == NULL) goto errout2; + memset(f, 0, sizeof(*f)); h2 = 16; if (tb[TCA_RSVP_SRC-1]) { err = -EINVAL; @@ -530,9 +532,10 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, /* No session found. Create new one. */ err = -ENOBUFS; - s = kzalloc(sizeof(struct rsvp_session), GFP_KERNEL); + s = kmalloc(sizeof(struct rsvp_session), GFP_KERNEL); if (s == NULL) goto errout; + memset(s, 0, sizeof(*s)); memcpy(s->dst, dst, sizeof(s->dst)); if (pinfo) { diff --git a/trunk/net/sched/cls_tcindex.c b/trunk/net/sched/cls_tcindex.c index 5af8a59e1503..7870e7bb0bac 100644 --- a/trunk/net/sched/cls_tcindex.c +++ b/trunk/net/sched/cls_tcindex.c @@ -148,10 +148,11 @@ static int tcindex_init(struct tcf_proto *tp) struct tcindex_data *p; DPRINTK("tcindex_init(tp %p)\n",tp); - p = kzalloc(sizeof(struct tcindex_data),GFP_KERNEL); + p = kmalloc(sizeof(struct tcindex_data),GFP_KERNEL); if (!p) return -ENOMEM; + memset(p, 0, sizeof(*p)); p->mask = 0xffff; p->hash = DEFAULT_HASH_SIZE; p->fall_through = 1; @@ -295,14 +296,16 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, err = -ENOMEM; if (!cp.perfect && !cp.h) { if (valid_perfect_hash(&cp)) { - cp.perfect = kcalloc(cp.hash, sizeof(*r), GFP_KERNEL); + cp.perfect = kmalloc(cp.hash * sizeof(*r), GFP_KERNEL); if (!cp.perfect) goto errout; + memset(cp.perfect, 0, cp.hash * sizeof(*r)); balloc = 1; } else { - cp.h = kcalloc(cp.hash, sizeof(f), GFP_KERNEL); + cp.h = kmalloc(cp.hash * sizeof(f), GFP_KERNEL); if (!cp.h) goto errout; + memset(cp.h, 0, cp.hash * sizeof(f)); balloc = 2; } } @@ -313,9 +316,10 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, r = tcindex_lookup(&cp, handle) ? : &new_filter_result; if (r == &new_filter_result) { - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc(sizeof(*f), GFP_KERNEL); if (!f) goto errout_alloc; + memset(f, 0, sizeof(*f)); } if (tb[TCA_TCINDEX_CLASSID-1]) { diff --git a/trunk/net/sched/cls_u32.c b/trunk/net/sched/cls_u32.c index eea366966740..d712edcd1bcf 100644 --- a/trunk/net/sched/cls_u32.c +++ b/trunk/net/sched/cls_u32.c @@ -307,21 +307,23 @@ static int u32_init(struct tcf_proto *tp) if (tp_c->q == tp->q) break; - root_ht = kzalloc(sizeof(*root_ht), GFP_KERNEL); + root_ht = kmalloc(sizeof(*root_ht), GFP_KERNEL); if (root_ht == NULL) return -ENOBUFS; + memset(root_ht, 0, sizeof(*root_ht)); root_ht->divisor = 0; root_ht->refcnt++; root_ht->handle = tp_c ? gen_new_htid(tp_c) : 0x80000000; root_ht->prio = tp->prio; if (tp_c == NULL) { - tp_c = kzalloc(sizeof(*tp_c), GFP_KERNEL); + tp_c = kmalloc(sizeof(*tp_c), GFP_KERNEL); if (tp_c == NULL) { kfree(root_ht); return -ENOBUFS; } + memset(tp_c, 0, sizeof(*tp_c)); tp_c->q = tp->q; tp_c->next = u32_list; u32_list = tp_c; @@ -569,9 +571,10 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, if (handle == 0) return -ENOMEM; } - ht = kzalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL); + ht = kmalloc(sizeof(*ht) + divisor*sizeof(void*), GFP_KERNEL); if (ht == NULL) return -ENOBUFS; + memset(ht, 0, sizeof(*ht) + divisor*sizeof(void*)); ht->tp_c = tp_c; ht->refcnt = 0; ht->divisor = divisor; @@ -614,16 +617,18 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, s = RTA_DATA(tb[TCA_U32_SEL-1]); - n = kzalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); + n = kmalloc(sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key), GFP_KERNEL); if (n == NULL) return -ENOBUFS; + memset(n, 0, sizeof(*n) + s->nkeys*sizeof(struct tc_u32_key)); #ifdef CONFIG_CLS_U32_PERF - n->pf = kzalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL); + n->pf = kmalloc(sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64), GFP_KERNEL); if (n->pf == NULL) { kfree(n); return -ENOBUFS; } + memset(n->pf, 0, sizeof(struct tc_u32_pcnt) + s->nkeys*sizeof(u64)); #endif memcpy(&n->sel, s, sizeof(*s) + s->nkeys*sizeof(struct tc_u32_key)); diff --git a/trunk/net/sched/em_meta.c b/trunk/net/sched/em_meta.c index 61e3b740ab1a..698372954f4d 100644 --- a/trunk/net/sched/em_meta.c +++ b/trunk/net/sched/em_meta.c @@ -773,9 +773,10 @@ static int em_meta_change(struct tcf_proto *tp, void *data, int len, TCF_META_ID(hdr->right.kind) > TCF_META_ID_MAX) goto errout; - meta = kzalloc(sizeof(*meta), GFP_KERNEL); + meta = kmalloc(sizeof(*meta), GFP_KERNEL); if (meta == NULL) goto errout; + memset(meta, 0, sizeof(*meta)); memcpy(&meta->lvalue.hdr, &hdr->left, sizeof(hdr->left)); memcpy(&meta->rvalue.hdr, &hdr->right, sizeof(hdr->right)); diff --git a/trunk/net/sched/ematch.c b/trunk/net/sched/ematch.c index 0fd0768a17c6..2405a86093a2 100644 --- a/trunk/net/sched/ematch.c +++ b/trunk/net/sched/ematch.c @@ -321,9 +321,10 @@ int tcf_em_tree_validate(struct tcf_proto *tp, struct rtattr *rta, list_len = RTA_PAYLOAD(rt_list); matches_len = tree_hdr->nmatches * sizeof(*em); - tree->matches = kzalloc(matches_len, GFP_KERNEL); + tree->matches = kmalloc(matches_len, GFP_KERNEL); if (tree->matches == NULL) goto errout; + memset(tree->matches, 0, matches_len); /* We do not use rtattr_parse_nested here because the maximum * number of attributes is unknown. This saves us the allocation diff --git a/trunk/net/sched/estimator.c b/trunk/net/sched/estimator.c index 0ebc98e9be2d..5d3ae03e22a7 100644 --- a/trunk/net/sched/estimator.c +++ b/trunk/net/sched/estimator.c @@ -139,10 +139,11 @@ int qdisc_new_estimator(struct tc_stats *stats, spinlock_t *stats_lock, struct r if (parm->interval < -2 || parm->interval > 3) return -EINVAL; - est = kzalloc(sizeof(*est), GFP_KERNEL); + est = kmalloc(sizeof(*est), GFP_KERNEL); if (est == NULL) return -ENOBUFS; + memset(est, 0, sizeof(*est)); est->interval = parm->interval + 2; est->stats = stats; est->stats_lock = stats_lock; diff --git a/trunk/net/sched/sch_api.c b/trunk/net/sched/sch_api.c index a19eff12cf78..c7844bacbbcb 100644 --- a/trunk/net/sched/sch_api.c +++ b/trunk/net/sched/sch_api.c @@ -430,7 +430,7 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) } #endif - err = -ENOENT; + err = -EINVAL; if (ops == NULL) goto err_out; diff --git a/trunk/net/sched/sch_cbq.c b/trunk/net/sched/sch_cbq.c index bac881bfe362..80b7f6a8d008 100644 --- a/trunk/net/sched/sch_cbq.c +++ b/trunk/net/sched/sch_cbq.c @@ -1926,9 +1926,10 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t } err = -ENOBUFS; - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kmalloc(sizeof(*cl), GFP_KERNEL); if (cl == NULL) goto failure; + memset(cl, 0, sizeof(*cl)); cl->R_tab = rtab; rtab = NULL; cl->refcnt = 1; diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index 0834c2ee9174..d735f51686a1 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -432,9 +432,10 @@ struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) size = QDISC_ALIGN(sizeof(*sch)); size += ops->priv_size + (QDISC_ALIGNTO - 1); - p = kzalloc(size, GFP_KERNEL); + p = kmalloc(size, GFP_KERNEL); if (!p) goto errout; + memset(p, 0, size); sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); sch->padded = (char *) sch - (char *) p; diff --git a/trunk/net/sched/sch_gred.c b/trunk/net/sched/sch_gred.c index 18e81a8ffb01..0cafdd5feb1b 100644 --- a/trunk/net/sched/sch_gred.c +++ b/trunk/net/sched/sch_gred.c @@ -406,9 +406,10 @@ static inline int gred_change_vq(struct Qdisc *sch, int dp, struct gred_sched_data *q; if (table->tab[dp] == NULL) { - table->tab[dp] = kzalloc(sizeof(*q), GFP_KERNEL); + table->tab[dp] = kmalloc(sizeof(*q), GFP_KERNEL); if (table->tab[dp] == NULL) return -ENOMEM; + memset(table->tab[dp], 0, sizeof(*q)); } q = table->tab[dp]; diff --git a/trunk/net/sched/sch_hfsc.c b/trunk/net/sched/sch_hfsc.c index 6a6735a2ed35..6b1b4a981e88 100644 --- a/trunk/net/sched/sch_hfsc.c +++ b/trunk/net/sched/sch_hfsc.c @@ -1123,9 +1123,10 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (rsc == NULL && fsc == NULL) return -EINVAL; - cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL); + cl = kmalloc(sizeof(struct hfsc_class), GFP_KERNEL); if (cl == NULL) return -ENOBUFS; + memset(cl, 0, sizeof(struct hfsc_class)); if (rsc != NULL) hfsc_change_rsc(cl, rsc, 0); diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 880a3394a51f..cc5f339e6f91 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -1559,9 +1559,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, goto failure; } err = -ENOBUFS; - if ((cl = kzalloc(sizeof(*cl), GFP_KERNEL)) == NULL) + if ((cl = kmalloc(sizeof(*cl), GFP_KERNEL)) == NULL) goto failure; + memset(cl, 0, sizeof(*cl)); cl->refcnt = 1; INIT_LIST_HEAD(&cl->sibling); INIT_LIST_HEAD(&cl->hlist); diff --git a/trunk/net/sched/sch_netem.c b/trunk/net/sched/sch_netem.c index a08ec4c7c55d..c5bd8064e6d8 100644 --- a/trunk/net/sched/sch_netem.c +++ b/trunk/net/sched/sch_netem.c @@ -148,8 +148,7 @@ static long tabledist(unsigned long mu, long sigma, static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct netem_sched_data *q = qdisc_priv(sch); - /* We don't fill cb now as skb_unshare() may invalidate it */ - struct netem_skb_cb *cb; + struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; struct sk_buff *skb2; int ret; int count = 1; @@ -201,7 +200,6 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } - cb = (struct netem_skb_cb *)skb->cb; if (q->gap == 0 /* not doing reordering */ || q->counter < q->gap /* inside last reordering gap */ || q->reorder < get_crandom(&q->reorder_cor)) { diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 27329ce9c311..9d05e13e92f6 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -441,8 +441,7 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, /* If the primary path is changing, assume that the * user wants to use this new path. */ - if ((transport->state == SCTP_ACTIVE) || - (transport->state == SCTP_UNKNOWN)) + if (transport->state != SCTP_INACTIVE) asoc->peer.active_path = transport; /* @@ -533,11 +532,11 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, port = addr->v4.sin_port; SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ", - " port: %d state:%d\n", + " port: %d state:%s\n", asoc, addr, addr->v4.sin_port, - peer_state); + peer_state == SCTP_UNKNOWN?"UNKNOWN":"ACTIVE"); /* Set the port if it has not been set yet. */ if (0 == asoc->peer.port) @@ -546,12 +545,9 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc, /* Check to see if this is a duplicate. */ peer = sctp_assoc_lookup_paddr(asoc, addr); if (peer) { - if (peer->state == SCTP_UNKNOWN) { - if (peer_state == SCTP_ACTIVE) - peer->state = SCTP_ACTIVE; - if (peer_state == SCTP_UNCONFIRMED) - peer->state = SCTP_UNCONFIRMED; - } + if (peer_state == SCTP_ACTIVE && + peer->state == SCTP_UNKNOWN) + peer->state = SCTP_ACTIVE; return peer; } @@ -743,8 +739,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, list_for_each(pos, &asoc->peer.transport_addr_list) { t = list_entry(pos, struct sctp_transport, transports); - if ((t->state == SCTP_INACTIVE) || - (t->state == SCTP_UNCONFIRMED)) + if (t->state == SCTP_INACTIVE) continue; if (!first || t->last_time_heard > first->last_time_heard) { second = first; @@ -764,8 +759,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc, * [If the primary is active but not most recent, bump the most * recently used transport.] */ - if (((asoc->peer.primary_path->state == SCTP_ACTIVE) || - (asoc->peer.primary_path->state == SCTP_UNKNOWN)) && + if (asoc->peer.primary_path->state != SCTP_INACTIVE && first != asoc->peer.primary_path) { second = first; first = asoc->peer.primary_path; @@ -1060,7 +1054,7 @@ void sctp_assoc_update(struct sctp_association *asoc, transports); if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr)) sctp_assoc_add_peer(asoc, &trans->ipaddr, - GFP_ATOMIC, trans->state); + GFP_ATOMIC, SCTP_ACTIVE); } asoc->ctsn_ack_point = asoc->next_tsn - 1; @@ -1100,8 +1094,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc) /* Try to find an active transport. */ - if ((t->state == SCTP_ACTIVE) || - (t->state == SCTP_UNKNOWN)) { + if (t->state != SCTP_INACTIVE) { break; } else { /* Keep track of the next transport in case diff --git a/trunk/net/sctp/bind_addr.c b/trunk/net/sctp/bind_addr.c index 2b9c12a170e5..2b962627f631 100644 --- a/trunk/net/sctp/bind_addr.c +++ b/trunk/net/sctp/bind_addr.c @@ -146,7 +146,7 @@ void sctp_bind_addr_free(struct sctp_bind_addr *bp) /* Add an address to the bind address list in the SCTP_bind_addr structure. */ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, - __u8 use_as_src, gfp_t gfp) + gfp_t gfp) { struct sctp_sockaddr_entry *addr; @@ -163,8 +163,6 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, if (!addr->a.v4.sin_port) addr->a.v4.sin_port = bp->port; - addr->use_as_src = use_as_src; - INIT_LIST_HEAD(&addr->list); list_add_tail(&addr->list, &bp->address_list); SCTP_DBG_OBJCNT_INC(addr); @@ -276,7 +274,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, } af->from_addr_param(&addr, rawaddr, port, 0); - retval = sctp_add_bind_addr(bp, &addr, 1, gfp); + retval = sctp_add_bind_addr(bp, &addr, gfp); if (retval) { /* Can't finish building the list, clean up. */ sctp_bind_addr_clean(bp); @@ -369,7 +367,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest, (((AF_INET6 == addr->sa.sa_family) && (flags & SCTP_ADDR6_ALLOWED) && (flags & SCTP_ADDR6_PEERSUPP)))) - error = sctp_add_bind_addr(dest, addr, 1, gfp); + error = sctp_add_bind_addr(dest, addr, gfp); } return error; diff --git a/trunk/net/sctp/endpointola.c b/trunk/net/sctp/endpointola.c index ffda1d680529..67bd53070ee0 100644 --- a/trunk/net/sctp/endpointola.c +++ b/trunk/net/sctp/endpointola.c @@ -158,12 +158,6 @@ void sctp_endpoint_add_asoc(struct sctp_endpoint *ep, void sctp_endpoint_free(struct sctp_endpoint *ep) { ep->base.dead = 1; - - ep->base.sk->sk_state = SCTP_SS_CLOSED; - - /* Unlink this endpoint, so we can't find it again! */ - sctp_unhash_endpoint(ep); - sctp_endpoint_put(ep); } @@ -172,6 +166,11 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep) { SCTP_ASSERT(ep->base.dead, "Endpoint is not dead", return); + ep->base.sk->sk_state = SCTP_SS_CLOSED; + + /* Unlink this endpoint, so we can't find it again! */ + sctp_unhash_endpoint(ep); + /* Free up the HMAC transform. */ sctp_crypto_free_tfm(sctp_sk(ep->base.sk)->hmac); diff --git a/trunk/net/sctp/ipv6.c b/trunk/net/sctp/ipv6.c index 99c0cefc04e0..8ef08070c8b6 100644 --- a/trunk/net/sctp/ipv6.c +++ b/trunk/net/sctp/ipv6.c @@ -290,8 +290,7 @@ static void sctp_v6_get_saddr(struct sctp_association *asoc, sctp_read_lock(addr_lock); list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if ((laddr->use_as_src) && - (laddr->a.sa.sa_family == AF_INET6) && + if ((laddr->a.sa.sa_family == AF_INET6) && (scope <= sctp_scope(&laddr->a))) { bmatchlen = sctp_v6_addr_match_len(daddr, &laddr->a); if (!baddr || (matchlen < bmatchlen)) { diff --git a/trunk/net/sctp/outqueue.c b/trunk/net/sctp/outqueue.c index 30b710c54e64..e5faa351aaad 100644 --- a/trunk/net/sctp/outqueue.c +++ b/trunk/net/sctp/outqueue.c @@ -691,8 +691,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) if (!new_transport) { new_transport = asoc->peer.active_path; - } else if ((new_transport->state == SCTP_INACTIVE) || - (new_transport->state == SCTP_UNCONFIRMED)) { + } else if (new_transport->state == SCTP_INACTIVE) { /* If the chunk is Heartbeat or Heartbeat Ack, * send it to chunk->transport, even if it's * inactive. @@ -849,8 +848,7 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) */ new_transport = chunk->transport; if (!new_transport || - ((new_transport->state == SCTP_INACTIVE) || - (new_transport->state == SCTP_UNCONFIRMED))) + new_transport->state == SCTP_INACTIVE) new_transport = asoc->peer.active_path; /* Change packets if necessary. */ @@ -1466,8 +1464,7 @@ static void sctp_check_transmitted(struct sctp_outq *q, /* Mark the destination transport address as * active if it is not so marked. */ - if ((transport->state == SCTP_INACTIVE) || - (transport->state == SCTP_UNCONFIRMED)) { + if (transport->state == SCTP_INACTIVE) { sctp_assoc_control_transport( transport->asoc, transport, diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 1ab03a27a76e..816c033d7886 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -240,7 +240,7 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, (((AF_INET6 == addr->a.sa.sa_family) && (copy_flags & SCTP_ADDR6_ALLOWED) && (copy_flags & SCTP_ADDR6_PEERSUPP)))) { - error = sctp_add_bind_addr(bp, &addr->a, 1, + error = sctp_add_bind_addr(bp, &addr->a, GFP_ATOMIC); if (error) goto end_copy; @@ -486,8 +486,6 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if (!laddr->use_as_src) - continue; sctp_v4_dst_saddr(&dst_saddr, dst, bp->port); if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) goto out_unlock; @@ -508,8 +506,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc, list_for_each(pos, &bp->address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if ((laddr->use_as_src) && - (AF_INET == laddr->a.sa.sa_family)) { + if (AF_INET == laddr->a.sa.sa_family) { fl.fl4_src = laddr->a.v4.sin_addr.s_addr; if (!ip_route_output_key(&rt, &fl)) { dst = &rt->u.dst; diff --git a/trunk/net/sctp/sm_make_chunk.c b/trunk/net/sctp/sm_make_chunk.c index 4f11f5858209..2a8773691695 100644 --- a/trunk/net/sctp/sm_make_chunk.c +++ b/trunk/net/sctp/sm_make_chunk.c @@ -1493,7 +1493,7 @@ struct sctp_association *sctp_unpack_cookie( /* Also, add the destination address. */ if (list_empty(&retval->base.bind_addr.address_list)) { - sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, 1, + sctp_add_bind_addr(&retval->base.bind_addr, &chunk->dest, GFP_ATOMIC); } @@ -2017,7 +2017,7 @@ static int sctp_process_param(struct sctp_association *asoc, af->from_addr_param(&addr, param.addr, asoc->peer.port, 0); scope = sctp_scope(peer_addr); if (sctp_in_scope(&addr, scope)) - if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED)) + if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_ACTIVE)) return 0; break; @@ -2418,7 +2418,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc, * Due to Resource Shortage'. */ - peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_UNCONFIRMED); + peer = sctp_assoc_add_peer(asoc, &addr, GFP_ATOMIC, SCTP_ACTIVE); if (!peer) return SCTP_ERROR_RSRC_LOW; @@ -2565,7 +2565,6 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, union sctp_addr_param *addr_param; struct list_head *pos; struct sctp_transport *transport; - struct sctp_sockaddr_entry *saddr; int retval = 0; addr_param = (union sctp_addr_param *) @@ -2579,11 +2578,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, case SCTP_PARAM_ADD_IP: sctp_local_bh_disable(); sctp_write_lock(&asoc->base.addr_lock); - list_for_each(pos, &bp->address_list) { - saddr = list_entry(pos, struct sctp_sockaddr_entry, list); - if (sctp_cmp_addr_exact(&saddr->a, &addr)) - saddr->use_as_src = 1; - } + retval = sctp_add_bind_addr(bp, &addr, GFP_ATOMIC); sctp_write_unlock(&asoc->base.addr_lock); sctp_local_bh_enable(); break; @@ -2596,7 +2591,6 @@ static int sctp_asconf_param_success(struct sctp_association *asoc, list_for_each(pos, &asoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); - dst_release(transport->dst); sctp_transport_route(transport, NULL, sctp_sk(asoc->base.sk)); } diff --git a/trunk/net/sctp/sm_sideeffect.c b/trunk/net/sctp/sm_sideeffect.c index 9c10bdec1afe..c5beb2ad7ef7 100644 --- a/trunk/net/sctp/sm_sideeffect.c +++ b/trunk/net/sctp/sm_sideeffect.c @@ -430,11 +430,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, /* The check for association's overall error counter exceeding the * threshold is done in the state function. */ - /* When probing UNCONFIRMED addresses, the association overall - * error count is NOT incremented - */ - if (transport->state != SCTP_UNCONFIRMED) - asoc->overall_error_count++; + asoc->overall_error_count++; if (transport->state != SCTP_INACTIVE && (transport->error_count++ >= transport->pathmaxrxt)) { @@ -614,7 +610,7 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, /* Mark the destination transport address as active if it is not so * marked. */ - if ((t->state == SCTP_INACTIVE) || (t->state == SCTP_UNCONFIRMED)) + if (t->state == SCTP_INACTIVE) sctp_assoc_control_transport(asoc, t, SCTP_TRANSPORT_UP, SCTP_HEARTBEAT_SUCCESS); @@ -624,10 +620,6 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, */ hbinfo = (sctp_sender_hb_info_t *) chunk->skb->data; sctp_transport_update_rto(t, (jiffies - hbinfo->sent_at)); - - /* Update the heartbeat timer. */ - if (!mod_timer(&t->hb_timer, sctp_transport_timeout(t))) - sctp_transport_hold(t); } /* Helper function to do a transport reset at the expiry of the hearbeat diff --git a/trunk/net/sctp/sm_statefuns.c b/trunk/net/sctp/sm_statefuns.c index ead3f1b0ea3d..9e58144f4851 100644 --- a/trunk/net/sctp/sm_statefuns.c +++ b/trunk/net/sctp/sm_statefuns.c @@ -846,7 +846,6 @@ static sctp_disposition_t sctp_sf_heartbeat(const struct sctp_endpoint *ep, hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t)); hbinfo.daddr = transport->ipaddr; hbinfo.sent_at = jiffies; - hbinfo.hb_nonce = transport->hb_nonce; /* Send a heartbeat to our peer. */ paylen = sizeof(sctp_sender_hb_info_t); @@ -1049,10 +1048,6 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep, return SCTP_DISPOSITION_DISCARD; } - /* Validate the 64-bit random nonce. */ - if (hbinfo->hb_nonce != link->hb_nonce) - return SCTP_DISPOSITION_DISCARD; - max_interval = link->hbinterval + link->rto; /* Check if the timestamp looks valid. */ @@ -5283,6 +5278,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, datalen -= sizeof(sctp_data_chunk_t); deliver = SCTP_CMD_CHUNK_ULP; + chunk->data_accepted = 1; /* Think about partial delivery. */ if ((datalen >= asoc->rwnd) && (!asoc->ulpq.pd_mode)) { @@ -5361,8 +5357,6 @@ static int sctp_eat_data(const struct sctp_association *asoc, if (SCTP_CMD_CHUNK_ULP == deliver) sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_TSN, SCTP_U32(tsn)); - chunk->data_accepted = 1; - /* Note: Some chunks may get overcounted (if we drop) or overcounted * if we renege and the chunk arrives again. */ diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 54722e622e6d..0a2c71d0d8aa 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -369,7 +369,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len) /* Use GFP_ATOMIC since BHs are disabled. */ addr->v4.sin_port = ntohs(addr->v4.sin_port); - ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); + ret = sctp_add_bind_addr(bp, addr, GFP_ATOMIC); addr->v4.sin_port = htons(addr->v4.sin_port); sctp_write_unlock(&ep->base.addr_lock); sctp_local_bh_enable(); @@ -491,7 +491,6 @@ static int sctp_send_asconf_add_ip(struct sock *sk, struct sctp_chunk *chunk; struct sctp_sockaddr_entry *laddr; union sctp_addr *addr; - union sctp_addr saveaddr; void *addr_buf; struct sctp_af *af; struct list_head *pos; @@ -559,26 +558,14 @@ static int sctp_send_asconf_add_ip(struct sock *sk, } retval = sctp_send_asconf(asoc, chunk); - if (retval) - goto out; - /* Add the new addresses to the bind address list with - * use_as_src set to 0. + /* FIXME: After sending the add address ASCONF chunk, we + * cannot append the address to the association's binding + * address list, because the new address may be used as the + * source of a message sent to the peer before the ASCONF + * chunk is received by the peer. So we should wait until + * ASCONF_ACK is received. */ - sctp_local_bh_disable(); - sctp_write_lock(&asoc->base.addr_lock); - addr_buf = addrs; - for (i = 0; i < addrcnt; i++) { - addr = (union sctp_addr *)addr_buf; - af = sctp_get_af_specific(addr->v4.sin_family); - memcpy(&saveaddr, addr, af->sockaddr_len); - saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); - retval = sctp_add_bind_addr(bp, &saveaddr, 0, - GFP_ATOMIC); - addr_buf += af->sockaddr_len; - } - sctp_write_unlock(&asoc->base.addr_lock); - sctp_local_bh_enable(); } out: @@ -689,15 +676,12 @@ static int sctp_send_asconf_del_ip(struct sock *sk, struct sctp_sock *sp; struct sctp_endpoint *ep; struct sctp_association *asoc; - struct sctp_transport *transport; struct sctp_bind_addr *bp; struct sctp_chunk *chunk; union sctp_addr *laddr; - union sctp_addr saveaddr; void *addr_buf; struct sctp_af *af; - struct list_head *pos, *pos1; - struct sctp_sockaddr_entry *saddr; + struct list_head *pos; int i; int retval = 0; @@ -764,42 +748,14 @@ static int sctp_send_asconf_del_ip(struct sock *sk, goto out; } - /* Reset use_as_src flag for the addresses in the bind address - * list that are to be deleted. - */ - sctp_local_bh_disable(); - sctp_write_lock(&asoc->base.addr_lock); - addr_buf = addrs; - for (i = 0; i < addrcnt; i++) { - laddr = (union sctp_addr *)addr_buf; - af = sctp_get_af_specific(laddr->v4.sin_family); - memcpy(&saveaddr, laddr, af->sockaddr_len); - saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port); - list_for_each(pos1, &bp->address_list) { - saddr = list_entry(pos1, - struct sctp_sockaddr_entry, - list); - if (sctp_cmp_addr_exact(&saddr->a, &saveaddr)) - saddr->use_as_src = 0; - } - addr_buf += af->sockaddr_len; - } - sctp_write_unlock(&asoc->base.addr_lock); - sctp_local_bh_enable(); + retval = sctp_send_asconf(asoc, chunk); - /* Update the route and saddr entries for all the transports - * as some of the addresses in the bind address list are - * about to be deleted and cannot be used as source addresses. + /* FIXME: After sending the delete address ASCONF chunk, we + * cannot remove the addresses from the association's bind + * address list, because there maybe some packet send to + * the delete addresses, so we should wait until ASCONF_ACK + * packet is received. */ - list_for_each(pos1, &asoc->peer.transport_addr_list) { - transport = list_entry(pos1, struct sctp_transport, - transports); - dst_release(transport->dst); - sctp_transport_route(transport, NULL, - sctp_sk(asoc->base.sk)); - } - - retval = sctp_send_asconf(asoc, chunk); } out: return retval; @@ -5021,7 +4977,7 @@ static struct sctp_bind_bucket *sctp_bucket_create( /* Caller must hold hashbucket lock for this tb with local BH disabled */ static void sctp_bucket_destroy(struct sctp_bind_bucket *pp) { - if (pp && hlist_empty(&pp->owner)) { + if (hlist_empty(&pp->owner)) { if (pp->next) pp->next->pprev = pp->pprev; *(pp->pprev) = pp->next; diff --git a/trunk/net/sctp/transport.c b/trunk/net/sctp/transport.c index 2763aa93de1a..160f62ad1cc5 100644 --- a/trunk/net/sctp/transport.c +++ b/trunk/net/sctp/transport.c @@ -49,7 +49,6 @@ */ #include -#include #include #include @@ -86,6 +85,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->init_sent_count = 0; + peer->state = SCTP_ACTIVE; peer->param_flags = SPP_HB_DISABLE | SPP_PMTUD_ENABLE | SPP_SACKDELAY_ENABLE; @@ -109,9 +109,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, peer->hb_timer.function = sctp_generate_heartbeat_event; peer->hb_timer.data = (unsigned long)peer; - /* Initialize the 64-bit random nonce sent with heartbeat. */ - get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce)); - atomic_set(&peer->refcnt, 1); peer->dead = 0; @@ -520,9 +517,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport, unsigned long sctp_transport_timeout(struct sctp_transport *t) { unsigned long timeout; - timeout = t->rto + sctp_jitter(t->rto); - if (t->state != SCTP_UNCONFIRMED) - timeout += t->hbinterval; + timeout = t->hbinterval + t->rto + sctp_jitter(t->rto); timeout += jiffies; return timeout; } diff --git a/trunk/net/sunrpc/auth_gss/auth_gss.c b/trunk/net/sunrpc/auth_gss/auth_gss.c index 4a9aa9393b97..519ebc17c028 100644 --- a/trunk/net/sunrpc/auth_gss/auth_gss.c +++ b/trunk/net/sunrpc/auth_gss/auth_gss.c @@ -225,8 +225,9 @@ gss_alloc_context(void) { struct gss_cl_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (ctx != NULL) { + memset(ctx, 0, sizeof(*ctx)); ctx->gc_proc = RPC_GSS_PROC_DATA; ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ spin_lock_init(&ctx->gc_seq_lock); @@ -390,8 +391,9 @@ gss_alloc_msg(struct gss_auth *gss_auth, uid_t uid) { struct gss_upcall_msg *gss_msg; - gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); + gss_msg = kmalloc(sizeof(*gss_msg), GFP_KERNEL); if (gss_msg != NULL) { + memset(gss_msg, 0, sizeof(*gss_msg)); INIT_LIST_HEAD(&gss_msg->list); rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); init_waitqueue_head(&gss_msg->waitqueue); @@ -774,9 +776,10 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) dprintk("RPC: gss_create_cred for uid %d, flavor %d\n", acred->uid, auth->au_flavor); - if (!(cred = kzalloc(sizeof(*cred), GFP_KERNEL))) + if (!(cred = kmalloc(sizeof(*cred), GFP_KERNEL))) goto out_err; + memset(cred, 0, sizeof(*cred)); atomic_set(&cred->gc_count, 1); cred->gc_uid = acred->uid; /* diff --git a/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c b/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c index 70e1e53a632b..b8714a87b34c 100644 --- a/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/trunk/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -129,8 +129,9 @@ gss_import_sec_context_kerberos(const void *p, const void *end = (const void *)((const char *)p + len); struct krb5_ctx *ctx; - if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL))) goto out_err; + memset(ctx, 0, sizeof(*ctx)); p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); if (IS_ERR(p)) diff --git a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c index 3db745379d06..d88468d21c37 100644 --- a/trunk/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/trunk/net/sunrpc/auth_gss/gss_mech_switch.c @@ -237,8 +237,9 @@ gss_import_sec_context(const void *input_token, size_t bufsize, struct gss_api_mech *mech, struct gss_ctx **ctx_id) { - if (!(*ctx_id = kzalloc(sizeof(**ctx_id), GFP_KERNEL))) + if (!(*ctx_id = kmalloc(sizeof(**ctx_id), GFP_KERNEL))) return GSS_S_FAILURE; + memset(*ctx_id, 0, sizeof(**ctx_id)); (*ctx_id)->mech_type = gss_mech_get(mech); return mech->gm_ops diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c index 88dcb52d171b..3d0432aa45c1 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_mech.c @@ -152,8 +152,9 @@ gss_import_sec_context_spkm3(const void *p, size_t len, const void *end = (const void *)((const char *)p + len); struct spkm3_ctx *ctx; - if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) + if (!(ctx = kmalloc(sizeof(*ctx), GFP_KERNEL))) goto out_err; + memset(ctx, 0, sizeof(*ctx)); p = simple_get_netobj(p, end, &ctx->ctx_id); if (IS_ERR(p)) diff --git a/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c b/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c index 854a983ccf26..af0d7ce74686 100644 --- a/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c +++ b/trunk/net/sunrpc/auth_gss/gss_spkm3_token.c @@ -90,9 +90,10 @@ asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits) int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, int explen) { - if (!(out->data = kzalloc(explen,GFP_KERNEL))) + if (!(out->data = kmalloc(explen,GFP_KERNEL))) return 0; out->len = explen; + memset(out->data, 0, explen); memcpy(out->data, in, enclen); return 1; } diff --git a/trunk/net/sunrpc/cache.c b/trunk/net/sunrpc/cache.c index 00cb388ece03..7026b0866b7b 100644 --- a/trunk/net/sunrpc/cache.c +++ b/trunk/net/sunrpc/cache.c @@ -71,12 +71,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, new = detail->alloc(); if (!new) return NULL; - /* must fully initialise 'new', else - * we might get lose if we need to - * cache_put it soon. - */ cache_init(new); - detail->init(new, key); write_lock(&detail->hash_lock); @@ -90,6 +85,7 @@ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail, return tmp; } } + detail->init(new, key); new->next = *head; *head = new; detail->entries++; diff --git a/trunk/net/sunrpc/clnt.c b/trunk/net/sunrpc/clnt.c index d6409e757219..aa8965e9d307 100644 --- a/trunk/net/sunrpc/clnt.c +++ b/trunk/net/sunrpc/clnt.c @@ -125,9 +125,10 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, goto out_err; err = -ENOMEM; - clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); + clnt = kmalloc(sizeof(*clnt), GFP_KERNEL); if (!clnt) goto out_err; + memset(clnt, 0, sizeof(*clnt)); atomic_set(&clnt->cl_users, 0); atomic_set(&clnt->cl_count, 1); clnt->cl_parent = clnt; @@ -921,43 +922,26 @@ call_transmit(struct rpc_task *task) task->tk_status = xprt_prepare_transmit(task); if (task->tk_status != 0) return; - task->tk_action = call_transmit_status; /* Encode here so that rpcsec_gss can use correct sequence number. */ if (rpc_task_need_encode(task)) { - BUG_ON(task->tk_rqstp->rq_bytes_sent != 0); + task->tk_rqstp->rq_bytes_sent = 0; call_encode(task); /* Did the encode result in an error condition? */ if (task->tk_status != 0) - return; + goto out_nosend; } + task->tk_action = call_transmit_status; xprt_transmit(task); if (task->tk_status < 0) return; - /* - * On success, ensure that we call xprt_end_transmit() before sleeping - * in order to allow access to the socket to other RPC requests. - */ - call_transmit_status(task); - if (task->tk_msg.rpc_proc->p_decode != NULL) - return; - task->tk_action = rpc_exit_task; - rpc_wake_up_task(task); -} - -/* - * 5a. Handle cleanup after a transmission - */ -static void -call_transmit_status(struct rpc_task *task) -{ - task->tk_action = call_status; - /* - * Special case: if we've been waiting on the socket's write_space() - * callback, then don't call xprt_end_transmit(). - */ - if (task->tk_status == -EAGAIN) - return; - xprt_end_transmit(task); + if (!task->tk_msg.rpc_proc->p_decode) { + task->tk_action = rpc_exit_task; + rpc_wake_up_task(task); + } + return; +out_nosend: + /* release socket write lock before attempting to handle error */ + xprt_abort_transmit(task); rpc_task_force_reencode(task); } @@ -1009,7 +993,18 @@ call_status(struct rpc_task *task) } /* - * 6a. Handle RPC timeout + * 6a. Handle transmission errors. + */ +static void +call_transmit_status(struct rpc_task *task) +{ + if (task->tk_status != -EAGAIN) + rpc_task_force_reencode(task); + call_status(task); +} + +/* + * 6b. Handle RPC timeout * We do not release the request slot, so we keep using the * same XID for all retransmits. */ diff --git a/trunk/net/sunrpc/rpc_pipe.c b/trunk/net/sunrpc/rpc_pipe.c index a3bd2db2e024..dc6cb93c8830 100644 --- a/trunk/net/sunrpc/rpc_pipe.c +++ b/trunk/net/sunrpc/rpc_pipe.c @@ -667,11 +667,10 @@ rpc_mkdir(char *path, struct rpc_clnt *rpc_client) RPCAUTH_info, RPCAUTH_EOF); if (error) goto err_depopulate; - dget(dentry); out: mutex_unlock(&dir->i_mutex); rpc_release_path(&nd); - return dentry; + return dget(dentry); err_depopulate: rpc_depopulate(dentry); __rpc_rmdir(dir, dentry); @@ -732,11 +731,10 @@ rpc_mkpipe(char *path, void *private, struct rpc_pipe_ops *ops, int flags) rpci->flags = flags; rpci->ops = ops; inode_dir_notify(dir, DN_CREATE); - dget(dentry); out: mutex_unlock(&dir->i_mutex); rpc_release_path(&nd); - return dentry; + return dget(dentry); err_dput: dput(dentry); dentry = ERR_PTR(-ENOMEM); diff --git a/trunk/net/sunrpc/stats.c b/trunk/net/sunrpc/stats.c index bd98124c3a64..15c2db26767b 100644 --- a/trunk/net/sunrpc/stats.c +++ b/trunk/net/sunrpc/stats.c @@ -114,8 +114,13 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { */ struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { + unsigned int ops = clnt->cl_maxproc; + size_t size = ops * sizeof(struct rpc_iostats); struct rpc_iostats *new; - new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); + + new = kmalloc(size, GFP_KERNEL); + if (new) + memset(new, 0 , size); return new; } EXPORT_SYMBOL(rpc_alloc_iostats); diff --git a/trunk/net/sunrpc/svc.c b/trunk/net/sunrpc/svc.c index b76a227dd3ad..01ba60a49572 100644 --- a/trunk/net/sunrpc/svc.c +++ b/trunk/net/sunrpc/svc.c @@ -32,8 +32,9 @@ svc_create(struct svc_program *prog, unsigned int bufsize) int vers; unsigned int xdrsize; - if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) + if (!(serv = kmalloc(sizeof(*serv), GFP_KERNEL))) return NULL; + memset(serv, 0, sizeof(*serv)); serv->sv_name = prog->pg_name; serv->sv_program = prog; serv->sv_nrthreads = 1; @@ -158,10 +159,11 @@ svc_create_thread(svc_thread_fn func, struct svc_serv *serv) struct svc_rqst *rqstp; int error = -ENOMEM; - rqstp = kzalloc(sizeof(*rqstp), GFP_KERNEL); + rqstp = kmalloc(sizeof(*rqstp), GFP_KERNEL); if (!rqstp) goto out; + memset(rqstp, 0, sizeof(*rqstp)); init_waitqueue_head(&rqstp->rq_wait); if (!(rqstp->rq_argp = kmalloc(serv->sv_xdrsize, GFP_KERNEL)) diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index d9a95732df46..a27905a0ad27 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -1322,10 +1322,11 @@ svc_setup_socket(struct svc_serv *serv, struct socket *sock, struct sock *inet; dprintk("svc: svc_setup_socket %p\n", sock); - if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { + if (!(svsk = kmalloc(sizeof(*svsk), GFP_KERNEL))) { *errp = -ENOMEM; return NULL; } + memset(svsk, 0, sizeof(*svsk)); inet = sock->sk; diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index e8c2bc4977f3..02060d0e7be8 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -707,9 +707,12 @@ int xprt_prepare_transmit(struct rpc_task *task) return err; } -void xprt_end_transmit(struct rpc_task *task) +void +xprt_abort_transmit(struct rpc_task *task) { - xprt_release_write(task->tk_xprt, task); + struct rpc_xprt *xprt = task->tk_xprt; + + xprt_release_write(xprt, task); } /** @@ -758,6 +761,8 @@ void xprt_transmit(struct rpc_task *task) task->tk_status = -ENOTCONN; else if (!req->rq_received) rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer); + + xprt->ops->release_xprt(xprt, task); spin_unlock_bh(&xprt->transport_lock); return; } @@ -767,8 +772,18 @@ void xprt_transmit(struct rpc_task *task) * schedq, and being picked up by a parallel run of rpciod(). */ task->tk_status = status; - if (status == -ECONNREFUSED) + + switch (status) { + case -ECONNREFUSED: rpc_sleep_on(&xprt->sending, task, NULL, NULL); + case -EAGAIN: + case -ENOTCONN: + return; + default: + break; + } + xprt_release_write(xprt, task); + return; } static inline void do_xprt_reserve(struct rpc_task *task) @@ -893,8 +908,9 @@ static struct rpc_xprt *xprt_setup(int proto, struct sockaddr_in *ap, struct rpc struct rpc_xprt *xprt; struct rpc_rqst *req; - if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) + if ((xprt = kmalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) return ERR_PTR(-ENOMEM); + memset(xprt, 0, sizeof(*xprt)); /* Nnnngh! */ xprt->addr = *ap; diff --git a/trunk/net/sunrpc/xprtsock.c b/trunk/net/sunrpc/xprtsock.c index 441bd53f5eca..21006b109101 100644 --- a/trunk/net/sunrpc/xprtsock.c +++ b/trunk/net/sunrpc/xprtsock.c @@ -413,33 +413,6 @@ static int xs_tcp_send_request(struct rpc_task *task) return status; } -/** - * xs_tcp_release_xprt - clean up after a tcp transmission - * @xprt: transport - * @task: rpc task - * - * This cleans up if an error causes us to abort the transmission of a request. - * In this case, the socket may need to be reset in order to avoid confusing - * the server. - */ -static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) -{ - struct rpc_rqst *req; - - if (task != xprt->snd_task) - return; - if (task == NULL) - goto out_release; - req = task->tk_rqstp; - if (req->rq_bytes_sent == 0) - goto out_release; - if (req->rq_bytes_sent == req->rq_snd_buf.len) - goto out_release; - set_bit(XPRT_CLOSE_WAIT, &task->tk_xprt->state); -out_release: - xprt_release_xprt(xprt, task); -} - /** * xs_close - close a socket * @xprt: transport @@ -1277,7 +1250,7 @@ static struct rpc_xprt_ops xs_udp_ops = { static struct rpc_xprt_ops xs_tcp_ops = { .reserve_xprt = xprt_reserve_xprt, - .release_xprt = xs_tcp_release_xprt, + .release_xprt = xprt_release_xprt, .set_port = xs_set_port, .connect = xs_connect, .buf_alloc = rpc_malloc, @@ -1303,9 +1276,10 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) xprt->max_reqs = xprt_udp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); - xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); + xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; + memset(xprt->slot, 0, slot_table_size); xprt->prot = IPPROTO_UDP; xprt->port = xs_get_random_port(); @@ -1344,9 +1318,10 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) xprt->max_reqs = xprt_tcp_slot_table_entries; slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); - xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); + xprt->slot = kmalloc(slot_table_size, GFP_KERNEL); if (xprt->slot == NULL) return -ENOMEM; + memset(xprt->slot, 0, slot_table_size); xprt->prot = IPPROTO_TCP; xprt->port = xs_get_random_port(); diff --git a/trunk/net/tipc/bearer.c b/trunk/net/tipc/bearer.c index 75a5968c2139..7ef17a449cfd 100644 --- a/trunk/net/tipc/bearer.c +++ b/trunk/net/tipc/bearer.c @@ -665,9 +665,11 @@ int tipc_bearer_init(void) int res; write_lock_bh(&tipc_net_lock); - tipc_bearers = kcalloc(MAX_BEARERS, sizeof(struct bearer), GFP_ATOMIC); - media_list = kcalloc(MAX_MEDIA, sizeof(struct media), GFP_ATOMIC); + tipc_bearers = kmalloc(MAX_BEARERS * sizeof(struct bearer), GFP_ATOMIC); + media_list = kmalloc(MAX_MEDIA * sizeof(struct media), GFP_ATOMIC); if (tipc_bearers && media_list) { + memset(tipc_bearers, 0, MAX_BEARERS * sizeof(struct bearer)); + memset(media_list, 0, MAX_MEDIA * sizeof(struct media)); res = TIPC_OK; } else { kfree(tipc_bearers); diff --git a/trunk/net/tipc/cluster.c b/trunk/net/tipc/cluster.c index b46b5188a9fd..1dcb6940e338 100644 --- a/trunk/net/tipc/cluster.c +++ b/trunk/net/tipc/cluster.c @@ -57,25 +57,29 @@ struct cluster *tipc_cltr_create(u32 addr) struct _zone *z_ptr; struct cluster *c_ptr; int max_nodes; + int alloc; - c_ptr = kzalloc(sizeof(*c_ptr), GFP_ATOMIC); + c_ptr = (struct cluster *)kmalloc(sizeof(*c_ptr), GFP_ATOMIC); if (c_ptr == NULL) { warn("Cluster creation failure, no memory\n"); return NULL; } + memset(c_ptr, 0, sizeof(*c_ptr)); c_ptr->addr = tipc_addr(tipc_zone(addr), tipc_cluster(addr), 0); if (in_own_cluster(addr)) max_nodes = LOWEST_SLAVE + tipc_max_slaves; else max_nodes = tipc_max_nodes + 1; + alloc = sizeof(void *) * (max_nodes + 1); - c_ptr->nodes = kcalloc(max_nodes + 1, sizeof(void*), GFP_ATOMIC); + c_ptr->nodes = (struct node **)kmalloc(alloc, GFP_ATOMIC); if (c_ptr->nodes == NULL) { warn("Cluster creation failure, no memory for node area\n"); kfree(c_ptr); return NULL; } + memset(c_ptr->nodes, 0, alloc); if (in_own_cluster(addr)) tipc_local_nodes = c_ptr->nodes; diff --git a/trunk/net/tipc/discover.c b/trunk/net/tipc/discover.c index ee94de92ae99..2b8441203120 100644 --- a/trunk/net/tipc/discover.c +++ b/trunk/net/tipc/discover.c @@ -295,7 +295,7 @@ struct link_req *tipc_disc_init_link_req(struct bearer *b_ptr, { struct link_req *req; - req = kmalloc(sizeof(*req), GFP_ATOMIC); + req = (struct link_req *)kmalloc(sizeof(*req), GFP_ATOMIC); if (!req) return NULL; diff --git a/trunk/net/tipc/link.c b/trunk/net/tipc/link.c index 693f02eca6d6..c10e18a49b96 100644 --- a/trunk/net/tipc/link.c +++ b/trunk/net/tipc/link.c @@ -417,11 +417,12 @@ struct link *tipc_link_create(struct bearer *b_ptr, const u32 peer, struct tipc_msg *msg; char *if_name; - l_ptr = kzalloc(sizeof(*l_ptr), GFP_ATOMIC); + l_ptr = (struct link *)kmalloc(sizeof(*l_ptr), GFP_ATOMIC); if (!l_ptr) { warn("Link creation failed, no memory\n"); return NULL; } + memset(l_ptr, 0, sizeof(*l_ptr)); l_ptr->addr = peer; if_name = strchr(b_ptr->publ.name, ':') + 1; diff --git a/trunk/net/tipc/name_table.c b/trunk/net/tipc/name_table.c index 049242ea5c38..a6926ff07bcc 100644 --- a/trunk/net/tipc/name_table.c +++ b/trunk/net/tipc/name_table.c @@ -117,12 +117,14 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, u32 scope, u32 node, u32 port_ref, u32 key) { - struct publication *publ = kzalloc(sizeof(*publ), GFP_ATOMIC); + struct publication *publ = + (struct publication *)kmalloc(sizeof(*publ), GFP_ATOMIC); if (publ == NULL) { warn("Publication creation failure, no memory\n"); return NULL; } + memset(publ, 0, sizeof(*publ)); publ->type = type; publ->lower = lower; publ->upper = upper; @@ -142,7 +144,11 @@ static struct publication *publ_create(u32 type, u32 lower, u32 upper, static struct sub_seq *tipc_subseq_alloc(u32 cnt) { - struct sub_seq *sseq = kcalloc(cnt, sizeof(struct sub_seq), GFP_ATOMIC); + u32 sz = cnt * sizeof(struct sub_seq); + struct sub_seq *sseq = (struct sub_seq *)kmalloc(sz, GFP_ATOMIC); + + if (sseq) + memset(sseq, 0, sz); return sseq; } @@ -154,7 +160,8 @@ static struct sub_seq *tipc_subseq_alloc(u32 cnt) static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_head) { - struct name_seq *nseq = kzalloc(sizeof(*nseq), GFP_ATOMIC); + struct name_seq *nseq = + (struct name_seq *)kmalloc(sizeof(*nseq), GFP_ATOMIC); struct sub_seq *sseq = tipc_subseq_alloc(1); if (!nseq || !sseq) { @@ -164,6 +171,7 @@ static struct name_seq *tipc_nameseq_create(u32 type, struct hlist_head *seq_hea return NULL; } + memset(nseq, 0, sizeof(*nseq)); spin_lock_init(&nseq->lock); nseq->type = type; nseq->sseqs = sseq; @@ -1052,7 +1060,7 @@ int tipc_nametbl_init(void) { int array_size = sizeof(struct hlist_head) * tipc_nametbl_size; - table.types = kmalloc(array_size, GFP_ATOMIC); + table.types = (struct hlist_head *)kmalloc(array_size, GFP_ATOMIC); if (!table.types) return -ENOMEM; diff --git a/trunk/net/tipc/net.c b/trunk/net/tipc/net.c index a991bf8a7f74..e5a359ab4930 100644 --- a/trunk/net/tipc/net.c +++ b/trunk/net/tipc/net.c @@ -160,11 +160,14 @@ void tipc_net_send_external_routes(u32 dest) static int net_init(void) { + u32 sz = sizeof(struct _zone *) * (tipc_max_zones + 1); + memset(&tipc_net, 0, sizeof(tipc_net)); - tipc_net.zones = kcalloc(tipc_max_zones + 1, sizeof(struct _zone *), GFP_ATOMIC); + tipc_net.zones = (struct _zone **)kmalloc(sz, GFP_ATOMIC); if (!tipc_net.zones) { return -ENOMEM; } + memset(tipc_net.zones, 0, sz); return TIPC_OK; } diff --git a/trunk/net/tipc/port.c b/trunk/net/tipc/port.c index b9c8c6b9e94f..3251c8d8e53c 100644 --- a/trunk/net/tipc/port.c +++ b/trunk/net/tipc/port.c @@ -226,11 +226,12 @@ u32 tipc_createport_raw(void *usr_handle, struct tipc_msg *msg; u32 ref; - p_ptr = kzalloc(sizeof(*p_ptr), GFP_ATOMIC); + p_ptr = kmalloc(sizeof(*p_ptr), GFP_ATOMIC); if (!p_ptr) { warn("Port creation failed, no memory\n"); return 0; } + memset(p_ptr, 0, sizeof(*p_ptr)); ref = tipc_ref_acquire(p_ptr, &p_ptr->publ.lock); if (!ref) { warn("Port creation failed, reference table exhausted\n"); @@ -1057,7 +1058,7 @@ int tipc_createport(u32 user_ref, struct port *p_ptr; u32 ref; - up_ptr = kmalloc(sizeof(*up_ptr), GFP_ATOMIC); + up_ptr = (struct user_port *)kmalloc(sizeof(*up_ptr), GFP_ATOMIC); if (!up_ptr) { warn("Port creation failed, no memory\n"); return -ENOMEM; diff --git a/trunk/net/tipc/ref.c b/trunk/net/tipc/ref.c index e6d6ae22ea49..596d3c8ff750 100644 --- a/trunk/net/tipc/ref.c +++ b/trunk/net/tipc/ref.c @@ -79,7 +79,7 @@ int tipc_ref_table_init(u32 requested_size, u32 start) while (sz < requested_size) { sz <<= 1; } - table = vmalloc(sz * sizeof(*table)); + table = (struct reference *)vmalloc(sz * sizeof(struct reference)); if (table == NULL) return -ENOMEM; diff --git a/trunk/net/tipc/subscr.c b/trunk/net/tipc/subscr.c index c51600ba5f4a..e19b4bcd67ec 100644 --- a/trunk/net/tipc/subscr.c +++ b/trunk/net/tipc/subscr.c @@ -393,11 +393,12 @@ static void subscr_named_msg_event(void *usr_handle, /* Create subscriber object */ - subscriber = kzalloc(sizeof(struct subscriber), GFP_ATOMIC); + subscriber = kmalloc(sizeof(struct subscriber), GFP_ATOMIC); if (subscriber == NULL) { warn("Subscriber rejected, no memory\n"); return; } + memset(subscriber, 0, sizeof(struct subscriber)); INIT_LIST_HEAD(&subscriber->subscription_list); INIT_LIST_HEAD(&subscriber->subscriber_list); subscriber->ref = tipc_ref_acquire(subscriber, &subscriber->lock); diff --git a/trunk/net/tipc/user_reg.c b/trunk/net/tipc/user_reg.c index 04d1b9be9c51..1e3ae57c7228 100644 --- a/trunk/net/tipc/user_reg.c +++ b/trunk/net/tipc/user_reg.c @@ -82,8 +82,9 @@ static int reg_init(void) spin_lock_bh(®_lock); if (!users) { - users = kzalloc(USER_LIST_SIZE, GFP_ATOMIC); + users = (struct tipc_user *)kmalloc(USER_LIST_SIZE, GFP_ATOMIC); if (users) { + memset(users, 0, USER_LIST_SIZE); for (i = 1; i <= MAX_USERID; i++) { users[i].next = i - 1; } diff --git a/trunk/net/tipc/zone.c b/trunk/net/tipc/zone.c index f5b00ea2d5ac..316c4872ff5b 100644 --- a/trunk/net/tipc/zone.c +++ b/trunk/net/tipc/zone.c @@ -52,12 +52,13 @@ struct _zone *tipc_zone_create(u32 addr) return NULL; } - z_ptr = kzalloc(sizeof(*z_ptr), GFP_ATOMIC); + z_ptr = (struct _zone *)kmalloc(sizeof(*z_ptr), GFP_ATOMIC); if (!z_ptr) { warn("Zone creation failed, insufficient memory\n"); return NULL; } + memset(z_ptr, 0, sizeof(*z_ptr)); z_num = tipc_zone(addr); z_ptr->addr = tipc_addr(z_num, 0, 0); tipc_net.zones[z_num] = z_ptr; diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index de6ec519272e..f70475bfb62a 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -128,17 +128,23 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); #define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) #ifdef CONFIG_SECURITY_NETWORK -static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) +static void unix_get_peersec_dgram(struct sk_buff *skb) { - memcpy(UNIXSID(skb), &scm->secid, sizeof(u32)); + int err; + + err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb), + UNIXSECLEN(skb)); + if (err) + *(UNIXSECDATA(skb)) = NULL; } static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) { - scm->secid = *UNIXSID(skb); + scm->secdata = *UNIXSECDATA(skb); + scm->seclen = *UNIXSECLEN(skb); } #else -static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) +static inline void unix_get_peersec_dgram(struct sk_buff *skb) { } static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) @@ -657,10 +663,11 @@ static int unix_autobind(struct socket *sock) goto out; err = -ENOMEM; - addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL); + addr = kmalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL); if (!addr) goto out; + memset(addr, 0, sizeof(*addr) + sizeof(short) + 16); addr->name->sun_family = AF_UNIX; atomic_set(&addr->refcnt, 1); @@ -1316,7 +1323,8 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); if (siocb->scm->fp) unix_attach_fds(siocb->scm, skb); - unix_get_secdata(siocb->scm, skb); + + unix_get_peersec_dgram(skb); skb->h.raw = skb->data; err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); diff --git a/trunk/net/wanrouter/af_wanpipe.c b/trunk/net/wanrouter/af_wanpipe.c index 6f39faa15832..a690cf773b6a 100644 --- a/trunk/net/wanrouter/af_wanpipe.c +++ b/trunk/net/wanrouter/af_wanpipe.c @@ -370,11 +370,12 @@ static int wanpipe_listen_rcv (struct sk_buff *skb, struct sock *sk) * used by the ioctl call to read call information * and to execute commands. */ - if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) { + if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) { wanpipe_kill_sock_irq (newsk); release_device(dev); return -ENOMEM; } + memset(mbox_ptr, 0, sizeof(mbox_cmd_t)); memcpy(mbox_ptr,skb->data,skb->len); /* Register the lcn on which incoming call came @@ -506,10 +507,11 @@ static struct sock *wanpipe_alloc_socket(void) if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL) return NULL; - if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { + if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { sk_free(sk); return NULL; } + memset(wan_opt, 0x00, sizeof(struct wanpipe_opt)); wp_sk(sk) = wan_opt; @@ -2009,9 +2011,10 @@ static int set_ioctl_cmd (struct sock *sk, void *arg) dev_put(dev); - if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) + if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) return -ENOMEM; + memset(mbox_ptr, 0, sizeof(mbox_cmd_t)); wp_sk(sk)->mbox = mbox_ptr; wanpipe_link_driver(dev,sk); diff --git a/trunk/net/wanrouter/wanmain.c b/trunk/net/wanrouter/wanmain.c index 9479659277ae..ad8e8a797790 100644 --- a/trunk/net/wanrouter/wanmain.c +++ b/trunk/net/wanrouter/wanmain.c @@ -642,16 +642,18 @@ static int wanrouter_device_new_if(struct wan_device *wandev, if (cnf->config_id == WANCONFIG_MPPP) { #ifdef CONFIG_WANPIPE_MULTPPP - pppdev = kzalloc(sizeof(struct ppp_device), GFP_KERNEL); + pppdev = kmalloc(sizeof(struct ppp_device), GFP_KERNEL); err = -ENOBUFS; if (pppdev == NULL) goto out; - pppdev->dev = kzalloc(sizeof(struct net_device), GFP_KERNEL); + memset(pppdev, 0, sizeof(struct ppp_device)); + pppdev->dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); if (pppdev->dev == NULL) { kfree(pppdev); err = -ENOBUFS; goto out; } + memset(pppdev->dev, 0, sizeof(struct net_device)); err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf); dev = pppdev->dev; #else @@ -661,10 +663,11 @@ static int wanrouter_device_new_if(struct wan_device *wandev, goto out; #endif } else { - dev = kzalloc(sizeof(struct net_device), GFP_KERNEL); + dev = kmalloc(sizeof(struct net_device), GFP_KERNEL); err = -ENOBUFS; if (dev == NULL) goto out; + memset(dev, 0, sizeof(struct net_device)); err = wandev->new_if(wandev, dev, cnf); } diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index f35bc676128c..405b741dff43 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -307,9 +307,10 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp) { struct xfrm_policy *policy; - policy = kzalloc(sizeof(struct xfrm_policy), gfp); + policy = kmalloc(sizeof(struct xfrm_policy), gfp); if (policy) { + memset(policy, 0, sizeof(struct xfrm_policy)); atomic_set(&policy->refcnt, 1); rwlock_init(&policy->lock); init_timer(&policy->timer); diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 0021aad5db43..43f00fc28a3d 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -194,9 +194,10 @@ struct xfrm_state *xfrm_state_alloc(void) { struct xfrm_state *x; - x = kzalloc(sizeof(struct xfrm_state), GFP_ATOMIC); + x = kmalloc(sizeof(struct xfrm_state), GFP_ATOMIC); if (x) { + memset(x, 0, sizeof(struct xfrm_state)); atomic_set(&x->refcnt, 1); atomic_set(&x->tunnel_users, 0); INIT_LIST_HEAD(&x->bydst); diff --git a/trunk/scripts/Kbuild.include b/trunk/scripts/Kbuild.include index bb19c1561f1e..2180c88cfe89 100644 --- a/trunk/scripts/Kbuild.include +++ b/trunk/scripts/Kbuild.include @@ -77,20 +77,14 @@ cc-option-align = $(subst -functions=0,,\ # cc-version # Usage gcc-ver := $(call cc-version, $(CC)) -cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) +cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh \ + $(if $(1), $(1), $(CC))) # cc-ifversion # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) cc-ifversion = $(shell if [ $(call cc-version, $(CC)) $(1) $(2) ]; then \ echo $(3); fi;) -# ld-option -# Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both) -ld-option = $(shell if $(CC) $(1) \ - -nostdlib -o ldtest$$$$.out -xc /dev/null \ - > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi; \ - rm -f ldtest$$$$.out) - ### # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= # Usage: diff --git a/trunk/scripts/Makefile.modpost b/trunk/scripts/Makefile.modpost index 0a64688c2b5d..a49550205dcc 100644 --- a/trunk/scripts/Makefile.modpost +++ b/trunk/scripts/Makefile.modpost @@ -40,7 +40,7 @@ include scripts/Kbuild.include include scripts/Makefile.lib kernelsymfile := $(objtree)/Module.symvers -modulesymfile := $(KBUILD_EXTMOD)/Module.symvers +modulesymfile := $(KBUILD_EXTMOD)/Modules.symvers # Step 1), find all modules listed in $(MODVERDIR)/ __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) diff --git a/trunk/scripts/kconfig/confdata.c b/trunk/scripts/kconfig/confdata.c index a69d8acbf274..2ee48c377b66 100644 --- a/trunk/scripts/kconfig/confdata.c +++ b/trunk/scripts/kconfig/confdata.c @@ -357,7 +357,7 @@ int conf_read(const char *name) for (e = prop->expr; e; e = e->left.expr) if (e->right.sym->visible != no) flags &= e->right.sym->flags; - sym->flags &= flags | ~SYMBOL_DEF_USER; + sym->flags |= flags & SYMBOL_DEF_USER; } sym_change_count += conf_warnings || conf_unsaved; diff --git a/trunk/scripts/kernel-doc b/trunk/scripts/kernel-doc index c9ca0c23bd91..f9460a6218de 100755 --- a/trunk/scripts/kernel-doc +++ b/trunk/scripts/kernel-doc @@ -1518,7 +1518,6 @@ sub dump_function($$) { $prototype =~ s/^asmlinkage +//; $prototype =~ s/^inline +//; $prototype =~ s/^__inline__ +//; - $prototype =~ s/__devinit +//; $prototype =~ s/^#define +//; #ak added $prototype =~ s/__attribute__ \(\([a-z,]*\)\)//; diff --git a/trunk/scripts/mod/file2alias.c b/trunk/scripts/mod/file2alias.c index 44312926b849..37f67c23e11b 100644 --- a/trunk/scripts/mod/file2alias.c +++ b/trunk/scripts/mod/file2alias.c @@ -52,23 +52,6 @@ do { \ sprintf(str + strlen(str), "*"); \ } while(0) -/** - * Check that sizeof(device_id type) are consistent with size of section - * in .o file. If in-consistent then userspace and kernel does not agree - * on actual size which is a bug. - **/ -static void device_id_size_check(const char *modname, const char *device_id, - unsigned long size, unsigned long id_size) -{ - if (size % id_size || size < id_size) { - fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " - "of the size of section __mod_%s_device_table=%lu.\n" - "Fix definition of struct %s_device_id " - "in mod_devicetable.h\n", - modname, device_id, id_size, device_id, size, device_id); - } -} - /* USB is special because the bcdDevice can be matched against a numeric range */ /* Looks like "usb:vNpNdNdcNdscNdpNicNiscNipN" */ static void do_usb_entry(struct usb_device_id *id, @@ -169,8 +152,10 @@ static void do_usb_table(void *symval, unsigned long size, unsigned int i; const unsigned long id_size = sizeof(struct usb_device_id); - device_id_size_check(mod->name, "usb", size, id_size); - + if (size % id_size || size < id_size) { + warn("%s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); + } /* Leave last one: it's the terminator. */ size -= id_size; @@ -449,7 +434,6 @@ static inline int sym_is(const char *symbol, const char *name) static void do_table(void *symval, unsigned long size, unsigned long id_size, - const char *device_id, void *function, struct module *mod) { @@ -457,7 +441,10 @@ static void do_table(void *symval, unsigned long size, char alias[500]; int (*do_entry)(const char *, void *entry, char *alias) = function; - device_id_size_check(mod->name, device_id, size, id_size); + if (size % id_size || size < id_size) { + warn("%s ids %lu bad size " + "(each on %lu)\n", mod->name, size, id_size); + } /* Leave last one: it's the terminator. */ size -= id_size; @@ -489,51 +476,40 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, + sym->st_value; if (sym_is(symname, "__mod_pci_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pci_device_id), "pci", + do_table(symval, sym->st_size, sizeof(struct pci_device_id), do_pci_entry, mod); else if (sym_is(symname, "__mod_usb_device_table")) /* special case to handle bcdDevice ranges */ do_usb_table(symval, sym->st_size, mod); else if (sym_is(symname, "__mod_ieee1394_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ieee1394_device_id), "ieee1394", + do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id), do_ieee1394_entry, mod); else if (sym_is(symname, "__mod_ccw_device_table")) - do_table(symval, sym->st_size, - sizeof(struct ccw_device_id), "ccw", + do_table(symval, sym->st_size, sizeof(struct ccw_device_id), do_ccw_entry, mod); else if (sym_is(symname, "__mod_serio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct serio_device_id), "serio", + do_table(symval, sym->st_size, sizeof(struct serio_device_id), do_serio_entry, mod); else if (sym_is(symname, "__mod_pnp_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pnp_device_id), "pnp", + do_table(symval, sym->st_size, sizeof(struct pnp_device_id), do_pnp_entry, mod); else if (sym_is(symname, "__mod_pnp_card_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pnp_card_device_id), "pnp_card", + do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id), do_pnp_card_entry, mod); else if (sym_is(symname, "__mod_pcmcia_device_table")) - do_table(symval, sym->st_size, - sizeof(struct pcmcia_device_id), "pcmcia", + do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id), do_pcmcia_entry, mod); else if (sym_is(symname, "__mod_of_device_table")) - do_table(symval, sym->st_size, - sizeof(struct of_device_id), "of", + do_table(symval, sym->st_size, sizeof(struct of_device_id), do_of_entry, mod); else if (sym_is(symname, "__mod_vio_device_table")) - do_table(symval, sym->st_size, - sizeof(struct vio_device_id), "vio", + do_table(symval, sym->st_size, sizeof(struct vio_device_id), do_vio_entry, mod); else if (sym_is(symname, "__mod_i2c_device_table")) - do_table(symval, sym->st_size, - sizeof(struct i2c_device_id), "i2c", + do_table(symval, sym->st_size, sizeof(struct i2c_device_id), do_i2c_entry, mod); else if (sym_is(symname, "__mod_input_device_table")) - do_table(symval, sym->st_size, - sizeof(struct input_device_id), "input", + do_table(symval, sym->st_size, sizeof(struct input_device_id), do_input_entry, mod); } diff --git a/trunk/security/dummy.c b/trunk/security/dummy.c index 58c6d399c844..bbbfda70e131 100644 --- a/trunk/security/dummy.c +++ b/trunk/security/dummy.c @@ -791,7 +791,8 @@ static int dummy_socket_getpeersec_stream(struct socket *sock, char __user *optv return -ENOPROTOOPT; } -static int dummy_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static int dummy_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, + u32 *seclen) { return -ENOPROTOOPT; } @@ -875,15 +876,6 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz return -EINVAL; } -static int dummy_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) -{ - return -EOPNOTSUPP; -} - -static void dummy_release_secctx(char *secdata, u32 seclen) -{ -} - #ifdef CONFIG_KEYS static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx, unsigned long flags) @@ -1036,8 +1028,6 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, d_instantiate); set_to_dummy_if_null(ops, getprocattr); set_to_dummy_if_null(ops, setprocattr); - set_to_dummy_if_null(ops, secid_to_secctx); - set_to_dummy_if_null(ops, release_secctx); #ifdef CONFIG_SECURITY_NETWORK set_to_dummy_if_null(ops, unix_stream_connect); set_to_dummy_if_null(ops, unix_may_send); diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 5d1b8c733199..a91c961ba38b 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -3524,21 +3524,25 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op return err; } -static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *skb, u32 *secid) +static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) { - u32 peer_secid = SECSID_NULL; int err = 0; + u32 peer_sid; - if (sock && (sock->sk->sk_family == PF_UNIX)) - selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); - else if (skb) - peer_secid = selinux_socket_getpeer_dgram(skb); + if (skb->sk->sk_family == PF_UNIX) + selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket), + &peer_sid); + else + peer_sid = selinux_socket_getpeer_dgram(skb); - if (peer_secid == SECSID_NULL) - err = -EINVAL; - *secid = peer_secid; + if (peer_sid == SECSID_NULL) + return -EINVAL; - return err; + err = security_sid_to_context(peer_sid, secdata, seclen); + if (err) + return err; + + return 0; } static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) @@ -4403,17 +4407,6 @@ static int selinux_setprocattr(struct task_struct *p, return size; } -static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) -{ - return security_sid_to_context(secid, secdata, seclen); -} - -static void selinux_release_secctx(char *secdata, u32 seclen) -{ - if (secdata) - kfree(secdata); -} - #ifdef CONFIG_KEYS static int selinux_key_alloc(struct key *k, struct task_struct *tsk, @@ -4594,9 +4587,6 @@ static struct security_operations selinux_ops = { .getprocattr = selinux_getprocattr, .setprocattr = selinux_setprocattr, - .secid_to_secctx = selinux_secid_to_secctx, - .release_secctx = selinux_release_secctx, - .unix_stream_connect = selinux_socket_unix_stream_connect, .unix_may_send = selinux_socket_unix_may_send, diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index f03960e697ce..0111990ba837 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -644,18 +644,10 @@ void policydb_destroy(struct policydb *p) kfree(lra); for (rt = p->range_tr; rt; rt = rt -> next) { - if (lrt) { - ebitmap_destroy(&lrt->range.level[0].cat); - ebitmap_destroy(&lrt->range.level[1].cat); - kfree(lrt); - } - lrt = rt; - } - if (lrt) { - ebitmap_destroy(&lrt->range.level[0].cat); - ebitmap_destroy(&lrt->range.level[1].cat); kfree(lrt); + lrt = rt; } + kfree(lrt); if (p->type_attr_map) { for (i = 0; i < p->p_types.nprim; i++) diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index 85e429884393..d2e80e62ff0c 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -833,8 +833,6 @@ static int security_compute_sid(u32 ssid, goto out; } - context_init(&newcontext); - POLICY_RDLOCK; scontext = sidtab_search(&sidtab, ssid); @@ -852,6 +850,8 @@ static int security_compute_sid(u32 ssid, goto out_unlock; } + context_init(&newcontext); + /* Set the user identity. */ switch (specified) { case AVTAB_TRANSITION: diff --git a/trunk/sound/aoa/codecs/snd-aoa-codec-toonie.c b/trunk/sound/aoa/codecs/snd-aoa-codec-toonie.c index 3c7d1d8a9a6f..bcc555647e79 100644 --- a/trunk/sound/aoa/codecs/snd-aoa-codec-toonie.c +++ b/trunk/sound/aoa/codecs/snd-aoa-codec-toonie.c @@ -51,13 +51,6 @@ static struct transfer_info toonie_transfers[] = { {} }; -static int toonie_usable(struct codec_info_item *cii, - struct transfer_info *ti, - struct transfer_info *out) -{ - return 1; -} - #ifdef CONFIG_PM static int toonie_suspend(struct codec_info_item *cii, pm_message_t state) { @@ -76,7 +69,6 @@ static struct codec_info toonie_codec_info = { .sysclock_factor = 256, .bus_factor = 64, .owner = THIS_MODULE, - .usable = toonie_usable, #ifdef CONFIG_PM .suspend = toonie_suspend, .resume = toonie_resume, @@ -87,20 +79,19 @@ static int toonie_init_codec(struct aoa_codec *codec) { struct toonie *toonie = codec_to_toonie(codec); - /* nothing connected? what a joke! */ - if (toonie->codec.connected != 1) - return -ENOTCONN; - if (aoa_snd_device_new(SNDRV_DEV_LOWLEVEL, toonie, &ops)) { printk(KERN_ERR PFX "failed to create toonie snd device!\n"); return -ENODEV; } + /* nothing connected? what a joke! */ + if (toonie->codec.connected != 1) + return -ENOTCONN; + if (toonie->codec.soundbus_dev->attach_codec(toonie->codec.soundbus_dev, aoa_get_card(), &toonie_codec_info, toonie)) { printk(KERN_ERR PFX "error creating toonie pcm\n"); - snd_device_free(aoa_get_card(), toonie); return -ENODEV; } diff --git a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c index f69d33357a28..7ae0c0bdfad8 100644 --- a/trunk/sound/aoa/core/snd-aoa-gpio-feature.c +++ b/trunk/sound/aoa/core/snd-aoa-gpio-feature.c @@ -112,10 +112,7 @@ static struct device_node *get_gpio(char *name, static void get_irq(struct device_node * np, int *irqptr) { - if (np) - *irqptr = irq_of_parse_and_map(np, 0); - else - *irqptr = NO_IRQ; + *irqptr = irq_of_parse_and_map(np, 0); } /* 0x4 is outenable, 0x1 is out, thus 4 or 5 */ @@ -325,7 +322,7 @@ static int ftr_set_notify(struct gpio_runtime *rt, return -EINVAL; } - if (irq == NO_IRQ) + if (irq == -1) return -ENODEV; mutex_lock(¬if->mutex); diff --git a/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c b/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c index 2836c3218391..3d57fd1aec4b 100644 --- a/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c +++ b/trunk/sound/aoa/core/snd-aoa-gpio-pmf.c @@ -18,7 +18,7 @@ static void pmf_gpio_set_##name(struct gpio_runtime *rt, int on)\ \ if (unlikely(!rt)) return; \ rc = pmf_call_function(rt->node, #name "-mute", &args); \ - if (rc && rc != -ENODEV) \ + if (rc) \ printk(KERN_WARNING "pmf_gpio_set_" #name \ " failed, rc: %d\n", rc); \ rt->implementation_private &= ~(1<index == 0 && (kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0)) != NULL) { struct snd_ctl_elem_info *uinfo; - uinfo = kzalloc(sizeof(*uinfo), GFP_KERNEL); + uinfo = kmalloc(sizeof(*uinfo), GFP_KERNEL); if (! uinfo) { up_read(&mixer->card->controls_rwsem); return -ENOMEM; } + memset(uinfo, 0, sizeof(*uinfo)); if (kctl->info(kctl, uinfo)) { up_read(&mixer->card->controls_rwsem); return 0; diff --git a/trunk/sound/core/oss/pcm_oss.c b/trunk/sound/core/oss/pcm_oss.c index 472fce0ee0e8..f5ff4f4a16ee 100644 --- a/trunk/sound/core/oss/pcm_oss.c +++ b/trunk/sound/core/oss/pcm_oss.c @@ -2228,8 +2228,6 @@ static int snd_pcm_oss_open_file(struct file *file, for (idx = 0; idx < 2; idx++) { if (setup[idx].disable) continue; - if (! pcm->streams[idx].substream_count) - continue; /* no matching substream */ if (idx == SNDRV_PCM_STREAM_PLAYBACK) { if (! (f_mode & FMODE_WRITE)) continue; diff --git a/trunk/sound/core/seq/seq_device.c b/trunk/sound/core/seq/seq_device.c index 102ff548ce69..4260de90f36f 100644 --- a/trunk/sound/core/seq/seq_device.c +++ b/trunk/sound/core/seq/seq_device.c @@ -372,9 +372,10 @@ static struct ops_list * create_driver(char *id) { struct ops_list *ops; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kmalloc(sizeof(*ops), GFP_KERNEL); if (ops == NULL) return ops; + memset(ops, 0, sizeof(*ops)); /* set up driver entry */ strlcpy(ops->id, id, sizeof(ops->id)); diff --git a/trunk/sound/core/sgbuf.c b/trunk/sound/core/sgbuf.c index c30669f14ac0..6e4d4ab34632 100644 --- a/trunk/sound/core/sgbuf.c +++ b/trunk/sound/core/sgbuf.c @@ -68,18 +68,21 @@ void *snd_malloc_sgbuf_pages(struct device *device, dmab->area = NULL; dmab->addr = 0; - dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); + dmab->private_data = sgbuf = kmalloc(sizeof(*sgbuf), GFP_KERNEL); if (! sgbuf) return NULL; + memset(sgbuf, 0, sizeof(*sgbuf)); sgbuf->dev = device; pages = snd_sgbuf_aligned_pages(size); sgbuf->tblsize = sgbuf_align_table(pages); - sgbuf->table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->table), GFP_KERNEL); + sgbuf->table = kmalloc(sizeof(*sgbuf->table) * sgbuf->tblsize, GFP_KERNEL); if (! sgbuf->table) goto _failed; - sgbuf->page_table = kcalloc(sgbuf->tblsize, sizeof(*sgbuf->page_table), GFP_KERNEL); + memset(sgbuf->table, 0, sizeof(*sgbuf->table) * sgbuf->tblsize); + sgbuf->page_table = kmalloc(sizeof(*sgbuf->page_table) * sgbuf->tblsize, GFP_KERNEL); if (! sgbuf->page_table) goto _failed; + memset(sgbuf->page_table, 0, sizeof(*sgbuf->page_table) * sgbuf->tblsize); /* allocate each page */ for (i = 0; i < pages; i++) { diff --git a/trunk/sound/drivers/vx/vx_pcm.c b/trunk/sound/drivers/vx/vx_pcm.c index 7e65a103fbb2..c4af84995d05 100644 --- a/trunk/sound/drivers/vx/vx_pcm.c +++ b/trunk/sound/drivers/vx/vx_pcm.c @@ -1252,15 +1252,18 @@ static int vx_init_audio_io(struct vx_core *chip) chip->audio_info = rmh.Stat[1]; /* allocate pipes */ - chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL); + chip->playback_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_outs, GFP_KERNEL); if (!chip->playback_pipes) return -ENOMEM; - chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL); + chip->capture_pipes = kmalloc(sizeof(struct vx_pipe *) * chip->audio_ins, GFP_KERNEL); if (!chip->capture_pipes) { kfree(chip->playback_pipes); return -ENOMEM; } + memset(chip->playback_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_outs); + memset(chip->capture_pipes, 0, sizeof(struct vx_pipe *) * chip->audio_ins); + preferred = chip->ibl.size; chip->ibl.size = 0; vx_set_ibl(chip, &chip->ibl); /* query the info */ diff --git a/trunk/sound/pci/echoaudio/echoaudio.c b/trunk/sound/pci/echoaudio/echoaudio.c index c3dafa29054f..27a8dbe6f6a8 100644 --- a/trunk/sound/pci/echoaudio/echoaudio.c +++ b/trunk/sound/pci/echoaudio/echoaudio.c @@ -236,9 +236,9 @@ static int pcm_open(struct snd_pcm_substream *substream, chip = snd_pcm_substream_chip(substream); runtime = substream->runtime; - pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL); - if (!pipe) + if (!(pipe = kmalloc(sizeof(struct audiopipe), GFP_KERNEL))) return -ENOMEM; + memset(pipe, 0, sizeof(struct audiopipe)); pipe->index = -1; /* Not configured yet */ /* Set up hw capabilities and contraints */ diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 79f24cdf5fbf..f9b5c3dc3b34 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -936,17 +936,6 @@ static struct snd_emu_chip_details emu_chip_details[] = { .ca0151_chip = 1, .spk71 = 1, .spdif_bug = 1} , - /* Dell OEM/Creative Labs Audigy 2 ZS */ - /* See ALSA bug#1365 */ - {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102, - .driver = "Audigy2", .name = "Audigy 2 ZS [SB0353]", - .id = "Audigy2", - .emu10k2_chip = 1, - .ca0102_chip = 1, - .ca0151_chip = 1, - .spk71 = 1, - .spdif_bug = 1, - .ac97_chip = 1} , {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", .id = "Audigy2", diff --git a/trunk/sound/pci/emu10k1/irq.c b/trunk/sound/pci/emu10k1/irq.c index 1076af4c3669..a8b31286b6db 100644 --- a/trunk/sound/pci/emu10k1/irq.c +++ b/trunk/sound/pci/emu10k1/irq.c @@ -37,13 +37,9 @@ irqreturn_t snd_emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs) int handled = 0; while ((status = inl(emu->port + IPR)) != 0) { - //snd_printk(KERN_INFO "emu10k1 irq - status = 0x%x\n", status); + //printk("emu10k1 irq - status = 0x%x\n", status); orig_status = status; handled = 1; - if ((status & 0xffffffff) == 0xffffffff) { - snd_printk(KERN_INFO "snd-emu10k1: Suspected sound card removal\n"); - break; - } if (status & IPR_PCIERROR) { snd_printk(KERN_ERR "interrupt: PCI error\n"); snd_emu10k1_intr_disable(emu, INTE_PCIERRORENABLE); diff --git a/trunk/sound/ppc/awacs.c b/trunk/sound/ppc/awacs.c index 05dabe454658..82d791be7499 100644 --- a/trunk/sound/ppc/awacs.c +++ b/trunk/sound/ppc/awacs.c @@ -801,10 +801,11 @@ snd_pmac_awacs_init(struct snd_pmac *chip) chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf; #ifdef PMAC_AMP_AVAIL if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) { - struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL); + struct awacs_amp *amp = kmalloc(sizeof(*amp), GFP_KERNEL); if (! amp) return -ENOMEM; chip->mixer_data = amp; + memset(amp, 0, sizeof(*amp)); chip->mixer_free = awacs_amp_free; awacs_amp_set_vol(amp, 0, 63, 63, 0); /* mute and zero vol */ awacs_amp_set_vol(amp, 1, 63, 63, 0); diff --git a/trunk/sound/ppc/daca.c b/trunk/sound/ppc/daca.c index 57202b0f033e..46eebf5610e3 100644 --- a/trunk/sound/ppc/daca.c +++ b/trunk/sound/ppc/daca.c @@ -258,9 +258,10 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip) request_module("i2c-powermac"); #endif /* CONFIG_KMOD */ - mix = kzalloc(sizeof(*mix), GFP_KERNEL); + mix = kmalloc(sizeof(*mix), GFP_KERNEL); if (! mix) return -ENOMEM; + memset(mix, 0, sizeof(*mix)); chip->mixer_data = mix; chip->mixer_free = daca_cleanup; mix->amp_on = 1; /* default on */ diff --git a/trunk/sound/ppc/keywest.c b/trunk/sound/ppc/keywest.c index 59482a4cd446..fb05938dcbd9 100644 --- a/trunk/sound/ppc/keywest.c +++ b/trunk/sound/ppc/keywest.c @@ -64,10 +64,11 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) if (strncmp(i2c_device_name(adapter), "mac-io", 6)) return 0; /* ignored */ - new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); if (! new_client) return -ENOMEM; + memset(new_client, 0, sizeof(*new_client)); new_client->addr = keywest_ctx->addr; i2c_set_clientdata(new_client, keywest_ctx); new_client->adapter = adapter; diff --git a/trunk/sound/ppc/powermac.c b/trunk/sound/ppc/powermac.c index 2264574fa06b..fa9a44ab487e 100644 --- a/trunk/sound/ppc/powermac.c +++ b/trunk/sound/ppc/powermac.c @@ -181,14 +181,21 @@ static int __init alsa_card_pmac_init(void) if ((err = platform_driver_register(&snd_pmac_driver)) < 0) return err; device = platform_device_register_simple(SND_PMAC_DRIVER, -1, NULL, 0); - return 0; + if (!IS_ERR(device)) { + if (platform_get_drvdata(device)) + return 0; + platform_device_unregister(device); + err = -ENODEV; + } else + err = PTR_ERR(device); + platform_driver_unregister(&snd_pmac_driver); + return err; } static void __exit alsa_card_pmac_exit(void) { - if (!IS_ERR(device)) - platform_device_unregister(device); + platform_device_unregister(device); platform_driver_unregister(&snd_pmac_driver); } diff --git a/trunk/sound/ppc/tumbler.c b/trunk/sound/ppc/tumbler.c index 84f6b19c07ca..692c61177678 100644 --- a/trunk/sound/ppc/tumbler.c +++ b/trunk/sound/ppc/tumbler.c @@ -1316,9 +1316,10 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) request_module("i2c-powermac"); #endif /* CONFIG_KMOD */ - mix = kzalloc(sizeof(*mix), GFP_KERNEL); + mix = kmalloc(sizeof(*mix), GFP_KERNEL); if (! mix) return -ENOMEM; + memset(mix, 0, sizeof(*mix)); mix->headphone_irq = -1; chip->mixer_data = mix; diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index 1b7f499c549d..d32d83d970cc 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -2260,9 +2260,10 @@ static int add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct aud } /* create a new pcm */ - as = kzalloc(sizeof(*as), GFP_KERNEL); + as = kmalloc(sizeof(*as), GFP_KERNEL); if (! as) return -ENOMEM; + memset(as, 0, sizeof(*as)); as->pcm_index = chip->pcm_devs; as->chip = chip; as->fmt_type = fp->fmt_type; @@ -2632,12 +2633,13 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) csep = NULL; } - fp = kzalloc(sizeof(*fp), GFP_KERNEL); + fp = kmalloc(sizeof(*fp), GFP_KERNEL); if (! fp) { snd_printk(KERN_ERR "cannot malloc\n"); return -ENOMEM; } + memset(fp, 0, sizeof(*fp)); fp->iface = iface_no; fp->altsetting = altno; fp->altset_idx = i;