···146147int rtlx_open(int index, int can_sleep)148{149- int ret;150- struct rtlx_channel *chan;151 volatile struct rtlx_info **p;00152153 if (index >= RTLX_CHANNELS) {154 printk(KERN_DEBUG "rtlx_open index out of range\n");···165 if (rtlx == NULL) {166 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {167 if (can_sleep) {168- DECLARE_WAITQUEUE(wait, current);169170- /* go to sleep */171- add_wait_queue(&channel_wqs[index].lx_queue, &wait);172-173- set_current_state(TASK_INTERRUPTIBLE);174- while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {175- schedule();176- set_current_state(TASK_INTERRUPTIBLE);177- }178-179- set_current_state(TASK_RUNNING);180- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);181-182- /* back running */183 } else {184 printk( KERN_DEBUG "No SP program loaded, and device "185 "opened with O_NONBLOCK\n");186 channel_wqs[index].in_open = 0;187- return -ENOSYS;0188 }189 }190191 if (*p == NULL) {192 if (can_sleep) {193- DECLARE_WAITQUEUE(wait, current);194195- /* go to sleep */196- add_wait_queue(&channel_wqs[index].lx_queue, &wait);197-198- set_current_state(TASK_INTERRUPTIBLE);199- while (*p == NULL) {200- schedule();201-202- /* reset task state to interruptable otherwise203- we'll whizz round here like a very fast loopy204- thing. schedule() appears to return with state205- set to TASK_RUNNING.206-207- If the loaded SP program, for whatever reason,208- doesn't set up the shared structure *p will never209- become true. So whoever connected to either /dev/rt?210- or if it was kspd, will then take up rather a lot of211- processor cycles.212- */213-214- set_current_state(TASK_INTERRUPTIBLE);215- }216-217- set_current_state(TASK_RUNNING);218- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);219-220- /* back running */221- }222- else {223 printk(" *vpe_get_shared is NULL. "224 "Has an SP program been loaded?\n");225 channel_wqs[index].in_open = 0;226- return -ENOSYS;0227 }228 }229···203 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "204 "maybe an error code %d\n", (int)*p);205 channel_wqs[index].in_open = 0;206- return -ENOSYS;0207 }208209- if ((ret = rtlx_init(*p)) < 0) {210 channel_wqs[index].in_open = 0;211 return ret;212 }···223 chan->lx_state = RTLX_STATE_OPENED;224 channel_wqs[index].in_open = 0;225 return 0;00000226}227228int rtlx_release(int index)···248 /* data available to read? */249 if (chan->lx_read == chan->lx_write) {250 if (can_sleep) {251- DECLARE_WAITQUEUE(wait, current);252253- /* go to sleep */254- add_wait_queue(&channel_wqs[index].lx_queue, &wait);000255256- set_current_state(TASK_INTERRUPTIBLE);257- while (chan->lx_read == chan->lx_write) {258- schedule();259-260- set_current_state(TASK_INTERRUPTIBLE);261-262- if (sp_stopping) {263- set_current_state(TASK_RUNNING);264- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);265- return 0;266- }267- }268-269- set_current_state(TASK_RUNNING);270- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);271-272- /* back running */273- }274- else275 return 0;276 }277···419{420 int minor;421 struct rtlx_channel *rt;422- DECLARE_WAITQUEUE(wait, current);423424 minor = iminor(file->f_path.dentry->d_inode);425 rt = &rtlx->channel[minor];426427 /* any space left... */428 if (!rtlx_write_poll(minor)) {0429430 if (file->f_flags & O_NONBLOCK)431 return -EAGAIN;432433- add_wait_queue(&channel_wqs[minor].rt_queue, &wait);434- set_current_state(TASK_INTERRUPTIBLE);435-436- while (!rtlx_write_poll(minor))437- schedule();438-439- set_current_state(TASK_RUNNING);440- remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);441 }442443 return rtlx_write(minor, (void *)buffer, count, 1);
···146147int rtlx_open(int index, int can_sleep)148{00149 volatile struct rtlx_info **p;150+ struct rtlx_channel *chan;151+ int ret = 0;152153 if (index >= RTLX_CHANNELS) {154 printk(KERN_DEBUG "rtlx_open index out of range\n");···165 if (rtlx == NULL) {166 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {167 if (can_sleep) {168+ int ret = 0;169170+ __wait_event_interruptible(channel_wqs[index].lx_queue,171+ (p = vpe_get_shared(RTLX_TARG_VPE)),172+ ret);173+ if (ret)174+ goto out_fail;00000000175 } else {176 printk( KERN_DEBUG "No SP program loaded, and device "177 "opened with O_NONBLOCK\n");178 channel_wqs[index].in_open = 0;179+ ret = -ENOSYS;180+ goto out_fail;181 }182 }183184 if (*p == NULL) {185 if (can_sleep) {186+ int ret = 0;187188+ __wait_event_interruptible(channel_wqs[index].lx_queue,189+ *p != NULL,190+ ret);191+ if (ret)192+ goto out_fail;193+ } else {0000000000000000000000194 printk(" *vpe_get_shared is NULL. "195 "Has an SP program been loaded?\n");196 channel_wqs[index].in_open = 0;197+ ret = -ENOSYS;198+ goto out_fail;199 }200 }201···231 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "232 "maybe an error code %d\n", (int)*p);233 channel_wqs[index].in_open = 0;234+ ret = -ENOSYS;235+ goto out_fail;236 }237238+ if ((ret = rtlx_init(*p)) < 0) {239 channel_wqs[index].in_open = 0;240 return ret;241 }···250 chan->lx_state = RTLX_STATE_OPENED;251 channel_wqs[index].in_open = 0;252 return 0;253+254+out_fail:255+ channel_wqs[index].in_open--;256+257+ return ret;258}259260int rtlx_release(int index)···270 /* data available to read? */271 if (chan->lx_read == chan->lx_write) {272 if (can_sleep) {273+ int ret = 0;274275+ __wait_event_interruptible(channel_wqs[index].lx_queue,276+ chan->lx_read != chan->lx_write || sp_stopping,277+ ret);278+ if (ret)279+ return ret;280281+ if (sp_stopping)282+ return 0;283+ } else0000000000000000284 return 0;285 }286···454{455 int minor;456 struct rtlx_channel *rt;0457458 minor = iminor(file->f_path.dentry->d_inode);459 rt = &rtlx->channel[minor];460461 /* any space left... */462 if (!rtlx_write_poll(minor)) {463+ int ret = 0;464465 if (file->f_flags & O_NONBLOCK)466 return -EAGAIN;467468+ __wait_event_interruptible(channel_wqs[minor].rt_queue,469+ rtlx_write_poll(minor),470+ ret);471+ if (ret)472+ return ret;000473 }474475 return rtlx_write(minor, (void *)buffer, count, 1);