···146146147147int rtlx_open(int index, int can_sleep)148148{149149- int ret;150150- struct rtlx_channel *chan;151149 volatile struct rtlx_info **p;150150+ struct rtlx_channel *chan;151151+ int ret = 0;152152153153 if (index >= RTLX_CHANNELS) {154154 printk(KERN_DEBUG "rtlx_open index out of range\n");···165165 if (rtlx == NULL) {166166 if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {167167 if (can_sleep) {168168- DECLARE_WAITQUEUE(wait, current);168168+ int ret = 0;169169170170- /* go to sleep */171171- add_wait_queue(&channel_wqs[index].lx_queue, &wait);172172-173173- set_current_state(TASK_INTERRUPTIBLE);174174- while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) {175175- schedule();176176- set_current_state(TASK_INTERRUPTIBLE);177177- }178178-179179- set_current_state(TASK_RUNNING);180180- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);181181-182182- /* back running */170170+ __wait_event_interruptible(channel_wqs[index].lx_queue,171171+ (p = vpe_get_shared(RTLX_TARG_VPE)),172172+ ret);173173+ if (ret)174174+ goto out_fail;183175 } else {184176 printk( KERN_DEBUG "No SP program loaded, and device "185177 "opened with O_NONBLOCK\n");186178 channel_wqs[index].in_open = 0;187187- return -ENOSYS;179179+ ret = -ENOSYS;180180+ goto out_fail;188181 }189182 }190183191184 if (*p == NULL) {192185 if (can_sleep) {193193- DECLARE_WAITQUEUE(wait, current);186186+ int ret = 0;194187195195- /* go to sleep */196196- add_wait_queue(&channel_wqs[index].lx_queue, &wait);197197-198198- set_current_state(TASK_INTERRUPTIBLE);199199- while (*p == NULL) {200200- schedule();201201-202202- /* reset task state to interruptable otherwise203203- we'll whizz round here like a very fast loopy204204- thing. schedule() appears to return with state205205- set to TASK_RUNNING.206206-207207- If the loaded SP program, for whatever reason,208208- doesn't set up the shared structure *p will never209209- become true. So whoever connected to either /dev/rt?210210- or if it was kspd, will then take up rather a lot of211211- processor cycles.212212- */213213-214214- set_current_state(TASK_INTERRUPTIBLE);215215- }216216-217217- set_current_state(TASK_RUNNING);218218- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);219219-220220- /* back running */221221- }222222- else {188188+ __wait_event_interruptible(channel_wqs[index].lx_queue,189189+ *p != NULL,190190+ ret);191191+ if (ret)192192+ goto out_fail;193193+ } else {223194 printk(" *vpe_get_shared is NULL. "224195 "Has an SP program been loaded?\n");225196 channel_wqs[index].in_open = 0;226226- return -ENOSYS;197197+ ret = -ENOSYS;198198+ goto out_fail;227199 }228200 }229201···203231 printk(KERN_WARNING "vpe_get_shared returned an invalid pointer "204232 "maybe an error code %d\n", (int)*p);205233 channel_wqs[index].in_open = 0;206206- return -ENOSYS;234234+ ret = -ENOSYS;235235+ goto out_fail;207236 }208237209209- if ((ret = rtlx_init(*p)) < 0) {238238+ if ((ret = rtlx_init(*p)) < 0) {210239 channel_wqs[index].in_open = 0;211240 return ret;212241 }···223250 chan->lx_state = RTLX_STATE_OPENED;224251 channel_wqs[index].in_open = 0;225252 return 0;253253+254254+out_fail:255255+ channel_wqs[index].in_open--;256256+257257+ return ret;226258}227259228260int rtlx_release(int index)···248270 /* data available to read? */249271 if (chan->lx_read == chan->lx_write) {250272 if (can_sleep) {251251- DECLARE_WAITQUEUE(wait, current);273273+ int ret = 0;252274253253- /* go to sleep */254254- add_wait_queue(&channel_wqs[index].lx_queue, &wait);275275+ __wait_event_interruptible(channel_wqs[index].lx_queue,276276+ chan->lx_read != chan->lx_write || sp_stopping,277277+ ret);278278+ if (ret)279279+ return ret;255280256256- set_current_state(TASK_INTERRUPTIBLE);257257- while (chan->lx_read == chan->lx_write) {258258- schedule();259259-260260- set_current_state(TASK_INTERRUPTIBLE);261261-262262- if (sp_stopping) {263263- set_current_state(TASK_RUNNING);264264- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);265265- return 0;266266- }267267- }268268-269269- set_current_state(TASK_RUNNING);270270- remove_wait_queue(&channel_wqs[index].lx_queue, &wait);271271-272272- /* back running */273273- }274274- else281281+ if (sp_stopping)282282+ return 0;283283+ } else275284 return 0;276285 }277286···419454{420455 int minor;421456 struct rtlx_channel *rt;422422- DECLARE_WAITQUEUE(wait, current);423457424458 minor = iminor(file->f_path.dentry->d_inode);425459 rt = &rtlx->channel[minor];426460427461 /* any space left... */428462 if (!rtlx_write_poll(minor)) {463463+ int ret = 0;429464430465 if (file->f_flags & O_NONBLOCK)431466 return -EAGAIN;432467433433- add_wait_queue(&channel_wqs[minor].rt_queue, &wait);434434- set_current_state(TASK_INTERRUPTIBLE);435435-436436- while (!rtlx_write_poll(minor))437437- schedule();438438-439439- set_current_state(TASK_RUNNING);440440- remove_wait_queue(&channel_wqs[minor].rt_queue, &wait);468468+ __wait_event_interruptible(channel_wqs[minor].rt_queue,469469+ rtlx_write_poll(minor),470470+ ret);471471+ if (ret)472472+ return ret;441473 }442474443475 return rtlx_write(minor, (void *)buffer, count, 1);