diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp index 524f2a9caf..55400b2aba 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp +++ b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.cpp @@ -7,6 +7,7 @@ */ #include #include +#include #include #include #include @@ -21,7 +22,8 @@ char *gDeviceNames[DEVICES_COUNT + 1]; config_manager_for_driver_module_info *gConfigManagerModule = NULL; isa_module_info *gISAModule = NULL; pci_module_info *gPCIModule = NULL; -tty_module_info *gTTYModule = NULL; +//XXX: ifndef __HAIKU__ +tty_module_info_v1_bone *gTTYModule = NULL; struct ddomain gSerialDomain; sem_id gDriverLock = -1; bool gHandleISA = false; @@ -236,7 +238,7 @@ scan_bus(bus_type bus) { const char *bus_name = "Unknown"; uint64 cookie = 0; - status_t status; + //status_t status; struct { device_info di; pci_info pi; @@ -342,7 +344,7 @@ scan_bus(bus_type bus) resource_descriptor res[16]; } config; if (gConfigManagerModule->get_size_of_current_configuration_for( - cookie) > sizeof(config)) { + cookie) > (int)sizeof(config)) { TRACE_ALWAYS("config size too big for device\n"); continue; } @@ -450,6 +452,7 @@ next_split: #endif } } + return B_OK; } // this version doesn't use config_manager, but can't probe the IRQ yet @@ -541,6 +544,52 @@ init_driver() if (status < B_OK) goto err_tty; +#ifndef __HAIKU__ + // due to BONE having a different function count and ordering, + // but the same version, to avoid crashing we detect it at runtime. + { + static tty_module_info_v1_bone sTTYModuleBONE; + static tty_module_info_v1_r5 *ttyModuleR5 = + (tty_module_info_v1_r5 *)gTTYModule; + image_info info; + int32 cookie = 0; + while (get_next_image_info(/*B_KERNEL_TEAM*/1, &cookie, &info) == B_OK) { + //dprintf(DRIVER_NAME ": checking image %32s\n", info.name); + if ((char *)(gTTYModule->ttyopen) >= (char *)info.text + && (char *)(gTTYModule->ttyopen) < ((char *)info.text + info.text_size)) { + void *symbol; + dprintf(DRIVER_NAME ": detected tty module %32s\n", info.name); + if (get_image_symbol(info.id, "ttydeselect", + B_SYMBOL_TYPE_ANY, &symbol) != B_OK) { + dprintf(DRIVER_NAME ": no ttydeselect() in tty module, assuming R5\n"); + // let's fake a BONE module with NULL select hooks + memcpy(&sTTYModuleBONE.mi, &ttyModuleR5->mi, sizeof(ttyModuleR5->mi)); + sTTYModuleBONE.ttyopen = ttyModuleR5->ttyopen; + sTTYModuleBONE.ttyclose = ttyModuleR5->ttyclose; + sTTYModuleBONE.ttyfree = ttyModuleR5->ttyfree; + sTTYModuleBONE.ttyread = ttyModuleR5->ttyread; + sTTYModuleBONE.ttywrite = ttyModuleR5->ttywrite; + sTTYModuleBONE.ttycontrol = ttyModuleR5->ttycontrol; + sTTYModuleBONE.ttyinit = ttyModuleR5->ttyinit; + sTTYModuleBONE.ttyilock = ttyModuleR5->ttyilock; + sTTYModuleBONE.ttyhwsignal = ttyModuleR5->ttyhwsignal; + sTTYModuleBONE.ttyin = ttyModuleR5->ttyin; + sTTYModuleBONE.ttyout = ttyModuleR5->ttyout; + sTTYModuleBONE.ddrstart = ttyModuleR5->ddrstart; + sTTYModuleBONE.ddrdone = ttyModuleR5->ddrdone; + sTTYModuleBONE.ddacquire = ttyModuleR5->ddacquire; + // no select hooks + sTTYModuleBONE.ttyselect = NULL; + sTTYModuleBONE.ttydeselect = NULL; + + gTTYModule = &sTTYModuleBONE; + } + break; + } + } + } +#endif + status = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCIModule); if (status < B_OK) goto err_pci; @@ -582,7 +631,7 @@ init_driver() TRACE_FUNCRET("< init_driver() returns\n"); return B_OK; -err_none: +//err_none: delete_sem(gDriverLock); err_sem: put_module(B_CONFIG_MANAGER_FOR_DRIVER_MODULE_NAME); diff --git a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.h b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.h index f2cd62cca7..8a01467fbd 100644 --- a/src/add-ons/kernel/drivers/ports/pc_serial/Driver.h +++ b/src/add-ons/kernel/drivers/ports/pc_serial/Driver.h @@ -30,7 +30,10 @@ extern "C" { // whether we should handle default COM ports +// not for BeOS, it has a "zz" driver for this. +#ifdef __HAIKU__ #define HANDLE_ISA_COM +#endif #define DRIVER_NAME "pc_serial" // driver name for debug output #define DEVICES_COUNT 20 // max simultaneously open devices @@ -120,10 +123,61 @@ typedef struct pc_serial_line_coding_s { #define CLS_LINE_DTR 0x0001 #define CLS_LINE_RTS 0x0002 +#ifndef __HAIKU__ + +typedef bool (*beos_tty_service_func)(struct tty *tty, struct ddrover *rover, uint op); + +// this version is compatible with BeOS R5 +struct tty_module_info_v1_r5 { + // not a real bus manager... no rescan() ! + module_info mi; + status_t (*ttyopen)(struct ttyfile *, struct ddrover *, beos_tty_service_func); + status_t (*ttyclose)(struct ttyfile *, struct ddrover *); + status_t (*ttyfree)(struct ttyfile *, struct ddrover *); + status_t (*ttyread)(struct ttyfile *, struct ddrover *, char *, size_t *); + status_t (*ttywrite)(struct ttyfile *, struct ddrover *, const char *, size_t *); + status_t (*ttycontrol)(struct ttyfile *, struct ddrover *, ulong, void *, size_t); + void (*ttyinit)(struct tty *, bool); + void (*ttyilock)(struct tty *, struct ddrover *, bool ); + void (*ttyhwsignal)(struct tty *, struct ddrover *, int, bool); + int (*ttyin)(struct tty *, struct ddrover *, int); + int (*ttyout)(struct tty *, struct ddrover *); + struct ddrover *(*ddrstart)(struct ddrover *); + void (*ddrdone)(struct ddrover *); + void (*ddacquire)(struct ddrover *, struct ddomain *); +}; + +// BeOS BONE has a different module with the same version... +struct tty_module_info_v1_bone { + // not a real bus manager... no rescan() ! + module_info mi; + status_t (*ttyopen)(struct ttyfile *, struct ddrover *, beos_tty_service_func); + status_t (*ttyclose)(struct ttyfile *, struct ddrover *); + status_t (*ttyfree)(struct ttyfile *, struct ddrover *); + status_t (*ttyread)(struct ttyfile *, struct ddrover *, char *, size_t *); + status_t (*ttywrite)(struct ttyfile *, struct ddrover *, const char *, size_t *); + status_t (*ttycontrol)(struct ttyfile *, struct ddrover *, ulong, void *, size_t); + status_t (*ttyselect)(struct ttyfile *, struct ddrover *, uint8, uint32, selectsync *); + status_t (*ttydeselect)(struct ttyfile *, struct ddrover *, uint8, selectsync *); + + void (*ttyinit)(struct tty *, bool); + void (*ttyilock)(struct tty *, struct ddrover *, bool ); + void (*ttyhwsignal)(struct tty *, struct ddrover *, int, bool); + int (*ttyin)(struct tty *, struct ddrover *, int); + int (*ttyout)(struct tty *, struct ddrover *); + struct ddrover *(*ddrstart)(struct ddrover *); + void (*ddrdone)(struct ddrover *); + void (*ddacquire)(struct ddrover *, struct ddomain *); +}; +#endif + + + extern config_manager_for_driver_module_info *gConfigManagerModule; extern isa_module_info *gISAModule; extern pci_module_info *gPCIModule; -extern tty_module_info *gTTYModule; +//extern tty_module_info *gTTYModule; +extern tty_module_info_v1_bone *gTTYModule; extern struct ddomain gSerialDomain; extern "C" { @@ -146,4 +200,6 @@ const char **publish_devices(); device_hooks *find_device(const char *name); } + + #endif //_PC_SERIAL_DRIVER_H_