Page 1 of 3

PCI Question(s)

Posted: Thu Aug 14, 2008 4:26 am
by Omega
Hi. I plan on using the PCI for talking with a SCSI Hard Disk Controller, so I was wondering if I needed to remap its IRQ for anything? I figure I wouldn't need to considering that I am dealing with a mass storage device and using the BARs to send and receive data/commands, so it isn't like I need to wait for an IRQ to signal a reply from the controller. The reason I ask is because I looked at some linux PCI code (modified versions) and I noticed them using callbacks and though I really didn't understand why or how, thus *assuming* they remapped the IRQ belonging to that controller. Please clarify.

Furthermore, in reference to this code:

Code: Select all

#define HDC_DRV_SELECT 0x1F6
#define HDC_IDENTIFY 0xEC
#define HDC_COMMAND_PORT 0x1F7 

unsigned int IsATA(unsigned char drive)
{
	outl(drive,HDC_DRV_SELECT);
	delay(1);
	outl(HDC_IDENTIFY,HDC_COMMAND_PORT);
	return inl(HDC_COMMAND_PORT);
}
This code is not working at all. I receive a false positive when in my test env I should receive a number greater than 0 which I do, because I have an IDE Device (though emu), and on real hardware I should receive a 0 thus indicating no device on IDE bus. However, the case is that I am told by the above function that indeed I do have something attached to the IDE Bus, could this be my ATAPI-CD-ROM and if so, how can I tell if it is a mass storage device and not a CD-ROM device?

That function above is going out as an unsigned int (32 bits or 4 bytes) which I know is 4 times more than I need (8 bits or unsigned char); however, I couldn't use my outb because I was receiving this error:
warning: large integer implicitly truncated to unsigned type
So, I tried using my outl which compiled without error, but works in error nevertheless. Please advise.

One last question: Does anyone have an example of C code where one is actually using their PCI driver? If so, please post.

Thanks

Re: PCI Question(s)

Posted: Thu Aug 14, 2008 2:58 pm
by bewing
1) You will need to use IRQs with PCI. Most PCI devices will use Busmastering DMA. The only way that your OS will know that a DMA transfer is complete is that the device will send you an IRQ. But the BIOS has already mapped the IRQs for the PCI devices, and you probably wil not need to fool with changing it.

2) Clearly your code for outb is screwy. If you post it, maybe we can fix it.

3) Yes, your ATAPI device will definitely show up as existing, but it will throw an error just after receiving the IDENTIFY command.

4) If any device exists, and does not error out immediately after the IDENTIFY, then you must read the 256 words of IDENTIFY data -- the controller will not let you send a command to any other drive until you have read in the data that you just requested.

5) You judge the type of attached hardware (ATAPI, SATA) by the "error message" that you get back from the controller after you send an ATA IDENTIFY, if the ERR bit is set in the Status Register (0x1F7).

6) Outputting a long, like this, onto the IO Port bus will probably have funny effects. The thing is, I forget which order the long will be sent. If it sends the 0xEC first, then a string of three zero bytes to the command port, then the zero bytes will cause the device to drop the ERR flag. So you will never know if the device got an error, and you will never be able to detect ATAPI/SATA.

7) 0xFF is just as legal a return value from your inl call as 0. So you need to be testing on more than just a 0 return.

Re: PCI Question(s)

Posted: Thu Aug 14, 2008 2:58 pm
by Omega
anyone know?

EDIT: Look at that, we posted the exact same time. :)

Code: Select all

void outb(unsigned short _port, unsigned char _data) //output a byte to a port
{
  // "a" (_data) means: load EAX with _data
  // "d" (_port) means: load EDX with _port
  __asm__ __volatile__("outb %%al, %%dx" : :"a" (_data), "d" (_port));
}
There is my outb.

EDIT: In regards to IRQs. My Raid Controller is using IRQ 11, so can I treat it like everything else and install a handler for it, something like:

Code: Select all

void pci_handler(void)
{
//do stuff
//send acknowledgment?
}

void init_pci(void)
{
irq_install_handler(11,pci_handler)
}
EDIT: When a driver issues a PIO read or write command, it needs to wait until the drive is ready before transferring data. There are two ways to know when the drive is ready for the data. The drive will send an IRQ when it is good and ready. Or, a driver can poll one of the Status ports (either the Regular or Alternate Status).

There are two advantages to polling, and one gigantic disadvantage. Advantages: Polling responds more quickly than an IRQ. The logic of polling is much simpler than waiting on an IRQ.

The disadvantage: In a multitasking environment, polling will eat up all your CPU time. However, in singletasking mode this is not an issue (the CPU has nothing better to do) -- so polling is a good thing, then.

How to poll (waiting for the drive to be ready to transfer data): Read the Regular Status port until bit 7 (BSY, value = 0x80) clears, and bit 3 (DRQ, value = 8) sets -- or until bit 0 (ERR, value = 1) or bit 5 (DF, value = 0x20) sets. If neither error bit is set, the device is ready right then.

I use a single-tasking OS, so do I really need the IRQ or can I just query the status port after all? thanks

Re: PCI Question(s)

Posted: Thu Aug 14, 2008 5:26 pm
by bewing
If you are intending to stick with singletasking forever, then yes, you can also stick with polling forever, and forget about IRQs -- except that you will still need to do little EOI-type housekeeping details, of course.

I'm not a GCC expert, so I can't see any reason why that outb function would give you that error message.

Re: PCI Question(s)

Posted: Thu Aug 14, 2008 5:55 pm
by Omega
Can I achieve that same thing just by allocating let's say 512 bytes and polling until I get 512 bytes? No need to know when the device is done reading, because once it gives me all 512 bytes I am done, right? Unless an EOI is needed to tell the Device to rest or something.

No worries about the function, I am re-writing that function based on the ATA PIO wiki thing. Hopefully I can swing it. thanks

Re: PCI Question(s)

Posted: Thu Aug 14, 2008 9:22 pm
by Omega
It is obvious that neither one of us was looking at my code clearly. I discovered that I was sending the ports in the data position and vice-versa, so I was just putting values in the outb function backwards. It compiled now, so I guess that is cleared up now. As for the other questions above, I still am looking for clarification/code examples:

To repeat:

01. Can I just allocate memory without using IRQs for EOI or is EOI necessary regardless?

EDIT: Got it. No need for EOI if I am not using IRQs.

02. Will someone please show me an example of them actually using their PCI driver?

thanks

EDIT: I thought I finally got my is_ide_ata function working. I am testing in MS-VPC and I turned off my IDE thing in the settings and it returned 255 or 0xFF (no ata on ide), then I turned it back on and it returns 88 (so there is an ata on ide bus). Now, when I try it on real hardware, it returns something else (haven't captured the return on that yet), thus denoting that there is an ata on ide, but there is not an ata on ide! I mean wtf could be causing this now? I want to just disconnect my cd-roms from the ide and test it, but that requires me to break open my box and fiddle with my junk and I prefer not to fiddle with my own junk unless necessary, so am I missing something here:

Code: Select all

//once upon a time...
unsigned int is_ide_ata(unsigned short drive)
{
	//HarddiskWaitForController(); //device wait; waits forever, so I comment it out... wanna help?
	outb(0x1F6, drive); //select pri:0xA0 or sec: 0xB0, or E0/FO for LBA, I like LBA!!
	delay(1); //400ns, give or take a view ns, more like one second... how do you do it so well?
	outb(0x1F7,0xEC); //send ATA IDENTIFY Command right this very instant!!
	return inb(0x1F7); //read response, it better be there or I am going after PCI!!
}
//look out down below...
if(is_ide_ata(0xE0)!=255)
{
    //ATA found riding the IDE bus
} else {
   //ATA must be living in PCI Land or could it be SCSI, or both?? Mine is, is yours?
}
//the end
I just feel like something is missing or could be improved, did I mention this doesn't work on real hardware? thanks

Re: PCI Question(s)

Posted: Fri Aug 15, 2008 10:18 pm
by Omega
I really hope someone will help me out now. I have taken a look at my Device Manager in Windows and it shows that I have an IDE ATA/ATAPI controller on the PCI Bus, and I can enum it using my OS drivers but it returns 1 when reading the BARs, what does this mean?

I also noticed that my Hard Disk is SCSI and is located bus 0, Target ID 1, LUN 0. What does this mean, LUN and Target ID? How do I access them? I have been getting use to using Bus, Dev, Fun, so I have never heard of LUN or Target ID.

If I am trying to access my hard disk, should I be going for the RAID Controller, this PCI IDE controller, or this SCSI controller (e.g., the LUN, Target ID thing)? thanks

Re: PCI Question(s)

Posted: Mon Aug 18, 2008 5:11 am
by JamesM
Hi,

When reading the BARs - have you actually set them first? I.e. writing 0xFFFFFFFF to the BAR, then reading back (remember to read TWICE to avoid bus ghosts).

I apologise if this is patronising but you haven't mentioned whether you've done it or not!

Cheers,

James

Re: PCI Question(s)

Posted: Mon Aug 18, 2008 8:58 am
by Brendan
Hi,
Omega wrote:I really hope someone will help me out now. I have taken a look at my Device Manager in Windows and it shows that I have an IDE ATA/ATAPI controller on the PCI Bus, and I can enum it using my OS drivers but it returns 1 when reading the BARs, what does this mean?
I'm guessing, but it probably means the ATA/ATAPI controller is still in "compatibility mode" (where it ignores the BARs and tries to pretend it's a legacy ISA device). Did you check the "Programming Interface" field (the byte at offset 0x09) in PCI Configuration Space?

Here's a description of this byte, from the relevant documentation:
"Bit 0 - Determines the mode that the primary IDE channel is operating in. Zero corresponds to 'compatibility', one means native-PCI mode. This bit is implemented as read-only if the channel supports only one mode, or read-write if both modes are supported. The powerup state for this bit (when writable) can be either 0 or 1.
Bit 1 - This bit indicates whether or not the primary channel has a fixed mode of operation. If this bit is zero, the mode is fixed and is determined by the (read-only) value of bit 0. If this bit is one, the channel supports both modes and may be set to either mode by writing bit 0.
Bit 2 - Determines the mode that the secondary IDE channel is operating in. Zero corresponds to 'compatibility', one means native-PCI mode. This bit is implemented as read-only if the channel supports only one mode, or read-write if both modes are supported. The powerup state for this bit (when writable) can be either 0 or 1.
Bit 3 - This bit indicates whether or not the secondary channel has a fixed mode of operation. If this bit is zero, the mode is fixed and is determined by the (read-only) value of bit 0. If this bit is one, the channel supports both modes and may be set to either mode by writing bit 0.
"
Omega wrote:I also noticed that my Hard Disk is SCSI and is located bus 0, Target ID 1, LUN 0. What does this mean, LUN and Target ID? How do I access them? I have been getting use to using Bus, Dev, Fun, so I have never heard of LUN or Target ID.
Think of the SCSI controller as a kind of bridge, with the PCI bus on one side and one or more SCSI buses on the other side. On the SCSI bus devices have a LUN (Logical Unit Number) and so does the controller. This means that "PCI bus 1, device 2, function 3" could be the address of the SCSI controller on the PCI bus, "SCSI bus 0, LUN 7" might be the address of the same controller on the SCSI bus, and "SCSI bus 0, LUN 0" might be the address of a disk drive on the SCSI bus. I don't really know what the intended purpose of the Target ID is (it seems to have the same purpose as the LUN)...
Omega wrote:If I am trying to access my hard disk, should I be going for the RAID Controller, this PCI IDE controller, or this SCSI controller (e.g., the LUN, Target ID thing)? thanks
If your hard drive is a SCSI drive then it'd be connected to the SCSI controller (or maybe a SCSI RAID controller), and wouldn't be connected to an IDE/ATA/ATAPI controller (or to an IDE/ATA/ATAPI RAID controller). In this case you're partially screwed, because each SCSI controller has it's own low-level programming interface, so you'd need the documentation for your specific controller - it's not like IDE/ATA/ATAPI/SATA where all manufacturers use the same low-level programming interface (or more correctly, the same set of low-level programming interfaces).


Cheers,

Brendan

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 3:05 pm
by Omega
Very informative! Thank you so much!

Here is what I have:

Here is what I have been going after:

Code: Select all

 Bus 1 (PCI), Device Number 11, Device Function 0
 Vendor 1095h Silicon Image Inc (Was: CMD Technology Inc)
 Device 3112h SiI 3112 SATARaid Controller
 Command 0007h (I/O Access, Memory Access, BusMaster)
 Status 02B0h (Has Capabilities List, Supports 66MHz, Supports Back-To-Back Trans., Medium Timing)
 Revision 02h, Header Type 00h, Bus Latency Timer 20h
 Self test 00h (Self test not supported)
 Cache line size 32 Bytes (8 DWords)
 PCI Class Storage, type RAID
 Subsystem ID 61121095h SiI 3112 SATARaid Controller
 Subsystem Vendor 1095h Silicon Image Inc (Was: CMD Technology Inc)
 Address 0 is an I/O Port : 00009800h
 Address 1 is an I/O Port : 00009C00h
 Address 2 is an I/O Port : 0000A000h
 Address 3 is an I/O Port : 0000A400h
 Address 4 is an I/O Port : 0000A800h
 Address 5 is a Memory Address (anywhere in 0-4Gb) : DF006000h
 System IRQ 18, INT# A
 Expansion ROM of 512Kb decoded by this card (Currently disabled)
 New Capabilities List Present:
   Power Management Capability, Version 1.1
     Supports low power State D1
     Supports low power State D2
     Does not support PME# signalling
     Current Power State : D0 (Device operational, no power saving)
     Power Data Registers Information:
      D0 Power Consumed: 1000mW
      D1 Power Consumed: 1000mW
      D2 Power Consumed: 1000mW
      D3 Power Consumed: 1000mW
      D0 Power Dissipated: 1000mW
      D1 Power Dissipated: 1000mW
      D2 Power Dissipated: 1000mW
      D3 Power Dissipated: 1000mW
I actually return the correct vendor/device ID as well as the correct BARs and sizes/type (I/O||Memory). When I scan the PCI bus I don't actually return anything for the SCSI Hard Disk I mentioned above even though it is on PCI Bus #0. In fact, on Bus 0 I have:

1. AGP Controller
5. Memory Controllers
1. ISA Bridge
1. SMBus Controller
3. USB Controllers
1. Network Adapter
1. Audio Processing Unit
1. Audio Codec
1. CPU to PCI Bridge
1. ATA Controller (No bars)
1. Firewire Controller
1. AGP Bridge

Could this thing be on the ISA Bridge? Or disguised as ATA?

Code: Select all

 Bus 0 (PCI), Device Number 9, Device Function 0
 Vendor 10DEh Nvidia Corp
 Device 0065h nForce2 ATA Controller
 Command 0005h (I/O Access, BusMaster)
 Status 00B0h (Has Capabilities List, Supports 66MHz, Supports Back-To-Back Trans., Fast Timing)
 Revision A2h, Header Type 00h, Bus Latency Timer 00h
 Minimum Bus Grant 03h, Maximum Bus Latency 01h
 Self test 00h (Self test not supported)
 PCI Class Storage, type IDE (ATA)
 PCI EIDE Controller Features :
   BusMaster EIDE is supported
   Primary   Channel is at I/O Port 01F0h and IRQ 14
   Secondary Channel is at I/O Port 0170h and IRQ 15
 Subsystem ID 1C00147Bh Unknown
 Subsystem Vendor 147Bh Abit Computer Corp
 Address 4 is an I/O Port : 0000F000h
 New Capabilities List Present:
   Power Management Capability, Version 1.1
     Does not support low power State D1 or D2
     Does not support PME# signalling
     Current Power State : D0 (Device operational, no power saving)
Or, is it behind this RAID Controller?

Code: Select all

 Bus 1 (PCI), Device Number 11, Device Function 0
 Vendor 1095h Silicon Image Inc (Was: CMD Technology Inc)
 Device 3112h SiI 3112 SATARaid Controller
 Command 0007h (I/O Access, Memory Access, BusMaster)
 Status 02B0h (Has Capabilities List, Supports 66MHz, Supports Back-To-Back Trans., Medium Timing)
 Revision 02h, Header Type 00h, Bus Latency Timer 20h
 Self test 00h (Self test not supported)
 Cache line size 32 Bytes (8 DWords)
 PCI Class Storage, type RAID
 Subsystem ID 61121095h SiI 3112 SATARaid Controller
 Subsystem Vendor 1095h Silicon Image Inc (Was: CMD Technology Inc)
 Address 0 is an I/O Port : 00009800h
 Address 1 is an I/O Port : 00009C00h
 Address 2 is an I/O Port : 0000A000h
 Address 3 is an I/O Port : 0000A400h
 Address 4 is an I/O Port : 0000A800h
 Address 5 is a Memory Address (anywhere in 0-4Gb) : DF006000h
 System IRQ 18, INT# A
 Expansion ROM of 512Kb decoded by this card (Currently disabled)
 New Capabilities List Present:
   Power Management Capability, Version 1.1
     Supports low power State D1
     Supports low power State D2
     Does not support PME# signalling
     Current Power State : D0 (Device operational, no power saving)
     Power Data Registers Information:
      D0 Power Consumed: 1000mW
      D1 Power Consumed: 1000mW
      D2 Power Consumed: 1000mW
      D3 Power Consumed: 1000mW
      D0 Power Dissipated: 1000mW
      D1 Power Dissipated: 1000mW
      D2 Power Dissipated: 1000mW
      D3 Power Dissipated: 1000mW
thanks

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 4:56 pm
by Omega
I also wanted to indicate that my "SCSI" Hard Disk is actually a S-ATA. I think it identifies as SCSI but on the actual hardware it prints S-ATA, so you think it is behind that RAID controller? Gosh, I hope so. How can I reach through and ask who it is? Here is the specs for my disk: http://www.roscopc.com/p.php?p=1011

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 6:23 pm
by bewing
Yes, you only have one SATA controller on the system -- the RAID controller. If you have a SATA drive, then it is being controlled by that controller.

To understand how to query the drives on that controller, you need the programmer's manual for the RAID controller. You will need to make a device-specific driver for it. Go to the manufacturer's website and look for documentation. It may be "closed-source hardware", and you may not be able to get the programmer's manual. If so, you are pretty much SOL -- unless there is an open-source Linux driver for it.

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 8:34 pm
by quok
bewing wrote:Yes, you only have one SATA controller on the system -- the RAID controller. If you have a SATA drive, then it is being controlled by that controller.

To understand how to query the drives on that controller, you need the programmer's manual for the RAID controller. You will need to make a device-specific driver for it. Go to the manufacturer's website and look for documentation. It may be "closed-source hardware", and you may not be able to get the programmer's manual. If so, you are pretty much SOL -- unless there is an open-source Linux driver for it.
Even if there is an open source Linux driver for it, you may still be SOL if you want to use code from it (or even get ideas) in your hobby OS, unless your OS is also licensed under the GPL. I typically point people to one of the BSDs when they are looking for sample source code. Not because the source is any easier to read, but just because in most cases I don't know the license of the person's OS, and the BSD license is much friendlier to those of us who aren't using the GPL for our projects.

That being said, I'm not certain if any of the BSDs even support this device, and I'm a bit too lazy to look, but openbsd.org is your friend. :)

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 8:48 pm
by Brynet-Inc
OpenBSD seems to support this device via its pciide(4) driver.

Searching through the source tree shows several chipset specific helper/workaround functions.. perhaps you should look into it.

Relevant files:
/usr/src/sys/dev/pci/pciide.c
/usr/src/sys/dev/pci/pciide_sii3112_reg.h

Good luck.. there is a postscript document floating around that might be helpful, pciide.ps.

Re: PCI Question(s)

Posted: Mon Aug 25, 2008 9:12 pm
by Omega
All I can say is... OMG!!! That code is so f-ed up!! It looks like I am going to be stripping the hell out of this one. I'll be back in about a month, maybe longer. lol

thanks for the help guys.

P.s. Google is your Friend too. ;)