After I committed my previous set of CardBus fixes, reports came in about interrupt storms, first with 16-bit cards, and later with 32-bit cards. These have been corrected in my latest fixes. We always act the CSTS interrupt when we see it. In addition, I've changed the acking of the 16-bit ExCA register to only happen when there's a "R2" or 16-bit card in the slot. Otherwise we now skip it. Hopefilly, this will help the shared interrupt case as well by eliminating some PCI bus cycles...
The CSTS bit is interesting. It is the least well documented bit in the CardBus standard. It is unclear when it fires from reading the standard, but seems to be related to the card finishing its reset sequence. How this differs from the power-up interrupt, I'm not sure. I think we could further optimize the bring up of CardBus cards with it.
In addition, I noticed there's a READY bit in the ExCA CSC register. We're currently doing busy waits to bring up the cards, including a couple of millisecond long DELAYs. I'll have to look into the prospect of using that interrupt to get around these issues there.
Finally, I'm looking in earnest at the Alchemy Au1550 CPU for the OpenMicroServer port I'm doing. I've noticed that it uses a 16-bit PC Card interface. Maybe I'll finally need to rewrite the old PCIC driver from OLDCARD to make use of it (snagging the exca routines to make that easier). The OpenMicroServer has a CF card attached to it.
Showing posts with label PC Card. Show all posts
Showing posts with label PC Card. Show all posts
20081213
20081204
Cardbus Fixes
I just checked into the tree some CardBus fixes. The biggest change was to the power-up sequence, as well as transitioning to using filters for the card change events. These two changes are somewhat intertwined, unfortunately, since the latter exposed some holes in the former. In a nutshell, we now register a filter for the card status change events. This means we can mark the card as bad right away before any additional interaction can happen to the card. We defer doing anything about the badness for a little bit (basically until the machine is idle enough for the cardbus kernel thread to run). The interlock mechanism is also much ligher weight, having moved from mutexes and CVs to simple msleeps. Fast interrupts require some care to get right, so I hope I've gotten it all right. The move is dictated by what you can and cannot do in a fast interrupt handler.
Before making these changes, my atheros card would often reset for no reason. After these changes, I've not had it reset until I started using a kernel without the changes. I'm not sure why this would make such a big difference, and I hate mysteries. They indicate that there's something I don't understand, which I also hate. I'd be interested to see if I still see this when the fully integrated code is committed and looped back (I have several trees, and I most frequently run an unmodified kernel from svn, but sometimes also run one of these trees). There's a small chance that one of my other local changes could be the cause, but given what they are it seems doubtful. Still, a good datapoint if it is.
In addition, these fixes add a retry option for the BadVcc errors that we'd see sometimes. These are annoying on some machines, and often times the best way to get around them was to reload the driver. They don't happen at all on TI based chipsets that I've seen (at least more recent ones). Instead, they were confined to the Ricoh chipsets. Since I switched my laptop a couple of years ago, I haven't seen them. These changes post-date the change, but have been tested lightly on another Ricoh laptop that I have. They've been heavily tested on the TI laptop. They are based only on the description of the problem in the NetBSD PR, since the implementations are so different for the different BSDs in this area.
Finally, I did some comment tweaking and shuffling. I also managed a style change or two. These should have absolutely no effect on the running code, but hopefully help the reader of the code understand it better. Past experience has shown that these types of commits are most likely to provoke comment, even though the other two parts of my commits are actually quite a bit more important.
Oh, why the flurry of commits? I was low on disk space, so I thought I'd go clean up. 11MB free just isn't enough. So I was looking around and discovered I still had a CVS tree and was going to blow it away. I did a final update just to see what changes I had. I'm glad I did, since I found these, and a few others. I still have more local changes there than I realized. Sometimes I guess it is good to run out of disk space and go on a cleaning spree? It also makes for smaller backups when you don't have top copy 5GB of /usr/obj and kernel build trees...
Before making these changes, my atheros card would often reset for no reason. After these changes, I've not had it reset until I started using a kernel without the changes. I'm not sure why this would make such a big difference, and I hate mysteries. They indicate that there's something I don't understand, which I also hate. I'd be interested to see if I still see this when the fully integrated code is committed and looped back (I have several trees, and I most frequently run an unmodified kernel from svn, but sometimes also run one of these trees). There's a small chance that one of my other local changes could be the cause, but given what they are it seems doubtful. Still, a good datapoint if it is.
In addition, these fixes add a retry option for the BadVcc errors that we'd see sometimes. These are annoying on some machines, and often times the best way to get around them was to reload the driver. They don't happen at all on TI based chipsets that I've seen (at least more recent ones). Instead, they were confined to the Ricoh chipsets. Since I switched my laptop a couple of years ago, I haven't seen them. These changes post-date the change, but have been tested lightly on another Ricoh laptop that I have. They've been heavily tested on the TI laptop. They are based only on the description of the problem in the NetBSD PR, since the implementations are so different for the different BSDs in this area.
Finally, I did some comment tweaking and shuffling. I also managed a style change or two. These should have absolutely no effect on the running code, but hopefully help the reader of the code understand it better. Past experience has shown that these types of commits are most likely to provoke comment, even though the other two parts of my commits are actually quite a bit more important.
Oh, why the flurry of commits? I was low on disk space, so I thought I'd go clean up. 11MB free just isn't enough. So I was looking around and discovered I still had a CVS tree and was going to blow it away. I did a final update just to see what changes I had. I'm glad I did, since I found these, and a few others. I still have more local changes there than I realized. Sometimes I guess it is good to run out of disk space and go on a cleaning spree? It also makes for smaller backups when you don't have top copy 5GB of /usr/obj and kernel build trees...
20080623
Old cards and the information gap
This time I'll explore some of the issues relating to hacking on older hardware. I'll talk about expanding the work I did for the Olicom OC-2220 to the combo OC-2232 and the problems encountered.
In a previous edition, I talked about the Olicom OC-2220 card and getting it working. It works great, and in fact, I'm using it right now to make this blog entry. However, the next card I tried didn't fare so well. This is the Olicom OC-2232, which added a 33.6k modem to the same basic design as the OC-2220. It exposes the ethernet and modem such that I had to augment the PC Card system to access. I had to be able to specify the config entry to use to configure the resources for the card. However, when I started, FreeBSD's PC Card system lacked this feature.
I was able to augment FreeBSD's PC Card system to have a feature that's been requested infrequently. The ability for the driver to select the config entry to use. Right now, all of the FreeBSD PC Card drivers have been able to use the config entry that the system guesses is the right one. However, there are some combo cards that pre-date the PCMCIA multifunction standard that need to select a config entry.
So, after adding this, it was a simple matter to get the ex driver selecting the appropriate alternate config entry for the Olicom OC-2232 that I have. This card has the Intel 82595 and a 16550 compatible 33.6k modem on it. By default, FreeBSD will happen to pick the entry that corresponds to the modem only. However, with my hacks I have been able to make it select either the ethernet side only or both. FreeBSD needs a few changes to allow it to support both of these devices at the same time, but I'll write more about that at another time.
So the card comes up, and I'm able to attach to the ex driver. But there's a problem. dhclient doesn't finish. For the OC-2220, this returns immediately, so I know that the dongle cable is good, as is the port on the hub. The OC-2232 uses the same cables, as far as I can tell, but when I try to push packets through, I never get any interrupts, so dhclient never finishes. I've not instrumented the driver to see if adding a watchdog timeout would help make this work in the absence of interrupts or not.
This leads me think about some of these old cards that I have. It is impossible to get information on them. The best I've been able to find is binary only Windows and DOS drivers for them. These drivers don't work with the current version of Windows that I have on my laptop. This makes it hard to know if the problem I'm encountering is a hardware problem or a software problem. There's no support for this card in Linux (the base kernel doesn't support and 82595 based PC Cards, and it is nearly impossible to find a driver for the few cards that used this chip that wasn't incorporated into the kernel).
So assuming the card is good, there's no source available for it. I knew there was a similar card made by Silicom called the EtherSerial card. It has a real serial port in addition to the 82595 ethernet controller on it. Searching for it was difficult. Most likely there's a trick to forcing google to tell me "Where do I find the file silpmcica-1.02b.tar.gz?" with all the variant spellings and encodings (.tgz, tar.bz2, .tbz, .tbz2, etc), but I didn't see it. Altavista used to have this feature, and I'm sure that some sharp reader will tell me how to make google do it.
I was able to find, using the internet archive, the driver for the Silicom card. Well, kinda. I was able to discover the name of the file, and also discover that the internet archive didn't cache the files that people put on their FTP sites, so when I clicked on the driver link there, it tried to grab it from Silicom's current FTP server, which isn't setup for anonymous operation.
I was able to find the datasheets for this old part, however. I was lucky this part was popular enough that the various datasheet web sites have it available. There were three variants of the part, and only the FX variant appears to have been used in the PC Card devices.
So the resort of looking for data for this card was somewhat less successful than looking for data for the Crystal Semi based card that I had. There I was able to find everything I needed, but my needs were more meager. Now, I'm left wondering: do I have bad hardware? Do I need to prod some hidden register to turn on interrupts? Do I need to disassemble the drivers that I found to make further progress? These are all good questions, and I don't have the answers to any of them. All the questions that lead me to make progress involve a lot of time doing unfun tasks that really gain me no pleasure or knowledge.
Anyway, my trip down memory lane must end soon. I have other commitments in FreeBSD that I need to return to soon. This was a fun diversion (and hardware that's easy to carry), but I'm afraid this unsatisfying dead-end will likely be where this problem sits for a while as I have some processor porting work to do for people that have donated hardware to me. I've put that off long enough based on the fun I had one night with one PC Card. I'm afraid I'm going to have to put them back on the back burner unless new information surfaces. The other hardware is more relevant, and while it is fun to misbehave sometimes with something that may not be relevant for the fun of it, there's a different kind of fun to be had when doing things with more relevant hardware, and I think it is time I got back to that kind of fun in my spare time.
In a previous edition, I talked about the Olicom OC-2220 card and getting it working. It works great, and in fact, I'm using it right now to make this blog entry. However, the next card I tried didn't fare so well. This is the Olicom OC-2232, which added a 33.6k modem to the same basic design as the OC-2220. It exposes the ethernet and modem such that I had to augment the PC Card system to access. I had to be able to specify the config entry to use to configure the resources for the card. However, when I started, FreeBSD's PC Card system lacked this feature.
I was able to augment FreeBSD's PC Card system to have a feature that's been requested infrequently. The ability for the driver to select the config entry to use. Right now, all of the FreeBSD PC Card drivers have been able to use the config entry that the system guesses is the right one. However, there are some combo cards that pre-date the PCMCIA multifunction standard that need to select a config entry.
So, after adding this, it was a simple matter to get the ex driver selecting the appropriate alternate config entry for the Olicom OC-2232 that I have. This card has the Intel 82595 and a 16550 compatible 33.6k modem on it. By default, FreeBSD will happen to pick the entry that corresponds to the modem only. However, with my hacks I have been able to make it select either the ethernet side only or both. FreeBSD needs a few changes to allow it to support both of these devices at the same time, but I'll write more about that at another time.
So the card comes up, and I'm able to attach to the ex driver. But there's a problem. dhclient doesn't finish. For the OC-2220, this returns immediately, so I know that the dongle cable is good, as is the port on the hub. The OC-2232 uses the same cables, as far as I can tell, but when I try to push packets through, I never get any interrupts, so dhclient never finishes. I've not instrumented the driver to see if adding a watchdog timeout would help make this work in the absence of interrupts or not.
This leads me think about some of these old cards that I have. It is impossible to get information on them. The best I've been able to find is binary only Windows and DOS drivers for them. These drivers don't work with the current version of Windows that I have on my laptop. This makes it hard to know if the problem I'm encountering is a hardware problem or a software problem. There's no support for this card in Linux (the base kernel doesn't support and 82595 based PC Cards, and it is nearly impossible to find a driver for the few cards that used this chip that wasn't incorporated into the kernel).
So assuming the card is good, there's no source available for it. I knew there was a similar card made by Silicom called the EtherSerial card. It has a real serial port in addition to the 82595 ethernet controller on it. Searching for it was difficult. Most likely there's a trick to forcing google to tell me "Where do I find the file silpmcica-1.02b.tar.gz?" with all the variant spellings and encodings (.tgz, tar.bz2, .tbz, .tbz2, etc), but I didn't see it. Altavista used to have this feature, and I'm sure that some sharp reader will tell me how to make google do it.
I was able to find, using the internet archive, the driver for the Silicom card. Well, kinda. I was able to discover the name of the file, and also discover that the internet archive didn't cache the files that people put on their FTP sites, so when I clicked on the driver link there, it tried to grab it from Silicom's current FTP server, which isn't setup for anonymous operation.
I was able to find the datasheets for this old part, however. I was lucky this part was popular enough that the various datasheet web sites have it available. There were three variants of the part, and only the FX variant appears to have been used in the PC Card devices.
So the resort of looking for data for this card was somewhat less successful than looking for data for the Crystal Semi based card that I had. There I was able to find everything I needed, but my needs were more meager. Now, I'm left wondering: do I have bad hardware? Do I need to prod some hidden register to turn on interrupts? Do I need to disassemble the drivers that I found to make further progress? These are all good questions, and I don't have the answers to any of them. All the questions that lead me to make progress involve a lot of time doing unfun tasks that really gain me no pleasure or knowledge.
Anyway, my trip down memory lane must end soon. I have other commitments in FreeBSD that I need to return to soon. This was a fun diversion (and hardware that's easy to carry), but I'm afraid this unsatisfying dead-end will likely be where this problem sits for a while as I have some processor porting work to do for people that have donated hardware to me. I've put that off long enough based on the fun I had one night with one PC Card. I'm afraid I'm going to have to put them back on the back burner unless new information surfaces. The other hardware is more relevant, and while it is fun to misbehave sometimes with something that may not be relevant for the fun of it, there's a different kind of fun to be had when doing things with more relevant hardware, and I think it is time I got back to that kind of fun in my spare time.
20080613
Olicom OC-2220 works
After applying John Bladwin's MPSAFE patches to the ex driver, the ex driver works with the Olicom OC-2220. If you are unfamiliar with this card, I'm not surprised. It was made in the mid 1990's. From a network perspective, it isn't that important. It is a slow 10BaseT card that doesn't seem to do full duplex.
However, from the PC Card perspective, there's some interesting things with ex. There's the Olicom OC-2232 that includes a modem. But it includes it in an interesting way that isn't quite standard. How do we pull in the serial port in this case? There's also some cards from Silicom that have a serial port bolted on as well, but in a different way. i've not seen good documentation for either of these cards, but at least there's a driver for the silicom available (or was once upon a time) for Linux. I sure hope that wasn't one of the things I lost in my disk crash...
So again, despite the age of the underlying chip, there's some interesting problems here. The trouble is that the problems are such that they can't easily be solved in an hour of hacking, so they may continue to linger....
However, from the PC Card perspective, there's some interesting things with ex. There's the Olicom OC-2232 that includes a modem. But it includes it in an interesting way that isn't quite standard. How do we pull in the serial port in this case? There's also some cards from Silicom that have a serial port bolted on as well, but in a different way. i've not seen good documentation for either of these cards, but at least there's a driver for the silicom available (or was once upon a time) for Linux. I sure hope that wasn't one of the things I lost in my disk crash...
So again, despite the age of the underlying chip, there's some interesting problems here. The trouble is that the problems are such that they can't easily be solved in an hour of hacking, so they may continue to linger....
20080612
Crystal Semiconductor Driver
Since I've been maintaining the PC Card layer in FreeBSD, I've accumulated a lot of PC Card hardware. Well over 100 different PC Card r2 (16-bit) and CardBus (32-bit) cards. Recently, Robert Watson started pushing to have all the network drivers in the tree be MPSAFE. John Bladwin posted some patches to the if_cs driver to bring it up to those standards. Since I had a soft spot in my heart for this driver for reasons I don't entirely understand, I took the IBM EtherJet PC Card that I had with me on a recent buisiness trip with the vague notion of testing out John's patches.
I discovered that the driver didn't work. It didn't work before the patches, nor after them. The breakage was minor and I likely wouldn't have noticed it except for the fact that I didn't have the Ethernet cable plugged in when I was doing the early testing. Since the breakage annoyed me, I went ahead and fixed it. I also noticed that the reading of the EEPROM was very slow, and caused me to drop characters when I inserted the card. I hate that. I discovered a number of DELAY statements in the EEPROM reading which were the cause of the problem. I thought "this is nuts" to myself, and went off to locate the datasheet for this part. After reading through it, I discovered the EEPROM busy bit that I polled in place of the hard coded 3ms DELAY. I went from having about 1.2s of DELAY and other busy waiting when I inserted the card to having on the order of 800us, a speedup of about 1500x.
This brings up a number of philosophical questions. Why did I bother with such an outdated chip? Why speed up a one time operation? Why spend any time at all on this after a busy day of meetings and crisis management?
Let's answer the last question first. I did it because I was absolutely exhausted by my meetings. While productive, and they helped to drive the problems of the project I was working on towards resolution, they were draining. By hacking on this driver I had a very safe area to make improvements. Unless I broke the build, nobody would notice the work, yet I'd have the satisfaction of a job well done. Since it is in an out-of-the way part of the kernel, I had the room to fail without throngs beating down my door. I had complete freedom to tinker and tidy as I saw fit, and doing so was very relaxing and invigorating after a long, hard day. Maybe I'm just weird, but sometimes a little bit of hacking to make something better is just what my brain needs to relax and unwind.
The reason I was spending any time at all on this was that this part made a resurgence in recent years inside embedded systems. There are several embedded designs that use this part when they don't have the ethernet on the SoC. More recent parts have all this built into the SoC, so the popularity has waned once again, but I knew some ARM boards used it, so in the back of my mind I had a justification for spending time on it based on my FreeBSD embedded hat that I wear from time to time. I was shocked to get email from someone who had one of these boards and wanted to know how to write a front end for this driver for that board within a day of my committing the cleanups. That was a nice bonus. Time will tell if he follows through, of course, but I was very amused by it.
Finally, why spend time optimizing an operation that happens only once at startup? I hate losing characters when I type. Since I didn't want to re-write the syscons keyboard driver to have a fast interrupt handler to read the keystrokes and queue them for later processing (the only thing that will interrupt a DELAY is a fast interrupt handler), I thought this was the easier path to solving my problem. I spend a lot of time at work making sure that the right priority calls are made, and it felt good to be "bad" and work on something that clearly is the wrong priority call in terms of everything else that's going on in FreeBSD.
I guess it all boils down to "I had an itch, and it felt good to scratch it." rather than any rational thought process. Sure, I justified it after the fact in many different ways, but it felt fundamentally good to just make something better for the sake of making it better and not have to worry about big picture this, or deadline that, or you broke my whatsit complaints. I had a well defined technical problem, I had to research solutions and hack a bit of code. It felt good being able to find the data I needed, fix the code, test it and see it working and passing packets again. I wish all problems that I faced in my technical life were so easy and rewarding.
Oh yea, and it turned out that I found a bug in John's patches and he was able to commit them to the tree, eliminating one more Giant Locked driver. I'm sure Robert will be happy. I'm sure there are others that would have been just as happy to have the impending removal of Giant Locked network drivers sweep it into the dustbin of history. Maybe I have that soft spot in my heart for it because it was one of the drivers that the Japanese Mobile community hacked years ago and seeing it the tree reminds me of happy trips to Japan, drinking way too much sake, and speaking bad Japanese as a result? Who knows....
I discovered that the driver didn't work. It didn't work before the patches, nor after them. The breakage was minor and I likely wouldn't have noticed it except for the fact that I didn't have the Ethernet cable plugged in when I was doing the early testing. Since the breakage annoyed me, I went ahead and fixed it. I also noticed that the reading of the EEPROM was very slow, and caused me to drop characters when I inserted the card. I hate that. I discovered a number of DELAY statements in the EEPROM reading which were the cause of the problem. I thought "this is nuts" to myself, and went off to locate the datasheet for this part. After reading through it, I discovered the EEPROM busy bit that I polled in place of the hard coded 3ms DELAY. I went from having about 1.2s of DELAY and other busy waiting when I inserted the card to having on the order of 800us, a speedup of about 1500x.
This brings up a number of philosophical questions. Why did I bother with such an outdated chip? Why speed up a one time operation? Why spend any time at all on this after a busy day of meetings and crisis management?
Let's answer the last question first. I did it because I was absolutely exhausted by my meetings. While productive, and they helped to drive the problems of the project I was working on towards resolution, they were draining. By hacking on this driver I had a very safe area to make improvements. Unless I broke the build, nobody would notice the work, yet I'd have the satisfaction of a job well done. Since it is in an out-of-the way part of the kernel, I had the room to fail without throngs beating down my door. I had complete freedom to tinker and tidy as I saw fit, and doing so was very relaxing and invigorating after a long, hard day. Maybe I'm just weird, but sometimes a little bit of hacking to make something better is just what my brain needs to relax and unwind.
The reason I was spending any time at all on this was that this part made a resurgence in recent years inside embedded systems. There are several embedded designs that use this part when they don't have the ethernet on the SoC. More recent parts have all this built into the SoC, so the popularity has waned once again, but I knew some ARM boards used it, so in the back of my mind I had a justification for spending time on it based on my FreeBSD embedded hat that I wear from time to time. I was shocked to get email from someone who had one of these boards and wanted to know how to write a front end for this driver for that board within a day of my committing the cleanups. That was a nice bonus. Time will tell if he follows through, of course, but I was very amused by it.
Finally, why spend time optimizing an operation that happens only once at startup? I hate losing characters when I type. Since I didn't want to re-write the syscons keyboard driver to have a fast interrupt handler to read the keystrokes and queue them for later processing (the only thing that will interrupt a DELAY is a fast interrupt handler), I thought this was the easier path to solving my problem. I spend a lot of time at work making sure that the right priority calls are made, and it felt good to be "bad" and work on something that clearly is the wrong priority call in terms of everything else that's going on in FreeBSD.
I guess it all boils down to "I had an itch, and it felt good to scratch it." rather than any rational thought process. Sure, I justified it after the fact in many different ways, but it felt fundamentally good to just make something better for the sake of making it better and not have to worry about big picture this, or deadline that, or you broke my whatsit complaints. I had a well defined technical problem, I had to research solutions and hack a bit of code. It felt good being able to find the data I needed, fix the code, test it and see it working and passing packets again. I wish all problems that I faced in my technical life were so easy and rewarding.
Oh yea, and it turned out that I found a bug in John's patches and he was able to commit them to the tree, eliminating one more Giant Locked driver. I'm sure Robert will be happy. I'm sure there are others that would have been just as happy to have the impending removal of Giant Locked network drivers sweep it into the dustbin of history. Maybe I have that soft spot in my heart for it because it was one of the drivers that the Japanese Mobile community hacked years ago and seeing it the tree reminds me of happy trips to Japan, drinking way too much sake, and speaking bad Japanese as a result? Who knows....
Subscribe to:
Posts (Atom)