Delete usb_printer driver.

It has been unused since 2010, when the usb_port printer transport
was rewritten to use the USBKit.

Change-Id: I224e07fb35cd9696c07b8f22dd51d3c67d92e0a9
Reviewed-on: https://review.haiku-os.org/c/869
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Augustin Cavalier
2019-01-11 17:02:21 +00:00
committed by waddlesplash
parent 315ab3328e
commit c5cb2cbd86
7 changed files with 0 additions and 705 deletions
-1
View File
@@ -73,7 +73,6 @@ AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
AddDriversToPackage bus : usb_raw fw_raw@x86 ;
AddDriversToPackage disk floppy : pc_floppy@x86 ;
AddDriversToPackage disk usb : usb_disk ;
AddDriversToPackage printer usb : usb_printer ;
AddDriversToPackage disk virtual : nbd ;
AddDriversToPackage dvb : cx23882 ;
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
-1
View File
@@ -71,7 +71,6 @@ AddDriversToPackage midi : $(SYSTEM_ADD_ONS_DRIVERS_MIDI) ;
AddDriversToPackage bus : usb_raw fw_raw@x86 ;
AddDriversToPackage disk floppy : pc_floppy@x86 ;
AddDriversToPackage disk usb : usb_disk ;
AddDriversToPackage printer usb : usb_printer ;
AddDriversToPackage disk virtual : nbd ;
AddDriversToPackage graphics : $(SYSTEM_ADD_ONS_DRIVERS_GRAPHICS) ;
AddDriversToPackage input : ps2_hid usb_hid wacom ;
-1
View File
@@ -15,7 +15,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers misc ;
SubInclude HAIKU_TOP src add-ons kernel drivers network ;
SubInclude HAIKU_TOP src add-ons kernel drivers ports ;
SubInclude HAIKU_TOP src add-ons kernel drivers power ;
SubInclude HAIKU_TOP src add-ons kernel drivers printer ;
SubInclude HAIKU_TOP src add-ons kernel drivers timer ;
SubInclude HAIKU_TOP src add-ons kernel drivers tty ;
SubInclude HAIKU_TOP src add-ons kernel drivers video ;
@@ -1,3 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel drivers printer ;
SubInclude HAIKU_TOP src add-ons kernel drivers printer usb ;
@@ -1,8 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel drivers printer usb ;
SubDirSysHdrs $(HAIKU_TOP) src add-ons kernel bus_managers usb ;
UsePrivateKernelHeaders ;
KernelAddon usb_printer :
usb_printer.cpp
;
@@ -1,632 +0,0 @@
/*
* Copyright 2008-2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <[email protected]>
* Michael Pfeiffer <[email protected]>
*/
#include <ByteOrder.h>
#include <KernelExport.h>
#include <Drivers.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include "usb_printer.h"
#include "USB_printer.h"
#define DRIVER_NAME "usb_printer"
#define DEVICE_NAME_BASE "printer/usb/"
#define DEVICE_NAME DEVICE_NAME_BASE "%" B_PRId32
#define SECONDS ((bigtime_t)1000 * 1000)
#define MINUTES (60 * SECONDS)
#define HOURS (60 * MINUTES)
// large timeout so user can fix any issues (for instance insert paper)
// before printing can start or continue
#define WRITE_TIMEOUT (1 * HOURS)
#define READ_TIMEOUT (2 * SECONDS)
// #define TRACE_USB_PRINTER 1
#ifdef TRACE_USB_PRINTER
#define TRACE(x...) dprintf(DRIVER_NAME ": " x)
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
#else
#define TRACE(x...) /* nothing */
#define TRACE_ALWAYS(x...) dprintf(DRIVER_NAME ": " x)
#endif
int32 api_version = B_CUR_DRIVER_API_VERSION;
static usb_module_info *gUSBModule = NULL;
static printer_device *gDeviceList = NULL;
static uint32 gDeviceCount = 0;
static mutex gDeviceListLock;
static char **gDeviceNames = NULL;
//
//#pragma mark - Forward Declarations
//
static void usb_printer_callback(void *cookie, status_t status, void *data,
size_t actualLength);
status_t usb_printer_transfer_data(printer_device *device, bool directionIn,
void *data, size_t dataLength);
//
//#pragma mark - Device Allocation Helper Functions
//
void
usb_printer_free_device(printer_device *device)
{
mutex_lock(&device->lock);
mutex_destroy(&device->lock);
delete_sem(device->notify);
free(device);
}
//
//#pragma mark - Bulk-only Functions
//
void
usb_printer_reset_recovery(printer_device *device)
{
gUSBModule->clear_feature(device->bulk_in, USB_FEATURE_ENDPOINT_HALT);
gUSBModule->clear_feature(device->bulk_out, USB_FEATURE_ENDPOINT_HALT);
}
status_t
usb_printer_transfer_data(printer_device *device, bool directionIn, void *data,
size_t dataLength)
{
status_t result = gUSBModule->queue_bulk(directionIn ? device->bulk_in
: device->bulk_out, data, dataLength, usb_printer_callback, device);
if (result != B_OK) {
TRACE_ALWAYS("failed to queue data transfer\n");
return result;
}
do {
bigtime_t timeout = directionIn ? READ_TIMEOUT : WRITE_TIMEOUT;
result = acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT,
timeout);
if (result == B_TIMED_OUT) {
// Cancel the transfer and collect the sem that should now be
// released through the callback on cancel. Handling of device
// reset is done in usb_printer_operation() when it detects that
// the transfer failed.
gUSBModule->cancel_queued_transfers(directionIn ? device->bulk_in
: device->bulk_out);
acquire_sem_etc(device->notify, 1, B_RELATIVE_TIMEOUT, 0);
}
} while (result == B_INTERRUPTED);
if (result != B_OK) {
TRACE_ALWAYS("acquire_sem failed while waiting for data transfer\n");
return result;
}
return B_OK;
}
//
//#pragma mark - Device Attach/Detach Notifications and Callback
//
static void
usb_printer_callback(void *cookie, status_t status, void *data,
size_t actualLength)
{
printer_device *device = (printer_device *)cookie;
device->status = status;
device->actual_length = actualLength;
release_sem(device->notify);
}
static status_t
usb_printer_device_added(usb_device newDevice, void **cookie)
{
TRACE("device_added(0x%08" B_PRIx32 ")\n", newDevice);
printer_device *device = (printer_device *)malloc(sizeof(printer_device));
device->device = newDevice;
device->removed = false;
device->open_count = 0;
device->interface = 0xff;
device->alternate_setting = 0;
// scan through the interfaces to find our bulk-only data interface
const usb_configuration_info *configuration =
gUSBModule->get_configuration(newDevice);
if (configuration == NULL) {
free(device);
return B_ERROR;
}
for (size_t i = 0; i < configuration->interface_count; i++) {
for (size_t j = 0; j < configuration->interface[i].alt_count; j++) {
usb_interface_info *interface = &configuration->interface[i].alt[j];
if (interface == NULL
|| interface->descr->interface_class != PRINTER_INTERFACE_CLASS
|| interface->descr->interface_subclass !=
PRINTER_INTERFACE_SUBCLASS
|| !(interface->descr->interface_protocol == PIT_UNIDIRECTIONAL
|| interface->descr->interface_protocol == PIT_BIDIRECTIONAL
|| interface->descr->interface_protocol
== PIT_1284_4_COMPATIBLE)) {
continue;
}
bool hasIn = false;
bool hasOut = false;
for (size_t k = 0; k < interface->endpoint_count; k++) {
usb_endpoint_info *endpoint = &interface->endpoint[k];
if (endpoint == NULL
|| endpoint->descr->attributes != USB_ENDPOINT_ATTR_BULK) {
continue;
}
if (!hasIn && (endpoint->descr->endpoint_address
& USB_ENDPOINT_ADDR_DIR_IN)) {
device->bulk_in = endpoint->handle;
hasIn = true;
} else if (!hasOut && (endpoint->descr->endpoint_address
& USB_ENDPOINT_ADDR_DIR_IN) == 0) {
device->bulk_out = endpoint->handle;
hasOut = true;
}
if (hasIn && hasOut)
break;
}
if (!(hasIn && hasOut))
continue;
device->interface = interface->descr->interface_number;
device->alternate = j;
device->alternate_setting = interface->descr->alternate_setting;
break;
}
}
if (device->interface == 0xff) {
TRACE_ALWAYS("no valid interface found\n");
free(device);
return B_ERROR;
}
status_t status = gUSBModule->set_alt_interface(newDevice,
&configuration->interface[device->interface].alt[device->alternate]);
if (status < B_OK) {
free(device);
return B_ERROR;
}
mutex_init(&device->lock, "usb_printer device lock");
device->notify = create_sem(0, "usb_printer callback notify");
if (device->notify < B_OK) {
mutex_destroy(&device->lock);
status_t result = device->notify;
free(device);
return result;
}
mutex_lock(&gDeviceListLock);
uint32 freeDeviceMask = 0;
device->device_number = 0;
printer_device *other = gDeviceList;
while (other != NULL) {
// set max device number + 1
if (other->device_number >= device->device_number)
device->device_number = other->device_number + 1;
// record used devices
if (other->device_number < 32) {
freeDeviceMask |= 1 << other->device_number;
}
other = other->link;
}
if (freeDeviceMask != (uint32)-1) {
// reuse device number of first 32 devices
for (int32 deviceNumber = 0; deviceNumber < 32; deviceNumber++) {
if ((freeDeviceMask & (1 << deviceNumber)) == 0) {
device->device_number = deviceNumber;
break;
}
}
}
device->link = gDeviceList;
gDeviceList = device;
uint32 deviceNumber = gDeviceCount++;
sprintf(device->name, DEVICE_NAME, deviceNumber);
mutex_unlock(&gDeviceListLock);
TRACE("new device: 0x%p\n", device);
*cookie = (void *)device;
return B_OK;
}
static status_t
usb_printer_device_removed(void *cookie)
{
TRACE("device_removed(0x%p)\n", cookie);
printer_device *device = (printer_device *)cookie;
mutex_lock(&gDeviceListLock);
if (gDeviceList == device) {
gDeviceList = device->link;
} else {
printer_device *element = gDeviceList;
while (element) {
if (element->link == device) {
element->link = device->link;
break;
}
element = element->link;
}
}
gDeviceCount--;
device->removed = true;
gUSBModule->cancel_queued_transfers(device->bulk_in);
gUSBModule->cancel_queued_transfers(device->bulk_out);
if (device->open_count == 0)
usb_printer_free_device(device);
mutex_unlock(&gDeviceListLock);
return B_OK;
}
//
//#pragma mark - Driver Hooks
//
static status_t
usb_printer_open(const char *name, uint32 flags, void **cookie)
{
TRACE("open(%s)\n", name);
if (strncmp(name, DEVICE_NAME_BASE, strlen(DEVICE_NAME_BASE)) != 0)
return B_NAME_NOT_FOUND;
mutex_lock(&gDeviceListLock);
printer_device *device = gDeviceList;
while (device) {
if (strncmp(name, device->name, 32) == 0) {
if (device->removed) {
mutex_unlock(&gDeviceListLock);
return B_ERROR;
}
device->open_count++;
*cookie = device;
mutex_unlock(&gDeviceListLock);
return B_OK;
}
device = device->link;
}
mutex_unlock(&gDeviceListLock);
return B_NAME_NOT_FOUND;
}
static status_t
usb_printer_close(void *cookie)
{
TRACE("close()\n");
return B_OK;
}
static status_t
usb_printer_free(void *cookie)
{
TRACE("free()\n");
mutex_lock(&gDeviceListLock);
printer_device *device = (printer_device *)cookie;
device->open_count--;
if (device->open_count == 0 && device->removed) {
// we can simply free the device here as it has been removed from
// the device list in the device removed notification hook
usb_printer_free_device(device);
}
mutex_unlock(&gDeviceListLock);
return B_OK;
}
static status_t
usb_printer_get_device_id(printer_device *device, void *buffer)
{
uint16 value = 0;
uint16 index = (device->interface << 8) | device->alternate_setting;
char device_id[USB_PRINTER_DEVICE_ID_LENGTH + 2];
size_t deviceIdSize = 0;
status_t status = gUSBModule->send_request(device->device, PRINTER_REQUEST,
REQUEST_GET_DEVICE_ID, value, index,
sizeof(device_id), device_id, &deviceIdSize);
if (status == B_OK && deviceIdSize > 2) {
// terminate string
device_id[deviceIdSize - 1] = '\0';
// skip first two bytes containing string length again
status = user_strlcpy((char *)buffer, &device_id[2],
USB_PRINTER_DEVICE_ID_LENGTH);
} else {
dprintf("%s: Failed to get device ID for interface %d "
"and alternate setting %d: %s\n",
DRIVER_NAME,
(int)device->interface,
(int)device->alternate_setting,
strerror(status));
status = user_strlcpy((char *)buffer,
"MFG:Unknown;CMD:Unknown;MDL:Unknown;",
USB_PRINTER_DEVICE_ID_LENGTH);
}
return status;
}
static status_t
usb_printer_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
{
printer_device *device = (printer_device *)cookie;
mutex_lock(&device->lock);
if (device->removed) {
mutex_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = B_DEV_INVALID_IOCTL;
switch (op) {
case USB_PRINTER_GET_DEVICE_ID: {
result = usb_printer_get_device_id(device, buffer);
break;
}
default:
TRACE_ALWAYS("unhandled ioctl %" B_PRIu32 "\n", op);
break;
}
mutex_unlock(&device->lock);
return result;
}
static status_t
usb_printer_transfer(printer_device* device, bool directionIn, void* buffer,
size_t* length)
{
status_t result = B_ERROR;
if (buffer == NULL || length == NULL || *length <= 0) {
return result;
}
result = usb_printer_transfer_data(device, directionIn, buffer, *length);
if (result != B_OK) {
return result;
}
size_t transferedData = device->actual_length;
if (device->status != B_OK || transferedData != *length) {
// sending or receiving of the data failed
if (device->status == B_DEV_STALLED) {
TRACE("stall while transfering data\n");
gUSBModule->clear_feature(directionIn ? device->bulk_in
: device->bulk_out, USB_FEATURE_ENDPOINT_HALT);
} else {
TRACE_ALWAYS("sending or receiving of the data failed\n");
usb_printer_reset_recovery(device);
return B_ERROR;
}
}
*length = transferedData;
return result;
}
static status_t
usb_printer_read(void *cookie, off_t position, void *buffer, size_t *length)
{
if (buffer == NULL || length == NULL)
return B_BAD_VALUE;
TRACE("read(%" B_PRIdOFF ", %" B_PRIuSIZE ")\n", position, *length);
printer_device *device = (printer_device *)cookie;
mutex_lock(&device->lock);
if (device->removed) {
*length = 0;
mutex_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = usb_printer_transfer(device, true, buffer, length);
mutex_unlock(&device->lock);
if (result == B_OK) {
TRACE("read successful with %" B_PRIuSIZE " bytes\n", *length);
return B_OK;
}
*length = 0;
TRACE_ALWAYS("read fails with 0x%08" B_PRIx32 "\n", result);
return result;
}
static status_t
usb_printer_write(void *cookie, off_t position, const void *buffer,
size_t *length)
{
if (buffer == NULL || length == NULL)
return B_BAD_VALUE;
TRACE("write(%" B_PRIdOFF ", %" B_PRIuSIZE ")\n", position, *length);
printer_device *device = (printer_device *)cookie;
mutex_lock(&device->lock);
if (device->removed) {
*length = 0;
mutex_unlock(&device->lock);
return B_DEV_NOT_READY;
}
status_t result = usb_printer_transfer(device, false, (void*)buffer,
length);
mutex_unlock(&device->lock);
if (result == B_OK) {
TRACE("write successful with %" B_PRIuSIZE " bytes\n", *length);
return B_OK;
}
*length = 0;
TRACE_ALWAYS("write fails with 0x%08" B_PRIx32 "\n", result);
return result;
}
//
//#pragma mark - Driver Entry Points
//
status_t
init_hardware()
{
TRACE("init_hardware()\n");
return B_OK;
}
status_t
init_driver()
{
TRACE("init_driver()\n");
static usb_notify_hooks notifyHooks = {
&usb_printer_device_added,
&usb_printer_device_removed
};
static usb_support_descriptor supportedDevices = {
PRINTER_INTERFACE_CLASS,
PRINTER_INTERFACE_SUBCLASS,
0, // any protocol
0, // any vendor
0 // any product
};
gDeviceList = NULL;
gDeviceCount = 0;
mutex_init(&gDeviceListLock, "usb_printer device list lock");
TRACE("trying module %s\n", B_USB_MODULE_NAME);
status_t result = get_module(B_USB_MODULE_NAME,
(module_info **)&gUSBModule);
if (result < B_OK) {
TRACE_ALWAYS("getting module failed 0x%08" B_PRIx32 "\n", result);
mutex_destroy(&gDeviceListLock);
return result;
}
gUSBModule->register_driver(DRIVER_NAME, &supportedDevices, 1, NULL);
gUSBModule->install_notify(DRIVER_NAME, &notifyHooks);
return B_OK;
}
void
uninit_driver()
{
TRACE("uninit_driver()\n");
gUSBModule->uninstall_notify(DRIVER_NAME);
mutex_lock(&gDeviceListLock);
if (gDeviceNames) {
for (int32 i = 0; gDeviceNames[i]; i++)
free(gDeviceNames[i]);
free(gDeviceNames);
gDeviceNames = NULL;
}
mutex_destroy(&gDeviceListLock);
put_module(B_USB_MODULE_NAME);
}
const char **
publish_devices()
{
TRACE("publish_devices()\n");
if (gDeviceNames) {
for (int32 i = 0; gDeviceNames[i]; i++)
free(gDeviceNames[i]);
free(gDeviceNames);
gDeviceNames = NULL;
}
gDeviceNames = (char **)malloc(sizeof(char *) * (gDeviceCount + 1));
if (gDeviceNames == NULL)
return NULL;
int32 index = 0;
mutex_lock(&gDeviceListLock);
printer_device *device = gDeviceList;
while (device) {
gDeviceNames[index++] = strdup(device->name);
device = device->link;
}
gDeviceNames[index++] = NULL;
mutex_unlock(&gDeviceListLock);
return (const char **)gDeviceNames;
}
device_hooks *
find_device(const char *name)
{
TRACE("find_device()\n");
static device_hooks hooks = {
&usb_printer_open,
&usb_printer_close,
&usb_printer_free,
&usb_printer_ioctl,
&usb_printer_read,
&usb_printer_write,
NULL,
NULL,
NULL,
NULL
};
return &hooks;
}
@@ -1,59 +0,0 @@
/*
* Copyright 2009, Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Michael Lotz <[email protected]>
* Michael Pfeiffer <[email protected]>
*/
#ifndef _USB_PRINTER_H_
#define _USB_PRINTER_H_
#include <lock.h>
#include <USB3.h>
#define PRINTER_INTERFACE_CLASS 0x07
#define PRINTER_INTERFACE_SUBCLASS 0x01
// printer interface types
#define PIT_UNIDIRECTIONAL 0x01
#define PIT_BIDIRECTIONAL 0x02
#define PIT_1284_4_COMPATIBLE 0x03
#define PIT_VENDOR_SPECIFIC 0xff
// class specific requests
// bmRequestType
#define PRINTER_REQUEST (USB_REQTYPE_INTERFACE_IN \
| USB_REQTYPE_CLASS)
// bRequest
#define REQUEST_GET_DEVICE_ID 0x00
#define REQUEST_GET_PORT_STATUS 0x01
#define REQUEST_SOFT_RESET 0x02
typedef struct printer_device_s {
usb_device device;
uint32 device_number;
bool removed;
uint32 open_count;
mutex lock;
struct printer_device_s *
link;
// device state
usb_pipe bulk_in;
usb_pipe bulk_out;
uint8 interface;
uint8 alternate;
uint8 alternate_setting;
// used to store callback information
sem_id notify;
status_t status;
size_t actual_length;
char name[32];
} printer_device;
#endif // _USB_PRINTER_H_