When opening a port the dgap driver OOPs with a message: tty_init_dev: driver does not set tty->port... will crash the kernel... fix the driver... etc... Then I have to reboot the box. I think before too much more work is done on this driver (by me anyway), it should at least be in a usable state. There are a lot more changes to come and I would like to be able to "test" along the way. I've looked at some of the other drivers as examples and come up with this patch that does in fact allow me to use the driver. I would like to submit it but am uncertain that this is proper. Thanks for reviewing. mark diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 7cb1ad5..d56b3b2 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -223,7 +223,7 @@ static void dgap_get_vpd(struct board_t *brd); static void dgap_do_reset_board(struct board_t *brd); static void dgap_do_wait_for_bios(struct board_t *brd); static void dgap_do_wait_for_fep(struct board_t *brd); -static void dgap_sysfs_create(struct board_t *brd); +static int dgap_sysfs_create(struct board_t *brd); static int dgap_firmware_load(struct pci_dev *pdev, int card_type); /* Driver load/unload functions */ @@ -1098,7 +1098,9 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type) return ret; } - dgap_sysfs_create(brd); + ret = dgap_sysfs_create(brd); + if (ret) + return ret; brd->state = BOARD_READY; brd->dpastatus = BD_RUNNING; @@ -1730,6 +1732,7 @@ static void dgap_tty_uninit(struct board_t *brd) dgap_BoardsByMajor[brd->SerialDriver->major] = NULL; brd->dgap_Serial_Major = 0; for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->SerialPorts[i].port); dgap_remove_tty_sysfs(brd->channels[i]->ch_tun.un_sysfs); tty_unregister_device(brd->SerialDriver, i); } @@ -1737,6 +1740,7 @@ static void dgap_tty_uninit(struct board_t *brd) kfree(brd->SerialDriver->ttys); brd->SerialDriver->ttys = NULL; put_tty_driver(brd->SerialDriver); + kfree(brd->SerialPorts); brd->dgap_Major_Serial_Registered = FALSE; } @@ -1744,6 +1748,7 @@ static void dgap_tty_uninit(struct board_t *brd) dgap_BoardsByMajor[brd->PrintDriver->major] = NULL; brd->dgap_TransparentPrint_Major = 0; for (i = 0; i < brd->nasync; i++) { + tty_port_destroy(&brd->PrinterPorts[i].port); dgap_remove_tty_sysfs(brd->channels[i]->ch_pun.un_sysfs); tty_unregister_device(brd->PrintDriver, i); } @@ -1751,6 +1756,7 @@ static void dgap_tty_uninit(struct board_t *brd) kfree(brd->PrintDriver->ttys); brd->PrintDriver->ttys = NULL; put_tty_driver(brd->PrintDriver); + kfree(brd->PrinterPorts); brd->dgap_Major_TransparentPrint_Registered = FALSE; } } @@ -4813,25 +4819,51 @@ static int dgap_after_config_loaded(int board) /* * Create pr and tty device entries */ -static void dgap_sysfs_create(struct board_t *brd) +static int dgap_sysfs_create(struct board_t *brd) { struct channel_t *ch; - int j = 0; + struct dgap_port *p; + int j; + + brd->SerialPorts = kcalloc(brd->nasync, sizeof(*brd->SerialPorts), + GFP_KERNEL); + if (brd->SerialPorts == NULL) { + pr_err("dgap: Cannot allocate serial port memory\n"); + return -ENOMEM; + } + + for (j = 0, p = brd->SerialPorts; j < brd->nasync; j++, p++) + tty_port_init(&p->port); + + brd->PrinterPorts = kcalloc(brd->nasync, sizeof(*brd->PrinterPorts), + GFP_KERNEL); + if (brd->PrinterPorts == NULL) { + pr_err("dgap: Cannot allocate printer port memory\n"); + return -ENOMEM; + } + + for (j = 0, p = brd->PrinterPorts; j < brd->nasync; j++, p++) + tty_port_init(&p->port); ch = brd->channels[0]; for (j = 0; j < brd->nasync; j++, ch = brd->channels[j]) { struct device *classp; - classp = tty_register_device(brd->SerialDriver, j, - &(ch->ch_bd->pdev->dev)); + + classp = tty_port_register_device(&brd->SerialPorts[j].port, + brd->SerialDriver, brd->firstminor + j, NULL); + ch->ch_tun.un_sysfs = classp; dgap_create_tty_sysfs(&ch->ch_tun, classp); - classp = tty_register_device(brd->PrintDriver, j, - &(ch->ch_bd->pdev->dev)); + classp = tty_port_register_device(&brd->PrinterPorts[j].port, + brd->PrintDriver, brd->firstminor + j, NULL); + ch->ch_pun.un_sysfs = classp; dgap_create_tty_sysfs(&ch->ch_pun, classp); } dgap_create_ports_sysfiles(brd); + + return 0; } diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 573aa18..656d3ad 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -703,6 +703,9 @@ struct macounter #define BD_FEP5PLUS 0x0001 /* Supports FEP5 Plus commands */ #define BD_HAS_VPD 0x0002 /* Board has VPD info available */ +struct dgap_port { + struct tty_port port; +}; /* * Per-board information @@ -761,8 +764,10 @@ struct board_t struct channel_t *channels[MAXPORTS]; /* array of pointers to our channels. */ struct tty_driver *SerialDriver; + struct dgap_port *SerialPorts; char SerialName[200]; struct tty_driver *PrintDriver; + struct dgap_port *PrinterPorts; char PrintName[200]; u32 dgap_Major_Serial_Registered; _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel