static int write_hello (struct file *file,const char * buf, unsigned long count, void *data) { int length=count; struct proc_hello_data *usrsp=hello_data; length = (length<PROC_HELLO_LEN)? length:PROC_HELLO_LEN; printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "prepare to wait ..!\n", current->pid, current->comm); printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "waiting ..!\n", current->pid, current->comm); // sleep instead of wakeup. see next example for wakeup sleep_on_timeout(usrsp->proc_hello_wqh,10*HZ); // process awake message printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "finished waiting ..!\n", current->pid, current->comm); if (copy_from_user(usrsp->proc_hello_value, buf, length)) return -EFAULT; printk(KERN_ALERT "2470:10.1: writing message!\n"); usrsp->proc_hello_value[length-1]=0; usrsp->proc_hello_flag=1; // sleep instead of wakeup. see next example for wakeup // wake_up_interruptible(usrsp->proc_hello_wqh); // return(length); }
int s3c2410_adc_read(int ain, wait_queue_head_t *wait) { int ret = 0; if (down_interruptible(&adc_lock)) return -ERESTARTSYS; adc_wait = wait; START_ADC_AIN(ain); sleep_on_timeout(adc_wait, HZ/100); /* 10ms */ #if 0 if (signal_pending(current)) { up(&adc_lock); return -ERESTARTSYS; } #endif ret = ADCDAT0 ; up(&adc_lock); adc_wait = NULL; DPRINTK("AIN[%d] = 0x%04x, %d\n", ain, ret, ADCCON & 0x80 ? 1:0); return (ret & 0x3ff); }
int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev) { dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n"); sleep_on_timeout(&fbdev->wq, HZ / 10); dev_dbg(fbdev->dev, "got a VSYNC interrupt\n"); return 0; }
static int s3cfb_wait_for_vsync(void) { dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n"); sleep_on_timeout(&fbdev->wq, HZ / 10); dev_dbg(fbdev->dev, "got a VSYNC interrupt\n"); return 0; }
/*×Óœø³ÌŽŠÀíº¯Êý¶šÒå*/ int my_function(void * argc) { wait_queue_head_t head; wait_queue_t data; printk("<0>in the kernel thread function!\n"); init_waitqueue_head(&head); //³õÊŒ»¯µÈŽý¶ÓÁÐÍ·ÔªËØ init_waitqueue_entry(&data,current); //Óõ±Ç°œø³Ì³õÊŒ»¯µÈŽý¶ÓÁÐÔªËØ add_wait_queue(&head,&data); //œ«µ±Ç°œø³Ì²åÈ뵜µÈµœ¶ÓÁÐÖÐ sleep_on_timeout(&head,10); //œ«µÈŽý¶ÓÁÐÖÃÓÚ²»¿ÉÖжϵĵȎý׎̬ printk("<0>the current pid is:%d\n",current->pid); //ÏÔÊŸµ±Ç°œø³ÌµÄPIDÖµ printk("<0>the state of the real parent is:%ld\n",current->real_parent->state); //ÏÔÊŸžžœø³ÌµÄ׎̬ //complete(&comple); //µ÷Óú¯Êý»œÐÑœø³Ì£¬²¢žüžÄdone×ֶεÄÖµ printk("<0>out the kernel thread function\n"); return 0; }
static int sample_thread(void *num) { printk("%s called\n", __func__); for (;;) { sleep_on_timeout(&wait, 3 * HZ); if (kthread_should_stop()) break; } printk("%s leaved\n", __func__); return 0; }
/* * Block on a lock */ int nlmclnt_block(struct nlm_host *host, struct file_lock *fl, u32 *statp) { struct nlm_wait block, **head; int err; u32 pstate; block.b_host = host; block.b_lock = fl; init_waitqueue_head(&block.b_wait); block.b_status = NLM_LCK_BLOCKED; block.b_next = nlm_blocked; nlm_blocked = █ /* Remember pseudo nsm state */ pstate = host->h_state; /* Go to sleep waiting for GRANT callback. Some servers seem * to lose callbacks, however, so we're going to poll from * time to time just to make sure. * * For now, the retry frequency is pretty high; normally * a 1 minute timeout would do. See the comment before * nlmclnt_lock for an explanation. */ sleep_on_timeout(&block.b_wait, 30*HZ); for (head = &nlm_blocked; *head; head = &(*head)->b_next) { if (*head == &block) { *head = block.b_next; break; } } if (!signalled()) { *statp = block.b_status; return 0; } /* Okay, we were interrupted. Cancel the pending request * unless the server has rebooted. */ if (pstate == host->h_state && (err = nlmclnt_cancel(host, fl)) < 0) printk(KERN_NOTICE "lockd: CANCEL call failed (errno %d)\n", -err); return -ERESTARTSYS; }
static void moduleTestLoop ( void ) { int localCount = 0; while (1) { putABreakPointHere(); /* Waits 1 sec */ sleep_on_timeout(&wait,500); PRINTF("moduleTest thread woke up. Global is %s !\n", globalData); localCount++; count += 2; if (moduleTestExiting) { PRINTF("localCount = %d; count = %d; moduleTest thread exiting!\n", localCount, count); complete_and_exit(&evt_dead,0); } } }
/*Ä£¿éŒÓÔغ¯Êý¶šÒå*/ static int __init __wake_up_sync_key_init(void) { /*ŸÖ²¿±äÁ¿¶šÒå*/ int result=0; long left_time=0; wait_queue_t data; printk("<0>into __wake_up_sync_key_init.\n"); result=kernel_thread(my_function,NULL,CLONE_KERNEL); //ŽŽœšÐÂœø³Ì init_waitqueue_head(&head); //³õÊŒ»¯µÈŽý¶ÓÁÐÍ·ÖžÕë init_waitqueue_entry(&data,current); //Óõ±Ç°œø³Ì³õÊŒ»¯µÈŽý¶ÓÁÐÖеÄÒ»žöÔªËØ add_wait_queue(&head,&data); //œ«µ±Ç°œø³ÌŒÓÈëµÈŽý¶ÓÁÐ left_time=sleep_on_timeout(&head,100); //œ«µÈŽý¶ÓÁÐÖÃÓÚ²»¿ÉÖжϵĵȎý׎̬ printk("<0>the return result of the sleep_on_timeout is:%ld\n",left_time); //ÏÔÊŸº¯Êýsleep_on_timeout( )µÄ·µ»Øœá¹û printk("<0>the result of the kernel_thread is :%d\n",result); //ÏÔÊŸº¯Êýkernel_thread( )µÄ·µ»Øœá¹û printk("<0>the current pid is:%d\n",current->pid); //ÏÔÊŸµ±Ç°œø³ÌµÄPIDÖµ printk("<0>out __wake_up_sync_key_init.\n"); return 0; }
//Ä£¿éŒÓÔغ¯Êý¶šÒå static int __init sleep_on_timeout_init(void) { int result; long result1; wait_queue_head_t head; wait_queue_t data; printk("<0>into sleep_on_timeout_init.\n"); result=kernel_thread(my_function,NULL,CLONE_KERNEL); //ŽŽœšÐÂœø³Ì init_waitqueue_head(&head); //³õÊŒ»¯µÈŽý¶ÓÁеÄÍ·œáµã init_waitqueue_entry(&data,current); //Óõ±Ç°œø³Ì³õÊŒ»¯µÈŽý¶ÓÁÐÖеĜڵãÔªËØ add_wait_queue(&head,&data); //œ«µ±Ç°œø³ÌŒÓÈëµÈŽý¶ÓÁÐ result1=sleep_on_timeout(&head,100); //œ«µÈŽý¶ÓÁÐÖеĜø³ÌÖÃÓÚ˯Ãß׎̬ printk("<0>the result of the kernel_thread is :%d\n",result); //ÏÔÊŸkernel_thread()º¯ÊýµÄ·µ»Øœá¹û printk("<0>the result of the sleep_on_timeout is:%ld\n",result1); //ÏÔÊŸº¯Êýsleep_on_timeout()µÄ·µ»Øœá¹û printk("<0>the current pid is:%d\n",current->pid); //ÏÔÊŸµ±Ç°œø³ÌµÄPID printk("<0>out sleep_on_timeout_init.\n"); return 0; }
/* * Properly shut down an RPC client, terminating all outstanding * requests. Note that we must be certain that cl_oneshot and * cl_dead are cleared, or else the client would be destroyed * when the last task releases it. */ int rpc_shutdown_client(struct rpc_clnt *clnt) { dprintk("RPC: shutting down %s client for %s\n", clnt->cl_protname, clnt->cl_server); while (atomic_read(&clnt->cl_users)) { #ifdef RPC_DEBUG dprintk("RPC: rpc_shutdown_client: client %s, tasks=%d\n", clnt->cl_protname, atomic_read(&clnt->cl_users)); #endif /* Don't let rpc_release_client destroy us */ clnt->cl_oneshot = 0; clnt->cl_dead = 0; rpc_killall_tasks(clnt); sleep_on_timeout(&destroy_wait, 1*HZ); } return rpc_destroy_client(clnt); }
static int read_hello (char *buf, char **start, off_t offset, int len, int *eof, void *unused) { struct proc_hello_data *usrsp=hello_data; int n=0; *eof = 1; printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "prepare to wait ..!\n", current->pid, current->comm); prepare_to_wait(usrsp->proc_hello_wqh,usrsp->proc_hello_wq, TASK_INTERRUPTIBLE); printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "waiting ..!\n", current->pid, current->comm); sleep_on_timeout(usrsp->proc_hello_wqh,10*HZ); printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "done waiting ..!\n", current->pid, current->comm); /* while (usrsp->proc_hello_flag!=1) { printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "call schedule ..!\n", current->pid, current->comm); schedule(); } */ // process awake message printk(KERN_ALERT "2470:10.1 process(%d \"%s\") " "finished waiting ..!\n", current->pid, current->comm); finish_wait(usrsp->proc_hello_wqh,usrsp->proc_hello_wq); usrsp->proc_hello_flag=0; n=sprintf(buf, "Hello .. I got \"%s\"\n", usrsp->proc_hello_value); return n; }
/*×Óœø³ÌŽŠÀíº¯Êý¶šÒå*/ int my_function(void * argc) { bool done; wait_queue_head_t head; wait_queue_t data; printk("<0>in the kernel thread function!\n"); init_waitqueue_head(&head); //³õÊŒ»¯µÈŽý¶ÓÁÐÍ·ÔªËØ init_waitqueue_entry(&data,current); //Óõ±Ç°œø³Ì³õÊŒ»¯µÈŽý¶ÓÁÐÔªËØ add_wait_queue(&head,&data); //œ«µ±Ç°œø³Ì²åÈ뵜µÈµœ¶ÓÁÐÖÐ sleep_on_timeout(&head,10); //œ«µÈŽý¶ÓÁÐÖÃÓÚ²»¿ÉÖжϵĵȎý׎̬ complete(&comple); //µ÷Óú¯Êý»œÐÑœø³Ì£¬²¢žüžÄdone×ֶεÄÖµ printk("<0>the value of done of the comple is:%d\n",comple.done); //ÏÔÊŸ×Ö¶ÎdoneµÄÖµ done=try_wait_for_completion(&comple); //³¢ÊÔÎÞ×èÈûµÄÏûºÄÒ»žöcompletion£¬ŒŽŒõÉÙdone×ֶεÄÖµ printk("<0>the value of done of the comple is:%d\n",comple.done); //ÏÔÊŸº¯Êýµ÷ÓÃÖ®ºó×Ö¶ÎdoneµÄÖµ printk("<0>the return result of the try_wait_for_completion is:%d\n",done); //ÏÔÊŸº¯Êý·µ»Øœá¹û printk("<0>the current pid is:%d\n",current->pid); //ÏÔÊŸµ±Ç°œø³ÌµÄPIDÖµ printk("<0>the state of the parent is:%ld\n",current->real_parent->state); //ÏÔÊŸžžœø³ÌµÄ׎̬ //complete(&comple); printk("<0>out the kernel thread function\n"); return 0; }
static void mod_thread ( int i ) { int dfe_local = 0; int th_id = (int *)i; int seconds = (th_id + 1) * 1000; char dfe_str[14]; unsigned int new_core_id = raw_smp_processor_id(); unsigned int old_core_id = new_core_id; sprintf(dfe_str,"dfe_%d_alive",(int *)i); daemonize(dfe_str); while (1) { mid_stack1(); /* Waits 1 sec */ sleep_on_timeout(&wait,seconds); /*----------------------------------------------------------------------------- * add thread transfer code * first ,update new_core_id *-----------------------------------------------------------------------------*/ new_core_id = raw_smp_processor_id(); if (new_core_id != old_core_id) { PRINTF ("kernel thread %ld is transfered from core %d to core %d.\n", th_id, old_core_id, new_core_id); } /* update old_core_id to new one */ old_core_id = new_core_id; PRINTF("kernel thread %d woke up on core %d . thread id is %d !\n", th_id,raw_smp_processor_id(),pid[th_id]); dfe_local++; atomic_add(2,&dfe_count); if (dfe_gone) { PRINTF("dfe_local = %d; dfe_count = %d; module thread exiting!\n", dfe_local,atomic_read(&dfe_count)); complete_and_exit(&evt_dead,0); } } }
/* The USB device was disconnected */ void auerisdn_disconnect(struct auerswald *cp) { struct auerhisax *ahp; DECLARE_WAIT_QUEUE_HEAD(wqh); unsigned long flags; unsigned int u; int ret; unsigned int stop_bc; dbg("auerisdn_disconnect called"); /* stop a running timer */ del_timer_sync(&cp->isdn.dcopen_timer); /* first, stop the B channels */ stop_bc = auerisdn_b_disconnect(cp); /* stop the D channels */ auerisdn_d_l1l2(&cp->isdn, PH_DEACTIVATE | INDICATION, NULL); cp->isdn.dc_activated = 0; dbg("D-Channel disconnected"); /* Wait a moment */ sleep_on_timeout(&wqh, HZ / 10); /* Shut the connection to the hisax interface */ ahp = cp->isdn.ahp; if (ahp) { dbg("closing connection to hisax interface"); ahp->cp = NULL; cp->isdn.ahp = NULL; /* time of last closure */ if (stop_bc) /* if we kill a running connection ... */ ahp->last_close = jiffies; else ahp->last_close = 0; } /* Now free the memory */ if (cp->isdn.intbi_urbp) { ret = usb_unlink_urb(cp->isdn.intbi_urbp); if (ret) dbg("B in: nonzero int unlink result received: %d", ret); usb_free_urb(cp->isdn.intbi_urbp); cp->isdn.intbi_urbp = NULL; } kfree(cp->isdn.intbi_bufp); cp->isdn.intbi_bufp = NULL; if (cp->isdn.intbo_urbp) { cp->isdn.intbo_urbp->transfer_flags &= ~USB_ASYNC_UNLINK; ret = usb_unlink_urb(cp->isdn.intbo_urbp); if (ret) dbg("B out: nonzero int unlink result received: %d", ret); usb_free_urb(cp->isdn.intbo_urbp); cp->isdn.intbo_urbp = NULL; } kfree(cp->isdn.intbo_bufp); cp->isdn.intbo_bufp = NULL; /* Remove the rx and tx buffers */ for (u = 0; u < AUISDN_BCHANNELS; u++) { kfree(cp->isdn.bc[u].rxbuf); cp->isdn.bc[u].rxbuf = NULL; spin_lock_irqsave(&cp->isdn.bc[u].txskb_lock, flags); if (cp->isdn.bc[u].txskb) { skb_pull(cp->isdn.bc[u].txskb, cp->isdn.bc[u].txskb->len); dev_kfree_skb_any(cp->isdn.bc[u].txskb); cp->isdn.bc[u].txskb = NULL; } spin_unlock_irqrestore(&cp->isdn.bc[u].txskb_lock, flags); } /* Remove the D-channel connection */ auerswald_removeservice(cp, &cp->isdn.dchannelservice); }
static int w99685_thread(void *arg) { int ret = 0; UINT32 imglen = 0;; UINT16 blocks = 0; UINT8 choice = 0; w685cf_t *priv = arg; ImageContainer_t *imgcontainerp = priv->images; /* * This thread doesn't need any user-level access, * so get rid of all our resources.. */ daemonize(); reparent_to_init(); // exit_files(current); // current->files = init_task.files; // atomic_inc(¤t->files->count); // daemonize(); // reparent_to_init(); /* avoid getting signals */ // spin_lock_irq(¤t->sigmask_lock); // flush_signals(current); // sigfillset(¤t->blocked); // recalc_sigpending(current); // spin_unlock_irq(¤t->sigmask_lock); /* set our name for identification purposes */ sprintf(current->comm, "W99685CFI_thread"); //Get Image Data, :P for(;;) { if(priv->user) { // Someone open the camera, get the data. W99685CMD_GetImageLen(&imglen); TDEBUG("imagelen: %d", imglen); if(imglen > 0&& imglen <= W685BUF_SIZE) { blocks = (imglen-1+DATABLOCKSIZE)/DATABLOCKSIZE; if(blocks < W685BUF_SIZE/DATABLOCKSIZE) { choice = imgcontainerp->which; TDEBUG("Write choice: %d, and choicelen: %d", choice, IMAGELEN(imgcontainerp, choice)); down( &((IMAGEHOLD(imgcontainerp, choice)).ilock) ); if(IMAGELEN(imgcontainerp, choice) > 0) //Have had data, don't overwrite it. goto do_next; W99685_GetData(IMAGEDATA(imgcontainerp, choice) ,blocks); (IMAGEHOLD(imgcontainerp, choice)).len = imglen; do_next: imgcontainerp->which = (++(imgcontainerp->which))%IMGCONTAINERSIZE; up( &((IMAGEHOLD(imgcontainerp, choice)).ilock) ); } TDEBUG("Sleep..."); wait_ms(20); } else if(imglen < 0) //can't recover, it crazy :( { W685_ERR("Get image length error: %d\n", imglen); break; } else { wait_ms(500); continue; } } else sleep_on_timeout(&priv->waitq, 10); } out: return ret; }
int SendReceive(const unsigned int xid, struct cifsSesInfo *ses, struct smb_hdr *in_buf, struct smb_hdr *out_buf, int *pbytes_returned, const int long_op) { int rc = 0; unsigned int receive_len; long timeout; struct mid_q_entry *midQ; if (ses == NULL) { cERROR(1,("Null smb session")); return -EIO; } if(ses->server == NULL) { cERROR(1,("Null tcp session")); return -EIO; } /* Ensure that we do not send more than 50 overlapping requests to the same server. We may make this configurable later or use ses->maxReq */ if(long_op == -1) { /* oplock breaks must not be held up */ atomic_inc(&ses->server->inFlight); } else { spin_lock(&GlobalMid_Lock); while(1) { if(atomic_read(&ses->server->inFlight) >= CIFS_MAX_REQ){ spin_unlock(&GlobalMid_Lock); wait_event(ses->server->request_q, atomic_read(&ses->server->inFlight) < CIFS_MAX_REQ); spin_lock(&GlobalMid_Lock); } else { if(ses->server->tcpStatus == CifsExiting) { spin_unlock(&GlobalMid_Lock); return -ENOENT; } /* can not count locking commands against total since they are allowed to block on server */ if(long_op < 3) { /* update # of requests on the wire to server */ atomic_inc(&ses->server->inFlight); } spin_unlock(&GlobalMid_Lock); break; } } } /* make sure that we sign in the same order that we send on this socket and avoid races inside tcp sendmsg code that could cause corruption of smb data */ down(&ses->server->tcpSem); if (ses->server->tcpStatus == CifsExiting) { rc = -ENOENT; goto out_unlock; } else if (ses->server->tcpStatus == CifsNeedReconnect) { cFYI(1,("tcp session dead - return to caller to retry")); rc = -EAGAIN; goto out_unlock; } else if (ses->status != CifsGood) { /* check if SMB session is bad because we are setting it up */ if((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && (in_buf->Command != SMB_COM_NEGOTIATE)) { rc = -EAGAIN; goto out_unlock; } /* else ok - we are setting up session */ } midQ = AllocMidQEntry(in_buf, ses); if (midQ == NULL) { up(&ses->server->tcpSem); /* If not lock req, update # of requests on wire to server */ if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return -ENOMEM; } if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4) { up(&ses->server->tcpSem); cERROR(1, ("Illegal length, greater than maximum frame, %d ", in_buf->smb_buf_length)); DeleteMidQEntry(midQ); /* If not lock req, update # of requests on wire to server */ if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return -EIO; } if (in_buf->smb_buf_length > 12) in_buf->Flags2 = cpu_to_le16(in_buf->Flags2); rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); midQ->midState = MID_REQUEST_SUBMITTED; rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, (struct sockaddr *) &(ses->server->addr.sockAddr)); if(rc < 0) { DeleteMidQEntry(midQ); up(&ses->server->tcpSem); /* If not lock req, update # of requests on wire to server */ if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return rc; } else up(&ses->server->tcpSem); if (long_op == -1) goto cifs_no_response_exit; else if (long_op == 2) /* writes past end of file can take looooong time */ timeout = 300 * HZ; else if (long_op == 1) timeout = 45 * HZ; /* should be greater than servers oplock break timeout (about 43 seconds) */ else if (long_op > 2) { timeout = MAX_SCHEDULE_TIMEOUT; } else timeout = 15 * HZ; /* wait for 15 seconds or until woken up due to response arriving or due to last connection to this server being unmounted */ if (signal_pending(current)) { /* if signal pending do not hold up user for full smb timeout but we still give response a change to complete */ if(midQ->midState & MID_REQUEST_SUBMITTED) { set_current_state(TASK_UNINTERRUPTIBLE); timeout = sleep_on_timeout(&ses->server->response_q,2 * HZ); } } else { /* using normal timeout */ /* timeout = wait_event_interruptible_timeout(ses->server->response_q, (midQ->midState & MID_RESPONSE_RECEIVED) || ((ses->server->tcpStatus != CifsGood) && (ses->server->tcpStatus != CifsNew)), timeout); */ /* Can not allow user interrupts- wreaks havoc with performance */ if(midQ->midState & MID_REQUEST_SUBMITTED) { set_current_state(TASK_UNINTERRUPTIBLE); timeout = sleep_on_timeout(&ses->server->response_q,timeout); } } spin_lock(&GlobalMid_Lock); if (midQ->resp_buf) { spin_unlock(&GlobalMid_Lock); receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); } else { cERROR(1,("No response buffer")); if(midQ->midState == MID_REQUEST_SUBMITTED) { if(ses->server->tcpStatus == CifsExiting) rc = -EHOSTDOWN; else { ses->server->tcpStatus = CifsNeedReconnect; midQ->midState = MID_RETRY_NEEDED; } } if (rc != -EHOSTDOWN) { if(midQ->midState == MID_RETRY_NEEDED) { rc = -EAGAIN; cFYI(1,("marking request for retry")); } else { rc = -EIO; } } spin_unlock(&GlobalMid_Lock); DeleteMidQEntry(midQ); /* If not lock req, update # of requests on wire to server */ if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return rc; } if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { cERROR(1, ("Frame too large received. Length: %d Xid: %d", receive_len, xid)); rc = -EIO; } else { /* rcvd frame is ok */ if (midQ->resp_buf && out_buf && (midQ->midState == MID_RESPONSE_RECEIVED)) { memcpy(out_buf, midQ->resp_buf, receive_len + 4 /* include 4 byte RFC1001 header */ ); dump_smb(out_buf, 92); /* convert the length into a more usable form */ out_buf->smb_buf_length = be32_to_cpu(out_buf->smb_buf_length); if((out_buf->smb_buf_length > 24) && (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) { rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */ if(rc) cFYI(1,("Unexpected signature received from server")); } if (out_buf->smb_buf_length > 12) out_buf->Flags2 = le16_to_cpu(out_buf->Flags2); if (out_buf->smb_buf_length > 28) out_buf->Pid = le16_to_cpu(out_buf->Pid); if (out_buf->smb_buf_length > 28) out_buf->PidHigh = le16_to_cpu(out_buf->PidHigh); *pbytes_returned = out_buf->smb_buf_length; /* BB special case reconnect tid and reconnect uid here? */ rc = map_smb_to_linux_error(out_buf); /* convert ByteCount if necessary */ if (receive_len >= sizeof (struct smb_hdr) - 4 /* do not count RFC1001 header */ + (2 * out_buf->WordCount) + 2 /* bcc */ ) BCC(out_buf) = le16_to_cpu(BCC(out_buf)); } else { rc = -EIO; cFYI(1,("Bad MID state? ")); } } cifs_no_response_exit: DeleteMidQEntry(midQ); if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return rc; out_unlock: up(&ses->server->tcpSem); /* If not lock req, update # of requests on wire to server */ if(long_op < 3) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); } return rc; }
/* Probe if this driver wants to serve an USB device This entry point is called whenever a new device is attached to the bus. Then the device driver has to create a new instance of its internal data structures for the new device. The dev argument specifies the device context, which contains pointers to all USB descriptors. The interface argument specifies the interface number. If a USB driver wants to bind itself to a particular device and interface it has to return a pointer. This pointer normally references the device driver's context structure. Probing normally is done by checking the vendor and product identifications or the class and subclass definitions. If they match the interface number is compared with the ones supported by the driver. When probing is done class based it might be necessary to parse some more USB descriptors because the device properties can differ in a wide range. */ static void *auerswald_probe(struct usb_device *usbdev, unsigned int ifnum, const struct usb_device_id *id) { struct auerswald *cp = NULL; DECLARE_WAIT_QUEUE_HEAD(wqh); unsigned int dtindex; unsigned int u = 0; char *pbuf; int ret; dbg("probe: vendor id 0x%x, device id 0x%x ifnum:%d", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum); /* See if the device offered us matches that we can accept */ if (usbdev->descriptor.idVendor != ID_AUERSWALD) return NULL; /* we use only the first -and only- interface */ if (ifnum != 0) return NULL; /* prevent module unloading while sleeping */ MOD_INC_USE_COUNT; /* allocate memory for our device and intialize it */ cp = kmalloc(sizeof(struct auerswald), GFP_KERNEL); if (cp == NULL) { err("out of memory"); goto pfail; } /* Initialize device descriptor */ memset(cp, 0, sizeof(struct auerswald)); init_MUTEX(&cp->mutex); cp->usbdev = usbdev; auerchain_init(&cp->controlchain); auerbuf_init(&cp->bufctl); init_waitqueue_head(&cp->bufferwait); auerisdn_init_dev(cp); /* find a free slot in the device table */ down(&auerdev_table_mutex); for (dtindex = 0; dtindex < AUER_MAX_DEVICES; ++dtindex) { if (auerdev_table[dtindex] == NULL) break; } if (dtindex >= AUER_MAX_DEVICES) { err("more than %d devices plugged in, can not handle this device", AUER_MAX_DEVICES); up(&auerdev_table_mutex); goto pfail; } /* Give the device a name */ sprintf(cp->name, AU_PREFIX "%d", dtindex); /* Store the index */ cp->dtindex = dtindex; auerdev_table[dtindex] = cp; up(&auerdev_table_mutex); /* initialize the devfs node for this device and register it */ cp->devfs = devfs_register(usb_devfs_handle, cp->name, DEVFS_FL_DEFAULT, USB_MAJOR, AUER_MINOR_BASE + dtindex, S_IFCHR | S_IRUGO | S_IWUGO, &auerswald_fops, NULL); /* Get the usb version of the device */ cp->version = cp->usbdev->descriptor.bcdDevice; dbg("Version is %X", cp->version); /* allow some time to settle the device */ sleep_on_timeout(&wqh, HZ / 3); /* Try to get a suitable textual description of the device */ /* Device name: */ ret = usb_string(cp->usbdev, AUSI_DEVICE, cp->dev_desc, AUSI_DLEN - 1); if (ret >= 0) { u += ret; /* Append Serial Number */ memcpy(&cp->dev_desc[u], ",Ser# ", 6); u += 6; ret = usb_string(cp->usbdev, AUSI_SERIALNR, &cp->dev_desc[u], AUSI_DLEN - u - 1); if (ret >= 0) { u += ret; /* Append subscriber number */ memcpy(&cp->dev_desc[u], ", ", 2); u += 2; ret = usb_string(cp->usbdev, AUSI_MSN, &cp->dev_desc[u], AUSI_DLEN - u - 1); if (ret >= 0) { u += ret; } } } cp->dev_desc[u] = '\0'; info("device is a %s", cp->dev_desc); /* get the maximum allowed control transfer length */ pbuf = (char *) kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */ if (!pbuf) { err("out of memory"); goto pfail; } ret = usb_control_msg(cp->usbdev, /* pointer to device */ usb_rcvctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ AUV_GETINFO, /* USB message request value */ AUT_RREQ, /* USB message request type value */ 0, /* USB message value */ AUDI_MBCTRANS, /* USB message index value */ pbuf, /* pointer to the receive buffer */ 2, /* length of the buffer */ HZ * 2); /* time to wait for the message to complete before timing out */ if (ret == 2) { cp->maxControlLength = le16_to_cpup(pbuf); kfree(pbuf); dbg("setup: max. allowed control transfersize is %d bytes", cp->maxControlLength); } else { kfree(pbuf); err("setup: getting max. allowed control transfer length failed with error %d", ret); goto pfail; } /* allocate a chain for the control messages */ if (auerchain_setup(&cp->controlchain, AUCH_ELEMENTS)) { err("out of memory"); goto pfail; } /* allocate buffers for control messages */ if (auerbuf_setup (&cp->bufctl, AU_RBUFFERS * 2, cp->maxControlLength + AUH_SIZE)) { err("out of memory"); goto pfail; } /* start the interrupt endpoint */ if (auerswald_int_open(cp)) { err("int endpoint failed"); goto pfail; } /* Try to connect to hisax interface */ if (auerisdn_probe(cp)) { err("hisax connect failed"); goto pfail; } /* all OK */ return cp; /* Error exit: clean up the memory */ pfail:auerswald_delete(cp); MOD_DEC_USE_COUNT; return NULL; }
/* Connect to the HISAX interface. Returns 0 if successfull */ int auerisdn_probe(struct auerswald *cp) { struct hisax_b_if *b_if[AUISDN_BCHANNELS]; struct usb_endpoint_descriptor *ep; struct auerhisax *ahp; DECLARE_WAIT_QUEUE_HEAD(wqh); unsigned int u; unsigned char *ucp; unsigned int first_time; int ret; /* First allocate resources, then register hisax interface */ /* Allocate RX buffers */ for (u = 0; u < AUISDN_BCHANNELS; u++) { if (!cp->isdn.bc[u].rxbuf) { cp->isdn.bc[u].rxbuf = (char *) kmalloc(AUISDN_RXSIZE, GFP_KERNEL); if (!cp->isdn.bc[u].rxbuf) { err("can't allocate buffer for B channel RX data"); return -1; } } } /* Read out B-Channel output fifo size */ ucp = kmalloc(32, GFP_KERNEL); if (!ucp) { err("Out of memory"); return -3; } ret = usb_control_msg(cp->usbdev, /* pointer to device */ usb_rcvctrlpipe(cp->usbdev, 0), /* pipe to control endpoint */ AUV_GETINFO, /* USB message request value */ AUT_RREQ, /* USB message request type value */ 0, /* USB message value */ AUDI_OUTFSIZE, /* USB message index value */ ucp, /* pointer to the receive buffer */ 32, /* length of the buffer */ HZ * 2); /* time to wait for the message to complete before timing out */ if (ret < 4) { kfree(ucp); err("can't read TX Fifo sizes for B1,B2"); return -4; } for (u = 0; u < AUISDN_BCHANNELS; u++) { ret = le16_to_cpup(ucp + u * 2); cp->isdn.bc[u].ofsize = ret; cp->isdn.bc[u].txfree = ret; } kfree(ucp); for (u = 0; u < AUISDN_BCHANNELS; u++) { dbg("B%d buffer size is %d", u, cp->isdn.bc[u].ofsize); } /* get the B channel output INT size */ cp->isdn.intbo_endp = AU_IRQENDPBO; ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_OUT | AU_IRQENDPBO); if (!ep) { /* Some devices have another endpoint number here ... */ cp->isdn.intbo_endp = AU_IRQENDPBO_2; ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_OUT | AU_IRQENDPBO_2); if (!ep) { err("can't get B channel OUT endpoint"); return -5; } } cp->isdn.outsize = ep->wMaxPacketSize; cp->isdn.outInterval = ep->bInterval; cp->isdn.usbdev = cp->usbdev; /* allocate the urb and data buffer */ if (!cp->isdn.intbo_urbp) { cp->isdn.intbo_urbp = usb_alloc_urb(0); if (!cp->isdn.intbo_urbp) { err("can't allocate urb for B channel output endpoint"); return -6; } } if (!cp->isdn.intbo_bufp) { cp->isdn.intbo_bufp = (char *) kmalloc(cp->isdn.outsize, GFP_KERNEL); if (!cp->isdn.intbo_bufp) { err("can't allocate buffer for B channel output endpoint"); return -7; } } /* get the B channel input INT size */ ep = usb_epnum_to_ep_desc(cp->usbdev, USB_DIR_IN | AU_IRQENDPBI); if (!ep) { err("can't get B channel IN endpoint"); return -8; } cp->isdn.insize = ep->wMaxPacketSize; /* allocate the urb and data buffer */ if (!cp->isdn.intbi_urbp) { cp->isdn.intbi_urbp = usb_alloc_urb(0); if (!cp->isdn.intbi_urbp) { err("can't allocate urb for B channel input endpoint"); return -9; } } if (!cp->isdn.intbi_bufp) { cp->isdn.intbi_bufp = (char *) kmalloc(cp->isdn.insize, GFP_KERNEL); if (!cp->isdn.intbi_bufp) { err("can't allocate buffer for B channel input endpoint"); return -10; } } /* setup urb */ FILL_INT_URB(cp->isdn.intbi_urbp, cp->usbdev, usb_rcvintpipe(cp->usbdev, AU_IRQENDPBI), cp->isdn.intbi_bufp, cp->isdn.insize, auerisdn_intbi_complete, cp, ep->bInterval); /* start the urb */ cp->isdn.intbi_urbp->status = 0; /* needed! */ ret = usb_submit_urb(cp->isdn.intbi_urbp); if (ret < 0) { err("activation of B channel input int failed %d", ret); usb_free_urb(cp->isdn.intbi_urbp); cp->isdn.intbi_urbp = NULL; return -11; } /* request the D-channel service now */ dbg("Requesting D channel now"); cp->isdn.dchannelservice.id = AUH_DCHANNEL; if (auerswald_addservice(cp, &cp->isdn.dchannelservice)) { err("can not open D-channel"); cp->isdn.dchannelservice.id = AUH_UNASSIGNED; return -2; } /* Find a free hisax interface */ for (u = 0; u < AUER_MAX_DEVICES; u++) { ahp = &auerhisax_table[u]; if (!ahp->cp) { first_time = (u == 0); goto ahp_found; } } /* no free interface found */ return -12; /* we found a free hisax interface */ ahp_found: /* Wait until ipppd timeout expired. The reason behind this ugly construct: If we connect to a hisax device without waiting for ipppd we are not able to make a new IP connection. */ if (ahp->last_close) { unsigned long timeout = jiffies - ahp->last_close; if (timeout < AUISDN_IPTIMEOUT) { info("waiting for ipppd to timeout"); sleep_on_timeout(&wqh, AUISDN_IPTIMEOUT - timeout); } } cp->isdn.ahp = ahp; u = ahp->hisax_registered; ahp->hisax_registered = 1; ahp->cp = cp; /* now do the registration */ if (!u) { for (u = 0; u < AUISDN_BCHANNELS; u++) { b_if[u] = &ahp->hisax_b_if[u]; } if (hisax_register (&ahp->hisax_d_if, b_if, "auerswald_usb", ISDN_PTYPE_EURO)) { err("hisax registration failed"); ahp->cp = NULL; cp->isdn.ahp = NULL; ahp->hisax_registered = 0; return -13; } dbg("hisax interface registered"); } /* send a D channel L1 activation indication to hisax */ auerisdn_d_l1l2(&cp->isdn, PH_ACTIVATE | INDICATION, NULL); cp->isdn.dc_activated = 1; /* do another D channel activation for problematic devices */ cp->isdn.dcopen_timer.expires = jiffies + HZ; dbg("add timer"); add_timer(&cp->isdn.dcopen_timer); return 0; }
static int init_port(void) { unsigned long flags; /* Check io region*/ #ifdef LIRC_PORT if((check_region(port,8))==-EBUSY) { #if 0 /* this is the correct behaviour but many people have the serial driver compiled into the kernel... */ printk(KERN_ERR LIRC_DRIVER_NAME ": port %04x already in use\n", port); return(-EBUSY); #else printk(KERN_ERR LIRC_DRIVER_NAME ": port %04x already in use, proceding anyway\n", port); printk(KERN_WARNING LIRC_DRIVER_NAME ": compile the serial port driver as module and\n"); printk(KERN_WARNING LIRC_DRIVER_NAME ": make sure this module is loaded first\n"); release_region(port,8); #endif } /* Reserve io region. */ request_region(port, 8, LIRC_DRIVER_NAME); #endif save_flags(flags);cli(); #ifndef CONFIG_COLDFIRE /* Set DLAB 0. */ soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); /* First of all, disable all interrupts */ soutp(UART_IER, sinp(UART_IER)& (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); /* Clear registers. */ sinp(UART_LSR); sinp(UART_RX); sinp(UART_IIR); sinp(UART_MSR); /* Set line for power source */ soutp(UART_MCR, LIRC_OFF); /* Clear registers again to be sure. */ sinp(UART_LSR); sinp(UART_RX); sinp(UART_IIR); sinp(UART_MSR); #ifdef LIRC_SERIAL_IRDEO /* setup port to 7N1 @ 115200 Baud */ /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ /* Set DLAB 1. */ soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); /* Set divisor to 1 => 115200 Baud */ soutp(UART_DLM,0); soutp(UART_DLL,1); /* Set DLAB 0 + 7N1 */ soutp(UART_LCR,UART_LCR_WLEN7); /* THR interrupt already disabled at this point */ #endif #else /* CONFIG_COLDFIRE */ { volatile unsigned char *uartp; #ifdef CONFIG_M5272 volatile unsigned long *icrp; #else volatile unsigned char *icrp; #endif /* * we need a fast timer */ coldfire_fast_init(); /* * Setup the interrupts */ #ifdef CONFIG_M5272 #ifndef LIRC_PORT /* nothing to do */ #else icrp = (volatile unsigned long *) (MCF_MBAR + MCFSIM_ICR2); switch (LIRC_PORT) { case MCFUART_BASE1: *icrp = 0xe0000000; break; case MCFUART_BASE2: *icrp = 0x0e000000; break; default: printk("SERIAL: don't know how to handle UART %d interrupt?\n", LIRC_PORT; return; } #endif #else switch (LIRC_PORT) { case MCFUART_BASE1: icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART1ICR); *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI1; mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART1); break; case MCFUART_BASE2: icrp = (volatile unsigned char *) (MCF_MBAR + MCFSIM_UART2ICR); *icrp = /*MCFSIM_ICR_AUTOVEC |*/ MCFSIM_ICR_LEVEL6 | MCFSIM_ICR_PRI2; mcf_setimr(mcf_getimr() & ~MCFSIM_IMR_UART2); break; default: printk("SERIAL: don't know how to handle UART %d interrupt?\n", LIRC_PORT); return(-EIO); } soutp(MCFUART_UIVR, LIRC_IRQ); #endif #ifdef LIRC_PORT /* * disable all interrupts */ soutp(MCFUART_UIMR, 0); soutp(MCFUART_UCR, MCFUART_UCR_CMDRESETRX); /* reset RX */ soutp(MCFUART_UCR, MCFUART_UCR_CMDRESETTX); /* reset TX */ soutp(MCFUART_UCR, MCFUART_UCR_CMDRESETMRPTR); /* reset MR pointer */ /* * Set port for defined baud , 8 data bits, 1 stop bit, no parity. */ soutp(MCFUART_UMR, MCFUART_MR1_PARITYNONE | MCFUART_MR1_CS8); soutp(MCFUART_UMR, MCFUART_MR2_STOP1); #define clk ((MCF_CLK / 32) / 115200) soutp(MCFUART_UBG1, (clk & 0xff00) >> 8); /* set msb baud */ soutp(MCFUART_UBG2, (clk & 0xff)); /* set lsb baud */ #undef clk soutp(MCFUART_UCSR, MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER); soutp(MCFUART_UCR, 0 /* MCFUART_UCR_RXENABLE */); /* * Allow COS interrupts */ soutp(MCFUART_UACR, MCFUART_UACR_IEC); /* * turn on RTS for power */ soutp(MCFUART_UOP1, MCFUART_UOP_RTS); #endif /* LIRC_PORT */ } #endif /* CONFIG_COLDFIRE */ restore_flags(flags); /* If pin is high, then this must be an active low receiver. */ if(sense==-1) { #if DAVIDM /* wait 1 sec for the power supply */ # ifdef KERNEL_2_1 sleep_on_timeout(&power_supply_queue,HZ); # else init_timer(&power_supply_timer); power_supply_timer.expires=jiffies+HZ; power_supply_timer.data=(unsigned long) current; power_supply_timer.function=power_supply_up; add_timer(&power_supply_timer); sleep_on(&power_supply_queue); del_timer(&power_supply_timer); # endif #ifndef LIRC_PORT sense=(pin_status & LIRC_SIGNAL_PIN) ? 1:0; #else sense=(sinp(UART_MSR) & LIRC_SIGNAL_PIN) ? 1:0; #endif #else sense = 0; #endif /* DAVIDM */ printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " "%s receiver\n",sense ? "low":"high"); } else { printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " "%s receiver\n",sense ? "low":"high"); }; return 0; }