Пример #1
0
void BCMFASTPATH
osl_pktfree(osl_t *osh, void *p, bool send)
{
	struct sk_buff *skb, *nskb;
	unsigned long flags;

	skb = (struct sk_buff*) p;

	if (send && osh->pub.tx_fn)
		osh->pub.tx_fn(osh->pub.tx_ctx, p, 0);

	PKTDBG_TRACE(osh, (void *) skb, PKTLIST_PKTFREE);

	while (skb) {
		nskb = skb->next;
		skb->next = NULL;

#ifdef CTFPOOL
		if ((PKTISFAST(osh, skb)) && (atomic_read(&skb->users) == 1))
			osl_pktfastfree(osh, skb);
		else {
#else
		{
#endif

			if (skb->destructor)
				dev_kfree_skb_any(skb);
			else
				dev_kfree_skb(skb);
		}
		spin_lock_irqsave(&osh->pktalloc_lock, flags);
		osh->pub.pktalloced--;
		spin_unlock_irqrestore(&osh->pktalloc_lock, flags);
		skb = nskb;
	}
}

#ifdef CONFIG_DHD_USE_STATIC_BUF
#if defined(CUSTOMER_HW4) || defined(CUSTOMER_HW11)
void*
osl_pktget_static(osl_t *osh, uint len)
{
	int i = 0;
	struct sk_buff *skb;


	if (len > DHD_SKB_4PAGE_BUFSIZE) {
#ifdef USE_LOGGING_WHEN_HUGE_PACKET 
		printk("osl_pktget_static: Do we really need this big skb??"
			" len=%d\n", len);
#endif
		return osl_pktget(osh, len);
	}

	down(&bcm_static_skb->osl_pkt_sem);

	if (len <= DHD_SKB_1PAGE_BUFSIZE) {
		for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
			if (bcm_static_skb->pkt_use[i] == 0)
				break;
		}

		if (i != STATIC_PKT_MAX_NUM) {
			bcm_static_skb->pkt_use[i] = 1;
			up(&bcm_static_skb->osl_pkt_sem);

			skb = bcm_static_skb->skb_4k[i];
			skb->tail = skb->data + len;
			skb->len = len;

			return skb;
		}
	}

	if (len <= DHD_SKB_2PAGE_BUFSIZE) {

		for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
			if (bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM]
				== 0)
				break;
		}

		if (i != STATIC_PKT_MAX_NUM) {
			bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 1;
			up(&bcm_static_skb->osl_pkt_sem);
			skb = bcm_static_skb->skb_8k[i];
			skb->tail = skb->data + len;
			skb->len = len;

			return skb;
		}
	}

	if (bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] == 0) {
		bcm_static_skb->pkt_use[STATIC_PKT_MAX_NUM * 2] = 1;
		up(&bcm_static_skb->osl_pkt_sem);

		skb = bcm_static_skb->skb_16k;
		skb->tail = skb->data + len;
		skb->len = len;

		return skb;
	}

	up(&bcm_static_skb->osl_pkt_sem);
	printk("osl_pktget_static: all static pkt in use!\n");
	return osl_pktget(osh, len);
}
Пример #2
0
static ssize_t txstat_read_file(struct file *file, char __user *userbuf,
				size_t count, loff_t *ppos)
{
	const size_t len = REALLY_BIG_BUFFER_SIZE;

	struct bcm43xx_private *bcm = file->private_data;
	char *buf = really_big_buffer;
	size_t pos = 0;
	ssize_t res;
	unsigned long flags;
	struct bcm43xx_dfsentry *e;
	struct bcm43xx_xmitstatus *status;
	int i, cnt, j = 0;

	down(&big_buffer_sem);
	bcm43xx_lock(bcm, flags);

	fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
		BCM43xx_NR_LOGGED_XMITSTATUS);
	e = bcm->dfsentry;
	if (e->xmitstatus_printing == 0) {
		/* At the beginning, make a copy of all data to avoid
		 * concurrency, as this function is called multiple
		 * times for big logs. Without copying, the data might
		 * change between reads. This would result in total trash.
		 */
		e->xmitstatus_printing = 1;
		e->saved_xmitstatus_ptr = e->xmitstatus_ptr;
		e->saved_xmitstatus_cnt = e->xmitstatus_cnt;
		memcpy(e->xmitstatus_print_buffer, e->xmitstatus_buffer,
		       BCM43xx_NR_LOGGED_XMITSTATUS * sizeof(*(e->xmitstatus_buffer)));
	}
	i = e->saved_xmitstatus_ptr - 1;
	if (i < 0)
		i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
	cnt = e->saved_xmitstatus_cnt;
	while (cnt) {
		status = e->xmitstatus_print_buffer + i;
		fappend("0x%02x:   cookie: 0x%04x,  flags: 0x%02x,  "
			"cnt1: 0x%02x,  cnt2: 0x%02x,  seq: 0x%04x,  "
			"unk: 0x%04x\n", j,
			status->cookie, status->flags,
			status->cnt1, status->cnt2, status->seq,
			status->unknown);
		j++;
		cnt--;
		i--;
		if (i < 0)
			i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
	}

	bcm43xx_unlock(bcm, flags);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	bcm43xx_lock(bcm, flags);
	if (*ppos == pos) {
		/* Done. Drop the copied data. */
		e->xmitstatus_printing = 0;
	}
	bcm43xx_unlock(bcm, flags);
	up(&big_buffer_sem);
	return res;
}
Пример #3
0
/*
 * Deal with ioctls against the raw-device control interface, to bind
 * and unbind other raw devices.
 */
static int raw_ctl_ioctl(struct inode *inode, struct file *filp,
			unsigned int command, unsigned long arg)
{
	struct raw_config_request rq;
	struct raw_device_data *rawdev;
	int err = 0;

	switch (command) {
	case RAW_SETBIND:
	case RAW_GETBIND:

		/* First, find out which raw minor we want */

		if (copy_from_user(&rq, (void __user *) arg, sizeof(rq))) {
			err = -EFAULT;
			goto out;
		}

		if (rq.raw_minor < 0 || rq.raw_minor >= MAX_RAW_MINORS) {
			err = -EINVAL;
			goto out;
		}
		rawdev = &raw_devices[rq.raw_minor];

		if (command == RAW_SETBIND) {
			dev_t dev;

			/*
			 * This is like making block devices, so demand the
			 * same capability
			 */
			if (!capable(CAP_SYS_ADMIN)) {
				err = -EPERM;
				goto out;
			}

			/*
			 * For now, we don't need to check that the underlying
			 * block device is present or not: we can do that when
			 * the raw device is opened.  Just check that the
			 * major/minor numbers make sense.
			 */

			dev = MKDEV(rq.block_major, rq.block_minor);
			if ((rq.block_major == 0 && rq.block_minor != 0) ||
					MAJOR(dev) != rq.block_major ||
					MINOR(dev) != rq.block_minor) {
				err = -EINVAL;
				goto out;
			}

			down(&raw_mutex);
			if (rawdev->inuse) {
				up(&raw_mutex);
				err = -EBUSY;
				goto out;
			}
			if (rawdev->binding) {
				bdput(rawdev->binding);
				module_put(THIS_MODULE);
			}
			if (rq.block_major == 0 && rq.block_minor == 0) {
				/* unbind */
				rawdev->binding = NULL;
			} else {
				rawdev->binding = bdget(dev);
				if (rawdev->binding == NULL)
					err = -ENOMEM;
				else
					__module_get(THIS_MODULE);
			}
			up(&raw_mutex);
		} else {
			struct block_device *bdev;

			down(&raw_mutex);
			bdev = rawdev->binding;
			if (bdev) {
				rq.block_major = MAJOR(bdev->bd_dev);
				rq.block_minor = MINOR(bdev->bd_dev);
			} else {
				rq.block_major = rq.block_minor = 0;
			}
			up(&raw_mutex);
			if (copy_to_user((void __user *)arg, &rq, sizeof(rq))) {
				err = -EFAULT;
				goto out;
			}
		}
		break;
	default:
		err = -EINVAL;
		break;
	}
out:
	return err;
}
Пример #4
0
static void * mts_usb_probe (struct usb_device *dev, unsigned int interface)
{
	int i;
	int result;
	int ep_out = -1;
	int ep_in_set[3]; /* this will break if we have more than three endpoints
			   which is why we check */
	int *ep_in_current = ep_in_set;
	
	struct mts_desc * new_desc;
	struct vendor_product const* p;

	/* the altsettting 0 on the interface we're probing */
	struct usb_interface_descriptor *altsetting;

	MTS_DEBUG_GOT_HERE();
	MTS_DEBUG( "usb-device descriptor at %x\n", (int)dev );
	
	MTS_DEBUG( "product id = 0x%x, vendor id = 0x%x\n",
		   (int)dev->descriptor.idProduct,
		   (int)dev->descriptor.idVendor );

	MTS_DEBUG_GOT_HERE();
	
	/* checking IDs */
	for( p = mts_supported_products; p != mts_last_product; p++ )
		if ( dev->descriptor.idVendor == p->idVendor &&
		     dev->descriptor.idProduct == p->idProduct )
			goto is_supported;
		else
			MTS_DEBUG( "doesn't appear to be model %s\n", p->name );

	MTS_DEBUG( "returning NULL: unsupported\n" );
	
	return NULL;
	
 is_supported:

	MTS_DEBUG_GOT_HERE();

	MTS_DEBUG( "found model %s\n", p->name );
	if ( p->support_status != mts_sup_full )
		MTS_MESSAGE( "model %s is not known to be fully supported, reports welcome!\n",
			     p->name );
	
	/* the altsettting 0 on the interface we're probing */
	altsetting =
		&(dev->actconfig->interface[interface].altsetting[0]);	

	
	/* Check if the config is sane */

	if ( altsetting->bNumEndpoints != MTS_EP_TOTAL ) {
		MTS_WARNING( "expecting %d got %d endpoints! Bailing out.\n",
			     (int)MTS_EP_TOTAL, (int)altsetting->bNumEndpoints );
		return NULL;
	}

	for( i = 0; i < altsetting->bNumEndpoints; i++ ) {
		if ((altsetting->endpoint[i].bmAttributes & 
		     USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
			
			MTS_WARNING( "can only deal with bulk endpoints; endpoint %d is not bulk.\n",
			     (int)altsetting->endpoint[i].bEndpointAddress );
		} else {
			if (altsetting->endpoint[i].bEndpointAddress & 
			    USB_DIR_IN)
				*ep_in_current++
					= altsetting->endpoint[i].bEndpointAddress &
					USB_ENDPOINT_NUMBER_MASK;
			else {
				if ( ep_out != -1 ) {
					MTS_WARNING( "can only deal with one output endpoints. Bailing out." );
					return NULL;
				}
		
				ep_out = altsetting->endpoint[i].bEndpointAddress &
					USB_ENDPOINT_NUMBER_MASK;
			}
		}
		
	}
	

	if ( ep_out == -1 ) {
		MTS_WARNING( "couldn't find an output bulk endpoint. Bailing out.\n" );
		return NULL;
	}
	
	
	/* I don't understand the following fully (it's from usb-storage) -- John */

	/* set the interface -- STALL is an acceptable response here */
	result = usb_set_interface(dev, altsetting->bInterfaceNumber, 0);
	
	MTS_DEBUG("usb_set_interface returned %d.\n",result);
	switch( result )
	{
	case 0: /* no error */
		break;
		
	case -EPIPE:
		usb_clear_halt(dev, usb_sndctrlpipe(dev, 0));
		MTS_DEBUG( "clearing clearing stall on control interface\n" );
		break;
		
	default:
		MTS_DEBUG( "unknown error %d from usb_set_interface\n",
			(int)result );
 		return NULL;
	}
	
	
	/* allocating a new descriptor */
	new_desc = (struct mts_desc *)kmalloc(sizeof(struct mts_desc), GFP_KERNEL);
	if (new_desc == NULL)
	{
		MTS_ERROR("couldn't allocate scanner desc, bailing out!\n");
		return NULL;
	}

	/* As done by usb_alloc_urb */
	memset( new_desc, 0, sizeof(*new_desc) );
	spin_lock_init(&new_desc->urb.lock);
	
		
	/* initialising that descriptor */
	new_desc->usb_dev = dev;
	new_desc->interface = interface;

	init_MUTEX(&new_desc->lock);

	if(mts_list){
		new_desc->host_number = mts_list->host_number+1;
	} else {
		new_desc->host_number = 0;
	}
	
	/* endpoints */
	
	new_desc->ep_out = ep_out;
	new_desc->ep_response = ep_in_set[0];
	new_desc->ep_image = ep_in_set[1];
	

	if ( new_desc->ep_out != MTS_EP_OUT )
		MTS_WARNING( "will this work? Command EP is not usually %d\n",
			     (int)new_desc->ep_out );

	if ( new_desc->ep_response != MTS_EP_RESPONSE )
		MTS_WARNING( "will this work? Response EP is not usually %d\n",
			     (int)new_desc->ep_response );

	if ( new_desc->ep_image != MTS_EP_IMAGE )
		MTS_WARNING( "will this work? Image data EP is not usually %d\n",
			     (int)new_desc->ep_image );

	
	/* Initialize the host template based on the default one */
	memcpy(&(new_desc->ctempl), &mts_scsi_host_template, sizeof(mts_scsi_host_template)); 	
	/* HACK from usb-storage - this is needed for scsi detection */
	(struct mts_desc *)new_desc->ctempl.proc_dir = new_desc; /* FIXME */
	
	MTS_DEBUG("registering SCSI module\n");
	
	new_desc->ctempl.module = THIS_MODULE;
	result = scsi_register_module(MODULE_SCSI_HA, &(new_desc->ctempl));	
	/* Will get hit back in microtek_detect by this func */
	if ( result )
	{
		MTS_ERROR( "error %d from scsi_register_module! Help!\n",
			   (int)result );

		/* FIXME: need more cleanup? */
		kfree( new_desc );
		return NULL;
	}
	MTS_DEBUG_GOT_HERE();

	/* FIXME: the bomb is armed, must the host be registered under lock ? */
	/* join the list - lock it */
	down(&mts_list_semaphore);

	mts_add_nolock( new_desc );
	
	up(&mts_list_semaphore);
	
	
	MTS_DEBUG("completed probe and exiting happily\n");
	
	return (void *)new_desc;
}
Пример #5
0
static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev)
{
	struct jffs2_inode_info *f, *dir_f;
	struct jffs2_sb_info *c;
	struct inode *inode;
	struct jffs2_raw_inode *ri;
	struct jffs2_raw_dirent *rd;
	struct jffs2_full_dnode *fn;
	struct jffs2_full_dirent *fd;
	int namelen;
	union jffs2_device_node dev;
	int devlen = 0;
	uint32_t alloclen;
	int ret;

	if (!new_valid_dev(rdev))
		return -EINVAL;

	ri = jffs2_alloc_raw_inode();
	if (!ri)
		return -ENOMEM;

	c = JFFS2_SB_INFO(dir_i->i_sb);

	if (S_ISBLK(mode) || S_ISCHR(mode))
		devlen = jffs2_encode_dev(&dev, rdev);

	/* Try to reserve enough space for both node and dirent.
	 * Just the node will do for now, though
	 */
	namelen = dentry->d_name.len;
	ret = jffs2_reserve_space(c, sizeof(*ri) + devlen, &alloclen,
				  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);

	if (ret) {
		jffs2_free_raw_inode(ri);
		return ret;
	}

	inode = jffs2_new_inode(dir_i, mode, ri);

	if (IS_ERR(inode)) {
		jffs2_free_raw_inode(ri);
		jffs2_complete_reservation(c);
		return PTR_ERR(inode);
	}
	inode->i_op = &jffs2_file_inode_operations;
	init_special_inode(inode, inode->i_mode, rdev);

	f = JFFS2_INODE_INFO(inode);

	ri->dsize = ri->csize = cpu_to_je32(devlen);
	ri->totlen = cpu_to_je32(sizeof(*ri) + devlen);
	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));

	ri->compr = JFFS2_COMPR_NONE;
	ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));

	fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, ALLOC_NORMAL);

	jffs2_free_raw_inode(ri);

	if (IS_ERR(fn)) {
		/* Eeek. Wave bye bye */
		up(&f->sem);
		jffs2_complete_reservation(c);
		jffs2_clear_inode(inode);
		return PTR_ERR(fn);
	}
	/* No data here. Only a metadata node, which will be
	   obsoleted by the first data write
	*/
	f->metadata = fn;
	up(&f->sem);

	jffs2_complete_reservation(c);

	ret = jffs2_init_security(inode, dir_i);
	if (ret) {
		jffs2_clear_inode(inode);
		return ret;
	}
	ret = jffs2_init_acl(inode, dir_i);
	if (ret) {
		jffs2_clear_inode(inode);
		return ret;
	}

	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
				  ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
	if (ret) {
		/* Eep. */
		jffs2_clear_inode(inode);
		return ret;
	}

	rd = jffs2_alloc_raw_dirent();
	if (!rd) {
		/* Argh. Now we treat it like a normal delete */
		jffs2_complete_reservation(c);
		jffs2_clear_inode(inode);
		return -ENOMEM;
	}

	dir_f = JFFS2_INODE_INFO(dir_i);
	down(&dir_f->sem);

	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));

	rd->pino = cpu_to_je32(dir_i->i_ino);
	rd->version = cpu_to_je32(++dir_f->highest_version);
	rd->ino = cpu_to_je32(inode->i_ino);
	rd->mctime = cpu_to_je32(get_seconds());
	rd->nsize = namelen;

	/* XXX: This is ugly. */
	rd->type = (mode & S_IFMT) >> 12;

	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
	rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));

	fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);

	if (IS_ERR(fd)) {
		/* dirent failed to write. Delete the inode normally
		   as if it were the final unlink() */
		jffs2_complete_reservation(c);
		jffs2_free_raw_dirent(rd);
		up(&dir_f->sem);
		jffs2_clear_inode(inode);
		return PTR_ERR(fd);
	}

	dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));

	jffs2_free_raw_dirent(rd);

	/* Link the fd into the inode's list, obsoleting an old
	   one if necessary. */
	jffs2_add_fd_to_list(c, fd, &dir_f->dents);

	up(&dir_f->sem);
	jffs2_complete_reservation(c);

	d_instantiate(dentry, inode);

	return 0;
}
static void musb_id_pin_work(struct work_struct *data)
{
    //u8 devctl = 0;
    unsigned long flags;

    spin_lock_irqsave(&mtk_musb->lock, flags);
    musb_generic_disable(mtk_musb);
    spin_unlock_irqrestore(&mtk_musb->lock, flags);

	down(&mtk_musb->musb_lock);
	DBG(0, "work start, is_host=%d\n", mtk_musb->is_host);
	if(mtk_musb->in_ipo_off) {
		DBG(0, "do nothing due to in_ipo_off\n");
		goto out;
	}

	mtk_musb ->is_host = musb_is_host();
	DBG(0,"musb is as %s\n",mtk_musb->is_host?"host":"device");
	switch_set_state((struct switch_dev *)&otg_state, mtk_musb->is_host);

	if (mtk_musb->is_host) {
		//setup fifo for host mode
		ep_config_from_table_for_host(mtk_musb);
		wake_lock(&mtk_musb->usb_lock);
		musb_platform_set_vbus(mtk_musb, 1);

        /* for no VBUS sensing IP*/
        #if 0
		/* wait VBUS ready */
		msleep(100);
		/* clear session*/
		devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
		musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl&(~MUSB_DEVCTL_SESSION)));
		/* USB MAC OFF*/
		/* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */
		USBPHY_SET8(0x6c, 0x10);
		USBPHY_CLR8(0x6c, 0x2e);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
		/* wait */
		msleep(5);
		/* restart session */
		devctl = musb_readb(mtk_musb->mregs,MUSB_DEVCTL);
		musb_writeb(mtk_musb->mregs, MUSB_DEVCTL, (devctl| MUSB_DEVCTL_SESSION));
		/* USB MAC ONand Host Mode*/
		/* VBUSVALID=1, AVALID=1, BVALID=1, SESSEND=0, IDDIG=0 */
		USBPHY_CLR8(0x6c, 0x10);
		USBPHY_SET8(0x6c, 0x2c);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to host mode, 0x6d=%x, 0x6c=%x\n",USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
        #endif

		musb_start(mtk_musb);
		MUSB_HST_MODE(mtk_musb);
		switch_int_to_device(mtk_musb);
	} else {
		DBG(0,"devctl is %x\n",musb_readb(mtk_musb->mregs,MUSB_DEVCTL));
		musb_writeb(mtk_musb->mregs,MUSB_DEVCTL,0);
		if (wake_lock_active(&mtk_musb->usb_lock))
			wake_unlock(&mtk_musb->usb_lock);
		musb_platform_set_vbus(mtk_musb, 0);

        /* for no VBUS sensing IP */
        #if 0
        /* USB MAC OFF*/
		/* VBUSVALID=0, AVALID=0, BVALID=0, SESSEND=1, IDDIG=X */
		USBPHY_SET8(0x6c, 0x10);
		USBPHY_CLR8(0x6c, 0x2e);
		USBPHY_SET8(0x6d, 0x3e);
		DBG(0,"force PHY to idle, 0x6d=%x, 0x6c=%x\n", USBPHY_READ8(0x6d), USBPHY_READ8(0x6c));
        #endif

		musb_stop(mtk_musb);
		mtk_musb->xceiv->state =  OTG_STATE_B_IDLE;
		MUSB_DEV_MODE(mtk_musb);
		switch_int_to_host(mtk_musb);
	}
out:
	DBG(0, "work end, is_host=%d\n", mtk_musb->is_host);
	up(&mtk_musb->musb_lock);

}
Пример #7
0
int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
{
	int result;

	/* Set up for status notification */
	atomic_set(us->ip_wanted, 1);

	/* re-initialize the mutex so that we avoid any races with
	 * early/late IRQs from previous commands */
	init_MUTEX_LOCKED(&(us->ip_waitq));

	/* COMMAND STAGE */
	/* let's send the command via the control pipe */
	result = usb_stor_control_msg(us, usb_sndctrlpipe(us->pusb_dev,0),
				      US_CBI_ADSC, 
				      USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 
				      us->ifnum, srb->cmnd, srb->cmd_len);

	/* check the return code for the command */
	US_DEBUGP("Call to usb_stor_control_msg() returned %d\n", result);
	if (result < 0) {
		/* Reset flag for status notification */
		atomic_set(us->ip_wanted, 0);

		/* if the command was aborted, indicate that */
		if (result == -ENOENT)
			return USB_STOR_TRANSPORT_ABORTED;

		/* STALL must be cleared when they are detected */
		if (result == -EPIPE) {
			US_DEBUGP("-- Stall on control pipe. Clearing\n");
			result = usb_stor_clear_halt(us->pusb_dev,	
					    usb_sndctrlpipe(us->pusb_dev,
							    0));
			US_DEBUGP("-- usb_stor_clear_halt() returns %d\n", result);
			return USB_STOR_TRANSPORT_FAILED;
		}

		/* Uh oh... serious problem here */
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* DATA STAGE */
	/* transfer the data payload for this command, if one exists*/
	if (usb_stor_transfer_length(srb)) {
		usb_stor_transfer(srb, us);
		US_DEBUGP("CBI data stage result is 0x%x\n", srb->result);

		/* if it was aborted, we need to indicate that */
		if (srb->result == USB_STOR_TRANSPORT_ABORTED) {
			return USB_STOR_TRANSPORT_ABORTED;
		}
	}

	/* STATUS STAGE */

	/* go to sleep until we get this interrupt */
	US_DEBUGP("Current value of ip_waitq is: %d\n", atomic_read(&us->ip_waitq.count));
	down(&(us->ip_waitq));

	/* if we were woken up by an abort instead of the actual interrupt */
	if (atomic_read(us->ip_wanted)) {
		US_DEBUGP("Did not get interrupt on CBI\n");
		atomic_set(us->ip_wanted, 0);
		return USB_STOR_TRANSPORT_ABORTED;
	}

	US_DEBUGP("Got interrupt data (0x%x, 0x%x)\n", 
			us->irqdata[0], us->irqdata[1]);

	/* UFI gives us ASC and ASCQ, like a request sense
	 *
	 * REQUEST_SENSE and INQUIRY don't affect the sense data on UFI
	 * devices, so we ignore the information for those commands.  Note
	 * that this means we could be ignoring a real error on these
	 * commands, but that can't be helped.
	 */
	if (us->subclass == US_SC_UFI) {
		if (srb->cmnd[0] == REQUEST_SENSE ||
		    srb->cmnd[0] == INQUIRY)
			return USB_STOR_TRANSPORT_GOOD;
		else
			if (((unsigned char*)us->irq_urb->transfer_buffer)[0])
				return USB_STOR_TRANSPORT_FAILED;
			else
				return USB_STOR_TRANSPORT_GOOD;
	}

	/* If not UFI, we interpret the data as a result code 
	 * The first byte should always be a 0x0
	 * The second byte & 0x0F should be 0x0 for good, otherwise error 
	 */
	if (us->irqdata[0]) {
		US_DEBUGP("CBI IRQ data showed reserved bType %d\n",
				us->irqdata[0]);
		return USB_STOR_TRANSPORT_ERROR;
	}

	switch (us->irqdata[1] & 0x0F) {
		case 0x00: 
			return USB_STOR_TRANSPORT_GOOD;
		case 0x01: 
			return USB_STOR_TRANSPORT_FAILED;
		default: 
			return USB_STOR_TRANSPORT_ERROR;
	}

	/* we should never get here, but if we do, we're in trouble */
	return USB_STOR_TRANSPORT_ERROR;
}
Пример #8
0
void disp_ext_util_mipitx_lock( void )
{
    down(&disp_ext_util_mipitx_sem);
}
Пример #9
0
int jffs2_prepare_write (struct file *filp, struct page *pg, unsigned start, unsigned end)
{
	struct inode *inode = pg->mapping->host;
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT;
	int ret = 0;

	D1(printk(KERN_DEBUG "jffs2_prepare_write()\n"));

	if (pageofs > inode->i_size) {
		/* Make new hole frag from old EOF to new page */
		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
		struct jffs2_raw_inode ri;
		struct jffs2_full_dnode *fn;
		uint32_t phys_ofs, alloc_len;
		
		D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
			  (unsigned int)inode->i_size, pageofs));

		ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
		if (ret)
			return ret;

		down(&f->sem);
		memset(&ri, 0, sizeof(ri));

		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
		ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
		ri.totlen = cpu_to_je32(sizeof(ri));
		ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));

		ri.ino = cpu_to_je32(f->inocache->ino);
		ri.version = cpu_to_je32(++f->highest_version);
		ri.mode = cpu_to_jemode(inode->i_mode);
		ri.uid = cpu_to_je16(inode->i_uid);
		ri.gid = cpu_to_je16(inode->i_gid);
		ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
		ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
		ri.offset = cpu_to_je32(inode->i_size);
		ri.dsize = cpu_to_je32(pageofs - inode->i_size);
		ri.csize = cpu_to_je32(0);
		ri.compr = JFFS2_COMPR_ZERO;
		ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
		ri.data_crc = cpu_to_je32(0);
		
		fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);

		if (IS_ERR(fn)) {
			ret = PTR_ERR(fn);
			jffs2_complete_reservation(c);
			up(&f->sem);
			return ret;
		}
		ret = jffs2_add_full_dnode_to_inode(c, f, fn);
		if (f->metadata) {
			jffs2_mark_node_obsolete(c, f->metadata->raw);
			jffs2_free_full_dnode(f->metadata);
			f->metadata = NULL;
		}
		if (ret) {
			D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
			jffs2_mark_node_obsolete(c, fn->raw);
			jffs2_free_full_dnode(fn);
			jffs2_complete_reservation(c);
			up(&f->sem);
			return ret;
		}
		jffs2_complete_reservation(c);
		inode->i_size = pageofs;
		up(&f->sem);
	}
	
	/* Read in the page if it wasn't already present, unless it's a whole page */
	if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
		down(&f->sem);
		ret = jffs2_do_readpage_nolock(inode, pg);
		up(&f->sem);
	}
	D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags));
	return ret;
}
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    INT32 retval = -EIO;
    INT8 local[12] = {0};
    struct net_device *netdev = NULL;
    PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode;
    INT32 wait_cnt = 0;

    down(&wr_mtx);
    if (count <= 0) {
        WIFI_ERR_FUNC("WIFI_write invalid param\n");
        goto done;
    }

    if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) {
        local[11] = 0;
        WIFI_INFO_FUNC("WIFI_write %s\n", local);

        if (local[0] == '0') {
            if (powered == 0) {
                WIFI_INFO_FUNC("WIFI is already power off!\n");
                retval = count;
                wlan_mode = WLAN_MODE_HALT;
                goto done;
            }

            netdev = dev_get_by_name(&init_net, ifname);
            if (netdev == NULL) {
                WIFI_ERR_FUNC("Fail to get %s net device\n", ifname);
            }
            else {
                p2pmode.u4Enable = 0;
                p2pmode.u4Mode = 0;

                if (pf_set_p2p_mode) {
                    if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                        WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
                    } else {
                        WIFI_INFO_FUNC("Turn off p2p/ap mode");
                        wlan_mode = WLAN_MODE_HALT;
                    }
               }
               dev_put(netdev);
               netdev = NULL;
            }

            if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) {
                WIFI_ERR_FUNC("WMT turn off WIFI fail!\n");
                powered = 2;
            }
            else {
                WIFI_INFO_FUNC("WMT turn off WIFI OK!\n");
                powered = 0;
                retval = count;
                wlan_mode = WLAN_MODE_HALT;
            #if CFG_TC1_FEATURE
                ifname = WLAN_IFACE_NAME;
                wlan_if_changed = 0;
            #endif
            }
        }
        else if (local[0] == '1') {
            if (powered == 1) {
                WIFI_INFO_FUNC("WIFI is already power on!\n");
                retval = count;
                goto done;
            } else if (powered == 2) {
            	/* workaround for wifi turn off fail. otherwise, 
            	   will KE in register_netdevice with wrong dev->state */
                WIFI_ERR_FUNC("WIFI turn off fail last time, can't turn on again!\n");
                goto done;
            }

            if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
            }
            else {
                powered = 1;
                retval = count;
                WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
                wlan_mode = WLAN_MODE_HALT;
            }
        }
        else if (local[0] == 'D') {
            INT32 k = 0;
            /* 
             * 0: no debug
             * 1: common debug output
             * 2: more detials
             * 3: verbose
             */
            switch (local[1]) {
            case '0':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = 0;
                }
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '1':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO;
                }
                wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | \
                    DBG_CLASS_TRACE | \
                    DBG_CLASS_INFO);
                wlan_dbg_level[DBG_INTR_IDX] = 0;
                wlan_dbg_level[DBG_MEM_IDX] = 0;
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '2':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO;
                }	
                wlan_dbg_level[DBG_INTR_IDX] = 0;
                wlan_dbg_level[DBG_MEM_IDX] = 0;
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            case '3':
                for (k = 0; k < DBG_MODULE_NUM; k++) {
                    wlan_dbg_level[k] = DBG_CLASS_ERROR | \
                        DBG_CLASS_WARN | \
                        DBG_CLASS_STATE | \
                        DBG_CLASS_EVENT | \
                        DBG_CLASS_TRACE | \
                        DBG_CLASS_INFO | \
                        DBG_CLASS_LOUD;
                }	
                if (pf_set_dbg_level) {
                    pf_set_dbg_level(wlan_dbg_level);
                }
                break;
            default:
                break;
            }
        }
        else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') {
            if (powered == 2) {
                /* workaround for wifi turn off fail. otherwise, 
                   will KE in register_netdevice with wrong dev->state */
                WIFI_ERR_FUNC("WIFI turn off fail last time, can't turn on again!\n");
                goto done;
            }

            if (powered == 0) {
                /* If WIFI is off, turn on WIFI first */
                if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) {
                    WIFI_ERR_FUNC("WMT turn on WIFI fail!\n");
                    goto done;
                }
                else {
                    powered = 1;
                    WIFI_INFO_FUNC("WMT turn on WIFI success!\n");
                    wlan_mode = WLAN_MODE_HALT;
                }
            }

            if (pf_set_p2p_mode == NULL) {
                WIFI_ERR_FUNC("Set p2p mode handler is NULL\n");
                goto done;
            }

            netdev = dev_get_by_name(&init_net, ifname);
            while (netdev == NULL && wait_cnt < 10) {
                WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname);
                msleep(300);
                wait_cnt ++;
                netdev = dev_get_by_name(&init_net, ifname);
            }
            if (wait_cnt >= 10) {
                WIFI_ERR_FUNC("Get %s net device timeout\n", ifname);
                goto done;
            }

            if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) ||
                (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))){
                WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode);
                retval = count;
                goto done;
            }

            if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) ||
                (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))){
                p2pmode.u4Enable = 0;
                p2pmode.u4Mode = 0;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Turn off p2p/ap mode fail");
                    goto done;
                }
            }

            if (local[0] == 'S' || local[0] == 'P'){
            #if CFG_TC1_FEATURE
                /* Restore NIC name to wlan0 */
                rtnl_lock();
                if (strcmp(ifname, WLAN_IFACE_NAME) != 0){
                    if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0){
                        WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME);
                        rtnl_unlock();
                        goto done;
                    }
                    else{
                        WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, WLAN_IFACE_NAME);
                        ifname = WLAN_IFACE_NAME;
                        wlan_if_changed = 0;
                    }
                }
                rtnl_unlock();
            #endif
                p2pmode.u4Enable = 1;
                p2pmode.u4Mode = 0;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Set wlan mode fail\n");
                }
                else{
                    WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P);
                    wlan_mode = WLAN_MODE_STA_P2P;
                    retval = count;
                }
            } else if (local[0] == 'A'){
            #if CFG_TC1_FEATURE
                /* Change NIC name to legacy0, since wlan0 is used for AP */
                rtnl_lock();
                if (strcmp(ifname, LEGACY_IFACE_NAME) != 0){
                    if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0){
                        WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME);
                        rtnl_unlock();
                        goto done;
                    }
                    else{
                        WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, LEGACY_IFACE_NAME);
                        ifname = LEGACY_IFACE_NAME;
                        wlan_if_changed = 1;
                    }
                }
                rtnl_unlock();
            #endif
                p2pmode.u4Enable = 1;
                p2pmode.u4Mode = 1;
                if (pf_set_p2p_mode(netdev, p2pmode) != 0){
                    WIFI_ERR_FUNC("Set wlan mode fail\n");
                }
                else{
                    WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP);
                    wlan_mode = WLAN_MODE_AP;
                    retval = count;
                }
            }
            dev_put(netdev);
            netdev = NULL;
        }
    }
done:
    if (netdev != NULL){
        dev_put(netdev);
    }
    up(&wr_mtx);
    return (retval);
}
Пример #11
0
void disp_ext_util_disp_local_lock( void )
{
    down(&disp_local_mutex);
}
static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
{
	struct jffs2_full_dnode *old_metadata, *new_metadata;
	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
	struct jffs2_raw_inode *ri;
	unsigned short dev;
	unsigned char *mdata = NULL;
	int mdatalen = 0;
	unsigned int ivalid;
	uint32_t phys_ofs, alloclen;
	int ret;
	D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
	ret = inode_change_ok(inode, iattr);
	if (ret)
		return ret;

	/* Special cases - we don't want more than one data node
	   for these types on the medium at any time. So setattr
	   must read the original data associated with the node
	   (i.e. the device numbers or the target name) and write
	   it out again with the appropriate data attached */
	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
		/* For these, we don't actually need to read the old node */
		dev = old_encode_dev(inode->i_rdev);
		mdata = (char *)&dev;
		mdatalen = sizeof(dev);
		D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
	} else if (S_ISLNK(inode->i_mode)) {
		mdatalen = f->metadata->size;
		mdata = kmalloc(f->metadata->size, GFP_USER);
		if (!mdata)
			return -ENOMEM;
		ret = jffs2_read_dnode(c, f, f->metadata, mdata, 0, mdatalen);
		if (ret) {
			kfree(mdata);
			return ret;
		}
		D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
	}

	ri = jffs2_alloc_raw_inode();
	if (!ri) {
		if (S_ISLNK(inode->i_mode))
			kfree(mdata);
		return -ENOMEM;
	}

	ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen,
				ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
	if (ret) {
		jffs2_free_raw_inode(ri);
		if (S_ISLNK(inode->i_mode & S_IFMT))
			 kfree(mdata);
		return ret;
	}
	down(&f->sem);
	ivalid = iattr->ia_valid;

	ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
	ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
	ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));

	ri->ino = cpu_to_je32(inode->i_ino);
	ri->version = cpu_to_je32(++f->highest_version);

	ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
	ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);

	if (ivalid & ATTR_MODE)
		if (iattr->ia_mode & S_ISGID &&
		    !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
			ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
		else
			ri->mode = cpu_to_jemode(iattr->ia_mode);
	else
		ri->mode = cpu_to_jemode(inode->i_mode);


	ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
	ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
	ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
	ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));

	ri->offset = cpu_to_je32(0);
	ri->csize = ri->dsize = cpu_to_je32(mdatalen);
	ri->compr = JFFS2_COMPR_NONE;
	if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
		/* It's an extension. Make it a hole node */
		ri->compr = JFFS2_COMPR_ZERO;
		ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
		ri->offset = cpu_to_je32(inode->i_size);
	}
	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
	if (mdatalen)
		ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
	else
		ri->data_crc = cpu_to_je32(0);

	new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
	if (S_ISLNK(inode->i_mode))
		kfree(mdata);

	if (IS_ERR(new_metadata)) {
		jffs2_complete_reservation(c);
		jffs2_free_raw_inode(ri);
		up(&f->sem);
		return PTR_ERR(new_metadata);
	}
	/* It worked. Update the inode */
	inode->i_atime = ITIME(je32_to_cpu(ri->atime));
	inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
	inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
	inode->i_mode = jemode_to_cpu(ri->mode);
	inode->i_uid = je16_to_cpu(ri->uid);
	inode->i_gid = je16_to_cpu(ri->gid);


	old_metadata = f->metadata;

	if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
		jffs2_truncate_fragtree (c, &f->fragtree, iattr->ia_size);

	if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
		jffs2_add_full_dnode_to_inode(c, f, new_metadata);
		inode->i_size = iattr->ia_size;
		f->metadata = NULL;
	} else {
		f->metadata = new_metadata;
	}
	if (old_metadata) {
		jffs2_mark_node_obsolete(c, old_metadata->raw);
		jffs2_free_full_dnode(old_metadata);
	}
	jffs2_free_raw_inode(ri);

	up(&f->sem);
	jffs2_complete_reservation(c);

	/* We have to do the vmtruncate() without f->sem held, since
	   some pages may be locked and waiting for it in readpage().
	   We are protected from a simultaneous write() extending i_size
	   back past iattr->ia_size, because do_truncate() holds the
	   generic inode semaphore. */
	if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
		vmtruncate(inode, iattr->ia_size);

	return 0;
}
void jffs2_read_inode (struct inode *inode)
{
	struct jffs2_inode_info *f;
	struct jffs2_sb_info *c;
	struct jffs2_raw_inode latest_node;
	int ret;

	D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));

	f = JFFS2_INODE_INFO(inode);
	c = JFFS2_SB_INFO(inode->i_sb);

	jffs2_init_inode_info(f);
	down(&f->sem);

	ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);

	if (ret) {
		make_bad_inode(inode);
		up(&f->sem);
		return;
	}
	inode->i_mode = jemode_to_cpu(latest_node.mode);
	inode->i_uid = je16_to_cpu(latest_node.uid);
	inode->i_gid = je16_to_cpu(latest_node.gid);
	inode->i_size = je32_to_cpu(latest_node.isize);
	inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
	inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
	inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));

	inode->i_nlink = f->inocache->nlink;

	inode->i_blksize = PAGE_SIZE;
	inode->i_blocks = (inode->i_size + 511) >> 9;

	switch (inode->i_mode & S_IFMT) {
		jint16_t rdev;

	case S_IFLNK:
		inode->i_op = &jffs2_symlink_inode_operations;
		break;

	case S_IFDIR:
	{
		struct jffs2_full_dirent *fd;

		for (fd=f->dents; fd; fd = fd->next) {
			if (fd->type == DT_DIR && fd->ino)
				inode->i_nlink++;
		}
		/* and '..' */
		inode->i_nlink++;
		/* Root dir gets i_nlink 3 for some reason */
		if (inode->i_ino == 1)
			inode->i_nlink++;

		inode->i_op = &jffs2_dir_inode_operations;
		inode->i_fop = &jffs2_dir_operations;
		break;
	}
	case S_IFREG:
		inode->i_op = &jffs2_file_inode_operations;
		inode->i_fop = &jffs2_file_operations;
		inode->i_mapping->a_ops = &jffs2_file_address_operations;
		inode->i_mapping->nrpages = 0;
		break;

	case S_IFBLK:
	case S_IFCHR:
		/* Read the device numbers from the media */
		D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
		if (jffs2_read_dnode(c, f, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
			/* Eep */
			printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
			up(&f->sem);
			jffs2_do_clear_inode(c, f);
			make_bad_inode(inode);
			return;
		}

	case S_IFSOCK:
	case S_IFIFO:
		inode->i_op = &jffs2_file_inode_operations;
		init_special_inode(inode, inode->i_mode,
				   old_decode_dev((je16_to_cpu(rdev))));
		break;

	default:
		printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
	}

	up(&f->sem);

	D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
}
Пример #14
0
unsigned long probe_irq_on(void)
{
	unsigned int i;
	irq_desc_t *desc;
	unsigned long val;
	unsigned long delay;

	down(&probe_sem);
	/*
	 * something may have generated an irq long ago and we want to
	 * flush such a longstanding irq before considering it as spurious.
	 */
	for (i = NR_IRQS-1; i > 0; i--)  {
		desc = irq_desc + i;

		spin_lock_irq(&desc->lock);
		if (!irq_desc[i].action)
			irq_desc[i].handler->startup(i);
		spin_unlock_irq(&desc->lock);
	}

	/* Wait for longstanding interrupts to trigger. */
	for (delay = jiffies + HZ/50; time_after(delay, jiffies); )
		/* about 20ms delay */ synchronize_irq();

	/*
	 * enable any unassigned irqs
	 * (we must startup again here because if a longstanding irq
	 * happened in the previous stage, it may have masked itself)
	 */
	for (i = NR_IRQS-1; i > 0; i--) {
		desc = irq_desc + i;

		spin_lock_irq(&desc->lock);
		if (!desc->action) {
			desc->status |= IRQ_AUTODETECT | IRQ_WAITING;
			if (desc->handler->startup(i))
				desc->status |= IRQ_PENDING;
		}
		spin_unlock_irq(&desc->lock);
	}

	/*
	 * Wait for spurious interrupts to trigger
	 */
	for (delay = jiffies + HZ/10; time_after(delay, jiffies); )
		/* about 100ms delay */ synchronize_irq();

	/*
	 * Now filter out any obviously spurious interrupts
	 */
	val = 0;
	for (i = 0; i < NR_IRQS; i++) {
		irq_desc_t *desc = irq_desc + i;
		unsigned int status;

		spin_lock_irq(&desc->lock);
		status = desc->status;

		if (status & IRQ_AUTODETECT) {
			/* It triggered already - consider it spurious. */
			if (!(status & IRQ_WAITING)) {
				desc->status = status & ~IRQ_AUTODETECT;
				desc->handler->shutdown(i);
			} else
				if (i < 32)
					val |= 1 << i;
		}
		spin_unlock_irq(&desc->lock);
	}

	return val;
}
Пример #15
0
void synchronize_irq() {
  down(irq_sem);
  up(irq_sem);
}
Пример #16
0
void MobileVRInterface::set_position_from_sensors() {
	_THREAD_SAFE_METHOD_

	// this is a helper function that attempts to adjust our transform using our 9dof sensors
	// 9dof is a misleading marketing term coming from 3 accelerometer axis + 3 gyro axis + 3 magnetometer axis = 9 axis
	// but in reality this only offers 3 dof (yaw, pitch, roll) orientation

	uint64_t ticks = OS::get_singleton()->get_ticks_usec();
	uint64_t ticks_elapsed = ticks - last_ticks;
	float delta_time = (double)ticks_elapsed / 1000000.0;

	// few things we need
	Input *input = Input::get_singleton();
	Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
	Vector3 north(0.0, 0.0, 1.0); // North is Z positive

	// make copies of our inputs
	bool has_grav = false;
	Vector3 acc = input->get_accelerometer();
	Vector3 gyro = input->get_gyroscope();
	Vector3 grav = input->get_gravity();
	Vector3 magneto = scale_magneto(input->get_magnetometer()); // this may be overkill on iOS because we're already getting a calibrated magnetometer reading

	if (sensor_first) {
		sensor_first = false;
	} else {
		acc = scrub(acc, last_accerometer_data, 2, 0.2);
		magneto = scrub(magneto, last_magnetometer_data, 3, 0.3);
	};

	last_accerometer_data = acc;
	last_magnetometer_data = magneto;

	if (grav.length() < 0.1) {
		// not ideal but use our accelerometer, this will contain shakey shakey user behaviour
		// maybe look into some math but I'm guessing that if this isn't available, its because we lack the gyro sensor to actually work out
		// what a stable gravity vector is
		grav = acc;
		if (grav.length() > 0.1) {
			has_grav = true;
		};
	} else {
		has_grav = true;
	};

	bool has_magneto = magneto.length() > 0.1;
	if (gyro.length() > 0.1) {
		/* this can return to 0.0 if the user doesn't move the phone, so once on, it's on */
		has_gyro = true;
	};

	if (has_gyro) {
		// start with applying our gyro (do NOT smooth our gyro!)
		Basis rotate;
		rotate.rotate(orientation.get_axis(0), gyro.x * delta_time);
		rotate.rotate(orientation.get_axis(1), gyro.y * delta_time);
		rotate.rotate(orientation.get_axis(2), gyro.z * delta_time);
		orientation = rotate * orientation;

		tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
	};

	///@TODO improve this, the magnetometer is very fidgity sometimes flipping the axis for no apparent reason (probably a bug on my part)
	// if you have a gyro + accelerometer that combo tends to be better then combining all three but without a gyro you need the magnetometer..
	if (has_magneto && has_grav && !has_gyro) {
		// convert to quaternions, easier to smooth those out
		Quat transform_quat(orientation);
		Quat acc_mag_quat(combine_acc_mag(grav, magneto));
		transform_quat = transform_quat.slerp(acc_mag_quat, 0.1);
		orientation = Basis(transform_quat);

		tracking_state = ARVRInterface::ARVR_NORMAL_TRACKING;
	} else if (has_grav) {
		// use gravity vector to make sure down is down...
		// transform gravity into our world space
		grav.normalize();
		Vector3 grav_adj = orientation.xform(grav);
		float dot = grav_adj.dot(down);
		if ((dot > -1.0) && (dot < 1.0)) {
			// axis around which we have this rotation
			Vector3 axis = grav_adj.cross(down);
			axis.normalize();

			Basis drift_compensation(axis, acos(dot) * delta_time * 10);
			orientation = drift_compensation * orientation;
		};
	};

	// JIC
	orientation.orthonormalize();

	last_ticks = ticks;
};
Пример #17
0
/*
 * TODO: The kernel doesn't have a 'down_timeout' function -- had to
 * improvise.  The process is to sleep for one scheduler quantum
 * until the semaphore becomes available.  Downside is that this
 * may result in starvation for timeout-based waits when there's
 * lots of semaphore activity.
 *
 * TODO: Support for units > 1?
 */
acpi_status
acpi_os_wait_semaphore(
	acpi_handle		handle,
	u32			units,
	u16			timeout)
{
	acpi_status		status = AE_OK;
	struct semaphore	*sem = (struct semaphore*)handle;
	int			ret = 0;

	ACPI_FUNCTION_TRACE ("os_wait_semaphore");

	if (!sem || (units < 1))
		return_ACPI_STATUS (AE_BAD_PARAMETER);

	if (units > 1)
		return_ACPI_STATUS (AE_SUPPORT);

	ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout));

	if (in_atomic())
		timeout = 0;

	switch (timeout)
	{
		/*
		 * No Wait:
		 * --------
		 * A zero timeout value indicates that we shouldn't wait - just
		 * acquire the semaphore if available otherwise return AE_TIME
		 * (a.k.a. 'would block').
		 */
		case 0:
		if(down_trylock(sem))
			status = AE_TIME;
		break;

		/*
		 * Wait Indefinitely:
		 * ------------------
		 */
		case ACPI_WAIT_FOREVER:
		down(sem);
		break;

		/*
		 * Wait w/ Timeout:
		 * ----------------
		 */
		default:
		// TODO: A better timeout algorithm?
		{
			int i = 0;
			static const int quantum_ms = 1000/HZ;

			ret = down_trylock(sem);
			for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) {
				current->state = TASK_INTERRUPTIBLE;
				schedule_timeout(1);
				ret = down_trylock(sem);
			}
	
			if (ret != 0)
				status = AE_TIME;
		}
		break;
	}

	if (ACPI_FAILURE(status)) {
		ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Failed to acquire semaphore[%p|%d|%d], %s\n", 
			handle, units, timeout, acpi_format_exception(status)));
	}
	else {
		ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout));
	}

	return_ACPI_STATUS (status);
}
Пример #18
0
/*
 * This routine handles page faults.  It determines the problem, and
 * then passes it off to one of the appropriate routines.
 *
 * error_code:
 *	bit 0 == 0 means no page found, 1 means protection fault
 *	bit 1 == 0 means read, 1 means write
 *
 * If this routine detects a bad access, it returns 1, otherwise it
 * returns 0.
 */
int do_page_fault(struct pt_regs *regs, unsigned long address,
			      unsigned long error_code)
{
	struct mm_struct *mm = current->mm;
	struct vm_area_struct * vma;
	int write, fault;

#ifdef DEBUG
	printk ("do page fault:\nregs->sr=%#x, regs->pc=%#lx, address=%#lx, %ld, %p\n",
		regs->sr, regs->pc, address, error_code,
		current->mm->pgd);
#endif

	/*
	 * If we're in an interrupt or have no user
	 * context, we must not take the fault..
	 */
	if (in_interrupt() || !mm)
		goto no_context;

	down(&mm->mmap_sem);

	vma = find_vma(mm, address);
	if (!vma)
		goto map_err;
	if (vma->vm_flags & VM_IO)
		goto acc_err;
	if (vma->vm_start <= address)
		goto good_area;
	if (!(vma->vm_flags & VM_GROWSDOWN))
		goto map_err;
	if (user_mode(regs)) {
		/* Accessing the stack below usp is always a bug.  The
		   "+ 256" is there due to some instructions doing
		   pre-decrement on the stack and that doesn't show up
		   until later.  */
		if (address + 256 < rdusp())
			goto map_err;
	}
	if (expand_stack(vma, address))
		goto map_err;

/*
 * Ok, we have a good vm_area for this memory access, so
 * we can handle it..
 */
good_area:
#ifdef DEBUG
	printk("do_page_fault: good_area\n");
#endif
	write = 0;
	switch (error_code & 3) {
		default:	/* 3: write, present */
			/* fall through */
		case 2:		/* write, not present */
			if (!(vma->vm_flags & VM_WRITE))
				goto acc_err;
			write++;
			break;
		case 1:		/* read, present */
			goto acc_err;
		case 0:		/* read, not present */
			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
				goto acc_err;
	}

	/*
	 * If for any reason at all we couldn't handle the fault,
	 * make sure we exit gracefully rather than endlessly redo
	 * the fault.
	 */
	fault = handle_mm_fault(mm, vma, address, write);
#ifdef DEBUG
 	printk("handle_mm_fault returns %d\n",fault);
#endif
	if (fault < 0)
		goto out_of_memory;
	if (!fault)
		goto bus_err;

	/* There seems to be a missing invalidate somewhere in do_no_page.
	 * Until I found it, this one cures the problem and makes
	 * 1.2 run on the 68040 (Martin Apel).
	 */
	#warning should be obsolete now...
	if (CPU_IS_040_OR_060)
		flush_tlb_page(vma, address);
	up(&mm->mmap_sem);
	return 0;

/*
 * We ran out of memory, or some other thing happened to us that made
 * us unable to handle the page fault gracefully.
 */
out_of_memory:
	printk("VM: killing process %s\n", current->comm);
	if (user_mode(regs))
		do_exit(SIGKILL);

no_context:
	current->thread.signo = SIGBUS;
	current->thread.faddr = address;
	return send_fault_sig(regs);

bus_err:
	current->thread.signo = SIGBUS;
	current->thread.code = BUS_ADRERR;
	current->thread.faddr = address;
	goto send_sig;

map_err:
	current->thread.signo = SIGSEGV;
	current->thread.code = SEGV_MAPERR;
	current->thread.faddr = address;
	goto send_sig;

acc_err:
	current->thread.signo = SIGSEGV;
	current->thread.code = SEGV_ACCERR;
	current->thread.faddr = address;

send_sig:
	up(&mm->mmap_sem);
	return send_fault_sig(regs);
}
void j4fs_GrossLock(void)
{
	T(J4FS_TRACE_LOCK, ("j4fs locking %p\n", current));
	down(&device_info.grossLock);
	T(J4FS_TRACE_LOCK, ("j4fs locked %p\n", current));
}
Пример #20
0
//接收消息
//timeout为0,表示不等待,立刻返回。
//timeout为-1,表示一直等到。
//timeout非0和-1,则等待一定的毫秒。
int	IpcReceive(
	Message*	usermsg,	//消息正文缓冲区
	uint		flag,		//接收参数
	int		timeout		//超时值
){
	KThread* thr_src = NULL, * thr_cur;
	KMessage* kmsg;
	KQueueNode* nod;
	uint flags;
	int ret;
	uint startSleepTime = ArGetMilliSecond();
	if( usermsg->ThreadId != ANY_THREAD )
		thr_src = (KThread*)TmGetThreadById( usermsg->ThreadId );
	thr_cur = TmGetCurrentThread();
_recv_search:
	//锁定线程,避免在睡眠前切换了线程得到了消息
	down( &thr_cur->Semaphore );
	if( thr_src && usermsg->Command ){
		kmsg = RtlSearchQueue( &thr_cur->MessageQueue, usermsg,
			MessageSearcher3, &nod );
	}else if( thr_src ){
		kmsg = RtlSearchQueue( &thr_cur->MessageQueue, usermsg,
			MessageSearcher1, &nod );
	}else if( usermsg->Command ){
		kmsg = RtlSearchQueue( &thr_cur->MessageQueue, usermsg,
			MessageSearcher2, &nod );
	}else{	//receive any message
		kmsg = RtlPopBackQueue( &thr_cur->MessageQueue );
	}
	if( !kmsg ){
		if( timeout!=0 ){
			int rest;
			if( timeout!=INFINITE ){
				rest = timeout - (ArGetMilliSecond()-startSleepTime);
				if( rest < 0 ) //timeout happens
					return -ERR_TIMEOUT;
			}else{
				rest = INFINITE;
			}
			//禁止中断发生的理由: ???
			ArLocalSaveIrq( flags );
			up( &thr_cur->Semaphore );
			TmSleepThread( thr_cur, rest );
			ArLocalRestoreIrq( flags );
			goto _recv_search;
		}
		up( &thr_cur->Semaphore );
		//要求立即返回,但又没有取得消息
		return -ERR_NONE;
	}
	up( &thr_cur->Semaphore );
	//set return value
	ret = 1;
	//copy to user space
	*usermsg = kmsg->UserMessage;
	//check flag
	if( thr_src ){
		if( !(flag&MSG_KEEP ) ){
			RtlRemoveQueueElement( &thr_cur->MessageQueue, nod );
			MessageEraser( kmsg );
		}
	}else{
		if( flag&MSG_KEEP )
			RtlPushBackQueue( &thr_cur->MessageQueue, kmsg );
		else
			MessageEraser( kmsg );
	}
	//设置来源
	usermsg->ThreadId = kmsg->Source->ThreadId;
#if 0
	if( usermsg->Command != System_SleepThread )
		KdPrintf("%x recv from %x  cmd:%x arg1:%d\n", thr_cur->ThreadId, usermsg->ThreadId, 
			usermsg->Command, usermsg->Arguments[0] );
#endif
	return ret;
}
Пример #21
0
static
int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
{
	struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
	int err = 0;
	int res;

	MTS_DEBUG_GOT_HERE();
	mts_show_command(srb);
	mts_debug_dump(desc);
	
	if ( srb->device->lun || srb->device->id || srb->device->channel ) {

		MTS_DEBUG("Command to LUN=%d ID=%d CHANNEL=%d from SCSI layer\n",(int)srb->device->lun,(int)srb->device->id, (int)srb->device->channel );
		
		MTS_DEBUG("this device doesn't exist\n");

		srb->result = DID_BAD_TARGET << 16;

		if(callback)
			callback(srb);

		goto out;
	}	

	down(&desc->lock);

	MTS_DEBUG_GOT_HERE();
	mts_show_command(srb);
	

	FILL_BULK_URB(&desc->urb,
		      desc->usb_dev,
		      usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
		      srb->cmnd,
		      srb->cmd_len,
		      mts_command_done,
		      &desc->context
		      );
	
		
	mts_build_transfer_context( srb, desc );
	desc->context.final_callback = callback;
	desc->urb.timeout = 100;
	desc->urb.transfer_flags = USB_ASYNC_UNLINK;
	
/*	desc->urb.transfer_flags = USB_DISABLE_SPD;*/

	res=usb_submit_urb(&desc->urb);
	
	if(res){
		MTS_ERROR("error %d submitting URB\n",(int)res);
		srb->result = DID_ERROR << 16;

		if(callback)
			callback(srb);

		goto out;
	}	
	
	MTS_DEBUG_GOT_HERE();

 out:
	return err;
}
static int mipi_dsi_on(struct platform_device *pdev)
{
	int ret = 0;
	u32 clk_rate;
	struct msm_fb_data_type *mfd;
	struct fb_info *fbi;
	struct fb_var_screeninfo *var;
	struct msm_panel_info *pinfo;
	struct mipi_panel_info *mipi;
	u32 hbp, hfp, vbp, vfp, hspw, vspw, width, height;
	u32 ystride, bpp, data;
	u32 dummy_xres, dummy_yres;
	int target_type = 0;

	mfd = platform_get_drvdata(pdev);
	fbi = mfd->fbi;
	var = &fbi->var;
	pinfo = &mfd->panel_info;

	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
		mipi_dsi_pdata->dsi_power_save(1);

	cont_splash_clk_ctrl(0);
	mipi_dsi_prepare_clocks();

	mipi_dsi_ahb_ctrl(1);

	clk_rate = mfd->fbi->var.pixclock;
	clk_rate = min(clk_rate, mfd->panel_info.clk_max);

	mipi_dsi_phy_ctrl(1);

	if (mdp_rev == MDP_REV_42 && mipi_dsi_pdata)
		target_type = mipi_dsi_pdata->target_type;

	mipi_dsi_phy_init(0, &(mfd->panel_info), target_type);

	mipi_dsi_clk_enable();

	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 1);
	MIPI_OUTP(MIPI_DSI_BASE + 0x114, 0);

	hbp = var->left_margin;
	hfp = var->right_margin;
	vbp = var->upper_margin;
	vfp = var->lower_margin;
	hspw = var->hsync_len;
	vspw = var->vsync_len;
	width = mfd->panel_info.xres;
	height = mfd->panel_info.yres;

	mipi  = &mfd->panel_info.mipi;
	if (mfd->panel_info.type == MIPI_VIDEO_PANEL) {
		dummy_xres = mfd->panel_info.lcdc.xres_pad;
		dummy_yres = mfd->panel_info.lcdc.yres_pad;

		if (mdp_rev >= MDP_REV_41) {
			MIPI_OUTP(MIPI_DSI_BASE + 0x20,
				((hspw + hbp + width + dummy_xres) << 16 |
				(hspw + hbp)));
			MIPI_OUTP(MIPI_DSI_BASE + 0x24,
				((vspw + vbp + height + dummy_yres) << 16 |
				(vspw + vbp)));
			MIPI_OUTP(MIPI_DSI_BASE + 0x28,
				(vspw + vbp + height + dummy_yres +
					vfp - 1) << 16 | (hspw + hbp +
					width + dummy_xres + hfp - 1));
		} else {
			/* DSI_LAN_SWAP_CTRL */
			MIPI_OUTP(MIPI_DSI_BASE + 0x00ac, mipi->dlane_swap);

			MIPI_OUTP(MIPI_DSI_BASE + 0x20,
				((hbp + width + dummy_xres) << 16 | (hbp)));
			MIPI_OUTP(MIPI_DSI_BASE + 0x24,
				((vbp + height + dummy_yres) << 16 | (vbp)));
			MIPI_OUTP(MIPI_DSI_BASE + 0x28,
				(vbp + height + dummy_yres + vfp) << 16 |
					(hbp + width + dummy_xres + hfp));
		}

		MIPI_OUTP(MIPI_DSI_BASE + 0x2c, (hspw << 16));
		MIPI_OUTP(MIPI_DSI_BASE + 0x30, 0);
		MIPI_OUTP(MIPI_DSI_BASE + 0x34, (vspw << 16));

	} else {		/* command mode */
		if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB888)
			bpp = 3;
		else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB666)
			bpp = 3;
		else if (mipi->dst_format == DSI_CMD_DST_FORMAT_RGB565)
			bpp = 2;
		else
			bpp = 3;	/* Default format set to RGB888 */

		ystride = width * bpp + 1;

		/* DSI_COMMAND_MODE_MDP_STREAM_CTRL */
		data = (ystride << 16) | (mipi->vc << 8) | DTYPE_DCS_LWRITE;
		MIPI_OUTP(MIPI_DSI_BASE + 0x5c, data);
		MIPI_OUTP(MIPI_DSI_BASE + 0x54, data);

		/* DSI_COMMAND_MODE_MDP_STREAM_TOTAL */
		data = height << 16 | width;
		MIPI_OUTP(MIPI_DSI_BASE + 0x60, data);
		MIPI_OUTP(MIPI_DSI_BASE + 0x58, data);
	}

	mipi_dsi_host_init(mipi);

	if (mipi->force_clk_lane_hs) {
		u32 tmp;

		tmp = MIPI_INP(MIPI_DSI_BASE + 0xA8);
		tmp |= (1<<28);
		MIPI_OUTP(MIPI_DSI_BASE + 0xA8, tmp);
		wmb();
	}

	if (mdp_rev >= MDP_REV_41)
		mutex_lock(&mfd->dma->ov_mutex);
	else
		down(&mfd->dma->mutex);

	ret = panel_next_on(pdev);

	mipi_dsi_op_mode_config(mipi->mode);

	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
		if (pinfo->lcd.vsync_enable) {
			if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) {
				if (mdp_rev >= MDP_REV_41) {
					if (gpio_request(vsync_gpio,
						"MDP_VSYNC") == 0)
						gpio_direction_input(
							vsync_gpio);
					else
						pr_err("%s: unable to \
							request gpio=%d\n",
							__func__, vsync_gpio);
				} else if (mdp_rev == MDP_REV_303) {
					if (!tlmm_settings && gpio_request(
						vsync_gpio, "MDP_VSYNC") == 0) {
						ret = gpio_tlmm_config(
							GPIO_CFG(
							vsync_gpio, 1,
							GPIO_CFG_INPUT,
							GPIO_CFG_PULL_DOWN,
							GPIO_CFG_2MA),
							GPIO_CFG_ENABLE);

						if (ret) {
							pr_err(
							"%s: unable to config \
							tlmm = %d\n",
							__func__, vsync_gpio);
						}
						tlmm_settings = TRUE;

						gpio_direction_input(
							vsync_gpio);
					} else {
						if (!tlmm_settings) {
							pr_err(
							"%s: unable to request \
							gpio=%d\n",
							__func__, vsync_gpio);
						}
					}
				}
Пример #23
0
static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char *target)
{
	struct jffs2_inode_info *f, *dir_f;
	struct jffs2_sb_info *c;
	struct inode *inode;
	struct jffs2_raw_inode *ri;
	struct jffs2_raw_dirent *rd;
	struct jffs2_full_dnode *fn;
	struct jffs2_full_dirent *fd;
	int namelen;
	uint32_t alloclen;
	int ret, targetlen = strlen(target);

	/* FIXME: If you care. We'd need to use frags for the target
	   if it grows much more than this */
	if (targetlen > 254)
		return -EINVAL;

	ri = jffs2_alloc_raw_inode();

	if (!ri)
		return -ENOMEM;

	c = JFFS2_SB_INFO(dir_i->i_sb);

	/* Try to reserve enough space for both node and dirent.
	 * Just the node will do for now, though
	 */
	namelen = dentry->d_name.len;
	ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &alloclen,
				  ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);

	if (ret) {
		jffs2_free_raw_inode(ri);
		return ret;
	}

	inode = jffs2_new_inode(dir_i, S_IFLNK | S_IRWXUGO, ri);

	if (IS_ERR(inode)) {
		jffs2_free_raw_inode(ri);
		jffs2_complete_reservation(c);
		return PTR_ERR(inode);
	}

	inode->i_op = &jffs2_symlink_inode_operations;

	f = JFFS2_INODE_INFO(inode);

	inode->i_size = targetlen;
	ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
	ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
	ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));

	ri->compr = JFFS2_COMPR_NONE;
	ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
	ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));

	fn = jffs2_write_dnode(c, f, ri, target, targetlen, ALLOC_NORMAL);

	jffs2_free_raw_inode(ri);

	if (IS_ERR(fn)) {
		/* Eeek. Wave bye bye */
		up(&f->sem);
		jffs2_complete_reservation(c);
		jffs2_clear_inode(inode);
		return PTR_ERR(fn);
	}

	/* We use f->target field to store the target path. */
	f->target = kmalloc(targetlen + 1, GFP_KERNEL);
	if (!f->target) {
		printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
		up(&f->sem);
		jffs2_complete_reservation(c);
		jffs2_clear_inode(inode);
		return -ENOMEM;
	}

	memcpy(f->target, target, targetlen + 1);
	D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->target));

	/* No data here. Only a metadata node, which will be
	   obsoleted by the first data write
	*/
	f->metadata = fn;
	up(&f->sem);

	jffs2_complete_reservation(c);

	ret = jffs2_init_security(inode, dir_i);
	if (ret) {
		jffs2_clear_inode(inode);
		return ret;
	}
	ret = jffs2_init_acl(inode, dir_i);
	if (ret) {
		jffs2_clear_inode(inode);
		return ret;
	}

	ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &alloclen,
				  ALLOC_NORMAL, JFFS2_SUMMARY_DIRENT_SIZE(namelen));
	if (ret) {
		/* Eep. */
		jffs2_clear_inode(inode);
		return ret;
	}

	rd = jffs2_alloc_raw_dirent();
	if (!rd) {
		/* Argh. Now we treat it like a normal delete */
		jffs2_complete_reservation(c);
		jffs2_clear_inode(inode);
		return -ENOMEM;
	}

	dir_f = JFFS2_INODE_INFO(dir_i);
	down(&dir_f->sem);

	rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
	rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
	rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
	rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));

	rd->pino = cpu_to_je32(dir_i->i_ino);
	rd->version = cpu_to_je32(++dir_f->highest_version);
	rd->ino = cpu_to_je32(inode->i_ino);
	rd->mctime = cpu_to_je32(get_seconds());
	rd->nsize = namelen;
	rd->type = DT_LNK;
	rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
	rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));

	fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, ALLOC_NORMAL);

	if (IS_ERR(fd)) {
		/* dirent failed to write. Delete the inode normally
		   as if it were the final unlink() */
		jffs2_complete_reservation(c);
		jffs2_free_raw_dirent(rd);
		up(&dir_f->sem);
		jffs2_clear_inode(inode);
		return PTR_ERR(fd);
	}

	dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));

	jffs2_free_raw_dirent(rd);

	/* Link the fd into the inode's list, obsoleting an old
	   one if necessary. */
	jffs2_add_fd_to_list(c, fd, &dir_f->dents);

	up(&dir_f->sem);
	jffs2_complete_reservation(c);

	d_instantiate(dentry, inode);
	return 0;
}
static int mipi_dsi_off(struct platform_device *pdev)
{
	int ret = 0;
	struct msm_fb_data_type *mfd;
	struct msm_panel_info *pinfo;

	mfd = platform_get_drvdata(pdev);
	pinfo = &mfd->panel_info;

	if (mdp_rev >= MDP_REV_41)
		mutex_lock(&mfd->dma->ov_mutex);
	else
		down(&mfd->dma->mutex);

	mdp4_overlay_dsi_state_set(ST_DSI_SUSPEND);

	/*
	 * Description: dsi clock is need to perform shutdown.
	 * mdp4_dsi_cmd_dma_busy_wait() will enable dsi clock if disabled.
	 * also, wait until dma (overlay and dmap) finish.
	 */
	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
		if (mdp_rev >= MDP_REV_41) {
			mdp4_dsi_cmd_dma_busy_wait(mfd);
			mdp4_dsi_blt_dmap_busy_wait(mfd);
			mipi_dsi_mdp_busy_wait(mfd);
		} else {
			mdp3_dsi_cmd_dma_busy_wait(mfd);
		}
	} else {
		/* video mode, wait until fifo cleaned */
		mipi_dsi_controller_cfg(0);
	}

	/*
	 * Desctiption: change to DSI_CMD_MODE since it needed to
	 * tx DCS dsiplay off comamnd to panel
	 */
	mipi_dsi_op_mode_config(DSI_CMD_MODE);

	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
		if (pinfo->lcd.vsync_enable) {
			if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) {
				if (MDP_REV_303 != mdp_rev)
					gpio_free(vsync_gpio);
			}
			mipi_dsi_set_tear_off(mfd);
		}
	}

	ret = panel_next_off(pdev);

#ifdef CONFIG_MSM_BUS_SCALING
	mdp_bus_scale_update_request(0);
#endif

	local_bh_disable();
	mipi_dsi_clk_disable();
	local_bh_enable();

	/* disbale dsi engine */
	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, 0);

	mipi_dsi_phy_ctrl(0);


	local_bh_disable();
	mipi_dsi_ahb_ctrl(0);
	local_bh_enable();

	mipi_dsi_unprepare_clocks();
	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
		mipi_dsi_pdata->dsi_power_save(0);

	if (mdp_rev >= MDP_REV_41)
		mutex_unlock(&mfd->dma->ov_mutex);
	else
		up(&mfd->dma->mutex);

	pr_debug("%s-:\n", __func__);

	return ret;
}
Пример #25
0
static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
                        struct inode *new_dir_i, struct dentry *new_dentry)
{
	int ret;
	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
	struct jffs2_inode_info *victim_f = NULL;
	uint8_t type;
	uint32_t now;

	/* The VFS will check for us and prevent trying to rename a
	 * file over a directory and vice versa, but if it's a directory,
	 * the VFS can't check whether the victim is empty. The filesystem
	 * needs to do that for itself.
	 */
	if (new_dentry->d_inode) {
		victim_f = JFFS2_INODE_INFO(new_dentry->d_inode);
		if (S_ISDIR(new_dentry->d_inode->i_mode)) {
			struct jffs2_full_dirent *fd;

			down(&victim_f->sem);
			for (fd = victim_f->dents; fd; fd = fd->next) {
				if (fd->ino) {
					up(&victim_f->sem);
					return -ENOTEMPTY;
				}
			}
			up(&victim_f->sem);
		}
	}

	/* XXX: We probably ought to alloc enough space for
	   both nodes at the same time. Writing the new link,
	   then getting -ENOSPC, is quite bad :)
	*/

	/* Make a hard link */

	/* XXX: This is ugly */
	type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
	if (!type) type = DT_REG;

	now = get_seconds();
	ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
			    old_dentry->d_inode->i_ino, type,
			    new_dentry->d_name.name, new_dentry->d_name.len, now);

	if (ret)
		return ret;

	if (victim_f) {
		/* There was a victim. Kill it off nicely */
		drop_nlink(new_dentry->d_inode);
		/* Don't oops if the victim was a dirent pointing to an
		   inode which didn't exist. */
		if (victim_f->inocache) {
			down(&victim_f->sem);
			victim_f->inocache->nlink--;
			up(&victim_f->sem);
		}
	}

	/* If it was a directory we moved, and there was no victim,
	   increase i_nlink on its new parent */
	if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
		inc_nlink(new_dir_i);

	/* Unlink the original */
	ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
			      old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);

	/* We don't touch inode->i_nlink */

	if (ret) {
		/* Oh shit. We really ought to make a single node which can do both atomically */
		struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
		down(&f->sem);
		inc_nlink(old_dentry->d_inode);
		if (f->inocache)
			f->inocache->nlink++;
		up(&f->sem);

		printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
		/* Might as well let the VFS know */
		d_instantiate(new_dentry, old_dentry->d_inode);
		atomic_inc(&old_dentry->d_inode->i_count);
		new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
		return ret;
	}

	if (S_ISDIR(old_dentry->d_inode->i_mode))
		drop_nlink(old_dir_i);

	new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);

	return 0;
}
Пример #26
0
int nvram_commit(int index)
{
	unsigned long to;
	int i, len;
	char *p;

	RANV_CHECK_INDEX(-1);

	down(&nvram_sem);
	RANV_CHECK_VALID();

	if (!fb[index].dirty) {
		RANV_PRINT("nothing to be committed\n");
		up(&nvram_sem);
		return 0;
	}

	//construct env block
	len = fb[index].flash_max_len - sizeof(fb[index].env.crc);
	if (!fb[index].env.data) {
		fb[index].env.data = (char *)kmalloc(len, GFP_KERNEL);
		if (!fb[index].env.data)
			return -ENOMEM;
	}
	memset(fb[index].env.data, 0, len);
	p = fb[index].env.data;
	for (i = 0; i < MAX_CACHE_ENTRY; i++) {
		int l;

		if (!fb[index].cache[i].name || !fb[index].cache[i].value)
			break;
		l = strlen(fb[index].cache[i].name) + strlen(fb[index].cache[i].value) + 2;
		if (p - fb[index].env.data + 2 >= fb[index].flash_max_len) {
			RANV_ERROR("ENV_BLK_SIZE 0x%x is not enough!", ENV_BLK_SIZE);
			up(&nvram_sem);
			return -1;
		}
		snprintf(p, l, "%s=%s", fb[index].cache[i].name, fb[index].cache[i].value);
		p += l;
	}

	*p = '\0'; //ending null

	//calculate crc
	fb[index].env.crc = (unsigned long)nv_crc32(0, (unsigned char *)fb[index].env.data, len);

	//write crc to flash
	to = fb[index].flash_offset;
	len = sizeof(fb[index].env.crc);
	ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)&fb[index].env.crc);

	//write data to flash
	to = to + len;
	len = fb[index].flash_max_len - len;
	ra_mtd_write_nm(RALINK_NVRAM_MTDNAME, to, len, (unsigned char *)fb[index].env.data);

	fb[index].dirty = 0;

	up(&nvram_sem);

	return 0;
}
Пример #27
0
static ssize_t devinfo_read_file(struct file *file, char __user *userbuf,
				 size_t count, loff_t *ppos)
{
	const size_t len = REALLY_BIG_BUFFER_SIZE;

	struct bcm43xx_private *bcm = file->private_data;
	char *buf = really_big_buffer;
	size_t pos = 0;
	ssize_t res;
	struct net_device *net_dev;
	struct pci_dev *pci_dev;
	unsigned long flags;
	u16 tmp16;
	int i;

	down(&big_buffer_sem);

	bcm43xx_lock_mmio(bcm, flags);
	if (!bcm->initialized) {
		fappend("Board not initialized.\n");
		goto out;
	}
	net_dev = bcm->net_dev;
	pci_dev = bcm->pci_dev;

	/* This is where the information is written to the "devinfo" file */
	fappend("*** %s devinfo ***\n", net_dev->name);
	fappend("vendor:           0x%04x   device:           0x%04x\n",
		pci_dev->vendor, pci_dev->device);
	fappend("subsystem_vendor: 0x%04x   subsystem_device: 0x%04x\n",
		pci_dev->subsystem_vendor, pci_dev->subsystem_device);
	fappend("IRQ: %d\n", bcm->irq);
	fappend("mmio_addr: 0x%p   mmio_len: %u\n", bcm->mmio_addr, bcm->mmio_len);
	fappend("chip_id: 0x%04x   chip_rev: 0x%02x\n", bcm->chip_id, bcm->chip_rev);
	if ((bcm->core_80211[0].rev >= 3) && (bcm43xx_read32(bcm, 0x0158) & (1 << 16)))
		fappend("Radio disabled by hardware!\n");
	if ((bcm->core_80211[0].rev < 3) && !(bcm43xx_read16(bcm, 0x049A) & (1 << 4)))
		fappend("Radio disabled by hardware!\n");
	fappend("board_vendor: 0x%04x   board_type: 0x%04x\n", bcm->board_vendor,
	        bcm->board_type);

	fappend("\nCores:\n");
#define fappend_core(name, info) fappend("core \"" name "\" %s, %s, id: 0x%04x, "	\
					 "rev: 0x%02x, index: 0x%02x\n",		\
					 (info).available				\
						? "available" : "nonavailable",		\
					 (info).enabled					\
						? "enabled" : "disabled",		\
					 (info).id, (info).rev, (info).index)
	fappend_core("CHIPCOMMON", bcm->core_chipcommon);
	fappend_core("PCI", bcm->core_pci);
	fappend_core("first 80211", bcm->core_80211[0]);
	fappend_core("second 80211", bcm->core_80211[1]);
#undef fappend_core
	tmp16 = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
	fappend("LEDs: ");
	for (i = 0; i < BCM43xx_NR_LEDS; i++)
		fappend("%d ", !!(tmp16 & (1 << i)));
	fappend("\n");

out:
	bcm43xx_unlock_mmio(bcm, flags);
	res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
	up(&big_buffer_sem);
	return res;
}
Пример #28
0
void napi_disable() {
  napi_enabled = 0;
  down(napi_sem);
}
Пример #29
0
static int rec_thread( void *arg )
{
	struct snd_pcm_substream *substream = arg;
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct pcm_runtime_data *prtd = substream->runtime->private_data;
	NvError e;
	int size = 0;
	int offset = 0;
	int period_offset = 0;
	int rtbuffersize = 0;
	int buffer_to_prime = 0, buffer_in_queue = 0;
	NvAudioFxBufferDescriptor abd;
	NvAudioFxState state = NVALSA_INVALID_STATE;
	NvAudioFxPinFormatDescriptor pin_format;
	struct snd_pcm *pcm = substream->pcm;
	struct tegra_audio_data *ptscx = tegra_snd_cx[pcm->device];

	wait_for_completion(&prtd->thread_comp);
	rtbuffersize = frames_to_bytes(runtime, runtime->buffer_size);
	buffer_to_prime  = (rtbuffersize / TEGRA_DEFAULT_BUFFER_SIZE);

	for (;;) {
		switch (prtd->state) {
		case SNDRV_PCM_TRIGGER_START:
			if (state != NvAudioFxState_Run) {
				pin_format.Format.FormatTag = 1;
				pin_format.Format.SampleRate = runtime->rate;
				pin_format.Format.BitsPerSample = runtime->sample_bits;
				pin_format.Format.Channels = runtime->channels;
				pin_format.Format.ChannelMask = 0;
				pin_format.Format.ValidBitsPerSample = 0;
				pin_format.Pin = NvAudioFxSourcePin;

				e = ptscx->xrt_fxn.SetProperty(
						 prtd->stdinpath->Convert,
						 NvAudioFxPinProperty_Format,
						 sizeof(NvAudioFxPinFormatDescriptor),
						 &pin_format);
				if (e != NvSuccess) {
					snd_printk(KERN_ERR"set_property failed!\n");
				}

				e = ptscx->xrt_fxn.SetProperty(
						 prtd->stdinpath->Src,
						 NvAudioFxProperty_SampleRate,
						 sizeof(NvS32),
						 &pin_format.Format.SampleRate);
				if (e != NvSuccess) {
					snd_printk(KERN_ERR "set_property failed!\n");
				}

				state = NvAudioFxState_Run;
				ptscx->xrt_fxn.SetProperty(
						 prtd->stdinpath->Stream,
						 NvAudioFxProperty_State,
						 sizeof(NvAudioFxState),
						 &state);
			}
			break;
		case SNDRV_PCM_TRIGGER_STOP:
			if (state != NvAudioFxState_Stop) {
				state = NvAudioFxState_Stop;
				ptscx->xrt_fxn.SetProperty(
						 prtd->stdinpath->Stream,
						 NvAudioFxProperty_State,
						 sizeof(NvAudioFxState),
						 &state);
				down(&prtd->stop_done_sem);
				buffer_in_queue = 0;
			}
			goto EXIT;
		default:
			;
		}

		if ((state == NvAudioFxState_Run) &&
			(buffer_in_queue < buffer_to_prime)) {
			memset(&abd, 0, sizeof(NvAudioFxBufferDescriptor));

			size = TEGRA_DEFAULT_BUFFER_SIZE;
			if ((offset + size) > rtbuffersize) {
				size = rtbuffersize - offset;
			}

			abd.hMixBuffer = prtd->mixer_buffer;
			abd.Offset = offset;
			abd.Size = size;
			abd.Format.FormatTag = 1;
			abd.Format.SampleRate = runtime->rate;
			abd.Format.BitsPerSample = runtime->sample_bits;
			abd.Format.Channels = runtime->channels;
			abd.Format.ChannelMask = 0;

			e = ptscx->xrt_fxn.StreamAddBuffer(
				(NvAudioFxStreamHandle)prtd->stdinpath->Stream, &abd);
			buffer_in_queue++;
			offset += size;

			if (offset >= rtbuffersize)
				offset =0;
		}

		if ((buffer_to_prime == buffer_in_queue) &&
		    ((runtime->status->hw_ptr - runtime->control->appl_ptr) <
		    (runtime->buffer_size -runtime->period_size))) {
			down(&prtd->buf_done_sem);

			buffer_in_queue--;

			if ((frames_to_bytes(runtime, prtd->cur_pos) +
				TEGRA_DEFAULT_BUFFER_SIZE) > rtbuffersize) {
				size = rtbuffersize -
				       frames_to_bytes(runtime, prtd->cur_pos);
			} else {
				size = TEGRA_DEFAULT_BUFFER_SIZE;
			}

			prtd->cur_pos += bytes_to_frames(runtime, size);

			if (prtd->cur_pos < prtd->last_pos) {
				period_offset = (runtime->buffer_size +
						prtd->cur_pos) - prtd->last_pos;
			} else {
				period_offset = prtd->cur_pos - prtd->last_pos;
			}

			if (period_offset >= runtime->period_size) {
				prtd->last_pos = prtd->cur_pos;
				snd_pcm_period_elapsed(substream);
			}

			if (prtd->cur_pos >= runtime->buffer_size) {
				prtd->cur_pos -= runtime->buffer_size;
			}
		}
	}
EXIT:

	while (!kthread_should_stop()) {
	}

	return 0;
}
Пример #30
0
static int mipi_dsi_off(struct platform_device *pdev)
{
	int ret = 0;
	struct msm_fb_data_type *mfd;
	struct msm_panel_info *pinfo;

	pr_debug("%s+:\n", __func__);

	mfd = platform_get_drvdata(pdev);
	pinfo = &mfd->panel_info;

	if (mdp_rev >= MDP_REV_41)
		mutex_lock(&mfd->dma->ov_mutex);
	else
		down(&mfd->dma->mutex);

#if defined(FEATURE_SKYDISP_DISPLAY_FLICKER_SHARP_IPS)
	//printk(KERN_ERR "[SKY_LCD] %s : %d\n", __FUNCTION__, __LINE__);
	ret = panel_next_off(pdev);
#endif

	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
		mipi_dsi_prepare_clocks();
		mipi_dsi_ahb_ctrl(1);
		mipi_dsi_clk_enable();

		/* make sure dsi_cmd_mdp is idle */
		mipi_dsi_cmd_mdp_busy();
	}

	/*
	 * Desctiption: change to DSI_CMD_MODE since it needed to
	 * tx DCS dsiplay off comamnd to panel
	 */
	mipi_dsi_op_mode_config(DSI_CMD_MODE);

	if (mfd->panel_info.type == MIPI_CMD_PANEL) {
		if (pinfo->lcd.vsync_enable) {
			if (pinfo->lcd.hw_vsync_mode && vsync_gpio >= 0) {
				if (MDP_REV_303 != mdp_rev)
					gpio_free(vsync_gpio);
			}
			mipi_dsi_set_tear_off(mfd);
		}
	}

#if defined(FEATURE_SKYDISP_DISPLAY_FLICKER_SHARP_IPS) 
	/* panel_next_off changed : set before mipi_clock/mode_config etc... */
#else
	ret = panel_next_off(pdev);
#endif

#ifdef CONFIG_MSM_BUS_SCALING
	mdp_bus_scale_update_request(0);
#endif

	mipi_dsi_clk_disable();

	/* disbale dsi engine */
	MIPI_OUTP(MIPI_DSI_BASE + 0x0000, 0);

	mipi_dsi_phy_ctrl(0);

	mipi_dsi_ahb_ctrl(0);

	mipi_dsi_unprepare_clocks();
	if (mipi_dsi_pdata && mipi_dsi_pdata->dsi_power_save)
		mipi_dsi_pdata->dsi_power_save(0);

	if (mdp_rev >= MDP_REV_41)
		mutex_unlock(&mfd->dma->ov_mutex);
	else
		up(&mfd->dma->mutex);

	pr_debug("End of %s ....:\n", __func__);

	return ret;
}