diff options
Diffstat (limited to 'drivers')
30 files changed, 646 insertions, 433 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ed9b407e42d..4688dbf2d11 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -536,6 +536,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci }, /* MCP77 */ { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci }, /* MCP77 */ { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci }, /* MCP77 */ + { PCI_VDEVICE(NVIDIA, 0x0ab4), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0ab5), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0ab6), board_ahci }, /* MCP79 */ + { PCI_VDEVICE(NVIDIA, 0x0ab7), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci }, /* MCP79 */ { PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci }, /* MCP79 */ diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index c5779ad4abc..3cc27b51465 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c @@ -25,7 +25,7 @@ #include <linux/libata.h> #define DRV_NAME "pata_amd" -#define DRV_VERSION "0.3.9" +#define DRV_VERSION "0.3.10" /** * timing_setup - shared timing computation and load @@ -115,7 +115,8 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse } /* UDMA timing */ - pci_write_config_byte(pdev, offset + 0x10 + (3 - dn), t); + if (at.udma) + pci_write_config_byte(pdev, offset + 0x10 + (3 - dn), t); } /** diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index a4175fbdd17..453d72bf259 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -63,7 +63,7 @@ #include <linux/dmi.h> #define DRV_NAME "pata_via" -#define DRV_VERSION "0.3.2" +#define DRV_VERSION "0.3.3" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -296,7 +296,7 @@ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mo } /* Set UDMA unless device is not UDMA capable */ - if (udma_type) { + if (udma_type && t.udma) { u8 cable80_status; /* Get 80-wire cable detection bit */ diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 8d864e5e97e..fe0105d35ba 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -2503,6 +2503,15 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx) case chip_7042: hp_flags |= MV_HP_PCIE; + if (pdev->vendor == PCI_VENDOR_ID_TTI && + (pdev->device == 0x2300 || pdev->device == 0x2310)) + { + printk(KERN_WARNING "sata_mv: Highpoint RocketRAID BIOS" + " will CORRUPT DATA on attached drives when" + " configured as \"Legacy\". BEWARE!\n"); + printk(KERN_WARNING "sata_mv: Use BIOS \"JBOD\" volumes" + " instead for safety.\n"); + } case chip_6042: hpriv->ops = &mv6xxx_ops; hp_flags |= MV_HP_GEN_IIE; diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 44f9e5d9e36..ed5dc7cb50c 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -791,11 +791,13 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc) static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { - /* Since commands where a result TF is requested are not - executed in ADMA mode, the only time this function will be called - in ADMA mode will be if a command fails. In this case we - don't care about going into register mode with ADMA commands - pending, as the commands will all shortly be aborted anyway. */ + /* Other than when internal or pass-through commands are executed, + the only time this function will be called in ADMA mode will be + if a command fails. In the failure case we don't care about going + into register mode with ADMA commands pending, as the commands will + all shortly be aborted anyway. We assume that NCQ commands are not + issued via passthrough, which is the only way that switching into + ADMA mode could abort outstanding commands. */ nv_adma_register_mode(ap); ata_tf_read(ap, tf); @@ -1359,11 +1361,9 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc) struct nv_adma_port_priv *pp = qc->ap->private_data; /* ADMA engine can only be used for non-ATAPI DMA commands, - or interrupt-driven no-data commands, where a result taskfile - is not required. */ + or interrupt-driven no-data commands. */ if ((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) || - (qc->tf.flags & ATA_TFLAG_POLLING) || - (qc->flags & ATA_QCFLAG_RESULT_TF)) + (qc->tf.flags & ATA_TFLAG_POLLING)) return 1; if ((qc->flags & ATA_QCFLAG_DMAMAP) || @@ -1381,6 +1381,8 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc) NV_CPB_CTL_IEN; if (nv_adma_use_reg_mode(qc)) { + BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) && + (qc->flags & ATA_QCFLAG_DMAMAP)); nv_adma_register_mode(qc->ap); ata_qc_prep(qc); return; @@ -1425,9 +1427,21 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc) VPRINTK("ENTER\n"); + /* We can't handle result taskfile with NCQ commands, since + retrieving the taskfile switches us out of ADMA mode and would abort + existing commands. */ + if (unlikely(qc->tf.protocol == ATA_PROT_NCQ && + (qc->flags & ATA_QCFLAG_RESULT_TF))) { + ata_dev_printk(qc->dev, KERN_ERR, + "NCQ w/ RESULT_TF not allowed\n"); + return AC_ERR_SYSTEM; + } + if (nv_adma_use_reg_mode(qc)) { /* use ATA register mode */ VPRINTK("using ATA register mode: 0x%lx\n", qc->flags); + BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) && + (qc->flags & ATA_QCFLAG_DMAMAP)); nv_adma_register_mode(qc->ap); return ata_qc_issue_prot(qc); } else diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index fe6d2407bae..c2d23cae951 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c @@ -104,6 +104,11 @@ static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, for (j = 0; j < ARRAY_SIZE(rm); j++) { if (c == rm[j].on) { outl(m1, base + rm[j].wr_offset); + /* If enabling output, turn off AUX 1 and AUX 2 */ + if (c == 'O') { + outl(m0, base + 0x10); + outl(m0, base + 0x14); + } break; } else if (c == rm[j].off) { outl(m0, base + rm[j].wr_offset); diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index f59aecf5ec1..fd9c5d51870 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -267,13 +267,12 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) ts->irq_disabled = 0; enable_irq(spi->irq); - if (req->msg.status) - status = req->msg.status; - - /* on-wire is a must-ignore bit, a BE12 value, then padding */ - sample = be16_to_cpu(req->sample); - sample = sample >> 3; - sample &= 0x0fff; + if (status == 0) { + /* on-wire is a must-ignore bit, a BE12 value, then padding */ + sample = be16_to_cpu(req->sample); + sample = sample >> 3; + sample &= 0x0fff; + } kfree(req); return status ? status : sample; diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index a6469218f19..365024b83d3 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -176,8 +176,6 @@ mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len) DMA_FROM_DEVICE); status = spi_sync(host->spi, &host->readback); - if (status == 0) - status = host->readback.status; if (host->dma_dev) dma_sync_single_for_cpu(host->dma_dev, @@ -480,8 +478,6 @@ mmc_spi_command_send(struct mmc_spi_host *host, DMA_BIDIRECTIONAL); } status = spi_sync(host->spi, &host->m); - if (status == 0) - status = host->m.status; if (host->dma_dev) dma_sync_single_for_cpu(host->dma_dev, @@ -624,8 +620,6 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t) DMA_BIDIRECTIONAL); status = spi_sync(spi, &host->m); - if (status == 0) - status = host->m.status; if (status != 0) { dev_dbg(&spi->dev, "write error (%d)\n", status); @@ -726,8 +720,6 @@ mmc_spi_readblock(struct mmc_spi_host *host, struct spi_transfer *t) } status = spi_sync(spi, &host->m); - if (status == 0) - status = host->m.status; if (host->dma_dev) { dma_sync_single_for_cpu(host->dma_dev, @@ -905,8 +897,6 @@ mmc_spi_data_do(struct mmc_spi_host *host, struct mmc_command *cmd, DMA_BIDIRECTIONAL); tmp = spi_sync(spi, &host->m); - if (tmp == 0) - tmp = host->m.status; if (host->dma_dev) dma_sync_single_for_cpu(host->dma_dev, diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index c5975047c89..c5975047c89 100755..100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c diff --git a/drivers/net/chelsio/pm3393.c b/drivers/net/chelsio/pm3393.c index 2117c4fbb10..2117c4fbb10 100755..100644 --- a/drivers/net/chelsio/pm3393.c +++ b/drivers/net/chelsio/pm3393.c diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c index b301c0428ae..b301c0428ae 100755..100644 --- a/drivers/net/chelsio/sge.c +++ b/drivers/net/chelsio/sge.c diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h index cced9dff91c..cced9dff91c 100755..100644 --- a/drivers/net/chelsio/sge.h +++ b/drivers/net/chelsio/sge.h diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index bf5a7caa5b5..79f7eade477 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c @@ -422,7 +422,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status, (struct bcom_bd **)&bd); - dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_FROM_DEVICE); + dma_unmap_single(&dev->dev, bd->skb_pa, rskb->len, DMA_FROM_DEVICE); /* Test for errors in received frame */ if (status & BCOM_FEC_RX_BD_ERRORS) { @@ -467,7 +467,7 @@ static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id) bcom_prepare_next_buffer(priv->rx_dmatsk); bd->status = FEC_RX_BUFFER_SIZE; - bd->skb_pa = dma_map_single(&dev->dev, rskb->data, + bd->skb_pa = dma_map_single(&dev->dev, skb->data, FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE); bcom_submit_next_buffer(priv->rx_dmatsk, skb); diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 38268d7335a..0431e9ed0fa 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -696,7 +696,7 @@ int startup_gfar(struct net_device *dev) { struct txbd8 *txbdp; struct rxbd8 *rxbdp; - dma_addr_t addr; + dma_addr_t addr = 0; unsigned long vaddr; int i; struct gfar_private *priv = netdev_priv(dev); diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 0f306ddb563..8def8657251 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1979,6 +1979,7 @@ static int myri10ge_open(struct net_device *dev) lro_mgr->lro_arr = mgp->rx_done.lro_desc; lro_mgr->get_frag_header = myri10ge_get_frag_header; lro_mgr->max_aggr = myri10ge_lro_max_pkts; + lro_mgr->frag_align_pad = 2; if (lro_mgr->max_aggr > MAX_SKB_FRAGS) lro_mgr->max_aggr = MAX_SKB_FRAGS; diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 09b4fde8d92..816a59e801b 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -586,7 +586,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) /* CRC error flagged */ mac->netdev->stats.rx_errors++; mac->netdev->stats.rx_crc_errors++; - dev_kfree_skb_irq(skb); + /* No need to free skb, it'll be reused */ goto next; } @@ -1362,7 +1362,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64); - dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX | NETIF_F_SG; + dev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX | NETIF_F_SG; /* These should come out of the device tree eventually */ mac->dma_txch = index; diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index fc2f0e695a1..c30196d0ad1 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -91,9 +91,12 @@ int mdiobus_register(struct mii_bus *bus) err = device_register(&phydev->dev); - if (err) + if (err) { printk(KERN_ERR "phy %d failed to register\n", i); + phy_device_free(phydev); + phydev = NULL; + } } bus->phy_map[i] = phydev; @@ -110,10 +113,8 @@ void mdiobus_unregister(struct mii_bus *bus) int i; for (i = 0; i < PHY_MAX_ADDR; i++) { - if (bus->phy_map[i]) { + if (bus->phy_map[i]) device_unregister(&bus->phy_map[i]->dev); - kfree(bus->phy_map[i]); - } } } EXPORT_SYMBOL(mdiobus_unregister); diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index f6e484812a9..5b9e1751e1b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -44,6 +44,16 @@ static struct phy_driver genphy_driver; extern int mdio_bus_init(void); extern void mdio_bus_exit(void); +void phy_device_free(struct phy_device *phydev) +{ + kfree(phydev); +} + +static void phy_device_release(struct device *dev) +{ + phy_device_free(to_phy_device(dev)); +} + struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) { struct phy_device *dev; @@ -54,6 +64,8 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) if (NULL == dev) return (struct phy_device*) PTR_ERR((void*)-ENOMEM); + dev->dev.release = phy_device_release; + dev->speed = 0; dev->duplex = -1; dev->pause = dev->asym_pause = 0; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 3d1dfc94840..6197afb3ed8 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2906,16 +2906,14 @@ static void sky2_restart(struct work_struct *work) int i, err; rtnl_lock(); - sky2_write32(hw, B0_IMSK, 0); - sky2_read32(hw, B0_IMSK); - napi_disable(&hw->napi); - for (i = 0; i < hw->ports; i++) { dev = hw->dev[i]; if (netif_running(dev)) sky2_down(dev); } + napi_disable(&hw->napi); + sky2_write32(hw, B0_IMSK, 0); sky2_reset(hw); sky2_write32(hw, B0_IMSK, Y2_IS_BASE); napi_enable(&hw->napi); diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 1a3d80bfe9e..76cc1d3adf7 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -1299,9 +1299,9 @@ smc911x_rx_dma_irq(int dma, void *data) PRINT_PKT(skb->data, skb->len); dev->last_rx = jiffies; skb->protocol = eth_type_trans(skb, dev); - netif_rx(skb); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; + netif_rx(skb); spin_lock_irqsave(&lp->lock, flags); pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16; diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a4f56e95cf9..f1e00ff54ce 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -293,7 +293,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) return -EINVAL; /* Cannot register while the char dev is in use */ - if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags)) + if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) return -EBUSY; spin_lock_irq(&rtc->irq_task_lock); @@ -303,7 +303,7 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task) } spin_unlock_irq(&rtc->irq_task_lock); - clear_bit(RTC_DEV_BUSY, &rtc->flags); + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return retval; } diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index ae1bf177d62..025c60a17a4 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -26,7 +26,7 @@ static int rtc_dev_open(struct inode *inode, struct file *file) struct rtc_device, char_dev); const struct rtc_class_ops *ops = rtc->ops; - if (test_and_set_bit(RTC_DEV_BUSY, &rtc->flags)) + if (test_and_set_bit_lock(RTC_DEV_BUSY, &rtc->flags)) return -EBUSY; file->private_data = rtc; @@ -41,7 +41,7 @@ static int rtc_dev_open(struct inode *inode, struct file *file) } /* something has gone wrong */ - clear_bit(RTC_DEV_BUSY, &rtc->flags); + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return err; } @@ -402,7 +402,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file) if (rtc->ops->release) rtc->ops->release(rtc->dev.parent); - clear_bit(RTC_DEV_BUSY, &rtc->flags); + clear_bit_unlock(RTC_DEV_BUSY, &rtc->flags); return 0; } diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index 3e183cfee10..1f956dc5d56 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -89,13 +89,9 @@ static int max6902_get_reg(struct device *dev, unsigned char address, /* do the i/o */ status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else - return status; - - *data = chip->rx_buf[1]; + if (status == 0) + *data = chip->rx_buf[1]; return status; } @@ -125,9 +121,7 @@ static int max6902_get_datetime(struct device *dev, struct rtc_time *dt) /* do the i/o */ status = spi_sync(spi, &message); - if (status == 0) - status = message.status; - else + if (status) return status; /* The chip sends data in this order: diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 5e083d1f57e..15a5789b773 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -472,11 +472,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char if (rc) goto unregister_dev; - add_disk(dev_info->gd); - blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request); blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096); + add_disk(dev_info->gd); + switch (dev_info->segment_type) { case SEG_TYPE_SR: case SEG_TYPE_ER: diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 6db31089d2d..c3df2cd009a 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -451,6 +451,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) break; case -ENXIO: case -ENOMEM: + case -EIO: /* These should abort looping */ break; default: diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 2f6bf462425..156f3f9786b 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -113,6 +113,7 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) { struct subchannel *sch; struct ccw1 *ccw; + int ret; sch = to_subchannel(cdev->dev.parent); /* Setup sense channel program. */ @@ -124,9 +125,25 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) /* Reset device status. */ memset(&cdev->private->irb, 0, sizeof(struct irb)); - cdev->private->flags.intretry = 0; - return cio_start(sch, ccw, LPM_ANYPATH); + /* Try on every path. */ + ret = -ENODEV; + while (cdev->private->imask != 0) { + if ((sch->opm & cdev->private->imask) != 0 && + cdev->private->iretry > 0) { + cdev->private->iretry--; + /* Reset internal retry indication. */ + cdev->private->flags.intretry = 0; + ret = cio_start (sch, cdev->private->iccws, + cdev->private->imask); + /* ret is 0, -EBUSY, -EACCES or -ENODEV */ + if (ret != -EACCES) + return ret; + } + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + } + return ret; } void @@ -136,7 +153,8 @@ ccw_device_sense_id_start(struct ccw_device *cdev) memset (&cdev->private->senseid, 0, sizeof (struct senseid)); cdev->private->senseid.cu_type = 0xFFFF; - cdev->private->iretry = 3; + cdev->private->imask = 0x80; + cdev->private->iretry = 5; ret = __ccw_device_sense_id_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_id_done(cdev, ret); @@ -252,13 +270,14 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) ccw_device_sense_id_done(cdev, ret); break; case -EACCES: /* channel is not operational. */ + sch->lpm &= ~cdev->private->imask; + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + /* fall through. */ case -EAGAIN: /* try again. */ - cdev->private->iretry--; - if (cdev->private->iretry > 0) { - ret = __ccw_device_sense_id_start(cdev); - if (ret == 0 || ret == -EBUSY) - break; - } + ret = __ccw_device_sense_id_start(cdev); + if (ret == 0 || ret == -EBUSY) + break; /* fall through. */ default: /* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM) { diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index b3b6f654365..97adc701a81 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -2802,7 +2802,6 @@ void ctc_init_netdevice(struct net_device * dev) dev->type = ARPHRD_SLIP; dev->tx_queue_len = 100; dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(dev); } diff --git a/drivers/spi/at25.c b/drivers/spi/at25.c index e007833cca5..290dbe99647 100644 --- a/drivers/spi/at25.c +++ b/drivers/spi/at25.c @@ -21,6 +21,13 @@ #include <linux/spi/eeprom.h> +/* + * NOTE: this is an *EEPROM* driver. The vagaries of product naming + * mean that some AT25 products are EEPROMs, and others are FLASH. + * Handle FLASH chips with the drivers/mtd/devices/m25p80.c driver, + * not this one! + */ + struct at25_data { struct spi_device *spi; struct mutex lock; diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b31f4431849..93e9de46977 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -541,10 +541,7 @@ static void spi_complete(void *arg) * Also, the caller is guaranteeing that the memory associated with the * message will not be freed before this call returns. * - * The return value is a negative error code if the message could not be - * submitted, else zero. When the value is zero, then message->status is - * also defined; it's the completion code for the transfer, either zero - * or a negative error code from the controller driver. + * It returns zero on success, else a negative error code. */ int spi_sync(struct spi_device *spi, struct spi_message *message) { @@ -554,8 +551,10 @@ int spi_sync(struct spi_device *spi, struct spi_message *message) message->complete = spi_complete; message->context = &done; status = spi_async(spi, message); - if (status == 0) + if (status == 0) { wait_for_completion(&done); + status = message->status; + } message->context = NULL; return status; } @@ -589,7 +588,7 @@ int spi_write_then_read(struct spi_device *spi, const u8 *txbuf, unsigned n_tx, u8 *rxbuf, unsigned n_rx) { - static DECLARE_MUTEX(lock); + static DEFINE_MUTEX(lock); int status; struct spi_message message; @@ -615,7 +614,7 @@ int spi_write_then_read(struct spi_device *spi, } /* ... unless someone else is using the pre-allocated buffer */ - if (down_trylock(&lock)) { + if (!mutex_trylock(&lock)) { local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); if (!local_buf) return -ENOMEM; @@ -628,13 +627,11 @@ int spi_write_then_read(struct spi_device *spi, /* do the i/o */ status = spi_sync(spi, &message); - if (status == 0) { + if (status == 0) memcpy(rxbuf, x[1].rx_buf, n_rx); - status = message.status; - } if (x[0].tx_buf == buf) - up(&lock); + mutex_unlock(&lock); else kfree(local_buf); diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 2ef11bb70b2..22697b81220 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c @@ -1,17 +1,22 @@ /* - * File: drivers/spi/bfin5xx_spi.c - * Based on: N/A - * Author: Luke Yang (Analog Devices Inc.) + * File: drivers/spi/bfin5xx_spi.c + * Maintainer: + * Bryan Wu <bryan.wu@analog.com> + * Original Author: + * Luke Yang (Analog Devices Inc.) * - * Created: March. 10th 2006 - * Description: SPI controller driver for Blackfin 5xx - * Bugs: Enter bugs at http://blackfin.uclinux.org/ + * Created: March. 10th 2006 + * Description: SPI controller driver for Blackfin BF5xx + * Bugs: Enter bugs at http://blackfin.uclinux.org/ * * Modified: * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang) * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang) + * July 17, 2007 add support for BF54x SPI0 controller (Bryan Wu) + * July 30, 2007 add platfrom_resource interface to support multi-port + * SPI controller (Bryan Wu) * - * Copyright 2004-2006 Analog Devices Inc. + * Copyright 2004-2007 Analog Devices Inc. * |