Commit db3e9f28 authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/home/paulus/kernel/linux-2.5

into samba.org:/home/paulus/kernel/for-linus-ppc
parents 5d999784 9683c74d
...@@ -16,6 +16,9 @@ CONFIG_SYSVIPC=y ...@@ -16,6 +16,9 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=15 CONFIG_LOG_BUF_SHIFT=15
# CONFIG_EMBEDDED is not set
CONFIG_FUTEX=y
CONFIG_EPOLL=y
# #
# Loadable module support # Loadable module support
...@@ -795,6 +798,7 @@ CONFIG_IRDA_FAST_RR=y ...@@ -795,6 +798,7 @@ CONFIG_IRDA_FAST_RR=y
# CONFIG_WINBOND_FIR is not set # CONFIG_WINBOND_FIR is not set
# CONFIG_TOSHIBA_OLD is not set # CONFIG_TOSHIBA_OLD is not set
# CONFIG_TOSHIBA_FIR is not set # CONFIG_TOSHIBA_FIR is not set
# CONFIG_SMC_IRCC_OLD is not set
# CONFIG_SMC_IRCC_FIR is not set # CONFIG_SMC_IRCC_FIR is not set
# CONFIG_ALI_FIR is not set # CONFIG_ALI_FIR is not set
# CONFIG_VLSI_FIR is not set # CONFIG_VLSI_FIR is not set
...@@ -959,6 +963,8 @@ CONFIG_VFAT_FS=m ...@@ -959,6 +963,8 @@ CONFIG_VFAT_FS=m
CONFIG_PROC_FS=y CONFIG_PROC_FS=y
# CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y CONFIG_DEVPTS_FS=y
CONFIG_DEVPTS_FS_XATTR=y
# CONFIG_DEVPTS_FS_SECURITY is not set
# CONFIG_TMPFS is not set # CONFIG_TMPFS is not set
CONFIG_RAMFS=y CONFIG_RAMFS=y
...@@ -1111,6 +1117,7 @@ CONFIG_SND_ICE1712=m ...@@ -1111,6 +1117,7 @@ CONFIG_SND_ICE1712=m
CONFIG_SND_INTEL8X0=m CONFIG_SND_INTEL8X0=m
CONFIG_SND_SONICVIBES=m CONFIG_SND_SONICVIBES=m
# CONFIG_SND_VIA82XX is not set # CONFIG_SND_VIA82XX is not set
CONFIG_SND_VX222=m
# #
# ALSA USB devices # ALSA USB devices
......
This diff is collapsed.
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff) #define ETHER1394_GASP_SPECIFIER_ID_LO (ETHER1394_GASP_SPECIFIER_ID & 0xff)
#define ETHER1394_GASP_VERSION 1 #define ETHER1394_GASP_VERSION 1
#define ETHER1394_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */ #define ETHER1394_GASP_OVERHEAD (2 * sizeof(quadlet_t)) /* GASP header overhead */
/* Node set == 64 */ /* Node set == 64 */
#define NODE_SET (ALL_NODES + 1) #define NODE_SET (ALL_NODES + 1)
...@@ -56,10 +56,9 @@ struct pdg_list { ...@@ -56,10 +56,9 @@ struct pdg_list {
struct eth1394_priv { struct eth1394_priv {
struct net_device_stats stats; /* Device stats */ struct net_device_stats stats; /* Device stats */
struct hpsb_host *host; /* The card for this dev */ struct hpsb_host *host; /* The card for this dev */
unsigned char max_rec[NODE_SET];/* Max payload per node */ u16 maxpayload[NODE_SET]; /* Max payload per node */
unsigned char sspd[NODE_SET]; /* Max speed per node */ unsigned char sspd[NODE_SET]; /* Max speed per node */
u16 fifo_hi[ALL_NODES]; /* 16bit hi fifo offset per node */ u64 fifo[ALL_NODES]; /* FIFO offset per node */
u32 fifo_lo[ALL_NODES]; /* 32bit lo fifo offset per node */
u64 eui[ALL_NODES]; /* EUI-64 per node */ u64 eui[ALL_NODES]; /* EUI-64 per node */
spinlock_t lock; /* Private lock */ spinlock_t lock; /* Private lock */
int broadcast_channel; /* Async stream Broadcast Channel */ int broadcast_channel; /* Async stream Broadcast Channel */
...@@ -74,6 +73,21 @@ struct host_info { ...@@ -74,6 +73,21 @@ struct host_info {
struct net_device *dev; struct net_device *dev;
}; };
/* Define a fake hardware header format for the networking core. Note that
* header size cannot exceed 16 bytes as that is the size of the header cache.
* Also, we do not need the source address in the header so we omit it and
* keep the header to under 16 bytes */
#define ETH1394_ALEN (8)
#define ETH1394_HLEN (10)
struct eth1394hdr {
unsigned char h_dest[ETH1394_ALEN]; /* destination eth1394 addr */
unsigned short h_proto; /* packet type ID field */
} __attribute__((packed));
typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type; typedef enum {ETH1394_GASP, ETH1394_WRREQ} eth1394_tx_type;
/* IP1394 headers */ /* IP1394 headers */
......
...@@ -57,7 +57,6 @@ ...@@ -57,7 +57,6 @@
/* Maps speed values above to a string representation */ /* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[]; extern const char *hpsb_speedto_str[];
extern const u8 hpsb_speedto_maxrec[];
#define SELFID_PWRCL_NO_POWER 0x0 #define SELFID_PWRCL_NO_POWER 0x0
......
...@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache; ...@@ -61,7 +61,6 @@ static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */ /* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" }; const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
const u8 hpsb_speedto_maxrec[] = { 0x7, 0x8, 0x9, 0x10, 0x11, 0x12 };
static void dump_packet(const char *text, quadlet_t *data, int size) static void dump_packet(const char *text, quadlet_t *data, int size)
{ {
...@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host); ...@@ -1246,7 +1245,6 @@ EXPORT_SYMBOL(hpsb_unref_host);
/** ieee1394_core.c **/ /** ieee1394_core.c **/
EXPORT_SYMBOL(hpsb_speedto_str); EXPORT_SYMBOL(hpsb_speedto_str);
EXPORT_SYMBOL(hpsb_speedto_maxrec);
EXPORT_SYMBOL(hpsb_set_packet_complete_task); EXPORT_SYMBOL(hpsb_set_packet_complete_task);
EXPORT_SYMBOL(alloc_hpsb_packet); EXPORT_SYMBOL(alloc_hpsb_packet);
EXPORT_SYMBOL(free_hpsb_packet); EXPORT_SYMBOL(free_hpsb_packet);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sched.h>
#include "iso.h" #include "iso.h"
void hpsb_iso_stop(struct hpsb_iso *iso) void hpsb_iso_stop(struct hpsb_iso *iso)
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
#include "sbp2.h" #include "sbp2.h"
static char version[] __devinitdata = static char version[] __devinitdata =
"$Rev: 938 $ Ben Collins <bcollins@debian.org>"; "$Rev: 942 $ Ben Collins <bcollins@debian.org>";
/* /*
* Module load parameter definitions * Module load parameter definitions
...@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id, ...@@ -230,6 +230,8 @@ static void sbp2scsi_complete_command(struct scsi_id_instance_data *scsi_id,
static Scsi_Host_Template scsi_driver_template; static Scsi_Host_Template scsi_driver_template;
const u8 sbp2_speedto_max_payload[] = { 0x7, 0x8, 0x9, 0xA, 0xB, 0xC };
static struct hpsb_highlevel sbp2_highlevel = { static struct hpsb_highlevel sbp2_highlevel = {
.name = SBP2_DEVICE_NAME, .name = SBP2_DEVICE_NAME,
.remove_host = sbp2_remove_host, .remove_host = sbp2_remove_host,
...@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u ...@@ -779,7 +781,7 @@ static int sbp2_start_ud(struct sbp2scsi_host_info *hi, struct unit_directory *u
scsi_id->ne = ud->ne; scsi_id->ne = ud->ne;
scsi_id->hi = hi; scsi_id->hi = hi;
scsi_id->speed_code = SPEED_100; scsi_id->speed_code = SPEED_100;
scsi_id->max_payload_size = hpsb_speedto_maxrec[SPEED_100]; scsi_id->max_payload_size = sbp2_speedto_max_payload[SPEED_100];
atomic_set(&scsi_id->sbp2_login_complete, 0); atomic_set(&scsi_id->sbp2_login_complete, 0);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse);
INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed);
...@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id) ...@@ -1690,7 +1692,7 @@ static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id)
/* Payload size is the lesser of what our speed supports and what /* Payload size is the lesser of what our speed supports and what
* our host supports. */ * our host supports. */
scsi_id->max_payload_size = min(hpsb_speedto_maxrec[scsi_id->speed_code], scsi_id->max_payload_size = min(sbp2_speedto_max_payload[scsi_id->speed_code],
(u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1)); (u8)(((be32_to_cpu(hi->host->csr.rom[2]) >> 12) & 0xf) - 1));
SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]", SBP2_ERR("Node[" NODE_BUS_FMT "]: Max speed [%s] - Max payload [%u]",
......
...@@ -150,6 +150,14 @@ struct eventpoll { ...@@ -150,6 +150,14 @@ struct eventpoll {
/* Protect the this structure access */ /* Protect the this structure access */
rwlock_t lock; rwlock_t lock;
/*
* This semaphore is used to ensure that files are not removed
* while epoll is using them. This is read-held during the event
* collection loop and it is write-held during the file cleanup
* path, the epoll file exit code and the ctl operations.
*/
struct rw_semaphore sem;
/* Wait queue used by sys_epoll_wait() */ /* Wait queue used by sys_epoll_wait() */
wait_queue_head_t wq; wait_queue_head_t wq;
...@@ -279,16 +287,6 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, ...@@ -279,16 +287,6 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
/* Safe wake up implementation */ /* Safe wake up implementation */
static struct poll_safewake psw; static struct poll_safewake psw;
/*
* This semaphore is used to ensure that files are not removed
* while epoll is using them. Namely the f_op->poll(), since
* it has to be called from outside the lock, must be protected.
* This is read-held during the event transfer loop to userspace
* and it is write-held during the file cleanup path and the epoll
* file exit code.
*/
static struct rw_semaphore epsem;
/* Slab cache used to allocate "struct epitem" */ /* Slab cache used to allocate "struct epitem" */
static kmem_cache_t *epi_cache; static kmem_cache_t *epi_cache;
...@@ -357,8 +355,8 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) ...@@ -357,8 +355,8 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
list_for_each(lnk, lsthead) { list_for_each(lnk, lsthead) {
tncur = list_entry(lnk, struct wake_task_node, llink); tncur = list_entry(lnk, struct wake_task_node, llink);
if (tncur->task == this_task) { if (tncur->wq == wq ||
if (tncur->wq == wq || ++wake_nests > EP_MAX_POLLWAKE_NESTS) { (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) {
/* /*
* Ops ... loop detected or maximum nest level reached. * Ops ... loop detected or maximum nest level reached.
* We abort this wake by breaking the cycle itself. * We abort this wake by breaking the cycle itself.
...@@ -367,7 +365,6 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) ...@@ -367,7 +365,6 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
return; return;
} }
} }
}
/* Add the current task to the list */ /* Add the current task to the list */
tnode.task = this_task; tnode.task = this_task;
...@@ -437,14 +434,15 @@ void eventpoll_release(struct file *file) ...@@ -437,14 +434,15 @@ void eventpoll_release(struct file *file)
* The only hit might come from ep_free() but by holding the semaphore * The only hit might come from ep_free() but by holding the semaphore
* will correctly serialize the operation. * will correctly serialize the operation.
*/ */
down_write(&epsem);
while (!list_empty(lsthead)) { while (!list_empty(lsthead)) {
epi = list_entry(lsthead->next, struct epitem, fllink); epi = list_entry(lsthead->next, struct epitem, fllink);
EP_LIST_DEL(&epi->fllink); EP_LIST_DEL(&epi->fllink);
down_write(&epi->ep->sem);
ep_remove(epi->ep, epi); ep_remove(epi->ep, epi);
up_write(&epi->ep->sem);
} }
up_write(&epsem);
} }
...@@ -568,9 +566,18 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even ...@@ -568,9 +566,18 @@ asmlinkage long sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event *even
error = -EEXIST; error = -EEXIST;
break; break;
case EPOLL_CTL_DEL: case EPOLL_CTL_DEL:
if (epi) if (epi) {
/*
* We need to protect the remove operation because another
* thread might be doing an epoll_wait() and using the
* target file.
*/
down_write(&ep->sem);
error = ep_remove(ep, epi); error = ep_remove(ep, epi);
else
up_write(&ep->sem);
} else
error = -ENOENT; error = -ENOENT;
break; break;
case EPOLL_CTL_MOD: case EPOLL_CTL_MOD:
...@@ -703,10 +710,6 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile) ...@@ -703,10 +710,6 @@ static int ep_getfd(int *efd, struct inode **einode, struct file **efile)
file->f_vfsmnt = mntget(eventpoll_mnt); file->f_vfsmnt = mntget(eventpoll_mnt);
file->f_dentry = dget(dentry); file->f_dentry = dget(dentry);
/*
* Initialize the file as read/write because it could be used
* with write() to add/remove/change interest sets.
*/
file->f_pos = 0; file->f_pos = 0;
file->f_flags = O_RDONLY; file->f_flags = O_RDONLY;
file->f_op = &eventpoll_fops; file->f_op = &eventpoll_fops;
...@@ -815,6 +818,7 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits) ...@@ -815,6 +818,7 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits)
unsigned int i, hsize; unsigned int i, hsize;
rwlock_init(&ep->lock); rwlock_init(&ep->lock);
init_rwsem(&ep->sem);
init_waitqueue_head(&ep->wq); init_waitqueue_head(&ep->wq);
init_waitqueue_head(&ep->poll_wait); init_waitqueue_head(&ep->poll_wait);
INIT_LIST_HEAD(&ep->rdllist); INIT_LIST_HEAD(&ep->rdllist);
...@@ -841,11 +845,15 @@ static void ep_free(struct eventpoll *ep) ...@@ -841,11 +845,15 @@ static void ep_free(struct eventpoll *ep)
struct list_head *lsthead, *lnk; struct list_head *lsthead, *lnk;
struct epitem *epi; struct epitem *epi;
/* We need to release all tasks waiting for these file */
if (waitqueue_active(&ep->poll_wait))
ep_poll_safewake(&psw, &ep->poll_wait);
/* /*
* We need to lock this because we could be hit by * We need to lock this because we could be hit by
* eventpoll_release() while we're freeing the "struct eventpoll". * eventpoll_release() while we're freeing the "struct eventpoll".
*/ */
down_write(&epsem); down_write(&ep->sem);
/* /*
* Walks through the whole hash by unregistering poll callbacks. * Walks through the whole hash by unregistering poll callbacks.
...@@ -863,7 +871,7 @@ static void ep_free(struct eventpoll *ep) ...@@ -863,7 +871,7 @@ static void ep_free(struct eventpoll *ep)
/* /*
* Walks through the whole hash by freeing each "struct epitem". At this * Walks through the whole hash by freeing each "struct epitem". At this
* point we are sure no poll callbacks will be lingering around, and also by * point we are sure no poll callbacks will be lingering around, and also by
* write-holding "epsem" we can be sure that no file cleanup code will hit * write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock". * us during this operation. So we can avoid the lock on "ep->lock".
*/ */
for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) { for (i = 0, hsize = 1 << ep->hashbits; i < hsize; i++) {
...@@ -876,7 +884,7 @@ static void ep_free(struct eventpoll *ep) ...@@ -876,7 +884,7 @@ static void ep_free(struct eventpoll *ep)
} }
} }
up_write(&epsem); up_write(&ep->sem);
/* Free hash pages */ /* Free hash pages */
ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits)); ep_free_pages(ep->hpages, EP_HASH_PAGES(ep->hashbits));
...@@ -1337,20 +1345,6 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist ...@@ -1337,20 +1345,6 @@ static int ep_collect_ready_items(struct eventpoll *ep, struct list_head *txlist
/* If this file is already in the ready list we exit soon */ /* If this file is already in the ready list we exit soon */
if (!EP_IS_LINKED(&epi->txlink)) { if (!EP_IS_LINKED(&epi->txlink)) {
/*
* We need to increase the usage count of the "struct epitem" because
* another thread might call EPOLL_CTL_DEL on this target and make the
* object to vanish underneath our nose.
*/
ep_use_epitem(epi);
/*
* We need to increase the usage count of the "struct file" because
* another thread might call close() on this target and make the file
* to vanish before we will be able to call f_op->poll().
*/
get_file(epi->file);
/* /*
* This is initialized in this way so that the default * This is initialized in this way so that the default
* behaviour of the reinjecting code will be to push back * behaviour of the reinjecting code will be to push back
...@@ -1389,19 +1383,21 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, ...@@ -1389,19 +1383,21 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
struct epitem *epi; struct epitem *epi;
struct epoll_event event[EP_MAX_BUF_EVENTS]; struct epoll_event event[EP_MAX_BUF_EVENTS];
/*
* We can loop without lock because this is a task private list.
* The test done during the collection loop will guarantee us that
* another task will not try to collect this file. Also, items
* cannot vanish during the loop because we are holding "sem".
*/
list_for_each(lnk, txlist) { list_for_each(lnk, txlist) {
epi = list_entry(lnk, struct epitem, txlink); epi = list_entry(lnk, struct epitem, txlink);
/* Get the ready file event set */
revents = epi->file->f_op->poll(epi->file, NULL);
/* /*
* Release the file usage before checking the event mask. * Get the ready file event set. We can safely use the file
* In case this call will lead to the file removal, its * because we are holding the "sem" in read and this will
* ->event.events member has been already set to zero and * guarantee that both the file and the item will not vanish.
* this will make the event to be dropped.
*/ */
fput(epi->file); revents = epi->file->f_op->poll(epi->file, NULL);
/* /*
* Set the return event set for the current file descriptor. * Set the return event set for the current file descriptor.
...@@ -1416,17 +1412,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, ...@@ -1416,17 +1412,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
eventbuf++; eventbuf++;
if (eventbuf == EP_MAX_BUF_EVENTS) { if (eventbuf == EP_MAX_BUF_EVENTS) {
if (__copy_to_user(&events[eventcnt], event, if (__copy_to_user(&events[eventcnt], event,
eventbuf * sizeof(struct epoll_event))) { eventbuf * sizeof(struct epoll_event)))
/*
* We need to complete the loop to decrement the file
* usage before returning from this function.
*/
for (lnk = lnk->next; lnk != txlist; lnk = lnk->next) {
epi = list_entry(lnk, struct epitem, txlink);
fput(epi->file);
}
return -EFAULT; return -EFAULT;
}
eventcnt += eventbuf; eventcnt += eventbuf;
eventbuf = 0; eventbuf = 0;
} }
...@@ -1447,7 +1434,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist, ...@@ -1447,7 +1434,8 @@ static int ep_send_events(struct eventpoll *ep, struct list_head *txlist,
/* /*
* Walk through the transfer list we collected with ep_collect_ready_items() * Walk through the transfer list we collected with ep_collect_ready_items()
* and, if 1) the item is still "alive" 2) its event set is not empty 3) it's * and, if 1) the item is still "alive" 2) its event set is not empty 3) it's
* not already linked, links it to the ready list. * not already linked, links it to the ready list. Same as above, we are holding
* "sem" so items cannot vanish underneath our nose.
*/ */
static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
{ {
...@@ -1475,8 +1463,6 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist) ...@@ -1475,8 +1463,6 @@ static void ep_reinject_items(struct eventpoll *ep, struct list_head *txlist)
list_add_tail(&epi->rdllink, &ep->rdllist); list_add_tail(&epi->rdllink, &ep->rdllist);
ricnt++; ricnt++;
} }
ep_release_epitem(epi);
} }
if (ricnt) { if (ricnt) {
...@@ -1510,17 +1496,12 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, ...@@ -1510,17 +1496,12 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
/* /*
* We need to lock this because we could be hit by * We need to lock this because we could be hit by
* eventpoll_release() while we're transfering * eventpoll_release() and epoll_ctl(EPOLL_CTL_DEL).
* events to userspace. Read-holding "epsem" will lock
* out eventpoll_release() during the whole
* transfer loop and this will garantie us that the
* file will not vanish underneath our nose when
* we will call f_op->poll() from ep_send_events().
*/ */
down_read(&epsem); down_read(&ep->sem);
/* Collect/extract ready items */ /* Collect/extract ready items */
if (ep_collect_ready_items(ep, &txlist, maxevents)) { if (ep_collect_ready_items(ep, &txlist, maxevents) > 0) {
/* Build result set in userspace */ /* Build result set in userspace */
eventcnt = ep_send_events(ep, &txlist, events); eventcnt = ep_send_events(ep, &txlist, events);
...@@ -1528,7 +1509,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events, ...@@ -1528,7 +1509,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct epoll_event *events,
ep_reinject_items(ep, &txlist); ep_reinject_items(ep, &txlist);
} }
up_read(&epsem); up_read(&ep->sem);
return eventcnt; return eventcnt;
} }
...@@ -1652,9 +1633,6 @@ static int __init eventpoll_init(void) ...@@ -1652,9 +1633,6 @@ static int __init eventpoll_init(void)
{ {
int error; int error;
/* Initialize the semaphore used to syncronize the file cleanup code */
init_rwsem(&epsem);
/* Initialize the structure used to perform safe poll wait head wake ups */ /* Initialize the structure used to perform safe poll wait head wake ups */
ep_poll_safewake_init(&psw); ep_poll_safewake_init(&psw);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include "ioctl32.h" #include "ioctl32.h"
...@@ -136,15 +137,10 @@ struct sndrv_pcm_channel_info32 { ...@@ -136,15 +137,10 @@ struct sndrv_pcm_channel_info32 {
COPY(step);\ COPY(step);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_pcm_status32 { struct sndrv_pcm_status32 {
s32 state; s32 state;
struct timeval32 trigger_tstamp; struct compat_timespec trigger_tstamp;
struct timeval32 tstamp; struct compat_timespec tstamp;
u32 appl_ptr; u32 appl_ptr;
u32 hw_ptr; u32 hw_ptr;
s32 delay; s32 delay;
...@@ -159,9 +155,9 @@ struct sndrv_pcm_status32 { ...@@ -159,9 +155,9 @@ struct sndrv_pcm_status32 {
{\ {\
COPY(state);\ COPY(state);\
COPY(trigger_tstamp.tv_sec);\ COPY(trigger_tstamp.tv_sec);\
COPY(trigger_tstamp.tv_usec);\ COPY(trigger_tstamp.tv_nsec);\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_usec);\ COPY(tstamp.tv_nsec);\
COPY(appl_ptr);\ COPY(appl_ptr);\
COPY(hw_ptr);\ COPY(hw_ptr);\
COPY(delay);\ COPY(delay);\
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/rawmidi.h> #include <sound/rawmidi.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -42,14 +43,9 @@ struct sndrv_rawmidi_params32 { ...@@ -42,14 +43,9 @@ struct sndrv_rawmidi_params32 {
COPY(no_active_sensing);\ COPY(no_active_sensing);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
} __attribute__((packed));
struct sndrv_rawmidi_status32 { struct sndrv_rawmidi_status32 {
s32 stream; s32 stream;
struct timeval32 tstamp; struct compat_timespec tstamp;
u32 avail; u32 avail;
u32 xruns; u32 xruns;
unsigned char reserved[16]; unsigned char reserved[16];
...@@ -59,7 +55,7 @@ struct sndrv_rawmidi_status32 { ...@@ -59,7 +55,7 @@ struct sndrv_rawmidi_status32 {
{\ {\
COPY(stream);\ COPY(stream);\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_usec);\ COPY(tstamp.tv_nsec);\
COPY(avail);\ COPY(avail);\
COPY(xruns);\ COPY(xruns);\
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/compat.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/timer.h> #include <sound/timer.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
...@@ -31,7 +32,7 @@ struct sndrv_timer_info32 { ...@@ -31,7 +32,7 @@ struct sndrv_timer_info32 {
s32 card; s32 card;
unsigned char id[64]; unsigned char id[64];
unsigned char name[80]; unsigned char name[80];
u32 ticks; u32 reserved0;
u32 resolution; u32 resolution;
unsigned char reserved[64]; unsigned char reserved[64];
}; };
...@@ -42,17 +43,11 @@ struct sndrv_timer_info32 { ...@@ -42,17 +43,11 @@ struct sndrv_timer_info32 {
COPY(card);\ COPY(card);\
memcpy(dst->id, src->id, sizeof(src->id));\ memcpy(dst->id, src->id, sizeof(src->id));\
memcpy(dst->name, src->name, sizeof(src->name));\ memcpy(dst->name, src->name, sizeof(src->name));\
COPY(ticks);\
COPY(resolution);\ COPY(resolution);\
} }
struct timeval32 {
s32 tv_sec;
s32 tv_usec;
};
struct sndrv_timer_status32 { struct sndrv_timer_status32 {
struct timeval32 tstamp; struct compat_timespec tstamp;
u32 resolution; u32 resolution;
u32 lost; u32 lost;
u32 overrun; u32 overrun;
...@@ -63,7 +58,7 @@ struct sndrv_timer_status32 { ...@@ -63,7 +58,7 @@ struct sndrv_timer_status32 {
#define CVT_sndrv_timer_status()\ #define CVT_sndrv_timer_status()\
{\ {\
COPY(tstamp.tv_sec);\ COPY(tstamp.tv_sec);\
COPY(tstamp.tv_usec);\ COPY(tstamp.tv_nsec);\
COPY(resolution);\ COPY(resolution);\
COPY(lost);\ COPY(lost);\
COPY(overrun);\ COPY(overrun);\
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/asoundef.h> #include <sound/asoundef.h>
......
...@@ -716,10 +716,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) ...@@ -716,10 +716,12 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
{ {
unsigned int what = 0; unsigned int what = 0;
snd_pcm_substream_t *s = substream; snd_pcm_substream_t *s;
struct list_head *pos;
unsigned long flags; unsigned long flags;
do { snd_pcm_group_for_each(pos, substream) {
s = snd_pcm_group_substream_entry(pos);
if (s == chip->playback_substream) { if (s == chip->playback_substream) {
what |= CS4231_PLAYBACK_ENABLE; what |= CS4231_PLAYBACK_ENABLE;
snd_pcm_trigger_done(s, substream); snd_pcm_trigger_done(s, substream);
...@@ -727,8 +729,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd) ...@@ -727,8 +729,7 @@ static int snd_cs4231_trigger(snd_pcm_substream_t *substream, int cmd)
what |= CS4231_RECORD_ENABLE; what |= CS4231_RECORD_ENABLE;
snd_pcm_trigger_done(s, substream); snd_pcm_trigger_done(s, substream);
} }
s = s->link_next; }
} while (s != substream);
#if 0 #if 0
printk("TRIGGER: what[%x] on(%d)\n", printk("TRIGGER: what[%x] on(%d)\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment