static void falcon_get_lock( void ) { unsigned long flags; if (IS_A_TT()) return; local_irq_save(flags); while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() ) sleep_on( &falcon_fairness_wait ); while (!falcon_got_lock) { if (in_interrupt()) panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" ); if (!falcon_trying_lock) { falcon_trying_lock = 1; stdma_lock(scsi_falcon_intr, NULL); falcon_got_lock = 1; falcon_trying_lock = 0; wake_up( &falcon_try_wait ); } else { sleep_on( &falcon_try_wait ); } } local_irq_restore(flags); if (!falcon_got_lock) panic("Falcon SCSI: someone stole the lock :-(\n"); }
static void falcon_get_lock( void ) { unsigned long oldflags; if (IS_A_TT()) return; save_flags(oldflags); cli(); while( intr_count == 0 && falcon_got_lock && stdma_others_waiting() ) sleep_on( &falcon_fairness_wait ); while (!falcon_got_lock) { if (intr_count > 0) panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" ); if (!falcon_trying_lock) { falcon_trying_lock = 1; stdma_lock(scsi_falcon_intr, NULL); falcon_got_lock = 1; falcon_trying_lock = 0; wake_up( &falcon_try_wait ); } else { sleep_on( &falcon_try_wait ); } } restore_flags(oldflags); if (!falcon_got_lock) panic("Falcon SCSI: someone stole the lock :-(\n"); }
/* Seek to a given track */ static int floppy_seek(const struct floppy_ports *p, uint8_t trk) { long flags; if ( trk == status[1] ) return 1; /* Send the seek command */ lock_irq(flags); floppy_send(p, CMD_SEEK); floppy_send(p, 0); floppy_send(p, trk); sleep_on(&floppyq); unlock_irq(flags); if ( !(status[0] & ST0_SE) ) { printk("floppy: seek failed\n"); return 0; } if ( status[1] != trk ) { printk("floppy: seek to %u failed (%u)\n", trk, status[1]); return 0; } return 1; }
// Look through buffer cache for the nblk-th sector on device dev // If not found, allocate a fresh block. // In either case, return BUF_BUSY buffer struct buf *getblk(uint32_t dev, uint32_t nblk) { struct buf *bp; repeat: for(bp = bhead.next; bp != &bhead; bp = bp->next){ if(bp->dev == dev && bp->num == nblk){ if((bp->flags & BUF_BUSY) == 0){ bp->flags |= BUF_BUSY; return bp; } sleep_on(&bp->bwait); goto repeat; } } // block not cached yet for(bp = bhead.prev; bp != &bhead; bp = bp->prev){ if((bp->flags & (BUF_BUSY | BUF_DIRTY)) == 0){ bp->flags = BUF_BUSY; bp->dev = dev; bp->num = nblk; return bp; } } // no cache available panic("getblk: no buffers available"); }
static int ar7100fr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; switch(cmd) { case AR7100_FACTORY_RESET: /* Userspace process "factoryreset" is doing IOCTL * Hope AP is successfully UP * Turn the power LED on */ #ifdef CONFIG_AR9100 #define AP8x_GPIO_POWER_LED (0x01 << 14) ar7100_reg_wr(AR7100_GPIO_OE, AP8x_GPIO_POWER_LED); ar7100_reg_wr(AR7100_GPIO_OUT, ((ar7100_reg_rd(AR7100_GPIO_OUT)) | ((AP8x_GPIO_POWER_LED)))); #endif atomic_inc(&ar7100_fr_status); sleep_on(&ar7100_fr_wq); break; default: ret = -EINVAL; } return ret; }
static void wait_on_buffer(struct buffer_head *bh) { disable_int(); while(bh->b_lock) sleep_on(&bh->b_wait); enable_int(); }
asmlinkage long sys_doevent_wait(long event_id) { /*lock global lock*/ event_t * event = find_event_by_id(event_id); /*find event by event id*/ if(event==NULL) { /*unlock global lock*/ return -1; } event->count++; /*increase the num of process using the event*/ /*unlock global lock*/ /*lock event lock*/ if(event->invalid) /*if already close*/ { if(event->count==1) /*if last one of use*/ kfree(event); count--; /*after use of the event*/ return -1; } sleep_on(&event->Q); /*sleep on event*/ event->count--; /*after use of the event*/ /*unlock event lock*/ return 0; }
static int ar7240wdt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; wddbg("%s: called\n", __func__); switch(cmd) { case FACTORY_RESET: wddbg("%s: intr action\n", __func__); #ifndef CONFIG_MACH_HORNET if ((ret = request_irq( AR7240_MISC_IRQ_WATCHDOG, ar7240_wdt_isr, 0, "Watchdog Timer", wdt))) { wddbg("%s: request_irq %d\n", __func__, ret); return ret; } ar7240_set_wd_timer_action(AR7240_WD_ACT_GP_INTR); sleep_on(&wdt->wq); free_irq(AR7240_MISC_IRQ_WATCHDOG, wdt); #endif break; default: ret = -EINVAL; } return ret; }
//// 等待指定缓冲区解锁。 static _inline void wait_on_buffer(struct buffer_head * bh) { cli(); // 关中断。 while (bh->b_lock) // 如果已被上锁,则进程进入睡眠,等待其解锁。 sleep_on(&bh->b_wait); sti(); // 开中断。 }
void sleep_on1(void *p) { cli(); sleep_on(p); sti(); }
static struct buffer_head *get_free_buffer(void) { register struct buffer_head *bh; for (;;) { bh = bh_lru; do { #ifdef CONFIG_FS_EXTERNAL_BUFFER if (bh->b_count == 0 && !bh->b_dirty && !bh->b_lock && !bh->b_data) #else if (bh->b_count == 0 && !bh->b_dirty && !bh->b_lock) #endif { put_last_lru(bh); return bh; } } while((bh = bh->b_next_lru) != NULL); #if 0 fsync_dev(0); /* This causes a sleep until another process brelse's */ sleep_on(&bufwait); #endif sync_buffers(0, 0); } }
int reiserfs_rename ( struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir, struct dentry *new_dentry ) { static struct wait_queue * wait = NULL; static int lock = 0; int result; int windex ; struct reiserfs_transaction_handle th ; int jbegin_count = JOURNAL_PER_BALANCE_CNT * 3; while (lock) sleep_on(&wait); lock = 1; journal_begin(&th, old_dir->i_sb, jbegin_count) ; windex = push_journal_writer("reiesrfs_rename") ; /* we are trusting if_in_ram_update_sd to update the transaction ** info in each inode as they get chagned */ result = do_reiserfs_rename (&th, old_dir, old_dentry, new_dir, new_dentry); pop_journal_writer(windex) ; journal_end(&th, old_dir->i_sb, jbegin_count) ; lock = 0; wake_up(&wait); return result; }
void rw_abs_hd(int rw, unsigned int nr, unsigned int sec, unsigned int head, unsigned int cyl, struct buffer_head * bh) { struct hd_request * req; if (rw != READ && rw != WRITE) panic("Bad hd command, must be R/W"); lock_buffer(bh); repeat: for (req = 0 + request; req < NR_REQUEST + request; req++) if (req->hd < 0) break; if (req == NR_REQUEST + request) { sleep_on(&wait_for_request); goto repeat; } req->hd = nr; req->nsector = 2; req->sector = sec; req->head = head; req->cyl = cyl; req->cmd = ((rw == READ) ? WIN_READ : WIN_WRITE); req->bh = bh; req->errors = 0; req->next = NULL; add_request(req); wait_on_buffer(bh); }
static int getMcdStatus(int timeout) { int st; McdTimeout = timeout; SET_TIMER(mcdStatTimer, 1); sleep_on(&mcd_waitq); if (McdTimeout <= 0) return -1; st = inb(MCDPORT(0)) & 0xFF; if (st == 0xFF) return -1; if ((st & MST_BUSY) == 0 && audioStatus == CDROM_AUDIO_PLAY) /* XXX might be an error? look at q-channel? */ audioStatus = CDROM_AUDIO_COMPLETED; if (st & MST_DSK_CHG) { mcdDiskChanged = 1; tocUpToDate = 0; audioStatus = CDROM_AUDIO_NO_STATUS; } return st; }
uint32_t write_pipe(fs_node_t *node, uint32_t offset, uint32_t size, uint8_t *buffer) { assert(node->device != 0 && "Attempted to write to a fully-closed pipe."); /* Retreive the pipe object associated with this file node */ pipe_device_t * pipe = (pipe_device_t *)node->device; #if DEBUG_PIPES if (pipe->size > 300) { /* Ignore small pipes (ie, keyboard) */ debug_print(INFO, "[debug] Call to write to pipe 0x%x", node->device); debug_print(INFO, " Available space: %d", pipe_available(pipe)); debug_print(INFO, " Total size: %d", pipe->size); debug_print(INFO, " Request size: %d", size); debug_print(INFO, " Write pointer: %d", pipe->write_ptr); debug_print(INFO, " Read pointer: %d", pipe->read_ptr); debug_print(INFO, " Buffer address: 0x%x", pipe->buffer); debug_print(INFO, " Write: %s", buffer); } #endif if (pipe->dead) { debug_print(WARNING, "Pipe is dead?"); send_signal(getpid(), SIGPIPE); return 0; } size_t written = 0; while (written < size) { spin_lock(pipe->lock_write); #if 0 size_t available = 0; if (pipe->read_ptr <= pipe->write_ptr) { available = pipe->size - pipe->write_ptr; } else { available = pipe->read_ptr - pipe->write_ptr - 1; } if (available) { available = min(available, size - written); memcpy(&pipe->buffer[pipe->write_ptr], buffer, available); pipe_increment_write_by(pipe, available); written += available; } #else while (pipe_available(pipe) > 0 && written < size) { pipe->buffer[pipe->write_ptr] = buffer[written]; pipe_increment_write(pipe); written++; } #endif spin_unlock(pipe->lock_write); wakeup_queue(pipe->wait_queue_readers); pipe_alert_waiters(pipe); if (written < size) { sleep_on(pipe->wait_queue_writers); } } return written; }
void journal_sync_buffer(struct buffer_head *bh) { transaction_t *transaction; journal_t *journal; long sequence; /* If the buffer isn't journaled, this is easy: just sync it to * disk. */ if (bh->b_transaction == NULL) { /* If the buffer has already been journaled, then this * is a noop. */ if (bh->b_cp_transaction == NULL) return; ll_rw_block (WRITE, 1, &bh); wait_on_buffer (bh); return; } /* Otherwise, just wait until the transaction is synced to disk. */ transaction = bh->b_transaction; journal = transaction->t_journal; sequence = transaction->t_tid; jfs_debug(2, "requesting commit for bh %p\n", bh); log_start_commit (journal, transaction); while (tid_gt(sequence, journal->j_commit_sequence)) { wake_up(&journal->j_wait_done_commit); sleep_on(&journal->j_wait_done_commit); } }
static void locks_delete_lock(struct file_lock **fl_p, unsigned int wait) { struct file_lock *fl; struct file_lock *pfl; struct file_lock *nfl; fl = *fl_p; *fl_p = fl->fl_next; pfl = fl->fl_prevlink; nfl = fl->fl_nextlink; if (nfl != NULL) nfl->fl_prevlink = pfl; if (pfl != NULL) pfl->fl_nextlink = nfl; else file_lock_table = nfl; while ((nfl = fl->fl_block) != NULL) { fl->fl_block = nfl->fl_block; nfl->fl_block = NULL; wake_up(&nfl->fl_wait); if (wait) sleep_on(&nfl->fl_wait); } wake_up(&fl->fl_wait); kfree(fl); return; }
int write_pipe(struct m_inode * inode, char * buf, int count) { char * b=buf; wake_up(&inode->i_wait); if (inode->i_count != 2) { /* no readers */ current->signal |= (1<<(SIGPIPE-1)); return -1; } while (count-->0) { while (PIPE_FULL(*inode)) { wake_up(&inode->i_wait); if (inode->i_count != 2) { current->signal |= (1<<(SIGPIPE-1)); return b-buf; } sleep_on(&inode->i_wait); } ((char *)inode->i_size)[PIPE_HEAD(*inode)] = get_fs_byte(b++); INC_PIPE( PIPE_HEAD(*inode) ); wake_up(&inode->i_wait); } wake_up(&inode->i_wait); return b-buf; }
static inline void wait_on_buffer(struct buffer_head * bh) { cli(); while (bh->b_lock) sleep_on(&bh->b_wait); sti(); }
int write_pipe(struct m_inode * inode, char * buf, int count) { int chars, size, written = 0; while (count>0) { while (!(size=(PAGE_SIZE-1)-PIPE_SIZE(*inode))) { wake_up(&inode->i_wait); if (inode->i_count != 2) { /* no readers */ current->signal |= (1<<(SIGPIPE-1)); return written?written:-1; } sleep_on(&inode->i_wait); } chars = PAGE_SIZE-PIPE_HEAD(*inode); if (chars > count) chars = count; if (chars > size) chars = size; count -= chars; written += chars; size = PIPE_HEAD(*inode); PIPE_HEAD(*inode) += chars; PIPE_HEAD(*inode) &= (PAGE_SIZE-1); while (chars-->0) ((char *)inode->i_size)[size++]=get_fs_byte(buf++); } wake_up(&inode->i_wait); return written; }
int read_pipe(struct m_inode * inode, char * buf, int count) { int chars, size, read = 0; while (count>0) { while (!(size=PIPE_SIZE(*inode))) { wake_up(&inode->i_wait); if (inode->i_count != 2) /* are there any writers? */ return read; sleep_on(&inode->i_wait); } chars = PAGE_SIZE-PIPE_TAIL(*inode); if (chars > count) chars = count; if (chars > size) chars = size; count -= chars; read += chars; size = PIPE_TAIL(*inode); PIPE_TAIL(*inode) += chars; PIPE_TAIL(*inode) &= (PAGE_SIZE-1); while (chars-->0) put_fs_byte(((char *)inode->i_size)[size++],buf++); } wake_up(&inode->i_wait); return read; }
/* Flush the write buffer */ static int flush_write_buffer(int dev) { int offset, transfer, blks; int result; unsigned char cmd[10]; Scsi_Cmnd *SCpnt; #if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS if (scsi_tapes[dev].buffer->writing) { write_behind_check(dev); if (scsi_tapes[dev].buffer->last_result) { #ifdef DEBUG printk("st%d: Async write error %x.\n", dev, scsi_tapes[dev].buffer->last_result); #endif return (-EIO); } } #endif result = 0; if (scsi_tapes[dev].dirty==1) { SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1); offset = scsi_tapes[dev].buffer->buffer_bytes; transfer = ((offset + scsi_tapes[dev].block_size - 1) / scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size; #ifdef DEBUG printk("st%d: Flushing %d bytes.\n", dev, transfer); #endif memset(scsi_tapes[dev].buffer->b_data + offset, 0, transfer - offset); SCpnt->sense_buffer[0] = 0; memset(cmd, 0, 10); cmd[0] = WRITE_6; cmd[1] = 1; blks = transfer / scsi_tapes[dev].block_size; cmd[2] = blks >> 16; cmd[3] = blks >> 8; cmd[4] = blks; SCpnt->request.dev = dev; scsi_do_cmd (SCpnt, (void *) cmd, scsi_tapes[dev].buffer->b_data, transfer, st_sleep_done, ST_TIMEOUT, MAX_RETRIES); if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting ); if (SCpnt->result != 0) { printk("st%d: Error on flush:\n", dev); #ifdef DEBUG st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer); #endif result = (-EIO); } else { scsi_tapes[dev].dirty = 0; scsi_tapes[dev].buffer->buffer_bytes = 0; } SCpnt->request.dev = -1; /* Mark as not busy */ }
static void snooze(unsigned long snooze_time, unsigned minor) { instances[minor].timer_list.expires = jiffies + snooze_time + 1; instances[minor].timer_list.data = minor; add_timer(&instances[minor].timer_list); sleep_on (&instances[minor].wait_queue); }
static void make_request(int major,int rw, struct buffer_head * bh) { //debug("make_request1"); struct request * req; int rw_ahead; /* WRITEA/READA is special case - it is not really needed, so if the */ /* buffer is locked, we just forget about it, else it's a normal read */ if (rw_ahead = (rw == READA || rw == WRITEA)) { if (bh->b_lock) return; if (rw == READA) rw = READ; else rw = WRITE; } if (rw!=READ && rw!=WRITE) panic("Bad block dev command, must be R/W/RA/WA"); lock_buffer(bh); //debug("make_request2"); if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) { unlock_buffer(bh); return; } repeat: /* we don't allow the write-requests to fill up the queue completely: * we want some room for reads: they take precedence. The last third * of the requests are only for reads. */ if (rw == READ) req = request+NR_REQUEST; else req = request+((NR_REQUEST*2)/3); /* find an empty request */ while (--req >= request) if (req->dev<0) break; /* if none found, sleep on new requests: check for rw_ahead */ if (req < request) { if (rw_ahead) { unlock_buffer(bh); return; } sleep_on(&wait_for_request); goto repeat; } /* fill up the request-info, and add it to the queue */ req->dev = bh->b_dev; req->cmd = rw; req->errors=0; req->sector = bh->b_blocknr<<1; req->nr_sectors = 2; req->buffer = bh->b_data; req->waiting = NULL; req->bh = bh; req->next = NULL; //debug("before add request"); add_request(major+blk_dev,req); }
void flash_safe_acquire(void *part) { struct flashchip *chip = ((struct flashpartition *)part)->chip; while (chip->busy) sleep_on(&chip->wqueue); chip->busy = 1; }
void cleanup_module(void) { // because we can't unload without removing the timer first cleaning_up = 1; sleep_on (&WaitQ); if (log) printk (KERN_ALERT "[myuptime] uptime change is complete\n"); }
static inline void lock_buffer(struct buffer_head *bh) { disable_int(); while(bh->b_lock) sleep_on(&bh->b_wait); bh->b_lock = 1; enable_int(); }
static inline void wait_on_buffer(struct buffer_head * bh) { cli(); while (bh->b_lock){ debug("about to sleep"); sleep_on(&bh->b_wait); } sti(); }
/* Recalibrate the selected drive */ static void floppy_recal(const struct floppy_ports *p) { long flags; lock_irq(flags); floppy_send(p, CMD_RECAL); floppy_send(p, 0); sleep_on(&floppyq); unlock_irq(flags); }
void down(register short int *s) { /* Wait for the semaphore */ while (*s < 0) sleep_on((void *) s); /* Take it */ --(*s); }