Hi guys,
Thanks so much for your quick and prompt answers!
>
> A usb serial audio device? Huh? That doesn't sound correct at all.
>
Nope, I'm aware it doesn't :) But, again - I'm trying to learn more
about sound drivers, and since I have an FT232 based device, I took it
up as a learning challenge to have this device appear as a sound-card -
and possibly be able to play back/capture data received from FT232 on PC
speakers.
Even from my very limited understanding, I get that is generally not a
good plan - since FT232 supports only bulk transport, and I understand
for streaming data I'd want isochronous. But if I could get the device
to appear as a soundcard, and play back some data received from FT232 -
even with drops/retransmits and such - my learning goal is achieved :)
What exacly are you trying to do here that you would need to modify both
of these drivers?
>
> I'm missing the connection between these two drivers.
>
Well, I tried first by building based on usb-skeleton, and indeed I
could both read and write data to FT232 - but only after I executed stty
(that is, ftdi_open) using the original ftdi_sio (and then I could
modprobe -r the original ftdi_sio, and load my usb-skeleton).
As I realized building on usb-skeleton will probably not be trivial, I
thought about using ftdi_sio.c itself as a base - and allowing its
functions (like probe and shutdown) to first handle all usb-serial
related stuff - and then call other functions that will handle ALSA side
of things.
>
> The problem is you can't have 2 drivers binding to the same usb
> interface, which is what you are doing here. Bad things happen as you
> have seen :)
>
Thanks for this - its good to have this confirmed :)
I thought that I could "run away" from this, by keeping only the
ftdi_sio.c base as a "real" module (i.e. with #include <linux/module.h>
and <linux/kernel.h>) - the other .c file simply has functions
copypasted from usbaudio.c (starting from _probe and _disconnect, and
adding all needed functions until it builds, while commenting, say,
MIDI). But obviously it is not that easy :)
Maybe I could best explain what I want to do through an example.
Say the FT232 continuously sends 8 bit data - a 'sawtooth' from 0 to 255.
Then with a normal ftdi_sio, I could have a flow like this:
1) Plug in USB - _probe runs, /dev/ttyUSB0 appears
2) Run 'stty 115200 < /dev/ttyUSB0' - _open runs, baudrate is set
3) Run 'cat /dev/ttyUSB0' - _read* runs, data is pushed via tty, and we
are getting 0x00, 0x01, .. 0xFF, 0x00 ... etc in terminal.
With 'my' driver, I'd like the following flow to happen:
1) Plug in USB - _probe runs, /dev/ttyUSB0 appears and new card shows in
/dev/sndstat
2) Run 'stty 115200 < /dev/ttyUSB0' - _open runs, baudrate is set - and
pcm buffers are prepared
3) Run Audacity, select the new card, and click record - _read runs, and
as soon as data is ready to be sent to tty, it is also copied to PCM
buffers (with appropriate casting i.e. from 8bit to 16bit); and
hopefully the file recorded in Audacity is then the "stream" (well, bulk
messages data) sent by FT232.
[...] but its not even a variable :)
Yes it is, it's a variable otherwise you would not be able to reference
it :)
Heh, indeed, sorry for my hastened thought :) What I meant is that, we have:
static void ftdi_shutdown(struct usb_serial *serial)
and that function gets "somehow" transparently called by the system, and
*serial is passed by the system (well, usb-serial.c, I'm guessing) - it
is not something declared in ftdi_sio.c or .h, for instance.
But then, I guess I could set a break at ftdi_shutdown and then watch,
say, *interface = serial->interface :)
You must be using a rather old kernel. ftdi_shutdown hasn't existed
since 2.6.30.
Indeed I am:
uname -r: 2.6.28-18-generic
cat /etc/issue: Ubuntu 9.04 \n \l
Serial drivers like ftdi_sio aren't supposed to use the interface's
driver_data field. However, that doesn't matter: If the driver_data
field had not been set to NULL then it would contain a pointer to the
usb_serial structure -- and ftdi_sio_shutdown() is already provided
with such a pointer as its argument.
Since usb-serial already uses the interface's driver_data field for its
own purposes, you must not store audio data there too.
>> So these are the questions I have:
>>
>> - Is there an easy/obvious reason, why this pointer is reset at
>> _shutdown, that I'm missing?
>
> Yes: Because you're not supposed to be using the pointer.
>
Thanks so much for this explanation - it would otherwise have taken me
quite a lot to reach a similar conclusion :)
- How could I debug this? Ideally, I'd like to put a watch on
usb_serial->interface->dev->driver_data and see when it changes (and
what changes it) - but its not even a variable :)
There's nothing to debug; I can tell you where the pointer is set to
NULL. In usb-serial.c, near the start of usb_serial_disconnect()
you'll see:
usb_set_intfdata(interface, NULL);
That's what does it.
And even more, thanks for this - although logical for me now, I wouldn't
have easily thought, that I should take a look at usb-serial again.
The thing is - for the ALSA side of things, I tried to reuse usbaudio
code (and it uses ->driver_data), and I didn't think it would interfere
with usb-serial -- precisely because I saw ftdi_sio was not really
making a use of it.
>
> You could just use kdb if you like assembly language.
>
> I don't know if it was present in 2.6.30, but in more recent kernels
> you can look through samples/hw_breakpoint.
>
Thanks for the info, very useful !!
Well, thanks again for the great answers - I guess I need to take a step
back, and possibly rethink my strategy, but at least now I have a better
idea of what to focus on :) Btw, if there are more examples related to
what I'm trying to do, I'd love to hear about 'em :)
Best regards,
Cheers!
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html