Timer modifications, turning on debug messages, implementing more functions (but spinlocks are disabled now).

Now it detects attached device(s) and show info in debug messages.

svn path=/trunk/; revision=16800
This commit is contained in:
Aleksey Bragin 2005-07-27 14:57:33 +00:00
parent ad3464c9a6
commit 6cc3428516
8 changed files with 314 additions and 139 deletions

View file

@ -100,7 +100,7 @@ DECLARE_MUTEX (usb_bus_list_lock); /* exported only for usbfs */
EXPORT_SYMBOL_GPL (usb_bus_list_lock);
/* used when updating hcd data */
static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t hcd_data_lock;// = SPIN_LOCK_UNLOCKED;
/*-------------------------------------------------------------------------*/
@ -476,7 +476,7 @@ static int rh_status_urb (struct usb_hcd *hcd, struct urb *urb)
hcd->rh_timer.function = rh_report_status;
hcd->rh_timer.data = (unsigned long) urb;
/* USB 2.0 spec says 256msec; this is close enough */
hcd->rh_timer.expires = jiffies + HZ/4;
hcd->rh_timer.expires = HZ/4;
add_timer (&hcd->rh_timer);
urb->hcpriv = hcd; /* nonzero to indicate it's queued */
return 0;
@ -515,7 +515,7 @@ static void rh_report_status (unsigned long ptr)
urb->status = 0;
urb->hcpriv = 0;
} else
mod_timer (&hcd->rh_timer, jiffies + HZ/4);
mod_timer (&hcd->rh_timer, HZ/4);
spin_unlock (&hcd_data_lock);
spin_unlock (&urb->lock);
@ -982,7 +982,7 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
if (!hcd || !dev)
return -ENODEV;
// printk("submit_urb %p, # %i, t %i\n",urb,urb->dev->devnum,usb_pipetype(urb->pipe));
printk("submit_urb %p, # %i, t %i\n",urb,urb->dev->devnum,usb_pipetype(urb->pipe));
/*
* FIXME: make urb timeouts be generic, keeping the HCD cores
* as simple as possible.
@ -1053,10 +1053,12 @@ static int hcd_submit_urb (struct urb *urb, int mem_flags)
status = hcd->driver->urb_enqueue (hcd, urb, mem_flags);
done:
if (status) {
usb_put_urb (urb);
urb_unlink (urb);
}
return status;
}

View file

@ -42,7 +42,7 @@
#endif
/* Wakes up khubd */
//static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
static spinlock_t hub_event_lock;
//static DECLARE_MUTEX(usb_address0_sem);
static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */
@ -141,13 +141,24 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
case -ECONNRESET: /* async unlink */
case -ESHUTDOWN: /* hardware going away */
return;
case -EOVERFLOW:
if (hub->RestCounter>0) {
// we already resetted one time ...
hub->error = 0;
hub->nerrors = 0;
break;
}
hub->RestCounter++;
default: /* presumably an error */
/* Cause a hub reset after 10 consecutive errors */
//printe("hub_irq got ...: error %d URB: %d",hub->error,urb->status);
dev_dbg (&hub->intf->dev, "transfer --> %d\n", urb->status);
if ((++hub->nerrors < 10) || hub->error)
goto resubmit;
hub->error = urb->status;
/* FALL THROUGH */
/* let khubd handle things */
@ -155,6 +166,7 @@ static void hub_irq(struct urb *urb, struct pt_regs *regs)
break;
}
hub->nerrors = 0;
/* Something happened, let khubd figure it out */
@ -269,17 +281,40 @@ static void hub_power_on(struct usb_hub *hub)
{
struct usb_device *dev;
int i;
int DelayPerPort;
int DelayAfterPort;
DelayAfterPort = hub->descriptor->bPwrOn2PwrGood * 2;
DelayPerPort = 0;
switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
case 0x00:
DelayAfterPort = hub->descriptor->bPwrOn2PwrGood * 2;
DelayPerPort = 0;
break;
case 0x01:
DelayAfterPort = hub->descriptor->bPwrOn2PwrGood;
DelayPerPort = hub->descriptor->bPwrOn2PwrGood /4;
break;
case 0x02:
case 0x03:
//dev_dbg(hub_dev, "unknown reserved power switching mode\n");
break;
}
/* Enable power to the ports */
dev_dbg(hubdev(interface_to_usbdev(hub->intf)),
"enabling power on all ports\n");
dev = interface_to_usbdev(hub->intf);
for (i = 0; i < hub->descriptor->bNbrPorts; i++)
for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
wait_ms(DelayPerPort);
}
/* Wait for power to be enabled */
wait_ms(hub->descriptor->bPwrOn2PwrGood * 2);
wait_ms(DelayAfterPort);
}
static int hub_hub_status(struct usb_hub *hub,
@ -435,6 +470,9 @@ static int hub_configure(struct usb_hub *hub,
(hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND)
? "" : "not");
if (hub->descriptor->bPwrOn2PwrGood<3) hub->descriptor->bPwrOn2PwrGood = 3;
if (hub->descriptor->bPwrOn2PwrGood>20) hub->descriptor->bPwrOn2PwrGood = 20;
dev_dbg(hub_dev, "power on to power good time: %dms\n",
hub->descriptor->bPwrOn2PwrGood * 2);
dev_dbg(hub_dev, "hub controller current requirement: %dmA\n",
@ -560,27 +598,31 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
if ((desc->desc.bInterfaceSubClass != 0) &&
(desc->desc.bInterfaceSubClass != 1)) {
descriptor_error:
desc->desc.bInterfaceSubClass =0;
dev_err (&intf->dev, "bad descriptor, ignoring hub\n");
return -EIO;
//return -EIO;
}
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (desc->desc.bNumEndpoints != 1) {
goto descriptor_error;
desc->desc.bNumEndpoints = 1;
//goto descriptor_error;
}
endpoint = &desc->endpoint[0].desc;
/* Output endpoint? Curiouser and curiouser.. */
if (!(endpoint->bEndpointAddress & USB_DIR_IN)) {
goto descriptor_error;
//goto descriptor_error;
endpoint->bEndpointAddress |= USB_DIR_IN;
}
/* If it's not an interrupt endpoint, we'd better punt! */
if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
!= USB_ENDPOINT_XFER_INT) {
goto descriptor_error;
return -EIO;
endpoint->bmAttributes |= USB_ENDPOINT_XFER_INT;
//goto descriptor_error;
//return -EIO;
}
/* We found a hub */
@ -594,6 +636,8 @@ descriptor_error:
memset(hub, 0, sizeof(*hub));
hub->RestCounter = 0;
INIT_LIST_HEAD(&hub->event_list);
hub->intf = intf;
init_MUTEX(&hub->khubd_sem);
@ -606,12 +650,13 @@ descriptor_error:
usb_set_intfdata (intf, hub);
if (hub_configure(hub, endpoint) >= 0) {
if (hub_configure(hub, endpoint) >= 0)
{
strcpy (intf->dev.name, "Hub");
return 0;
}
hub_disconnect (intf);
//hub_disconnect (intf);
return -ENODEV;
}
@ -703,6 +748,9 @@ static int hub_port_status(struct usb_device *dev, int port,
struct usb_hub *hub = usb_get_intfdata (dev->actconfig->interface);
int ret;
if (!hub)
return -ENODEV;
ret = get_port_status(dev, port + 1, &hub->status->port);
if (ret < 0) {
dev_err (hubdev (dev),
@ -717,9 +765,10 @@ static int hub_port_status(struct usb_device *dev, int port,
}
#define HUB_RESET_TRIES 5
#define HUB_PROBE_TRIES 2
#define HUB_PROBE_TRIES 5
#define HUB_ROOT_RESET_TIME 40
#define HUB_SHORT_RESET_TIME 10
#define HUB_LONG_RESET_TIME 200
#define HUB_LONG_RESET_TIME 70
#define HUB_RESET_TIMEOUT 500
/* return: -1 on error, 0 on success, 1 on disconnect. */
@ -835,8 +884,8 @@ int hub_port_disable(struct usb_device *hub, int port)
*/
#define HUB_DEBOUNCE_TIMEOUT 400
#define HUB_DEBOUNCE_STEP 25
#define HUB_DEBOUNCE_STABLE 4
#define HUB_DEBOUNCE_STEP 5
#define HUB_DEBOUNCE_STABLE 3
/* return: -1 on error, 0 on success, 1 on disconnect. */
static int hub_port_debounce(struct usb_device *hub, int port)
@ -885,7 +934,11 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
struct usb_device *dev;
unsigned int delay = HUB_SHORT_RESET_TIME;
int i;
int DevcoosenAdress = 0;
//printe("port %d, status %x, change %x,\n",port + 1, portstatus, portchange);
dev_dbg (&hubstate->intf->dev,
"port %d, status %x, change %x, %s\n",
port + 1, portstatus, portchange, portspeed (portstatus));
@ -909,10 +962,17 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
dev_err (&hubstate->intf->dev,
"connect-debounce failed, port %d disabled\n",
port+1);
//printe("connect-debounce failed, port %d disabled\n", port+1);
hub_port_disable(hub, port);
return;
}
/* root hub ports have a slightly longer reset period
* (from USB 2.0 spec, section 7.1.7.5)
*/
if (!hub->parent)
delay = HUB_ROOT_RESET_TIME;
/* Some low speed devices have problems with the quick delay, so */
/* be a bit pessimistic with those devices. RHbug #23670 */
if (portstatus & USB_PORT_STAT_LOW_SPEED)
@ -932,7 +992,7 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
break;
}
hub->children[port] = dev;
dev->state = USB_STATE_POWERED;
/* Reset the device, and detect its speed */
@ -942,8 +1002,12 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
}
/* Find a new address for it */
usb_connect(dev);
if (DevcoosenAdress==0) {
usb_choose_address(dev);
DevcoosenAdress = dev->devnum;
}
dev->devnum = DevcoosenAdress ;
/* Set up TT records, if needed */
if (hub->tt) {
dev->tt = hub->tt;
@ -985,8 +1049,10 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
dev->dev.parent = dev->parent->dev.parent->parent;
/* Run it through the hoops (find a driver, etc) */
if (!usb_new_device(dev, &hub->dev))
if (!usb_new_device(dev, &hub->dev)) {
hub->children[port] = dev;
goto done;
}
/* Free the configuration if there was an error */
usb_put_dev(dev);
@ -995,7 +1061,7 @@ static void hub_port_connect_change(struct usb_hub *hubstate, int port,
delay = HUB_LONG_RESET_TIME;
}
hub->children[port] = NULL;
hub_port_disable(hub, port);
done:
up(&usb_address0_sem);
@ -1149,34 +1215,39 @@ static int STDCALL hub_thread(void *__hub)
daemonize("khubd");
allow_signal(SIGKILL);
// Initialize khubd spinlock
KeInitializeSpinLock((PKSPIN_LOCK)&hub_event_lock);
/* Send me a signal to get me die (for debugging) */
do {
LARGE_INTEGER delay;
/* The following is just for debug */
inc_jiffies(1);
do_all_timers();
handle_irqs(-1);
/* End of debug hack*/
hub_events();
/* The following is just for debug */
handle_irqs(-1);
/* End of debug hack*/
//FIXME: Correct this
//wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); // interruptable_sleep_on analog - below
//while (!list_empty(&hub_event_list)) {
// interruptible_sleep_on(&khubd_wait);
//}
delay.QuadPart = -10000*100; // convert to 100ns units
KeDelayExecutionThread(KernelMode, FALSE, &delay); //wait_us(1);
if (current->flags & PF_FREEZE)
refrigerator(PF_IOTHREAD);
} while (!signal_pending(current));
// dbg("hub_thread exiting");
dbg("hub_thread exiting");
complete_and_exit(&khubd_exited, 0);
}
@ -1361,20 +1432,24 @@ int usb_physical_reset_device(struct usb_device *dev)
return 1;
}
dev->actconfig = dev->config;
usb_set_maxpacket(dev);
usb_set_configuration(dev, dev->config[0].desc.bConfigurationValue);
return 1;
}
kfree(descriptor);
ret = usb_set_configuration(dev, dev->actconfig->desc.bConfigurationValue);
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
USB_REQ_SET_CONFIGURATION, 0,
dev->actconfig->desc.bConfigurationValue, 0,
NULL, 0, HZ * USB_CTRL_SET_TIMEOUT);
if (ret < 0) {
err("failed to set dev %s active configuration (error=%d)",
dev->devpath, ret);
return ret;
}
dev->state = USB_STATE_CONFIGURED;
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
struct usb_interface *intf = &dev->actconfig->interface[i];

View file

@ -40,6 +40,8 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
struct usb_api_data awd;
int status;
printk("usb_start_wait_urb(): urb devnum=%d, timeout=%d, urb->actual_length=%d\n", urb->dev->devnum, timeout, urb->actual_length);
init_waitqueue_head((PKEVENT)&awd.wqh);
awd.done = 0;
@ -48,6 +50,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
urb->context = &awd;
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status) {
// something went wrong
usb_free_urb(urb);
@ -55,7 +58,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
remove_wait_queue(&awd.wqh, &wait);
return status;
}
printk("TRACE 3.1, timeout=%d, awd.done=%d\n", timeout, awd.done);
while (timeout && !awd.done)
{
timeout = schedule_timeout(timeout);
@ -84,6 +87,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int* actual_length)
*actual_length = urb->actual_length;
usb_free_urb(urb);
return status;
}
@ -152,12 +156,10 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u
dr->wIndex = cpu_to_le16p(&index);
dr->wLength = cpu_to_le16p(&size);
//dbg("usb_control_msg");
printk("usb_control_msg: devnum=%d, size=%d, timeout=%d\n", dev->devnum, size, timeout);
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}

View file

@ -201,8 +201,8 @@ int STDCALL usb_submit_urb(struct urb *urb, int mem_flags)
struct usb_device *dev;
struct usb_operations *op;
int is_out;
// printk("sub dev %p bus %p num %i op %p sub %p\n",
// urb->dev, urb->dev->bus,urb->dev->devnum,urb->dev->bus->op, urb->dev->bus->op->submit_urb);
printk("sub dev %p bus %p num %i op %p sub %p\n",
urb->dev, urb->dev->bus,urb->dev->devnum,urb->dev->bus->op, urb->dev->bus->op->submit_urb);
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) ||

View file

@ -54,6 +54,7 @@
#include "hcd.h"
#endif
#define DEBUG
extern int usb_hub_init(void);
extern void usb_hub_cleanup(void);
@ -95,6 +96,9 @@ int usb_device_probe(struct device *dev)
if (!driver->probe)
return error;
/* driver claim() doesn't yet affect dev->driver... */
if (intf->driver)
return error;
id = usb_match_id (intf, driver->id_table);
if (id) {
@ -396,6 +400,14 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
{
struct usb_host_interface *intf;
struct usb_device *dev;
struct usb_device_id *save_id;
int firsttime;
firsttime = 1;
save_id = (struct usb_device_id*)id;
retry_id:
id = (struct usb_device_id*)save_id;
/* proc_connectinfo in devio.c may call us with id == NULL. */
if (id == NULL)
@ -967,6 +979,35 @@ void STDCALL usb_connect(struct usb_device *dev)
}
}
/**
* usb_choose_address - pick device address (usbcore-internal)
* @dev: newly detected device (in DEFAULT state)
*
* Picks a device address. It's up to the hub (or root hub) driver
* to handle and manage enumeration, starting from the DEFAULT state.
* Only hub drivers (but not virtual root hub drivers for host
* controllers) should ever call this.
*/
void usb_choose_address(struct usb_device *dev)
{
int devnum;
// FIXME needs locking for SMP!!
/* why? this is called only from the hub thread,
* which hopefully doesn't run on multiple CPU's simultaneously 8-)
*/
/* Try to allocate the next devnum beginning at bus->devnum_next. */
devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, dev->bus->devnum_next);
if (devnum >= 128)
devnum = find_next_zero_bit(dev->bus->devmap.devicemap, 128, 1);
dev->bus->devnum_next = ( devnum >= 127 ? 1 : devnum + 1);
if (devnum < 128) {
set_bit(devnum, dev->bus->devmap.devicemap);
dev->devnum = devnum;
}
}
// hub-only!! ... and only exported for reset/reinit path.
// otherwise used internally, for usb_new_device()
@ -1062,10 +1103,10 @@ static void set_device_description (struct usb_device *dev)
* controllers) should ever call this.
*/
#define NEW_DEVICE_RETRYS 2
#define SET_ADDRESS_RETRYS 2
#define SET_ADDRESS_RETRYS 20
int usb_new_device(struct usb_device *dev, struct device *parent)
{
int err = 0;
int err = -EINVAL;
int i;
int j;
@ -1108,7 +1149,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
i = 8;
break;
default:
return -EINVAL;
goto fail;
}
dev->epmaxpacketin [0] = i;
dev->epmaxpacketout[0] = i;
@ -1119,15 +1160,12 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
err = usb_set_address(dev);
if (err >= 0)
break;
wait_ms(200);
wait_ms(5);
}
if (err < 0) {
dev_err(&dev->dev, "USB device not accepting new address=%d (error=%d)\n",
dev->devnum, err);
dev->state = USB_STATE_DEFAULT;
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
goto fail;
}
wait_ms(10); /* Let the SET_ADDRESS settle */
@ -1140,17 +1178,13 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
}
if (err < 8) {
if (err < 0) {
dev_err(&dev->dev, "USB device not responding, giving up (error=%d)\n", err);
}
else {
dev_err(&dev->dev, "USB device descriptor short read (expected %i, got %i)\n", 8, err);
}
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
dev_err(&dev->dev, "device descriptor read/8, error %d\n", err);
goto fail;
}
if (dev->speed == USB_SPEED_FULL) {
//usb_disable_endpoint(dev, 0);
usb_endpoint_running(dev, 0, 1);
usb_endpoint_running(dev, 0, 0);
dev->epmaxpacketin [0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
}
@ -1159,26 +1193,15 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
err = usb_get_device_descriptor(dev);
if (err < (signed)sizeof(dev->descriptor)) {
if (err < 0) {
dev_err(&dev->dev, "unable to get device descriptor (error=%d)\n", err);
}
else {
dev_err(&dev->dev, "USB device descriptor short read (expected %Zi, got %i)\n",
sizeof(dev->descriptor), err);
}
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
dev_err(&dev->dev, "device descriptor read/all, error %d\n", err);
goto fail;
}
err = usb_get_configuration(dev);
if (err < 0) {
dev_err(&dev->dev, "unable to get device %d configuration (error=%d)\n",
dev->devnum, err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
dev_err(&dev->dev, "can't read configurations, error %d\n",
err);
goto fail;
}
/* we set the default configuration here */
@ -1186,9 +1209,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
if (err) {
dev_err(&dev->dev, "failed to set device %d default configuration (error=%d)\n",
dev->devnum, err);
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return 1;
goto fail;
}
/* USB device state == configured ... tell the world! */
@ -1234,7 +1255,7 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
"usb-%s-%s interface %d",
dev->bus->bus_name, dev->devpath,
desc->bInterfaceNumber);
DPRINT1("usb_new_device: %s\n", interface->dev.name);
DPRINT1(".........................usb_new_device: %s\n", interface->dev.name);
}
dev_dbg (&dev->dev, "%s - registering interface %s\n", __FUNCTION__, interface->dev.bus_id);
device_add (&interface->dev);
@ -1244,6 +1265,11 @@ int usb_new_device(struct usb_device *dev, struct device *parent)
usbfs_add_device(dev);
return 0;
fail:
dev->state = USB_STATE_DEFAULT;
clear_bit(dev->devnum, dev->bus->devmap.devicemap);
dev->devnum = -1;
return err;
}
/**

View file

@ -125,6 +125,27 @@ VOID STDCALL DriverUnload(PDRIVER_OBJECT DriverObject)
ohci_hcd_pci_cleanup();
}
void RegisterISR(PDEVICE_OBJECT DeviceObject)
{
#if 0
NTSTATUS Status;
POHCI_DEVICE_EXTENSION DeviceExtension = (POHCI_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* Connect interrupt and enable them */
Status = IoConnectInterrupt(
&DeviceExtension->InterruptObject, SerialInterruptService,
DeviceObject, NULL,
Vector, Dirql, Dirql,
InterruptMode, ShareInterrupt,
Affinity, FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("hci: IoConnectInterrupt() failed with status 0x%08x\n", Status);
return 1;
}
#endif
}
NTSTATUS
InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
{
@ -154,6 +175,9 @@ InitLinuxWrapper(PDEVICE_OBJECT DeviceObject)
// Probe device with real id now
ohci_pci_driver.probe(dev, pci_ids);
// Register interrupt here
RegisterISR(DeviceObject);
DPRINT1("InitLinuxWrapper() done\n");
return STATUS_SUCCESS;
@ -169,6 +193,9 @@ OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
POHCI_DEVICE_EXTENSION DeviceExtension;
PCM_RESOURCE_LIST AllocatedResources;
NTSTATUS Status; // debug
LONGLONG delay; // debug
/*
* Get the initialization data we saved in VideoPortInitialize.
*/
@ -236,7 +263,13 @@ OHCD_PnPStartDevice(IN PDEVICE_OBJECT DeviceObject,
/*
* Init wrapper with this object
*/
return InitLinuxWrapper(DeviceObject);
//return InitLinuxWrapper(DeviceObject);
Status = InitLinuxWrapper(DeviceObject);
delay = -10000000*60*2; // wait 2 minutes
KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&delay); //wait_us(1);
return Status;
}
// Dispatch PNP

View file

@ -34,7 +34,12 @@ typedef short s16;
typedef u32 dma_addr_t;
typedef int spinlock_t;
typedef struct
{
KSPIN_LOCK SpinLock;
KIRQL OldIrql;
} spinlock_t;
typedef int atomic_t;
#ifndef STANDALONE
#ifndef _MODE_T_
@ -156,7 +161,8 @@ struct pt_regs
};
struct completion {
unsigned int done;
wait_queue_head_t wait;
KEVENT wait;
//wait_queue_head_t wait;
};
// windows lookaside list head
@ -383,12 +389,19 @@ struct usbdevfs_hub_portinfo
#define init_MUTEX(x)
#define SPIN_LOCK_UNLOCKED 0
#define spin_lock_init(a) do {} while(0)
#define spin_lock(a) *(int*)a=1
#define spin_unlock(a) do {} while(0)
#define spin_lock_irqsave(a,b) b=0
#define spin_unlock_irqrestore(a,b)
#define spin_lock_init(a) my_spin_lock_init(a)
void my_spin_lock_init(spinlock_t *sl);
#define spin_lock(a) my_spin_lock(a)
void my_spin_lock(spinlock_t *sl);
#define spin_unlock(a) my_spin_unlock(a)
void my_spin_unlock(spinlock_t *sl);
#define spin_lock_irqsave(a,b) my_spin_lock_irqsave(a,b)
void my_spin_lock_irqsave(spinlock_t *sl, int flags);
#define spin_unlock_irqrestore(a,b) my_spin_unlock(a)
#if 0
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
@ -526,12 +539,15 @@ void my_init_waitqueue_head(PKEVENT a);
VOID KeMemoryBarrier(VOID);
#define mb() KeMemoryBarrier()
#define wmb() __asm__ __volatile__ ("": : :"memory")
#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
#define wmb() do {} while (0)
#define rmb() do {} while (0)
/*#define wmb() __asm__ __volatile__ ("": : :"memory")
#define rmb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")*/
#define in_interrupt() 0
#define init_completion(x) (x)->done=0
#define init_completion(x) my_init_completion(x)
void my_init_completion(struct completion *);
#define wait_for_completion(x) my_wait_for_completion(x)
void my_wait_for_completion(struct completion*);
@ -790,9 +806,10 @@ void my_wake_up(PKEVENT);
// cannot be mapped via macro due to collision with urb->complete
static void __inline__ complete(struct completion *p)
{
printk("completing event 0x%08x\n", (ULONG)p);
/* Wake up x->wait */
p->done++;
wake_up((PKEVENT)&p->wait);
wake_up((PKEVENT)&p->wait);
}
#define kernel_thread(a,b,c) my_kernel_thread(a,b,c)
@ -832,7 +849,5 @@ void inc_jiffies(int);
void init_wrapper(struct pci_dev *pci_dev);
void do_all_timers(void);
#define __KERNEL_DS 0x18
int my_pci_write_config_word(struct pci_dev *, int, u16);

View file

@ -242,56 +242,65 @@ extern unsigned int LAST_USB_IRQ;
int my_schedule_timeout(int x)
{
LONGLONG HH;
LONGLONG temp;
LONGLONG delay;
extern unsigned int LAST_USB_EVENT_TICK;
//LONGLONG temp;
LARGE_INTEGER delay;
//PULONG tmp_debug=NULL;
//extern unsigned int LAST_USB_EVENT_TICK;
//*tmp_debug = 0xFFAAFFAA;
printk("schedule_timeout: %d ms\n", x);
//delay.QuadPart = -x*10000; // convert to 100ns units
//KeDelayExecutionThread(KernelMode, FALSE, &delay); //wait_us(1);
/*
x+=5; // safety
x = x*1000; // to us format
*/
x = 300; // it's enough for most purposes
while(x>0)
{
KeQueryTickCount((LARGE_INTEGER *)&HH);//IoInputDword(0x8008);
temp = HH - LAST_USB_EVENT_TICK;
//temp = HH - LAST_USB_EVENT_TICK;
//if (temp>(3579)) { //3579 = 1ms!
if (temp>1000) {
//if (temp>1000) {
do_all_timers();
LAST_USB_EVENT_TICK = HH;
}
//if (LAST_USB_IRQ != OHCI_1_INTERRUPT ) {
// LAST_USB_IRQ = OHCI_1_INTERRUPT;
handle_irqs(-1);
// LAST_USB_EVENT_TICK = HH;
//}
handle_irqs(-1);
if (need_wakeup)
break;
delay = 10;
KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&delay); //wait_us(1);
delay.QuadPart = -10;
KeDelayExecutionThread(KernelMode, FALSE, &delay); //wait_us(1);
x-=1;
//DPRINT("schedule_timeout(): time left: %d\n", x);
}
need_wakeup=0;
printk("schedule DONE!!!!!!\n");
return x;
return 0;//x;
}
/*------------------------------------------------------------------------*/
void my_wait_for_completion(struct completion *x)
{
LONGLONG HH;
LONGLONG temp;
LONGLONG delay;
LARGE_INTEGER delay;
extern unsigned int LAST_USB_EVENT_TICK;
printk("wait for completion\n");
printk("wait for completion11, x=0x%08x\n", (DWORD)x);
int n=10;
n = n*1000; // to us format
while(!x->done && (n>0))
{
KeQueryTickCount((LARGE_INTEGER *)&HH);//IoInputDword(0x8008);
@ -299,23 +308,26 @@ void my_wait_for_completion(struct completion *x)
//if (temp>(3579)) {
if (temp>(1000)) {
do_all_timers();
// do_all_timers();
LAST_USB_EVENT_TICK = HH;
}
//if (LAST_USB_IRQ != OHCI_1_INTERRUPT ) {
// LAST_USB_IRQ = OHCI_1_INTERRUPT;
handle_irqs(-1);
//}
// handle_irqs(-1);
delay = 10;
KeDelayExecutionThread(KernelMode, FALSE, (LARGE_INTEGER *)&delay); //wait_us(1);
delay.QuadPart = -10;
KeDelayExecutionThread(KernelMode, FALSE, &delay); //wait_us(1);
n--;
}
printk("wait for completion done %i\n",x->done);
}
/*------------------------------------------------------------------------*/
void my_init_completion(struct completion *x)
{
x->done=0;
KeInitializeEvent(&x->wait, NotificationEvent, FALSE);
}
/*------------------------------------------------------------------------*/
void my_interruptible_sleep_on(PKEVENT evnt)
{
KeWaitForSingleObject(evnt, Executive, KernelMode, FALSE, NULL);
@ -364,6 +376,7 @@ int my_request_irq(unsigned int irq,
num_irqs++;
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
@ -609,8 +622,8 @@ struct pci_pool *my_pci_pool_create(const char * name, struct pci_dev * pdev, si
return 0;
retval = ExAllocatePool(NonPagedPool, sizeof(struct pci_pool)); // Non-paged because could be
// pci_pool is rather big struct
// accesses at IRQL < PASSIVE
// fill retval structure
strncpy (retval->name, name, sizeof retval->name);
retval->name[sizeof retval->name - 1] = 0;
@ -623,7 +636,7 @@ struct pci_pool *my_pci_pool_create(const char * name, struct pci_dev * pdev, si
retval->pages_allocated = 0;
retval->blocks_allocated = 0;
DPRINT1("pci_pool_create(): %s/%s size %d, %d/page (%d alloc)\n",
DPRINT("pci_pool_create(): %s/%s size %d, %d/page (%d alloc)\n",
pdev ? pdev->slot_name : NULL, retval->name, size,
retval->blocks_per_page, allocation);
@ -652,10 +665,11 @@ void * my_pci_pool_alloc(struct pci_pool * pool, int mem_flags, dma_addr_t *dma_
{
PVOID result;
POHCI_DEVICE_EXTENSION devExt = (POHCI_DEVICE_EXTENSION)pool->pdev->dev_ext;
//PHYSICAL_ADDRESS logicalAddr;
DPRINT1("pci_pool_alloc() called, blocks already allocated=%d\n", pool->blocks_allocated);
//size_t current_block_in_page;
int page,map,i,block,offset;
int page=0, offset;
int map, i, block;
//DPRINT1("pci_pool_alloc() called, blocks already allocated=%d, dma_handle=%p\n", pool->blocks_allocated, dma_handle);
//ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
if (pool->pages_allocated == 0)
{
@ -665,7 +679,7 @@ void * my_pci_pool_alloc(struct pci_pool * pool, int mem_flags, dma_addr_t *dma_
PAGE_SIZE, &pool->pages[pool->pages_allocated].dmaAddress, FALSE); //FIXME: Cache-enabled?
// mark all blocks as free (bit=set)
memset(pool->pages[pool->pages_allocated].bitmap, 0xFF, 128*sizeof(long));
memset(pool->pages[pool->pages_allocated].bitmap, 0xFF, 128*sizeof(unsigned long));
/* FIXME: the next line replaces physical address by virtual address:
* this change is needed to boot VMWare, but I'm really not sure this
@ -687,6 +701,7 @@ void * my_pci_pool_alloc(struct pci_pool * pool, int mem_flags, dma_addr_t *dma_
if ((i + block) < pool->blocks_per_page)
{
DPRINT("pci_pool_alloc(): Allocating block %p:%d:%d:%d\n", pool, page, map, block);
clear_bit(block, &pool->pages[page].bitmap[map]);
offset = (BITS_PER_LONG * map) + block;
offset *= pool->size;
@ -705,22 +720,6 @@ ready:
result = (char *)pool->pages[page].virtualAddress + offset;
pool->blocks_allocated++;
#if 0
// check do we have enough free blocks on the current page
if (pool->pages_allocated*pool->blocks_per_page < pool->blocks_allocated+1)
{
DPRINT1("Panic!! We need one more page to be allocated, and Fireball doesn't want to alloc it!\n");
*dma_handle = 0;
return NULL;
}
// Alloc one block now
pool->blocks_allocated++;
current_block_in_page = pool->blocks_allocated - (pool->blocks_allocated / pool->blocks_per_page) * pool->blocks_per_page;
*dma_handle = pool->pages[pool->pages_allocated-1].dmaAddress.QuadPart + pool->size*(current_block_in_page - 1);
result = pool->pages[pool->pages_allocated-1].virtualAddress + pool->size*(current_block_in_page - 1);
#endif
return result;
}
@ -764,8 +763,7 @@ void my_pci_pool_free (struct pci_pool * pool, void * vaddr, dma_addr_t dma)
set_bit (block, &pool->pages[page].bitmap[map]);
pool->blocks_allocated--;
DPRINT1("pci_pool_free(): alloc'd: %d\n", pool->blocks_allocated);
DPRINT("pci_pool_free(): alloc'd: %d\n", pool->blocks_allocated);
}
/*
@ -882,3 +880,27 @@ void my_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size
{
my_dma_unmap_single(&hwdev->dev, dma_addr, size, direction);
}
/*------------------------------------------------------------------------*/
/* SPINLOCK routines */
/*------------------------------------------------------------------------*/
void my_spin_lock_init(spinlock_t *sl)
{
KeInitializeSpinLock(&sl->SpinLock);
}
void my_spin_lock(spinlock_t *sl)
{
//KeAcquireSpinLock(&sl->SpinLock, &sl->OldIrql);
}
void my_spin_unlock(spinlock_t *sl)
{
//KeReleaseSpinLock(&sl->SpinLock, sl->OldIrql);
}
void my_spin_lock_irqsave(spinlock_t *sl, int flags)
{
my_spin_lock(sl);
}