From: Mark Hounschell <markh@compro.net>
To: Peter Hurley <peter@hurleysoftware.com>
Cc: linux-serial@vger.kernel.org, Mark Hounschell <dmarkh@cfl.rr.com>
Subject: Re: Out of tree GPL serial tty driver help?
Date: Fri, 26 Apr 2013 16:26:29 -0400 [thread overview]
Message-ID: <517AE2F5.4060200@compro.net> (raw)
In-Reply-To: <1367005866.3971.15.camel@thor.lan>
On 04/26/2013 03:51 PM, Peter Hurley wrote:
> On Fri, 2013-04-26 at 14:17 -0400, Mark Hounschell wrote:
>> On 04/26/2013 12:37 PM, Peter Hurley wrote:
>>> These drivers weren't really current at 3.4 though, either. I'm not sure
>>> what else you're going to find that doesn't work.
>>>
>>
>> No, I have kept them current, or I should say functional, to the best of
>> my ability from 2.6 up to and including 3.4.x.
>
> By 'current', I mean 'similar in structure and functionality to in-tree
> drivers'.
>
> The structure of this driver is more akin to a 2.5 driver (back when
> there were separate serial and callout tty drivers).
>
>> What I have here works
>> with kernels up to 3.4.x. I have not tried anything between 3.4 and 3.8.
>> As far as building against 3.8, the only issues were the change from
>> *termios to termios and the "structn_tty_data" no longer in an include
>> file so not easily directly accessible.
>
> What is this driver accessing in N_TTY's private data?
>
/* Decide how much data we can send into the tty layer */
if(dgdm_rawreadok && tty->real_raw)
flip_len = MYFLIPLEN;
else
flip_len = TTY_FLIPBUF_SIZE;
len = MIN(data_len, flip_len);
len = MIN(len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
dxb_return_fixed_cost(dxb, channel, 1);
ld = tty_ldisc_ref(tty);
.
.
.
.
/*
* In high performance mode, we don't have to update
* flag_buf or any of the counts or pointers into flip buf.
*/
if(!dgdm_rawreadok || !tty->real_raw) {
if (I_PARMRK(tty) || I_BRKINT(tty) ||
I_INPCK(tty)) {
parity_scan(dc, myflipbuf[boardnum],
myflipflagbuf[boardnum], &len);
} else {
memset(myflipflagbuf[boardnum],
TTY_NORMAL, len);
}
}
.
.
.
.
/*
* If we're doing raw reads, jam it right into the
* line disc bypassing the flip buffers.
* OPT OPP: do this only once per channel instead of
* once per dxb message.
*/
if(dgdm_rawreadok && tty->real_raw) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
tty->ldisc->ops->receive_buf(tty,
myflipbuf[boardnum], NULL, len);
#else
tty->ldisc.ops->receive_buf(tty,
myflipbuf[boardnum], NULL, len);
#endif
#else
tty->ldisc.receive_buf(tty,
myflipbuf[boardnum], NULL, len);
#endif
} else {
len = tty_buffer_request_room(tty, len);
tty_insert_flip_string_flags(tty,
myflipbuf[boardnum],
myflipflagbuf[boardnum], len);
/* Tell the tty layer its okay to "eat" the
data now */
tty_flip_buffer_push(tty);
}
.
.
.
/*
* Just go ahead and try to read some data into the flip buffer.
* If there isn't any data available, dxb_rxbuf_read will return
* 0 back to us right away.
*
* The dgdm_rawreadok case takes advantage of carnal knowldge that
* the char_buf and the flag_buf are next to each other and
* are each of (2 * TTY_FLIPBUF_SIZE) size.
*/
if(dgdm_rawreadok && tty->real_raw)
flip_len = MYFLIPLEN;
else
flip_len = TTY_FLIPBUF_SIZE;
flip_len = MIN(flip_len, (N_TTY_BUF_SIZE - 1) - tty->read_cnt);
len = dxb_rxbuf_read(brd->dxb, dc->dxbchan,
myflipbuf[boardnum], flip_len);
etc...
Looks like for hopes of performance????
>>> For both PCI and PCI-e, these drivers should _at a minimum_ be pci
>>> drivers that register the tty driver at module init and register _only_
>>> the tty devices for that particular PCI device at PCI probe time. Look
>>> at the end of synclink_gt.c for how this is supposed to look.
>>>
>>
>> I'll look at it some more but I have been there.
>
> Specifically, review:
> struct pci_driver
> device_init()
> init_one()
> remove_one()
> sglt_init()
> sglt_exit()
>
Ok, I'll will look more closely at these to try to understand what
should be done.
Here is the init_module funtion FYI.
GLOBAL int init_module(void)
{
int rc;
/* make sure that the globals are init'd before we do anything
else */
dgdm_init_globals();
dgdm_NumBoards = 0;
dgdm_Major_Serial_Registered = FALSE;
dgdm_Major_Callout_Registered = FALSE;
dgdm_Major_TransparentPrint_Registered = FALSE;
dgdm_Major_Control_Registered = FALSE;
dgdm_Major_ISDN_Registered = FALSE;
APR(("%s, Digi International Part Number %s\n", DG_NAME, DG_PART));
/*
* Find and configure all the cards
*/
rc = dgdm_init_pci();
if (!rc) {
/*
* At least one card was found, register the devices
* with the kernel.
*/
dgdm_proc_register_basic();
if (dgdm_tty) {
rc = dgdm_tty_init(); // This is the function
that creates all the device entries
if (rc < 0) {
dgdm_tty_uninit();
APR(("Can't init tty devices (%d)\n", rc));
return (rc);
}
/*
* Register FEP related /proc files
*/
dgdm_proc_register_fep();
}
if (!dgdm_Major_Control_Registered) {
/*
* Register memory/control/debug/mangement devices
*/
rc = register_chrdev(major + DGDM_CONTROL_MAJOR,
"dxb", &BoardFops);
if (rc < 0) {
APR(("Can't register ram device
(%d)\n", rc));
return (rc);
}
dgdm_Major_Control_Registered = TRUE;
}
if (dgdm_isdn && !dgdm_Major_ISDN_Registered) {
/*
* Register ISDN testing device
*/
rc = register_chrdev(major + DGDM_ISDN_MAJOR,
"dxbisdn",
&dgdm_BoardIsdnFops);
if (rc < 0) {
APR(("Can't register ISDN device
(%d)\n", rc));
return (rc);
}
dgdm_Major_ISDN_Registered = TRUE;
}
if(dgdm_NumBoards > 4) {
if (!dgdm_Major_Control2_Registered) {
rc =
register_chrdev(major+DGDM_CONTROL2_MAJOR,
"dxb2", &BoardFops);
if (rc < 0) {
APR(("Can't register high ram "
"device (%d)\n", rc));
return (rc);
}
dgdm_Major_Control2_Registered = TRUE;
}
if (dgdm_isdn && !dgdm_Major_ISDN2_Registered) {
rc = register_chrdev(major +
DGDM_ISDN2_MAJOR,
"dxbisdn2",
&dgdm_BoardIsdnFops);
if (rc < 0) {
APR(("Can't register high ISDN "
"devices (%d)\n", rc));
return (rc);
}
dgdm_Major_ISDN2_Registered = TRUE;
}
}
// Compro Computer Svcs udev support
// Need udev notification of the dgdm_mgmt device creation
//
// See config/99-dgdm.rules
"/etc/udev/rules.d/99-dgdm.rules"
// and /usr/local/sbin/dgdm
//
if (alloc_chrdev_region(&dgdm_mgmt_major, 0, 1,
"dgdm_mgmt") != 0) {
printk("DGDM: Unable to get MAJOR/MINOR device
numbers\n");
return -ENODEV;
}
dgdm_mgmt_device = cdev_alloc();
if (dgdm_mgmt_device <= 0) {
printk("DGDM: Unable to alloc cdev struct\n");
return -ENODEV;
}
cdev_init(dgdm_mgmt_device, &dgdm_BoardIsdnFops);
dgdm_mgmt_device->owner = THIS_MODULE;
if (cdev_add(dgdm_mgmt_device, dgdm_mgmt_major, 1) < 0) {
printk("DGDM: Error Registering chrdev device\n");
return -ENODEV;
}
dgdm_mgmt_class = class_create(THIS_MODULE, "dgdm_mgmt");
if (IS_ERR(dgdm_mgmt_class)) {
printk("DGDM: Error creating class\n");
return -ENODEV;
}
device_dgdm_mgmt = device_create(dgdm_mgmt_class, NULL,
dgdm_mgmt_major, NULL, "dgdm_mgmt");
if (IS_ERR(device_dgdm_mgmt)) {
printk("DGDM: Error creating device entry\n");
return -ENODEV;
}
} else {
cleanup_module();
}
return (rc);
}
Mark
next prev parent reply other threads:[~2013-04-26 20:26 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-24 17:44 Out of tree GPL serial tty driver help? Mark Hounschell
2013-04-25 21:41 ` Peter Hurley
2013-04-26 12:58 ` Mark Hounschell
2013-04-26 13:45 ` Peter Hurley
2013-04-26 14:28 ` Mark Hounschell
2013-04-26 14:35 ` Greg KH
2013-04-26 15:10 ` Mark Hounschell
2013-04-26 15:19 ` Greg KH
2013-04-26 15:39 ` Peter Hurley
2013-04-26 16:03 ` Greg KH
2013-04-26 17:58 ` Mark Hounschell
2013-04-26 23:21 ` Greg KH
2013-04-26 16:37 ` Peter Hurley
2013-04-26 18:17 ` Mark Hounschell
2013-04-26 19:51 ` Peter Hurley
2013-04-26 20:26 ` Mark Hounschell [this message]
2013-04-26 21:49 ` Peter Hurley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=517AE2F5.4060200@compro.net \
--to=markh@compro.net \
--cc=dmarkh@cfl.rr.com \
--cc=linux-serial@vger.kernel.org \
--cc=peter@hurleysoftware.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).