546e863132
- enhanced pkg-message. PR: 100413 Submitted by: Anish Mistry <amistry at am-productions.biz> (maintainer)
262 lines
7.1 KiB
C++
262 lines
7.1 KiB
C++
--- io/hpiod/device.cpp.orig Thu Jun 15 02:02:11 2006
|
|
+++ io/hpiod/device.cpp Sun Jul 16 16:57:30 2006
|
|
@@ -25,6 +25,9 @@
|
|
\*****************************************************************************/
|
|
|
|
#include "hpiod.h"
|
|
+#ifdef __FreeBSD__
|
|
+#include <dev/usb/usb.h>
|
|
+#endif
|
|
|
|
const unsigned char Venice_Power_On[] = {0x1b, '%','P','u','i','f','p','.',
|
|
'p','o','w','e','r',' ','1',';',
|
|
@@ -111,21 +114,240 @@
|
|
|
|
#elif defined(__FreeBSD__)
|
|
|
|
-/*
|
|
- * Anish Mistry amistry@am-productions.biz is working on libusb extensions for FreeBSD. His current implementation does not handle device exceptions (ie: paperout).
|
|
- * Once this issue is resolved we will be glade to add his code to the project.
|
|
- */
|
|
-
|
|
int Device::Write(int fd, const void *buf, int size)
|
|
{
|
|
- syslog(LOG_ERR, "error Write: unimplemented (freebsd) %s %s %d\n", URI, __FILE__, __LINE__);
|
|
- return -1;
|
|
+ int nwrote, total, write_len, r, ep, endpoint_fd;
|
|
+ void *tmp_buf = (void *)buf;
|
|
+ fd_set ready;
|
|
+ char *pEndPoint = NULL;
|
|
+
|
|
+ if (FD[fd].pHD == NULL)
|
|
+ {
|
|
+ syslog(LOG_ERR, "invalid Device::Write state: %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if ((ep = GetOutEP(dev, FD[fd].Config, FD[fd].Interface, FD[fd].AltSetting, USB_ENDPOINT_TYPE_BULK)) < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "invalid bulk out endpoint %s %s %d\n", URI, __FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* We only want the address, so mask out the direction bits */
|
|
+ ep = (ep & USB_ENDPOINT_ADDRESS_MASK);
|
|
+ /* open endpoint */
|
|
+ /* allocate data for the usb endpoint string */
|
|
+ pEndPoint = (char *)malloc(strlen(dev->filename)+20);
|
|
+ if(!pEndPoint)
|
|
+ return -1;
|
|
+ /* create device endpoint name string */
|
|
+ sprintf(pEndPoint, "%s.%d", dev->filename, ep);
|
|
+
|
|
+ /* open the endpoint with read write access */
|
|
+ endpoint_fd = open(pEndPoint, O_WRONLY, 0);
|
|
+ free(pEndPoint);
|
|
+ if(endpoint_fd < 0)
|
|
+ {
|
|
+ /* we failed to open the endpoint */
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ total = size;
|
|
+ write_len = size;
|
|
+
|
|
+ while (total > 0)
|
|
+ {
|
|
+ FD_ZERO(&ready);
|
|
+ FD_SET(endpoint_fd, &ready);
|
|
+
|
|
+ if (!FD_ISSET(endpoint_fd, &ready))
|
|
+ {
|
|
+ close(endpoint_fd);
|
|
+ return -1;
|
|
+ }
|
|
+ nwrote = write(endpoint_fd, tmp_buf, write_len);
|
|
+
|
|
+ if (nwrote < 0)
|
|
+ {
|
|
+ close(endpoint_fd);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ write_len -= nwrote;
|
|
+ tmp_buf = (void *)((long)tmp_buf + nwrote);
|
|
+ total -= nwrote;
|
|
+ }
|
|
+
|
|
+ close(endpoint_fd);
|
|
+ return size;
|
|
}
|
|
|
|
int Device::Read(int fd, void *buf, int size, int usec)
|
|
{
|
|
- syslog(LOG_ERR, "error Read: unimplemented (freebsd) %s %s %d\n", URI, __FILE__, __LINE__);
|
|
- return -2;
|
|
+ int nwrote, total, r, ep=0, endpoint_fd, i;
|
|
+ struct timeval t1, t2;
|
|
+ fd_set ready;
|
|
+ char *pEndPoint = NULL;
|
|
+ int bytes_want = 0;
|
|
+ int rlen = 0;
|
|
+ int bytes_read = 0;
|
|
+ int mili_timeout = usec/10;
|
|
+ unsigned char *pbuf_pos = NULL;
|
|
+ int total_usec, tmo_usec = usec;
|
|
+
|
|
+ if (FD[fd].pHD == NULL)
|
|
+ {
|
|
+ syslog(LOG_ERR, "invalid Device::Read state: %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if ((ep = GetInEP(dev, FD[fd].Config, FD[fd].Interface, FD[fd].AltSetting, USB_ENDPOINT_TYPE_BULK)) < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "invalid bulk in endpoint %s %s %d\n", URI, __FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* We only want the address, so mask out the direction bits */
|
|
+ ep = (ep & USB_ENDPOINT_ADDRESS_MASK);
|
|
+ /* open endpoint */
|
|
+ /* allocate data for the usb endpoint string */
|
|
+ pEndPoint = (char *)malloc(strlen(dev->filename)+20);
|
|
+ if(!pEndPoint)
|
|
+ return -1;
|
|
+ /* create device endpoint name string */
|
|
+ sprintf(pEndPoint, "%s.%d", dev->filename, ep);
|
|
+
|
|
+ /* open the endpoint with read write access */
|
|
+ endpoint_fd = open(pEndPoint, O_RDONLY, 0);
|
|
+ if(endpoint_fd < 0)
|
|
+ {
|
|
+ /* we failed to open the endpoint */
|
|
+ syslog(LOG_ERR, "unable to open bulk in endpoint (%s) %s %s %d\n", pEndPoint, URI, __FILE__, __LINE__);
|
|
+ free(pEndPoint);
|
|
+ return -1;
|
|
+ }
|
|
+ free(pEndPoint);
|
|
+
|
|
+ /* set short transfer so that we can allow "short" reads since we
|
|
+ will don't know exactly
|
|
+ what is coming so we can't specify exact byte amounts */
|
|
+ i = 1;
|
|
+ if (ioctl(endpoint_fd, USB_SET_SHORT_XFER, &i) < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "USB_SET_SHORT_XFER set failed Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ }
|
|
+
|
|
+ /* 0 timeout value will cause us the wait until the device has data
|
|
+ available or is disconnected */
|
|
+ if (ioctl(endpoint_fd, USB_SET_TIMEOUT, &mili_timeout) < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "USB_SET_TIMEOUT set failed Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ }
|
|
+
|
|
+ gettimeofday (&t1, NULL); /* get start time */
|
|
+
|
|
+ if (FD[fd].ucnt > 0)
|
|
+ {
|
|
+ /* copy buffered data to storage */
|
|
+ if (size <= FD[fd].ucnt)
|
|
+ {
|
|
+ memcpy(buf, FD[fd].ubuf, size);
|
|
+ FD[fd].uindex += size;
|
|
+ FD[fd].ucnt -= size;
|
|
+ bytes_read = size;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ memcpy(buf, FD[fd].ubuf, FD[fd].ucnt);
|
|
+ bytes_read += FD[fd].ucnt;
|
|
+ FD[fd].ucnt = 0;
|
|
+ }
|
|
+ }
|
|
+ else if (FD[fd].ucnt == 0 && bytes_read < size)
|
|
+ {
|
|
+ /* reset data buffer */
|
|
+ FD[fd].uindex = 0;
|
|
+ /* offset storage to not overwrite data copied from the buffer */
|
|
+ pbuf_pos = (unsigned char *)((long)buf + bytes_read);
|
|
+ bytes_want = size - bytes_read;
|
|
+ do
|
|
+ {
|
|
+ if (bytes_want >= BUFFER_SIZE)
|
|
+ {
|
|
+ /* check to see if the device is ready for a read */
|
|
+ FD_ZERO(&ready);
|
|
+ FD_SET(endpoint_fd, &ready);
|
|
+ if (!FD_ISSET(endpoint_fd, &ready))
|
|
+ {
|
|
+ syslog(LOG_ERR, "timeout Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ errno = ETIMEDOUT;
|
|
+ return -1;
|
|
+ }
|
|
+ /* read directly into storage */
|
|
+ rlen = read(endpoint_fd, pbuf_pos, BUFFER_SIZE);
|
|
+ if (rlen < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "error Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+ bytes_read += rlen;
|
|
+ bytes_want -= rlen;
|
|
+ pbuf_pos += rlen;
|
|
+ }
|
|
+ else if (bytes_want < BUFFER_SIZE)
|
|
+ {
|
|
+ /* check to see if the device is ready for a read */
|
|
+ FD_ZERO(&ready);
|
|
+ FD_SET(endpoint_fd, &ready);
|
|
+ if (!FD_ISSET(endpoint_fd, &ready))
|
|
+ {
|
|
+ syslog(LOG_ERR, "timeout Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ errno = ETIMEDOUT;
|
|
+ return -1;
|
|
+ }
|
|
+ /* read to buffer */
|
|
+ rlen = read(endpoint_fd, FD[fd].ubuf, BUFFER_SIZE);
|
|
+ if (rlen < 0)
|
|
+ {
|
|
+ syslog(LOG_ERR, "error Device::Read : %s %s %d\n", URI,__FILE__, __LINE__);
|
|
+ return -1;
|
|
+ }
|
|
+ if (rlen >= bytes_want)
|
|
+ {
|
|
+ memcpy(pbuf_pos, FD[fd].ubuf,
|
|
+ bytes_want);
|
|
+ FD[fd].uindex += bytes_want;
|
|
+ FD[fd].ucnt = rlen - bytes_want;
|
|
+ bytes_read += bytes_want;
|
|
+ bytes_want = 0;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ memcpy(pbuf_pos, FD[fd].ubuf, rlen);
|
|
+ bytes_want -= rlen;
|
|
+ bytes_read += rlen;
|
|
+ pbuf_pos += rlen;
|
|
+ }
|
|
+ }
|
|
+ /* Bulk_read has a timeout, but bulk_read can return zero byte packet(s), so we must use our own timeout here. */
|
|
+ gettimeofday(&t2, NULL); /* get current time */
|
|
+
|
|
+ total_usec = (t2.tv_sec - t1.tv_sec)*1000000;
|
|
+ total_usec += (t2.tv_usec > t1.tv_usec) ? t2.tv_usec - t1.tv_usec : t1.tv_usec - t2.tv_usec;
|
|
+ if (total_usec > usec)
|
|
+ {
|
|
+ size = -1; /* timeout */
|
|
+ errno = ETIMEDOUT;
|
|
+ break;
|
|
+ }
|
|
+ tmo_usec = usec - total_usec; /* decrease timeout */
|
|
+ continue;
|
|
+ }
|
|
+ while (bytes_want > 0);
|
|
+ }
|
|
+
|
|
+ close(endpoint_fd);
|
|
+ return size;
|
|
}
|
|
|
|
#else
|