From: Bernhard Urban Date: Sat, 26 Sep 2009 09:15:00 +0000 (+0200) Subject: some routines for removing a device on demand. thist do not work properly X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=ppcskel.git;a=commitdiff_plain;h=f80a808bafef8020c6d97d33cdf3cc613a70912b some routines for removing a device on demand. thist do not work properly (TODO!) --- diff --git a/main.c b/main.c index 530d9e8..67d6d88 100644 --- a/main.c +++ b/main.c @@ -128,6 +128,7 @@ int main(void) /* load HID keyboard driver */ usb_hidkb_init(); +wait_kb: /* wait for usb keyboard plugged in */ if(!usb_hidkb_inuse()) { print_str("plug in an usb keyboard", 23); @@ -149,7 +150,7 @@ int main(void) u16 old_x, old_y; struct kbrep *k, *old=NULL; - while(1) { + while(usb_hidkb_inuse()) { memset(str, '\0', 7); k = usb_hidkb_getChars(); j=0; @@ -219,6 +220,8 @@ int main(void) } } + goto wait_kb; + #if 0 printf("===============================\n"); diff --git a/usb/core/core.c b/usb/core/core.c index 0b38e77..97acc56 100644 --- a/usb/core/core.c +++ b/usb/core/core.c @@ -120,8 +120,8 @@ struct usb_device *usb_add_device(u8 lowspeed, u32 reg) if(ret < 0) { return (void*) -1; } - -#define WTF +// +//#define WTF #ifdef WTF volatile u8 wzf = 11; if(0 == wzf) { @@ -232,12 +232,27 @@ void lsusb(struct usb_device *dev) * Find currently detached device and remove * data structures */ -u8 usb_remove_device(struct usb_device * dev) +u8 usb_remove_device(struct usb_device *dev) { - // FIXME!!!! dieser quatsch ist nur temporaer - free(core.devices->head); - free(core.devices); - core.devices = list_create(); + /* trigger driver for this device */ + struct usb_driver *drv; + struct element *iterator = core.drivers->head; + while (iterator != NULL) { + drv = (struct usb_driver *) iterator->data; + if(drv->data && !memcmp(drv->data, dev, sizeof(struct usb_device))) { + drv->remove(); + break; + } + iterator = iterator->next; + } + + /* remove from device list */ + struct element *tmp = (struct element *) malloc(sizeof(struct element)); + tmp->data = (void *) dev; + list_delete_element(core.devices, tmp); + + printf("REMOVED\n"); + return 1; } diff --git a/usb/core/core.h b/usb/core/core.h index ce9cecf..98ab7ea 100644 --- a/usb/core/core.h +++ b/usb/core/core.h @@ -145,6 +145,7 @@ struct usb_driver { char* name; void (*probe)(void); void (*check)(void); + void (*remove)(void); void *data; struct usb_driver *next; }; diff --git a/usb/drivers/class/hid.c b/usb/drivers/class/hid.c index b79bcd3..933b592 100644 --- a/usb/drivers/class/hid.c +++ b/usb/drivers/class/hid.c @@ -21,6 +21,7 @@ struct usb_driver hidkb = { .name = "hidkb", .probe = usb_hidkb_probe, .check = usb_hidkb_check, + .remove = usb_hidkb_remove, .data = NULL }; @@ -90,6 +91,10 @@ u8 usb_hidkb_inuse() return hidkb.data ? 1 : 0; } +void usb_hidkb_remove() { + hidkb.data = NULL; +} + struct kbrep *usb_hidkb_getChars() { struct usb_device *dev = (struct usb_device*) hidkb.data; struct kbrep *ret = (struct kbrep*) malloc(sizeof(struct kbrep)); diff --git a/usb/drivers/class/hid.h b/usb/drivers/class/hid.h index e8218ad..04a2786 100644 --- a/usb/drivers/class/hid.h +++ b/usb/drivers/class/hid.h @@ -36,6 +36,7 @@ u8 usb_hidkb_inuse(); struct kbrep *usb_hidkb_getChars(); unsigned char usb_hidkb_get_char_from_keycode(u8 keycode, int shifted); void usb_hidkb_set_idle(struct usb_device *dev, u8 duration); +void usb_hidkb_remove(); #endif /* __HID_H */ diff --git a/usb/host/ohci.c b/usb/host/ohci.c index f243bca..64b77de 100644 --- a/usb/host/ohci.c +++ b/usb/host/ohci.c @@ -34,7 +34,7 @@ Copyright (C) 2009 Sebastian Falbesoner static struct general_td *allocate_general_td(); static void dbg_op_state(u32 reg); static void configure_ports(u8 from_init, u32 reg); -static void setup_port(u32 ohci, u32 reg, u8 from_init); +static struct usb_device *setup_port(u32 ohci, u32 reg, u8 pport, u8 from_init); static void set_target_hcca(u32 reg); static struct ohci_hcca hcca_oh0; @@ -498,6 +498,7 @@ void hcdi_init(u32 reg) dbg_op_state(reg); } +static struct usb_device *connected[2] = {NULL, NULL}; static void configure_ports(u8 from_init, u32 reg) { #ifdef _DU_OHCI_RH @@ -509,14 +510,31 @@ static void configure_ports(u8 from_init, u32 reg) printf("OHCI_HC_RH_PORT_STATUS_2:\t0x%08X\n", read32(reg+OHCI_HC_RH_PORT_STATUS_2)); #endif - setup_port(reg, reg+OHCI_HC_RH_PORT_STATUS_1, from_init); - setup_port(reg, reg+OHCI_HC_RH_PORT_STATUS_2, from_init); + struct usb_device *dtmp; + if(!(dtmp = setup_port(reg, reg+OHCI_HC_RH_PORT_STATUS_1, 0, from_init))) { + if(connected[0]) { + usb_remove_device(connected[0]); + connected[0] = NULL; + } + } else { + connected[0] = dtmp; + } + + if(!(dtmp = setup_port(reg, reg+OHCI_HC_RH_PORT_STATUS_2, 1, from_init))) { + if(connected[1]) { + usb_remove_device(connected[1]); + connected[1] = NULL; + } + } else { + connected[1] = dtmp; + } + #ifdef _DU_OHCI_RH printf("configure_ports done\n"); #endif } -static void setup_port(u32 ohci, u32 reg, u8 from_init) +static struct usb_device *setup_port(u32 ohci, u32 reg, u8 pport, u8 from_init) { u32 port = read32(reg); if((port & RH_PS_CCS) && ((port & RH_PS_CSC) || from_init)) { @@ -530,7 +548,7 @@ static void setup_port(u32 ohci, u32 reg, u8 from_init) #ifdef _DU_OHCI_RH printf("fu\n"); #endif - return; + return NULL; } write32(reg, RH_PS_PRS); @@ -542,8 +560,12 @@ static void setup_port(u32 ohci, u32 reg, u8 from_init) #endif /* returns usb_device struct */ - (void) usb_add_device((read32(reg) & RH_PS_LSDA) >> 8, ohci); + return usb_add_device((read32(reg) & RH_PS_LSDA) >> 8, ohci); + } + if(port & RH_PS_CCS) { + return connected[pport]; } + return NULL; } void hcdi_irq(u32 reg) diff --git a/usb/lib/list.c b/usb/lib/list.c index 39c9439..9ea2090 100644 --- a/usb/lib/list.c +++ b/usb/lib/list.c @@ -34,6 +34,8 @@ //#include #include "list.h" #include "../../malloc.h" +#include "../../string.h" +#include "../../bootmii_ppc.h" struct list* list_create() { @@ -53,7 +55,7 @@ u8 list_add_tail(struct list *l, struct element *e) } /* find last element */ - struct element * iterator = l->head; + struct element *iterator = l->head; while(iterator->next!=NULL) { iterator = iterator->next; @@ -65,9 +67,36 @@ u8 list_add_tail(struct list *l, struct element *e) -// FIXME: untested and unused!! +// FIXME: untested u8 list_delete_element(struct list *l, struct element *e) { + struct element *iterator = l->head; + struct element *delete = NULL; + + if(!l->head) { + return 0; + } else { + if(l->head->data && !(memcmp(l->head->data, e->data, sizeof(struct element)))) { + delete = l->head; + l->head = NULL; + } + } + + while(iterator->next!=NULL) { + if(iterator->next->data && !(memcmp(iterator->next->data, e->data, sizeof(struct element)))) { + delete = iterator->next; + iterator->next = iterator->next->next; + break; + } + + iterator = iterator->next; + } + + if(delete) { + free(delete->data); + free(delete); + } + return 1; }