diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c index 3221201..a03fbca 100644 --- a/arch/alpha/kernel/irq_srm.c +++ b/arch/alpha/kernel/irq_srm.c @@ -63,6 +63,8 @@ init_srm_irqs(long max, unsigned long ignore_mask) { long i; + if (NR_IRQS <= 16) + return; for (i = 16; i < max; ++i) { if (i < 64 && ((ignore_mask >> i) & 1)) continue; diff --git a/crypto/authenc.c b/crypto/authenc.c index fd9f06c..0861dc2 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -157,16 +157,19 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, dstp = sg_page(dst); vdst = PageHighMem(dstp) ? NULL : page_address(dstp) + dst->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, dst, vdst == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, dst, vdst == iv + ivsize); + dst = cipher; + } cryptlen = req->cryptlen + ivsize; - hash = crypto_authenc_hash(req, flags, cipher, cryptlen); + hash = crypto_authenc_hash(req, flags, dst, cryptlen); if (IS_ERR(hash)) return PTR_ERR(hash); - scatterwalk_map_and_copy(hash, cipher, cryptlen, + scatterwalk_map_and_copy(hash, dst, cryptlen, crypto_aead_authsize(authenc), 1); return 0; } @@ -284,11 +287,14 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, srcp = sg_page(src); vsrc = PageHighMem(srcp) ? NULL : page_address(srcp) + src->offset; - sg_init_table(cipher, 2); - sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, src, vsrc == iv + ivsize); + if (ivsize) { + sg_init_table(cipher, 2); + sg_set_buf(cipher, iv, ivsize); + authenc_chain(cipher, src, vsrc == iv + ivsize); + src = cipher; + } - return crypto_authenc_verify(req, cipher, cryptlen + ivsize); + return crypto_authenc_verify(req, src, cryptlen + ivsize); } static int crypto_authenc_decrypt(struct aead_request *req) diff --git a/crypto/ccm.c b/crypto/ccm.c index 7cf7e5a..c36d654 100644 --- a/crypto/ccm.c +++ b/crypto/ccm.c @@ -266,6 +266,8 @@ static int crypto_ccm_auth(struct aead_request *req, struct scatterlist *plain, if (assoclen) { pctx->ilen = format_adata(idata, assoclen); get_data_to_compute(cipher, pctx, req->assoc, req->assoclen); + } else { + pctx->ilen = 0; } /* compute plaintext into mac */ diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index 8fdb2ce..c5be6a1 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -87,6 +87,10 @@ enum { VIA_SATA_PATA = 0x800, /* SATA/PATA combined configuration */ }; +enum { + VIA_IDFLAG_SINGLE = (1 << 0), /* single channel controller) */ +}; + /* * VIA SouthBridge chips. */ @@ -98,8 +102,12 @@ static const struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { + { "vx855", PCI_DEVICE_ID_VIA_VX855, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, { "vx800", PCI_DEVICE_ID_VIA_VX800, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, + { "vt8261", PCI_DEVICE_ID_VIA_8261, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST }, { "vt8237s", PCI_DEVICE_ID_VIA_8237S, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_SATA_PATA }, @@ -123,6 +131,8 @@ static const struct via_isa_bridge { { "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK }, { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO | VIA_NO_UNMASK | VIA_BAD_ID }, + { "vtxxxx", PCI_DEVICE_ID_VIA_ANON, 0x00, 0x2f, + VIA_UDMA_133 | VIA_BAD_AST }, { NULL } }; @@ -461,6 +471,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) static int printed_version; u8 enable; u32 timing; + unsigned long flags = id->driver_data; int rc; if (!printed_version++) @@ -470,9 +481,13 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; + if (flags & VIA_IDFLAG_SINGLE) + ppi[1] = &ata_dummy_port_info; + /* To find out how the IDE will behave and what features we actually have to look at the bridge not the IDE controller */ - for (config = via_isa_bridges; config->id; config++) + for (config = via_isa_bridges; config->id != PCI_DEVICE_ID_VIA_ANON; + config++) if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + !!(config->flags & VIA_BAD_ID), config->id, NULL))) { @@ -483,10 +498,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_dev_put(isa); } - if (!config->id) { - printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n"); - return -ENODEV; - } pci_dev_put(isa); if (!(config->flags & VIA_NO_ENABLES)) { @@ -588,6 +599,7 @@ static const struct pci_device_id via[] = { { PCI_VDEVICE(VIA, 0x1571), }, { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, + { PCI_VDEVICE(VIA, 0xC409), VIA_IDFLAG_SINGLE }, { }, }; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 4a1508a..7e975eb 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -69,6 +69,8 @@ #define DRV_NAME "it821x" +#define QUIRK_VORTEX86 1 + struct it821x_dev { unsigned int smart:1, /* Are we in smart raid mode */ @@ -80,6 +82,7 @@ struct it821x_dev u16 pio[2]; /* Cached PIO values */ u16 mwdma[2]; /* Cached MWDMA values */ u16 udma[2]; /* Cached UDMA values (per drive) */ + u16 quirks; }; #define ATA_66 0 @@ -586,6 +589,12 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) hwif->ultra_mask = ATA_UDMA6; hwif->mwdma_mask = ATA_MWDMA2; + + /* Vortex86SX quirk: prevent Ultra-DMA mode to fix BadCRC issue */ + if (idev->quirks & QUIRK_VORTEX86) { + if (dev->revision == 0x11) + hwif->ultra_mask = 0; + } } static void __devinit it8212_disable_raid(struct pci_dev *dev) @@ -658,6 +667,8 @@ static int __devinit it821x_init_one(struct pci_dev *dev, const struct pci_devic return -ENOMEM; } + itdevs->quirks = id->driver_data; + rc = ide_pci_init_one(dev, &it821x_chipset, itdevs); if (rc) kfree(itdevs); @@ -677,6 +688,7 @@ static void __devexit it821x_remove(struct pci_dev *dev) static const struct pci_device_id it821x_pci_tbl[] = { { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), 0 }, { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), 0 }, + { PCI_VDEVICE(RDC, PCI_DEVICE_ID_RDC_D1010), QUIRK_VORTEX86 }, { 0, }, }; diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c index d32c1ee..59ff816 100644 --- a/drivers/misc/sgi-xp/xpc_sn2.c +++ b/drivers/misc/sgi-xp/xpc_sn2.c @@ -1841,6 +1841,7 @@ xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number) */ xpc_clear_remote_msgqueue_flags_sn2(ch); + smp_wmb(); /* ensure flags have been cleared before bte_copy */ ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put; dev_dbg(xpc_chan, "w_remote_GP.put changed to %ld, partid=%d, " @@ -1939,7 +1940,7 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch) break; get = ch_sn2->w_local_GP.get; - rmb(); /* guarantee that .get loads before .put */ + smp_rmb(); /* guarantee that .get loads before .put */ if (get == ch_sn2->w_remote_GP.put) break; @@ -1961,11 +1962,13 @@ xpc_get_deliverable_payload_sn2(struct xpc_channel *ch) msg = xpc_pull_remote_msg_sn2(ch, get); - DBUG_ON(msg != NULL && msg->number != get); - DBUG_ON(msg != NULL && (msg->flags & XPC_M_SN2_DONE)); - DBUG_ON(msg != NULL && !(msg->flags & XPC_M_SN2_READY)); + if (msg != NULL) { + DBUG_ON(msg->number != get); + DBUG_ON(msg->flags & XPC_M_SN2_DONE); + DBUG_ON(!(msg->flags & XPC_M_SN2_READY)); - payload = &msg->payload; + payload = &msg->payload; + } break; } @@ -2058,7 +2061,7 @@ xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags, while (1) { put = ch_sn2->w_local_GP.put; - rmb(); /* guarantee that .put loads before .get */ + smp_rmb(); /* guarantee that .put loads before .get */ if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) { /* There are available message entries. We need to try @@ -2191,7 +2194,7 @@ xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload, * The preceding store of msg->flags must occur before the following * load of local_GP->put. */ - mb(); + smp_mb(); /* see if the message is next in line to be sent, if so send it */ @@ -2292,7 +2295,7 @@ xpc_received_payload_sn2(struct xpc_channel *ch, void *payload) * The preceding store of msg->flags must occur before the following * load of local_GP->get. */ - mb(); + smp_mb(); /* * See if this message is next in line to be acknowledged as having diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 1ac694c..b8f8d50 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -1238,7 +1238,7 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload, atomic_inc(&ch->n_to_notify); msg_slot->key = key; - wmb(); /* a non-NULL func must hit memory after the key */ + smp_wmb(); /* a non-NULL func must hit memory after the key */ msg_slot->func = func; if (ch->flags & XPC_C_DISCONNECTING) { diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 53459db..8d44404 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c @@ -8078,6 +8078,9 @@ static int bnx2x_get_eeprom(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); int rc; + if (!netif_running(dev)) + return -EAGAIN; + DP(BNX2X_MSG_NVM, "ethtool_eeprom: cmd %d\n" DP_LEVEL " magic 0x%x offset 0x%x (%d) len 0x%x (%d)\n", eeprom->cmd, eeprom->magic, eeprom->offset, eeprom->offset, diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 1640096..ef84732 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -263,6 +263,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) usb_fill_bulk_urb(urb, priv->udev, usb_sndbulkpipe(priv->udev, ep), buf, skb->len, rtl8187_tx_cb, skb); + urb->transfer_flags |= URB_ZERO_PACKET; rc = usb_submit_urb(urb, GFP_ATOMIC); if (rc < 0) { usb_free_urb(urb); diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c index 1bae899..487593f 100644 --- a/drivers/net/wireless/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl8187_rtl8225.c @@ -287,7 +287,10 @@ static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) ofdm_power = priv->channels[channel - 1].hw_value >> 4; cck_power = min(cck_power, (u8)11); - ofdm_power = min(ofdm_power, (u8)35); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); @@ -540,7 +543,10 @@ static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) cck_power += priv->txpwr_base & 0xF; cck_power = min(cck_power, (u8)35); - ofdm_power = min(ofdm_power, (u8)15); + if (ofdm_power > (u8)15) + ofdm_power = 25; + else + ofdm_power += 10; ofdm_power += priv->txpwr_base >> 4; ofdm_power = min(ofdm_power, (u8)35); diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 6e18736..6d9b074 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -126,8 +126,10 @@ static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) mutex_lock(&slot->ctrl->crit_sect); /* has it been >1 sec since our last toggle? */ - if ((get_seconds() - slot->last_emi_toggle) < 1) + if ((get_seconds() - slot->last_emi_toggle) < 1) { + mutex_unlock(&slot->ctrl->crit_sect); return -EINVAL; + } /* see what our current state is */ retval = get_lock_status(hotplug_slot, &value); diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index c2f2393..fd0695b 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -2190,6 +2190,9 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_8_115200 }, + { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_7803, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_b2_8_460800 }, { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b2_8_115200 }, diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 20290c5..e52e54e 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1700,7 +1700,7 @@ const struct file_operations usbdev_file_operations = { .release = usbdev_release, }; -void usb_fs_classdev_common_remove(struct usb_device *udev) +static void usbdev_remove(struct usb_device *udev) { struct dev_state *ps; struct siginfo sinfo; @@ -1742,10 +1742,15 @@ static void usb_classdev_remove(struct usb_device *dev) { if (dev->usb_classdev) device_unregister(dev->usb_classdev); - usb_fs_classdev_common_remove(dev); } -static int usb_classdev_notify(struct notifier_block *self, +#else +#define usb_classdev_add(dev) 0 +#define usb_classdev_remove(dev) do {} while (0) + +#endif + +static int usbdev_notify(struct notifier_block *self, unsigned long action, void *dev) { switch (action) { @@ -1755,15 +1760,15 @@ static int usb_classdev_notify(struct notifier_block *self, break; case USB_DEVICE_REMOVE: usb_classdev_remove(dev); + usbdev_remove(dev); break; } return NOTIFY_OK; } static struct notifier_block usbdev_nb = { - .notifier_call = usb_classdev_notify, + .notifier_call = usbdev_notify, }; -#endif static struct cdev usb_device_cdev; @@ -1797,9 +1802,8 @@ int __init usb_devio_init(void) * to /sys/dev */ usb_classdev_class->dev_kobj = NULL; - - usb_register_notify(&usbdev_nb); #endif + usb_register_notify(&usbdev_nb); out: return retval; @@ -1810,8 +1814,8 @@ error_cdev: void usb_devio_cleanup(void) { -#ifdef CONFIG_USB_DEVICE_CLASS usb_unregister_notify(&usbdev_nb); +#ifdef CONFIG_USB_DEVICE_CLASS class_destroy(usb_classdev_class); #endif cdev_del(&usb_device_cdev); diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index db410e9..83887ff 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -716,7 +716,6 @@ static void usbfs_remove_device(struct usb_device *dev) fs_remove_file (dev->usbfs_dentry); dev->usbfs_dentry = NULL; } - usb_fs_classdev_common_remove(dev); } static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 9a1a45a..a9a6397 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -145,7 +145,6 @@ extern struct usb_driver usbfs_driver; extern const struct file_operations usbfs_devices_fops; extern const struct file_operations usbdev_file_operations; extern void usbfs_conn_disc_event(void); -extern void usb_fs_classdev_common_remove(struct usb_device *udev); extern int usb_devio_init(void); extern void usb_devio_cleanup(void); diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 0ada0fc..c542a98 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -37,6 +37,7 @@ #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) + #ifdef CONFIG_COMPAT #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) @@ -921,21 +922,6 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, } break; -#ifdef CONFIG_COMPAT - case MON_IOCX_GET32: { - struct mon_bin_get32 getb; - - if (copy_from_user(&getb, (void __user *)arg, - sizeof(struct mon_bin_get32))) - return -EFAULT; - - ret = mon_bin_get_event(file, rp, - compat_ptr(getb.hdr32), compat_ptr(getb.data32), - getb.alloc32); - } - break; -#endif - case MON_IOCX_MFETCH: { struct mon_bin_mfetch mfetch; @@ -962,7 +948,57 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, } break; + case MON_IOCG_STATS: { + struct mon_bin_stats __user *sp; + unsigned int nevents; + unsigned int ndropped; + + spin_lock_irqsave(&rp->b_lock, flags); + ndropped = rp->cnt_lost; + rp->cnt_lost = 0; + spin_unlock_irqrestore(&rp->b_lock, flags); + nevents = mon_bin_queued(rp); + + sp = (struct mon_bin_stats __user *)arg; + if (put_user(rp->cnt_lost, &sp->dropped)) + return -EFAULT; + if (put_user(nevents, &sp->queued)) + return -EFAULT; + + } + break; + + default: + return -ENOTTY; + } + + return ret; +} + #ifdef CONFIG_COMPAT +static long mon_bin_compat_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct mon_reader_bin *rp = file->private_data; + int ret; + + switch (cmd) { + + case MON_IOCX_GET32: { + struct mon_bin_get32 getb; + + if (copy_from_user(&getb, (void __user *)arg, + sizeof(struct mon_bin_get32))) + return -EFAULT; + + ret = mon_bin_get_event(file, rp, + compat_ptr(getb.hdr32), compat_ptr(getb.data32), + getb.alloc32); + if (ret < 0) + return ret; + } + return 0; + case MON_IOCX_MFETCH32: { struct mon_bin_mfetch32 mfetch; @@ -986,37 +1022,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, return ret; if (put_user(ret, &uptr->nfetch32)) return -EFAULT; - ret = 0; } - break; -#endif - - case MON_IOCG_STATS: { - struct mon_bin_stats __user *sp; - unsigned int nevents; - unsigned int ndropped; - - spin_lock_irqsave(&rp->b_lock, flags); - ndropped = rp->cnt_lost; - rp->cnt_lost = 0; - spin_unlock_irqrestore(&rp->b_lock, flags); - nevents = mon_bin_queued(rp); + return 0; - sp = (struct mon_bin_stats __user *)arg; - if (put_user(rp->cnt_lost, &sp->dropped)) - return -EFAULT; - if (put_user(nevents, &sp->queued)) - return -EFAULT; + case MON_IOCG_STATS: + return mon_bin_ioctl(NULL, file, cmd, + (unsigned long) compat_ptr(arg)); - } - break; + case MON_IOCQ_URB_LEN: + case MON_IOCQ_RING_SIZE: + case MON_IOCT_RING_SIZE: + case MON_IOCH_MFLUSH: + return mon_bin_ioctl(NULL, file, cmd, arg); default: - return -ENOTTY; + ; } - - return ret; + return -ENOTTY; } +#endif /* CONFIG_COMPAT */ static unsigned int mon_bin_poll(struct file *file, struct poll_table_struct *wait) @@ -1094,6 +1118,9 @@ static const struct file_operations mon_fops_binary = { /* .write = mon_text_write, */ .poll = mon_bin_poll, .ioctl = mon_bin_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = mon_bin_compat_ioctl, +#endif .release = mon_bin_release, .mmap = mon_bin_mmap, }; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6fcb6d1..aae786c 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -2047,6 +2047,12 @@ UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_DEVICE), +UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, + "ST", + "2A", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* patch submitted by Davide Perini * and Renato Perini */ diff --git a/fs/eventpoll.c b/fs/eventpoll.c index cb60f92..801de2c 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -234,8 +234,6 @@ struct ep_pqueue { /* * Configuration options available inside /proc/sys/fs/epoll/ */ -/* Maximum number of epoll devices, per user */ -static int max_user_instances __read_mostly; /* Maximum number of epoll watched descriptors, per user */ static int max_user_watches __read_mostly; @@ -261,14 +259,6 @@ static int zero; ctl_table epoll_table[] = { { - .procname = "max_user_instances", - .data = &max_user_instances, - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = &zero, - }, - { .procname = "max_user_watches", .data = &max_user_watches, .maxlen = sizeof(int), @@ -491,7 +481,6 @@ static void ep_free(struct eventpoll *ep) mutex_unlock(&epmutex); mutex_destroy(&ep->mtx); - atomic_dec(&ep->user->epoll_devs); free_uid(ep->user); kfree(ep); } @@ -581,10 +570,6 @@ static int ep_alloc(struct eventpoll **pep) struct eventpoll *ep; user = get_current_user(); - error = -EMFILE; - if (unlikely(atomic_read(&user->epoll_devs) >= - max_user_instances)) - goto free_uid; error = -ENOMEM; ep = kzalloc(sizeof(*ep), GFP_KERNEL); if (unlikely(!ep)) @@ -1137,7 +1122,6 @@ SYSCALL_DEFINE1(epoll_create1, int, flags) flags & O_CLOEXEC); if (fd < 0) ep_free(ep); - atomic_inc(&ep->user->epoll_devs); error_return: DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d) = %d\n", @@ -1362,8 +1346,10 @@ static int __init eventpoll_init(void) struct sysinfo si; si_meminfo(&si); - max_user_instances = 128; - max_user_watches = (((si.totalram - si.totalhigh) / 32) << PAGE_SHIFT) / + /* + * Allows top 4% of lomem to be allocated for epoll watches (per user). + */ + max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / EP_ITEM_COST; /* Initialize the structure used to perform safe poll wait head wake ups */ diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 1f55382..89b1c93 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c @@ -1374,7 +1374,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, struct fake_dirent *fde; blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); + dxtrace(printk(KERN_DEBUG "Creating index: inode %lu\n", dir->i_ino)); retval = ext3_journal_get_write_access(handle, bh); if (retval) { ext3_std_error(dir->i_sb, retval); @@ -1383,6 +1383,19 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, } root = (struct dx_root *) bh->b_data; + /* The 0th block becomes the root, move the dirents out */ + fde = &root->dotdot; + de = (struct ext3_dir_entry_2 *)((char *)fde + + ext3_rec_len_from_disk(fde->rec_len)); + if ((char *) de >= (((char *) root) + blocksize)) { + ext3_error(dir->i_sb, __func__, + "invalid rec_len for '..' in inode %lu", + dir->i_ino); + brelse(bh); + return -EIO; + } + len = ((char *) root) + blocksize - (char *) de; + bh2 = ext3_append (handle, dir, &block, &retval); if (!(bh2)) { brelse(bh); @@ -1391,11 +1404,6 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; data1 = bh2->b_data; - /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)fde + - ext3_rec_len_from_disk(fde->rec_len)); - len = ((char *) root) + blocksize - (char *) de; memcpy (data1, de, len); de = (struct ext3_dir_entry_2 *) data1; top = data1 + len; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 87250b6..279734f 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -281,7 +281,8 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) fc->blocked = 0; wake_up_all(&fc->blocked_waitq); } - if (fc->num_background == FUSE_CONGESTION_THRESHOLD) { + if (fc->num_background == FUSE_CONGESTION_THRESHOLD && + fc->connected) { clear_bdi_congested(&fc->bdi, READ); clear_bdi_congested(&fc->bdi, WRITE); } diff --git a/fs/fuse/file.c b/fs/fuse/file.c index c8206db..3ada9d7 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -54,7 +54,7 @@ struct fuse_file *fuse_file_alloc(void) ff->reserved_req = fuse_request_alloc(); if (!ff->reserved_req) { kfree(ff); - ff = NULL; + return NULL; } else { INIT_LIST_HEAD(&ff->write_entry); atomic_set(&ff->count, 0); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index d2249f1..57342a6 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -292,6 +292,7 @@ static void fuse_put_super(struct super_block *sb) list_del(&fc->entry); fuse_ctl_remove_conn(fc); mutex_unlock(&fuse_mutex); + bdi_destroy(&fc->bdi); fuse_conn_put(fc); } @@ -531,7 +532,6 @@ void fuse_conn_put(struct fuse_conn *fc) if (fc->destroy_req) fuse_request_free(fc->destroy_req); mutex_destroy(&fc->inst_mutex); - bdi_destroy(&fc->bdi); kfree(fc); } } @@ -832,12 +832,16 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) if (!file) return -EINVAL; - if (file->f_op != &fuse_dev_operations) + if (file->f_op != &fuse_dev_operations) { + fput(file); return -EINVAL; + } fc = new_conn(sb); - if (!fc) + if (!fc) { + fput(file); return -ENOMEM; + } fc->flags = d.flags; fc->user_id = d.user_id; diff --git a/fs/inotify_user.c b/fs/inotify_user.c index a13f487..5c92d90 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c @@ -427,10 +427,61 @@ static unsigned int inotify_poll(struct file *file, poll_table *wait) return ret; } +/* + * Get an inotify_kernel_event if one exists and is small + * enough to fit in "count". Return an error pointer if + * not large enough. + * + * Called with the device ev_mutex held. + */ +static struct inotify_kernel_event *get_one_event(struct inotify_device *dev, + size_t count) +{ + size_t event_size = sizeof(struct inotify_event); + struct inotify_kernel_event *kevent; + + if (list_empty(&dev->events)) + return NULL; + + kevent = inotify_dev_get_event(dev); + if (kevent->name) + event_size += kevent->event.len; + + if (event_size > count) + return ERR_PTR(-EINVAL); + + remove_kevent(dev, kevent); + return kevent; +} + +/* + * Copy an event to user space, returning how much we copied. + * + * We already checked that the event size is smaller than the + * buffer we had in "get_one_event()" above. + */ +static ssize_t copy_event_to_user(struct inotify_kernel_event *kevent, + char __user *buf) +{ + size_t event_size = sizeof(struct inotify_event); + + if (copy_to_user(buf, &kevent->event, event_size)) + return -EFAULT; + + if (kevent->name) { + buf += event_size; + + if (copy_to_user(buf, kevent->name, kevent->event.len)) + return -EFAULT; + + event_size += kevent->event.len; + } + return event_size; +} + static ssize_t inotify_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { - size_t event_size = sizeof (struct inotify_event); struct inotify_device *dev; char __user *start; int ret; @@ -440,81 +491,43 @@ static ssize_t inotify_read(struct file *file, char __user *buf, dev = file->private_data; while (1) { + struct inotify_kernel_event *kevent; prepare_to_wait(&dev->wq, &wait, TASK_INTERRUPTIBLE); mutex_lock(&dev->ev_mutex); - if (!list_empty(&dev->events)) { - ret = 0; - break; - } + kevent = get_one_event(dev, count); mutex_unlock(&dev->ev_mutex); - if (file->f_flags & O_NONBLOCK) { - ret = -EAGAIN; - break; - } - - if (signal_pending(current)) { - ret = -EINTR; - break; + if (kevent) { + ret = PTR_ERR(kevent); + if (IS_ERR(kevent)) + break; + ret = copy_event_to_user(kevent, buf); + free_kevent(kevent); + if (ret < 0) + break; + buf += ret; + count -= ret; + continue; } - schedule(); - } - - finish_wait(&dev->wq, &wait); - if (ret) - return ret; - - while (1) { - struct inotify_kernel_event *kevent; - - ret = buf - start; - if (list_empty(&dev->events)) + ret = -EAGAIN; + if (file->f_flags & O_NONBLOCK) break; - - kevent = inotify_dev_get_event(dev); - if (event_size + kevent->event.len > count) { - if (ret == 0 && count > 0) { - /* - * could not get a single event because we - * didn't have enough buffer space. - */ - ret = -EINVAL; - } + ret = -EINTR; + if (signal_pending(current)) break; - } - remove_kevent(dev, kevent); - /* - * Must perform the copy_to_user outside the mutex in order - * to avoid a lock order reversal with mmap_sem. - */ - mutex_unlock(&dev->ev_mutex); - - if (copy_to_user(buf, &kevent->event, event_size)) { - ret = -EFAULT; + if (start != buf) break; - } - buf += event_size; - count -= event_size; - - if (kevent->name) { - if (copy_to_user(buf, kevent->name, kevent->event.len)){ - ret = -EFAULT; - break; - } - buf += kevent->event.len; - count -= kevent->event.len; - } - - free_kevent(kevent); - mutex_lock(&dev->ev_mutex); + schedule(); } - mutex_unlock(&dev->ev_mutex); + finish_wait(&dev->wq, &wait); + if (start != buf && ret != -EFAULT) + ret = buf - start; return ret; } diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 006fc64..aa24484 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c @@ -62,6 +62,9 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off) loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; @@ -119,6 +122,9 @@ static ssize_t write(struct file *file, const char __user *userbuf, loff_t offs = *off; int count = min_t(size_t, bytes, PAGE_SIZE); + if (!bytes) + return 0; + if (size) { if (offs > size) return 0; diff --git a/include/asm-x86/pgalloc.h b/include/asm-x86/pgalloc.h index d63ea43..36ef40d 100644 --- a/include/asm-x86/pgalloc.h +++ b/include/asm-x86/pgalloc.h @@ -42,6 +42,7 @@ static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) static inline void pte_free(struct mm_struct *mm, struct page *pte) { + pgtable_page_dtor(pte); __free_page(pte); } diff --git a/include/linux/Kbuild b/include/linux/Kbuild index b68ec09..d5eb2e7 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -41,6 +41,7 @@ header-y += baycom.h header-y += bfs_fs.h header-y += blkpg.h header-y += bpqether.h +header-y += bsg.h header-y += can.h header-y += cdk.h header-y += chio.h diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f1624b3..391cbf3 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1346,6 +1346,7 @@ #define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8251 0x3287 +#define PCI_DEVICE_ID_VIA_8261 0x3402 #define PCI_DEVICE_ID_VIA_8237A 0x3337 #define PCI_DEVICE_ID_VIA_8237S 0x3372 #define PCI_DEVICE_ID_VIA_SATA_EIDE 0x5324 @@ -1355,10 +1356,13 @@ #define PCI_DEVICE_ID_VIA_CX700 0x8324 #define PCI_DEVICE_ID_VIA_CX700_IDE 0x0581 #define PCI_DEVICE_ID_VIA_VX800 0x8353 +#define PCI_DEVICE_ID_VIA_VX855 0x8409 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 #define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 +#define PCI_DEVICE_ID_VIA_C409_IDE 0XC409 +#define PCI_DEVICE_ID_VIA_ANON 0xFFFF #define PCI_VENDOR_ID_SIEMENS 0x110A #define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 @@ -1780,6 +1784,7 @@ #define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202 #define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401 #define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801 +#define PCI_DEVICE_ID_SEALEVEL_7803 0x7803 #define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804 #define PCI_VENDOR_ID_HYPERCOPE 0x1365 @@ -2148,6 +2153,7 @@ #define PCI_DEVICE_ID_RDC_R6040 0x6040 #define PCI_DEVICE_ID_RDC_R6060 0x6060 #define PCI_DEVICE_ID_RDC_R6061 0x6061 +#define PCI_DEVICE_ID_RDC_D1010 0x1010 #define PCI_VENDOR_ID_LENOVO 0x17aa diff --git a/include/linux/sched.h b/include/linux/sched.h index 086f5e1..03e0902 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -588,7 +588,6 @@ struct user_struct { atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ #endif #ifdef CONFIG_EPOLL - atomic_t epoll_devs; /* The number of epoll descriptors currently open */ atomic_t epoll_watches; /* The number of file descriptors currently watched */ #endif #ifdef CONFIG_POSIX_MQUEUE diff --git a/kernel/relay.c b/kernel/relay.c index 8d13a78..b0bbf6f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -664,8 +664,10 @@ int relay_late_setup_files(struct rchan *chan, mutex_lock(&relay_channels_mutex); /* Is chan already set up? */ - if (unlikely(chan->has_base_filename)) + if (unlikely(chan->has_base_filename)) { + mutex_unlock(&relay_channels_mutex); return -EEXIST; + } chan->has_base_filename = 1; chan->parent = parent; curr_cpu = get_cpu(); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 4788f7b..56ad58d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1335,8 +1335,10 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, if (is_multicast_ether_addr(hdr->addr3)) memcpy(hdr->addr1, hdr->addr3, ETH_ALEN); else - if (mesh_nexthop_lookup(skb, odev)) + if (mesh_nexthop_lookup(skb, odev)) { + dev_put(odev); return 0; + } if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.sta, fwded_frames); diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 24db2b4..0a22f00 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -469,6 +469,28 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi return rpc_run_task(&task_setup_data); } +/* + * In the case where rpc clients have been cloned, we want to make + * sure that we use the program number/version etc of the actual + * owner of the xprt. To do so, we walk back up the tree of parents + * to find whoever created the transport and/or whoever has the + * autobind flag set. + */ +static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt) +{ + struct rpc_clnt *parent = clnt->cl_parent; + + while (parent != clnt) { + if (parent->cl_xprt != clnt->cl_xprt) + break; + if (clnt->cl_autobind) + break; + clnt = parent; + parent = parent->cl_parent; + } + return clnt; +} + /** * rpcb_getport_async - obtain the port for a given RPC service on a given host * @task: task that is waiting for portmapper request @@ -478,10 +500,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi */ void rpcb_getport_async(struct rpc_task *task) { - struct rpc_clnt *clnt = task->tk_client; + struct rpc_clnt *clnt; struct rpc_procinfo *proc; u32 bind_version; - struct rpc_xprt *xprt = task->tk_xprt; + struct rpc_xprt *xprt; struct rpc_clnt *rpcb_clnt; static struct rpcbind_args *map; struct rpc_task *child; @@ -490,13 +512,13 @@ void rpcb_getport_async(struct rpc_task *task) size_t salen; int status; + clnt = rpcb_find_transport_owner(task->tk_client); + xprt = clnt->cl_xprt; + dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", task->tk_pid, __func__, clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot); - /* Autobind on cloned rpc clients is discouraged */ - BUG_ON(clnt->cl_parent != clnt); - /* Put self on the wait queue to ensure we get notified if * some other task is already attempting to bind the port */ rpc_sleep_on(&xprt->binding, task, NULL); @@ -558,7 +580,7 @@ void rpcb_getport_async(struct rpc_task *task) status = -ENOMEM; dprintk("RPC: %5u %s: no memory available\n", task->tk_pid, __func__); - goto bailout_nofree; + goto bailout_release_client; } map->r_prog = clnt->cl_prog; map->r_vers = clnt->cl_vers; @@ -578,11 +600,13 @@ void rpcb_getport_async(struct rpc_task *task) task->tk_pid, __func__); return; } - rpc_put_task(child); - task->tk_xprt->stat.bind_count++; + xprt->stat.bind_count++; + rpc_put_task(child); return; +bailout_release_client: + rpc_release_client(rpcb_clnt); bailout_nofree: rpcb_wake_rpcbind_waiters(xprt, status); task->tk_status = status; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 7c1eb23..a50089f 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1470,6 +1470,7 @@ static struct snd_pci_quirk cxt5047_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2000Z", CXT5047_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6700", CXT5047_LAPTOP), SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7225f0f..aa7dc03 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6631,6 +6631,7 @@ static int patch_alc882(struct hda_codec *codec) case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ case 0x106b2c00: /* Macbook Pro rev3 */ case 0x106b3600: /* Macbook 3.1 */ + case 0x106b3800: /* MacbookPro4,1 - latter revision */ board_config = ALC885_MBP3; break; default: diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fdef553..2f52cf1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2048,6 +2048,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec) info->name = "STAC92xx Analog"; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = + spec->multiout.dac_nids[0]; info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 01d7b75..82a7814 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -26,7 +26,7 @@ * SPI 0 -> 1st PCM1796 (front) * SPI 1 -> 2nd PCM1796 (surround) * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) + * SPI 4 -> 4th PCM1796 (back) and EEPROM self-destruct (do not use!) * * GPIO 2 -> M0 of CS5381 * GPIO 3 -> M1 of CS5381 @@ -142,6 +142,12 @@ struct xonar_data { static void pcm1796_write(struct oxygen *chip, unsigned int codec, u8 reg, u8 value) { + /* + * We don't want to do writes on SPI 4 because the EEPROM, which shares + * the same pin, might get confused and broken. We'd better take care + * that the driver works with the default register values ... + */ +#if 0 /* maps ALSA channel pair number to SPI output */ static const u8 codec_map[4] = { 0, 1, 2, 4 @@ -152,6 +158,7 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec, (codec_map[codec] << OXYGEN_SPI_CODEC_SHIFT) | OXYGEN_SPI_CEN_LATCH_CLOCK_HI, (reg << 8) | value); +#endif } static void cs4398_write(struct oxygen *chip, u8 reg, u8 value) @@ -539,6 +546,9 @@ static const DECLARE_TLV_DB_SCALE(cs4362a_db_scale, -12700, 100, 0); static int xonar_d2_control_filter(struct snd_kcontrol_new *template) { + if (!strncmp(template->name, "Master Playback ", 16)) + /* disable volume/mute because they would require SPI writes */ + return 1; if (!strncmp(template->name, "CD Capture ", 11)) /* CD in is actually connected to the video in pin */ template->private_value ^= AC97_CD ^ AC97_VIDEO; @@ -588,9 +598,8 @@ static const struct oxygen_model xonar_models[] = { .dac_volume_min = 0x0f, .dac_volume_max = 0xff, .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .function_flags = OXYGEN_FUNCTION_SPI, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }, [MODEL_D2X] = { @@ -619,9 +628,8 @@ static const struct oxygen_model xonar_models[] = { .dac_volume_min = 0x0f, .dac_volume_max = 0xff, .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .function_flags = OXYGEN_FUNCTION_SPI, + .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }, [MODEL_D1] = {