示例#1
0
/*
 * is called at user ioctl() with cmd = PCAN_READ_MSG
 */
static int pcan_ioctl_read(struct file *filep, struct pcandev *dev, 
								TPCANRdMsg *usr)
{
	int err = 0;
	TPCANRdMsg msg;

	//DPRINTK(KERN_DEBUG "%s: pcan_ioctl(PCAN_READ_MSG)\n", DEVICE_NAME);

	/* support nonblocking read if requested */
	if ((filep->f_flags & O_NONBLOCK) && (pcan_fifo_empty(&dev->readFifo)))
		return -EAGAIN;

	/* sleep until data are available */
	err = wait_event_interruptible(dev->read_queue, 
					!dev->ucPhysicallyInstalled || 
					!pcan_fifo_empty(&dev->readFifo));
	if (err)
		goto fail;

	/* if the device is plugged out */
	if (!dev->ucPhysicallyInstalled)
		return -ENODEV;

	/* get data out of fifo */
	err = pcan_fifo_get(&dev->readFifo, (void *)&msg);
	if (err) 
		goto fail;

	if (copy_to_user(usr, &msg, sizeof(*usr)))
		err = -EFAULT;

fail:
	return err;
}
示例#2
0
//----------------------------------------------------------------------------
// is called at user ioctl() with cmd = PCAN_DIAG
int pcan_ioctl_diag_common(struct pcandev *dev, TPDIAG *local)
{
	local->wType = dev->wType;

	switch (dev->wType) {
	case HW_ISA_SJA:
		local->dwBase = dev->port.isa.dwPort;
		local->wIrqLevel = dev->port.isa.wIrq;
		break;
	case HW_DONGLE_SJA:
	case HW_DONGLE_SJA_EPP:
		local->dwBase = dev->port.dng.dwPort;
		local->wIrqLevel = dev->port.dng.wIrq;
		break;
	case HW_PCI:
		local->dwBase = dev->port.pci.dwPort;
		local->wIrqLevel = dev->port.pci.wIrq;
		break;
	case HW_USB:
	case HW_USB_FD:
	case HW_USB_PRO:
	case HW_USB_PRO_FD:
#ifdef USB_SUPPORT
		local->dwBase = dev->port.usb.usb_if->dwSerialNumber;
		local->wIrqLevel = dev->port.usb.ucHardcodedDevNr;
#endif
		break;
	case HW_PCCARD:
#ifdef PCCARD_SUPPORT
		local->dwBase = dev->port.pccard.dwPort;
		local->wIrqLevel = dev->port.pccard.wIrq;
#endif
		break;
	}

	local->dwReadCounter = dev->readFifo.dwTotal;
	local->dwWriteCounter = dev->writeFifo.dwTotal;
	local->dwIRQcounter = dev->dwInterruptCounter;
	local->dwErrorCounter = dev->dwErrorCounter;
	local->wErrorFlag = dev->wCANStatus;

	// get infos for friends of polling operation
	if (pcan_fifo_empty(&dev->readFifo))
		local->wErrorFlag |= CAN_ERR_QRCVEMPTY;

	if (!pcan_fifo_not_full(&dev->writeFifo))
		local->wErrorFlag |= CAN_ERR_QXMTFULL;

	local->nLastError = dev->nLastError;
	local->nOpenPaths = dev->nOpenPaths;

	strncpy(local->szVersionString,
			pcan_drv.szVersionString, VERSIONSTRING_LEN);
	return 0;
}
示例#3
0
//----------------------------------------------------------------------------
// is called at user ioctl() with cmd = PCAN_GET_STATUS
int pcan_ioctl_status_common(struct pcandev *dev, TPSTATUS *local)
{
	local->wErrorFlag = dev->wCANStatus;

	// get infos for friends of polling operation
	if (pcan_fifo_empty(&dev->readFifo))
		local->wErrorFlag |= CAN_ERR_QRCVEMPTY;

	if (!pcan_fifo_not_full(&dev->writeFifo))
		local->wErrorFlag |= CAN_ERR_QXMTFULL;

	local->nLastError = dev->nLastError;

	return 0;
}
示例#4
0
//----------------------------------------------------------------------------
// is called at poll or select
static unsigned int pcan_poll(struct file *filep, poll_table *wait)
{
  struct fileobj *fobj = (struct fileobj *)filep->private_data;
  struct pcandev *dev  = fobj->dev;
  unsigned int mask = 0;

  poll_wait(filep, &dev->read_queue,  wait);
  poll_wait(filep, &dev->write_queue, wait);

  // return on ops that could be performed without blocking
  if (!pcan_fifo_empty(&dev->readFifo))    mask |= (POLLIN  | POLLRDNORM);
  if (pcan_fifo_not_full(&dev->writeFifo)) mask |= (POLLOUT | POLLWRNORM);

  return mask;
}
示例#5
0
//----------------------------------------------------------------------------
// is called at user ioctl() with cmd = PCAN_GET_EXT_STATUS
int pcan_ioctl_extended_status_common(struct pcandev *dev, 
					TPEXTENDEDSTATUS *local)
{
	local->wErrorFlag = dev->wCANStatus;

	local->nPendingReads = dev->readFifo.nStored;

	// get infos for friends of polling operation
	if (pcan_fifo_empty(&dev->readFifo))
		local->wErrorFlag |= CAN_ERR_QRCVEMPTY;

	local->nPendingWrites = (dev->writeFifo.nStored + \
				((atomic_read(&dev->DataSendReady)) ? 0 : 1));

	if (!pcan_fifo_not_full(&dev->writeFifo))
		local->wErrorFlag |= CAN_ERR_QXMTFULL;

	local->nLastError = dev->nLastError;

	return 0;
}
示例#6
0
/*
 * is called when read from the path
 */
static ssize_t pcan_read(struct file *filep, char *buf, size_t count, 
								loff_t *f_pos)
{
	int err;
	int len = 0;
	TPCANRdMsg msg;
	struct fileobj *fobj = (struct fileobj *)filep->private_data;
	struct pcandev *dev = fobj->dev;

	// DPRINTK(KERN_DEBUG "%s: pcan_read().\n", DEVICE_NAME);

	/* check whether this device is always linked. */
	if (!pcan_is_device_in_list(dev))
		return -ENODEV;

	/* if the device is plugged out */
	if (!dev->ucPhysicallyInstalled)
		return -ENODEV;

	if (fobj->nReadRest <= 0) {

		/* support nonblocking read if requested */
		if ((filep->f_flags & O_NONBLOCK) && 
					(pcan_fifo_empty(&dev->readFifo)))
			return -EAGAIN;

		/* sleep until data are available */
		err = wait_event_interruptible(dev->read_queue, 
					!dev->ucPhysicallyInstalled || 
					!pcan_fifo_empty(&dev->readFifo));
		if (err)
			return err;

		/* if the device is plugged out */
		if (!dev->ucPhysicallyInstalled)
			return -ENODEV;

		/* get read data out of FIFO */
		err = pcan_fifo_get(&dev->readFifo, &msg);
		if (err)
			return err;

		fobj->nReadRest = pcan_make_output(fobj->pcReadBuffer, &msg);
		fobj->pcReadPointer = fobj->pcReadBuffer;
	}

	/* give the data to the user */
	if (count > fobj->nReadRest) {
		/* put all data to user */
		len = fobj->nReadRest;
		fobj->nReadRest = 0;
		if (copy_to_user(buf, fobj->pcReadPointer, len))
			return -EFAULT;
		fobj->pcReadPointer = fobj->pcReadBuffer;
	} else {
		/* put only partial data to user */
		len = count;
		fobj->nReadRest -= count;
		if (copy_to_user(buf, fobj->pcReadPointer, len))
			return -EFAULT;
		fobj->pcReadPointer = (u8 *)((u8*)fobj->pcReadPointer + len);
	}

	*f_pos += len;
	fobj->nTotalReadCount += len;

	// DPRINTK(KERN_DEBUG "%s: pcan_read() is OK\n", DEVICE_NAME);

	return len;
}