# JMicron JMB362 AHCI Compatibility



## JohanDC (Aug 22, 2012)

hello all

First of all, I am a noob at FreeBSD, just started to play with it today and so far I am impressed!

Now while playing with FreeBSD 9 I noticed that one of my SATA controllers (JMicron JMB362 onboard controller on my ASUS M5A99X EVO MoBo) uses the ATA driver instead of the AHCI driver.

So I was wondering if there is any way to force FreeBSD to recognise it as an AHCI compliant controller?

So far I have checked & tried the following:
- Checked whether my onboard SATA controller is AHCI compliant: http://www.jmicron.com/PDF/JMB363/JMB362.pdf
- Checked whether it is supported by FreeBSD: http://www.jmicron.com/PDF/OSSupport/OS_Support.pdf
- Checked whether AHCI was enabled for this controller in my BIOS (which was already enabled)
- Updated my MoBo BIOS to the latest release (v1208)
- Added ahci_load="YES" to /boot/loader.conf (not sure whether this is still useful in FreeBSD9)

But so far none of these attempts resulted in recognising this controller as an AHCI device. 

[CMD=""]cat /var/log/system.log | grep ata[/CMD] shows me:

```
Aug 22 12:42:55 nas4free kernel: atapci1: <JMicron ATA controller> port 0x5028-0x502f,0x5020-0x5023,
0x5018-0x501f,0x5014-0x5017,0x5000-0x500f mem 0xd6500000-0xd65001ff irq 18 at device 0.0 on pci4
Aug 22 12:42:55 nas4free kernel: ata2: <ATA channel 0> on atapci1
Aug 22 12:42:55 nas4free kernel: ata3: <ATA channel 1> on atapci1
Aug 22 12:42:55 nas4free kernel: ada6 at ata2 bus 0 scbus8 target 1 lun 0
```

And [CMD=""]cat /var/log/system.log | grep ada6[/CMD] shows me:

```
Aug 22 12:42:55 nas4free kernel: ada6 at ata2 bus 0 scbus8 target 1 lun 0
Aug 22 12:42:55 nas4free kernel: ada6: <SAMSUNG HD103UJ 1AA01118> ATA-7 SATA 2.x device
Aug 22 12:42:55 nas4free kernel: ada6: 33.300MB/s transfers (UDMA2, PIO 8192bytes)
Aug 22 12:42:55 nas4free kernel: ada6: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
```

So currently my HDD is limited to UDMA2 mode which is 33MB/sec instead of 3Gb/sec! x(

And [CMD=""]pciconf -lbcv[/CMD] shows me this in regards to my SATA controller:

```
atapci1@pci0:4:0:0:	class=0x010185 card=0x84601043 chip=0x2362197b rev=0x10 hdr=0x00
    vendor     = 'JMicron Technology Corp.'
    device     = 'JMB362 AHCI Controller'
    class      = mass storage
    subclass   = ATA
    bar   [10] = type I/O Port, range 32, base 0x5028, size  8, enabled
    bar   [14] = type I/O Port, range 32, base 0x5020, size  4, enabled
    bar   [18] = type I/O Port, range 32, base 0x5018, size  8, enabled
    bar   [1c] = type I/O Port, range 32, base 0x5014, size  4, enabled
    bar   [20] = type I/O Port, range 32, base 0x5000, size 16, enabled
    bar   [24] = type Memory, range 32, base 0xd6500000, size 512, enabled
    cap 01[8c] = powerspec 3  supports D0 D3  current D0
    cap 10[50] = PCI-Express 1 endpoint max data 128(128) link x32(x32)
```

Then I stumbled on the following link: http://mail-index.netbsd.org/current-users/2012/03/28/msg019684.html where someone is stating that the JMB362 is not supported in NetBSD and that it can be added by adding the PCI ID somewhere, so perhaps my issue might be related to this?

If this is the case, then what should I do to make this controller work in AHCI mode?  As I said at the beginning of my post, I am a real noob at FreeBSD so any assistance would be greatly appreciated!


----------



## JohanDC (Aug 23, 2012)

Since I didn't receive any replies, I digged a bit further and came across the following file: ata-jmicron.c

Which contains the following sections which might be relevant in regards to this issue:

```
static const struct ata_chip_id const ids[] =
    {{ ATA_JMB360, 0, 1, 0, ATA_SA300, "JMB360" },
     { ATA_JMB361, 0, 1, 1, ATA_UDMA6, "JMB361" },
     { ATA_JMB363, 0, 2, 1, ATA_UDMA6, "JMB363" },
     { ATA_JMB365, 0, 1, 2, ATA_UDMA6, "JMB365" },
     { ATA_JMB366, 0, 2, 2, ATA_UDMA6, "JMB366" },
     { ATA_JMB368, 0, 0, 1, ATA_UDMA6, "JMB368" },
     { 0, 0, 0, 0, 0, 0}};
```

So why is the JMB362 missing in this structure?

Further more, I suspect that the following code is limiting my controller from using UDMA6 mode:

```
if (pci_read_config(dev, 0x40, 1) & 0x08)
		mode = ata_limit_mode(dev, mode, ATA_UDMA2);
	else
		mode = ata_limit_mode(dev, mode, ATA_UDMA6);
	if (!ata_controlcmd(dev, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode))
		atadev->mode = mode;
```

I am not really good at reading c code but I suspect because my model is missing in the first part, the 2nd part will set the mode to UDMA2 instead of UDMA6 which basically limits my controller speed.  Can anyone confirm whether this assumption is correct?

If so, is there an easy way to fix this issue?  Any help would be greatly appreciated!


----------



## mav@ (Aug 23, 2012)

According to datasheet, this chip is SATA-only. It means it could probably be supported by AHCI driver only. Try to add such lines to the sys/dev/ahci/ahci.c file and rebuild the kernel:

```
--- ahci.c      (revision 238989)
+++ ahci.c      (working copy)
@@ -175,7 +175,9 @@
        {0x1e0e8086, 0x00, "Intel Panther Point",       0},
        {0x1e0f8086, 0x00, "Intel Panther Point",       0},
        {0x23238086, 0x00, "Intel DH89xxCC",    0},
+       {0x2360197b, 0x00, "JMicron JMB360",    0},
        {0x2361197b, 0x00, "JMicron JMB361",    AHCI_Q_NOFORCE},
+       {0x2362197b, 0x00, "JMicron JMB362",    0},
        {0x2363197b, 0x00, "JMicron JMB363",    AHCI_Q_NOFORCE},
        {0x2365197b, 0x00, "JMicron JMB365",    AHCI_Q_NOFORCE},
        {0x2366197b, 0x00, "JMicron JMB366",    AHCI_Q_NOFORCE},
```


----------



## JohanDC (Aug 25, 2012)

mav@ said:
			
		

> According to datasheet, this chip is SATA-only. It means it could probably be supported by AHCI driver only. Try to add such lines to the sys/dev/ahci/ahci.c file and rebuild the kernel



This looks promising, does anyone know where I can find a good tutorial on how to rebuild the kernel?


----------



## wblock@ (Aug 25, 2012)

`# cd /usr/src ; make kernel`

That's simplest case, GENERIC kernel and assumes you already have source installed.


----------



## JohanDC (Aug 29, 2012)

mav@ said:
			
		

> Try to add such lines to the sys/dev/ahci/ahci.c file and rebuild the kernel:
> 
> ```
> --- ahci.c      (revision 238989)
> ...



Just tried this but it didn't seem to work as my controller is still detected as an ATA controller. 

I suspect that this is not the only place where I need to make some modifications?

Does anyone know how the hardware detection process works on FreeBSD, especially for the ATA/SATA controllers?  How does FreeBSD detect the controller type?  I would assume that it would first scan for storage controllers, then checks whether they are AHCI compliant, and if not then try to use it as an ATA controller?

If so, then it does not make any sense that the above modification did not work.

Or if someone can point me to a good document where this process is described then I might be able to figure this out too?


----------



## JohanDC (Aug 29, 2012)

*Success*

I looked some more into this issue and in the end I concluded that I had to make some additional modifications, so right now here is a list of items that I have added:

/usr/src/sys/dev/ahci/ahci.c

```
{0x2362197b, 0x00, "JMicron JMB362",    0},
```

/usr/src/sys/dev/ata/ata-pci.h

```
#define ATA_JMB362              0x2362197b
```

/usr/src/sys/dev/ata/chipsets/ata-jmicron.c

```
{ ATA_JMB362, 0, 4, 0, ATA_SA300, "JMB362" },
```


And here is the result:

/var/log/messages

```
Aug 29 18:45:30 FreeBSD9 kernel: atapci1: <JMicron JMB362 SATA300 controller> port 0x5028-0x502f,0x5020-0x5023,0x5018-0x501f,0x5014-0x5017,0x
Aug 29 18:45:30 FreeBSD9 kernel: ahci1: <JMicron JMB362 AHCI SATA controller> on atapci1
Aug 29 18:45:30 FreeBSD9 kernel: ahci1: AHCI v1.10 with 2 3Gbps ports, Port Multiplier supported
Aug 29 18:45:30 FreeBSD9 kernel: ahcich6: <AHCI channel> at channel 0 on ahci1
Aug 29 18:45:30 FreeBSD9 kernel: ahcich7: <AHCI channel> at channel 1 on ahci1
...
Aug 29 18:45:30 FreeBSD9 kernel: ada6 at ahcich7 bus 0 scbus9 target 0 lun 0
Aug 29 18:45:30 FreeBSD9 kernel: ada6: <SAMSUNG HD103UJ 1AA01118> ATA-7 SATA 2.x device
Aug 29 18:45:30 FreeBSD9 kernel: ada6: 150.000MB/s transfers (SATA 1.x, UDMA6, PIO 8192bytes)
Aug 29 18:45:30 FreeBSD9 kernel: ada6: Command Queueing enabled
Aug 29 18:45:30 FreeBSD9 kernel: ada6: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
```

So not bad, my controller is now being detected as an AHCI controller but the speed is limited to SATA1 while my controller supports SATA2 which means 150MB/sec instead of 300MB/sec, which is already a big improvement over the 33MB/sec that I was getting originally! x(

And NCQ is now active! 

So my question now is, how can I tell FreeBSD that my controller is SATAII instead of just SATA?

I suspect I still need to modify something in the following line:
/usr/src/sys/dev/ata/chipsets/ata-jmicron.c

```
{ ATA_JMB362, 0, 4, 0, ATA_SA300, "JMB362" },
```

In this line there are some parameters, currently set to: 0, 4, 0

The 4 means that my controller is an AHCI controller, but the two other 0's I have no idea just yet what they mean... If anyone knows what they mean then please let me know


----------



## mav@ (Aug 30, 2012)

Ah. I've found the reason why change to ahci.c was not enough:

```
/* Do not attach JMicrons with single PCI function. */  
if (pci_get_vendor(dev) == 0x197b &&                    
    (pci_read_config(dev, 0xdf, 1) & 0x40) == 0)
        return (ENXIO);
```

Way you solved it is fine, even though a bit excessive. I've committed these pieces to 10-CURRENT and going to merge them to 8/9-STABLE in a week.

Speed of 150MB/s you see may depend on disk drive (you should check driver for limiting jumper set), not the controller. Controller driver doesn't limit performance unless you request it explicitly with loader tunable.


----------



## JohanDC (Aug 31, 2012)

mav@ said:
			
		

> According to datasheet, this chip is SATA-only.



Are you sure about this?  My controller only has 2 SATAII ports but according to the datasheet it can also support a PATA port: Internal native interface multiplexed to 2-port SATA II and 1-port PATA


----------



## JohanDC (Aug 31, 2012)

mav@ said:
			
		

> Way you solved it is fine, even though a bit excessive. I've committed these pieces to 10-CURRENT and going to merge them to 8/9-STABLE in a week.



Thanks, can I download the 10-CURRENT release somewhere to verify that my controller is working in there?



			
				mav@ said:
			
		

> Speed of 150MB/s you see may depend on disk drive (you should check driver for limiting jumper set), not the controller. Controller driver doesn't limit performance unless you request it explicitly with loader tunable.



I don't suspect that it is the drive or a jumper on it because I have 5 of these disks in my system, the 4 others are connected to another onboard controller, an ATI IXP700 and they are all running at 300MB/sec


```
Aug 29 19:31:40 FreeBSD9 kernel: ahci0: <ATI IXP700 AHCI SATA controller> port 0x4028-0x402f,0x4020-
0x4023,0x4018-0x401f,0x4014-0x4017,0x4000
Aug 29 19:31:40 FreeBSD9 kernel: ahci0: AHCI v1.20 with 6 6Gbps ports, Port Multiplier supported
Aug 29 19:31:40 FreeBSD9 kernel: ahcich0: <AHCI channel> at channel 0 on ahci0
...
Aug 29 19:31:40 FreeBSD9 kernel: ada0 at ahcich0 bus 0 scbus2 target 0 lun 0
Aug 29 19:31:40 FreeBSD9 kernel: ada0: <SAMSUNG HD103UJ 1AA01118> ATA-7 SATA 2.x device
Aug 29 19:31:40 FreeBSD9 kernel: ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
Aug 29 19:31:40 FreeBSD9 kernel: ada0: Command Queueing enabled
Aug 29 19:31:40 FreeBSD9 kernel: ada0: 953869MB (1953525168 512 byte sectors: 16H 63S/T 16383C)
```

Can you also tell me how the detection of hardware/mass storage controllers works in FreeBSD?  Based upon what I have seen I would suspect that it works like this:
- When a mass storage controller is detected, the PCI ID of the device is matched to one of the files located at: /usr/src/sys/dev/ata/chipsets/
- If the PCI ID is defined in one of these files, there is a definition in there that tells how to handle this controller (ATA/SATA/AHCI) + Max Speed
- If the controller in there is defined as an AHCI controller then ahci.c is called to initialise it

Not sure whether this is correct, but I would love to know how this exactly works...


----------



## mav@ (Aug 31, 2012)

JohanDC said:
			
		

> Thanks, can I download the 10-CURRENT release somewhere to verify that my controller is working in there?



FreeBSD 10.0 release will happen only in about a year, as now it is development branch. You may build it from sources or look for some pre-built snapshot image.



			
				JohanDC said:
			
		

> I don't suspect that it is the drive or a jumper on it because I have 5 of these disks in my system, the 4 others are connected to another onboard controller, an ATI IXP700 and they are all running at 300MB/sec



That is strange, but as I've said, by default driver doesn't limit the speed and the negotiation is managed by hardware itself. Previously reported UDMA33 was a safety belt against unsupported controllers.



			
				JohanDC said:
			
		

> Can you also tell me how the detection of hardware/mass storage controllers works in FreeBSD?  Based upon what I have seen I would suspect that it works like this:
> - When a mass storage controller is detected, the PCI ID of the device is matched to one of the files located at: /usr/src/sys/dev/ata/chipsets/
> - If the PCI ID is defined in one of these files, there is a definition in there that tells how to handle this controller (ATA/SATA/AHCI) + Max Speed
> - If the controller in there is defined as an AHCI controller then ahci.c is called to initialise it



Detection process depends on the specific hardware, the bus and the driver. For PCI(e/-X) ATA controllers ID checked first. If ID is not found and the device type is Storage/ATA, controller is handled as generic PATA with UDMA33 mode limitation. Using ahci(4) driver on top of ata(4) driver is a specific solution to make combined SATA+PATA controllers work. It is not really needed in this case, as there is no PATA part, but that doesn't hurt much.


----------



## mav@ (Aug 31, 2012)

JohanDC said:
			
		

> Are you sure about this?  My controller only has 2 SATAII ports but according to the datasheet it can also support a PATA port: Internal native interface multiplexed to 2-port SATA II and 1-port PATA



There are several JMicron controllers with different number of SATA and PATA ports. This JMB362 as I see is "PCI Express to x2 SATA II Host Controller". JMB363 also has one PATA port. JMB368 has only PATA port and no SATA.


----------



## NiK0 (Feb 2, 2013)

Hello JohanDC, 

I have the same problem than you with JMicron JMB362 AHCI Compatibility in nas4free .

How do you compile the kernel?

ItÂ´s possible obtain the Nas4free  in any place with your changes?


Thanks in advance.


----------



## mav@ (Feb 2, 2013)

I think that question should be asked to developers of the nas4free. They may either import changes explicitly, or they will get it implicitly when migrating to the next FreeBSD version.


----------

