Update UniATA to Version 0.39j Credits go to Samuel Serapion
authorDaniel Reimer <reimer.daniel@freenet.de>
Fri, 28 Nov 2008 09:02:24 +0000 (09:02 +0000)
committerDaniel Reimer <reimer.daniel@freenet.de>
Fri, 28 Nov 2008 09:02:24 +0000 (09:02 +0000)
svn path=/trunk/; revision=37700

13 files changed:
reactos/drivers/storage/ide/uniata/atapi.h
reactos/drivers/storage/ide/uniata/bm_devs.h
reactos/drivers/storage/ide/uniata/bsmaster.h
reactos/drivers/storage/ide/uniata/id_ata.cpp
reactos/drivers/storage/ide/uniata/id_dma.cpp
reactos/drivers/storage/ide/uniata/id_init.cpp
reactos/drivers/storage/ide/uniata/id_probe.cpp
reactos/drivers/storage/ide/uniata/id_sata.cpp
reactos/drivers/storage/ide/uniata/idedma.rc
reactos/drivers/storage/ide/uniata/inc/CrossNt.h
reactos/drivers/storage/ide/uniata/ntddk_ex.h
reactos/drivers/storage/ide/uniata/uniata.rbuild
reactos/drivers/storage/ide/uniata/uniata_ver.h

index 3b7a0fb..bca43f8 100644 (file)
@@ -138,10 +138,6 @@ ScsiDebugPrint(
 
 #else // _DEBUG
 
-#ifdef KdPrint
-#undef KdPrint
-#endif
-
 #define PRINT_PREFIX "UniATA: "
 
 //#define KdPrint3(_x_) {if(LOG_ON_RAISED_IRQL_W2K || MajorVersion < 0x05 || KeGetCurrentIrql() <= 2){/*DbgPrint("%x: ", PsGetCurrentThread()) ;*/ DbgPrint _x_ ; if(g_LogToDisplay){ PrintNtConsole _x_ ;} }}
@@ -944,6 +940,30 @@ AtapiSoftReset(
     ULONG            DeviceNumber
     );
 
+/*#define IdeHardReset(BaseIoAddress,result) \
+{\
+    UCHAR statusByte;\
+    ULONG i;\
+    SelectDrive(BaseIoAddress,DeviceNumber); \
+    AtapiWritePort1(&BaseIoAddress->AltStatus,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_RESET_CONTROLLER );\
+    ScsiPortStallExecution(50 * 1000);\
+    AtapiWritePort1(&BaseIoAddress->AltStatus,IDE_DC_REENABLE_CONTROLLER);\
+     5 seconds for reset  \
+    for (i = 0; i < 1000 * (1+11); i++) {\
+        statusByte = AtapiReadPort1(&BaseIoAddress->AltStatus);\
+        if (statusByte != IDE_STATUS_IDLE && statusByte != IDE_STATUS_SUCCESS) {\
+            ScsiPortStallExecution((i<1000) ? 5 : 500);\
+        } else {\
+            break;\
+        }\
+    }\
+    KdPrint2((PRINT_PREFIX "IdeHardReset: Status %x\n", statusByte)); \
+    if (i == 1000*1000) {\
+        result = FALSE;\
+    }\
+    result = TRUE;\
+}*/
+
 #endif //USER_MODE
 
 #define IS_RDP(OperationCode)\
@@ -1129,7 +1149,7 @@ AtaCommand(
     IN UCHAR command,
     IN USHORT cylinder,
     IN UCHAR head,
-    IN UCHAR sector,
+    IN UCHAR sector, 
     IN UCHAR count,
     IN UCHAR feature,
     IN ULONG flags
@@ -1152,8 +1172,7 @@ AtapiDpcDispatch(
     IN PVOID SystemArgument2
     );
 
-
-//#define AtaCommand(de, devn, chan, cmd, cyl, hd, sec, cnt, feat, flg)
+//#define AtaCommand(de, devn, chan, cmd, cyl, hd, sec, cnt, feat, flg) 
 
 extern LONG
 AtaPio2Mode(LONG pio);
index 7e131e8..09028bc 100644 (file)
@@ -132,6 +132,7 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_AMD766             0x74111022
 #define ATA_AMD768             0x74411022
 #define ATA_AMD8111            0x74691022
+#define ATA_AMD5536             0x209a1022
 
 #define ATA_ACER_LABS_ID       0x10b9
 #define ATA_ALI_1533            0x153310b9
@@ -144,10 +145,17 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_ATI_ID              0x1002
 #define ATA_ATI_IXP200          0x43491002
 #define ATA_ATI_IXP300          0x43691002
-#define ATA_ATI_IXP400          0x43761002
 #define ATA_ATI_IXP300_S1       0x436e1002
+#define ATA_ATI_IXP400          0x43761002
 #define ATA_ATI_IXP400_S1       0x43791002
 #define ATA_ATI_IXP400_S2       0x437a1002
+#define ATA_ATI_IXP600          0x438c1002
+#define ATA_ATI_IXP600_S1       0x43801002
+#define ATA_ATI_IXP700          0x439c1002
+#define ATA_ATI_IXP700_S1       0x43901002
+
+#define ATA_CENATEK_ID          0x16ca
+#define ATA_CENATEK_ROCKET      0x000116ca
 
 #define ATA_CYRIX_ID           0x1078
 #define ATA_CYRIX_5530         0x01021078
@@ -187,6 +195,11 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_I6300ESB           0x25a28086
 #define ATA_I6300ESB_1         0x25a38086
 #define ATA_I6300ESB_2         0x25b08086
+#define ATA_I63XXESB2           0x269e8086
+#define ATA_I63XXESB2_S1        0x26808086
+#define ATA_I63XXESB2_S2        0x26818086
+#define ATA_I63XXESB2_R1        0x26828086
+#define ATA_I63XXESB2_R2        0x26838086
 #define ATA_I82801FB           0x266f8086
 #define ATA_I82801FB_S1                0x26518086
 #define ATA_I82801FB_R1                0x26528086
@@ -197,6 +210,20 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_I82801GB_AH         0x27c18086
 #define ATA_I82801GB_M          0x27c58086
 
+#define ATA_MARVELL_ID          0x11ab
+#define ATA_M88SX5040           0x504011ab
+#define ATA_M88SX5041           0x504111ab
+#define ATA_M88SX5080           0x508011ab
+#define ATA_M88SX5081           0x508111ab
+#define ATA_M88SX6041           0x604111ab
+#define ATA_M88SX6081           0x608111ab
+#define ATA_M88SX6101           0x610111ab
+#define ATA_M88SX6145           0x614511ab
+
+#define ATA_MICRON_ID           0x1042
+#define ATA_MICRON_RZ1000       0x10001042
+#define ATA_MICRON_RZ1001       0x10011042
+
 #define ATA_NATIONAL_ID                0x100b
 #define ATA_SC1100             0x0502100b
 
@@ -206,17 +233,32 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_NVIDIA_ID          0x10de
 #define ATA_NFORCE1            0x01bc10de
 #define ATA_NFORCE2            0x006510de
-#define ATA_NFORCE2_MCP                0x008510de
+#define ATA_NFORCE2_PRO         0x008510de
+#define ATA_NFORCE2_PRO_S1      0x008e10de
 #define ATA_NFORCE3            0x00d510de
 #define ATA_NFORCE3_PRO                0x00e510de
 #define ATA_NFORCE3_PRO_S1     0x00e310de
 #define ATA_NFORCE3_PRO_S2     0x00ee10de
-#define ATA_NFORCE3_MCP                0x003510de
-#define ATA_NFORCE3_MCP_S1     0x003610de
-#define ATA_NFORCE3_MCP_S2     0x003e10de
-#define ATA_NFORCE4            0x005310de
-#define ATA_NFORCE4_S1         0x005410de
-#define ATA_NFORCE4_S2         0x005510de
+#define ATA_NFORCE_MCP04        0x003510de
+#define ATA_NFORCE_MCP04_S1     0x003610de
+#define ATA_NFORCE_MCP04_S2     0x003e10de
+#define ATA_NFORCE_CK804        0x005310de
+#define ATA_NFORCE_CK804_S1     0x005410de
+#define ATA_NFORCE_CK804_S2     0x005510de
+#define ATA_NFORCE_MCP51        0x026510de
+#define ATA_NFORCE_MCP51_S1     0x026610de
+#define ATA_NFORCE_MCP51_S2     0x026710de
+#define ATA_NFORCE_MCP55        0x036e10de
+#define ATA_NFORCE_MCP55_S1     0x037e10de
+#define ATA_NFORCE_MCP55_S2     0x037f10de
+#define ATA_NFORCE_MCP61        0x03ec10de
+#define ATA_NFORCE_MCP61_S1     0x03e710de
+#define ATA_NFORCE_MCP61_S2     0x03f610de
+#define ATA_NFORCE_MCP61_S3     0x03f710de
+#define ATA_NFORCE_MCP65        0x044810de
+#define ATA_NFORCE_MCP67        0x056010de
+#define ATA_NFORCE_MCP73        0x056c10de
+#define ATA_NFORCE_MCP77        0x075910de
 
 #define ATA_PROMISE_ID         0x105a
 #define ATA_PDC20246           0x4d33105a
@@ -326,6 +368,8 @@ typedef struct _BUSMASTER_CONTROLLER_INFORMATION {
 #define ATA_VIA8233C           0x31091106
 #define ATA_VIA8235            0x31771106
 #define ATA_VIA8237            0x32271106
+#define ATA_VIA8237A            0x05911106
+#define ATA_VIA8237S           0x53371106
 #define ATA_VIA8251             0x33491106
 #define ATA_VIA8361            0x31121106
 #define ATA_VIA8363            0x03051106
@@ -466,13 +510,18 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 7411, 1022, 0x00, ATA_UDMA5, "AMD 766"          , AMDNVIDIA | AMDBUG                      ),
     PCI_DEV_HW_SPEC_BM( 7441, 1022, 0x00, ATA_UDMA5, "AMD 768"          , AMDNVIDIA                               ),
     PCI_DEV_HW_SPEC_BM( 7469, 1022, 0x00, ATA_UDMA6, "AMD 8111"         , AMDNVIDIA                               ),
+    PCI_DEV_HW_SPEC_BM( 209a, 1022, 0x00, ATA_UDMA5, "AMD CS5536"       , AMDNVIDIA                               ),
 
     PCI_DEV_HW_SPEC_BM( 4349, 1002, 0x00, ATA_UDMA5, "ATI IXP200"       , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 4369, 1002, 0x00, ATA_UDMA6, "ATI IXP300"       , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 4376, 1002, 0x00, ATA_UDMA6, "ATI IXP400"       , 0                                       ),
     PCI_DEV_HW_SPEC_BM( 436e, 1002, 0x00, ATA_SA150, "ATI IXP300"       , SIIMIO |                UNIATA_SATA     ),
     PCI_DEV_HW_SPEC_BM( 4379, 1002, 0x00, ATA_SA150, "ATI IXP400"       , SIIMIO | SIINOSATAIRQ | UNIATA_SATA     ),
-    PCI_DEV_HW_SPEC_BM( 437a, 1002, 0x00, ATA_SA150, "ATI IXP400"       , SIIMIO | SIINOSATAIRQ | UNIATA_SATA     ),
+    PCI_DEV_HW_SPEC_BM( 437a, 1002, 0x00, ATA_SA300, "ATI IXP400"       , SIIMIO | SIINOSATAIRQ | UNIATA_SATA     ),
+    PCI_DEV_HW_SPEC_BM( 438c, 1002, 0x00, ATA_UDMA6, "ATI IXP600"       , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 4380, 1002, 0x00, ATA_SA150, "ATI IXP600"       , UNIATA_SATA | UNIATA_AHCI               ),
+    PCI_DEV_HW_SPEC_BM( 439c, 1002, 0x00, ATA_UDMA6, "ATI IXP700"       , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 4390, 1002, 0x00, ATA_SA150, "ATI IXP700"       , UNIATA_SATA | UNIATA_AHCI               ),
 
     PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x05, ATA_UDMA6, "HighPoint HPT372" , HPT372 | 0x00   | UNIATA_RAID_CONTROLLER),
     PCI_DEV_HW_SPEC_BM( 0004, 1103, 0x03, ATA_UDMA5, "HighPoint HPT370" , HPT370 | 0x00   | UNIATA_RAID_CONTROLLER),
@@ -525,13 +574,24 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 2822, 8086, 0x00, ATA_SA300, "Intel ICH8"       , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2824, 8086, 0x00, ATA_SA300, "Intel ICH8"       , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2825, 8086, 0x00, ATA_SA300, "Intel ICH8"       , UNIATA_SATA | UNIATA_AHCI               ),
+//    PCI_DEV_HW_SPEC_BM( 2828, 8086, 0x00, ATA_SA300, "Intel ICH8M"      , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2829, 8086, 0x00, ATA_SA300, "Intel ICH8M"      , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 282a, 8086, 0x00, ATA_SA300, "Intel ICH8M"      , UNIATA_SATA | UNIATA_AHCI               ),
+//    PCI_DEV_HW_SPEC_BM( 2850, 8086, 0x00, ATA_SA300, "Intel ICH8M"      , UNIATA_SATA                             ),
     PCI_DEV_HW_SPEC_BM( 2920, 8086, 0x00, ATA_SA300, "Intel ICH9"       , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2926, 8086, 0x00, ATA_SA300, "Intel ICH9"       , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2923, 8086, 0x00, ATA_SA300, "Intel ICH9"       , UNIATA_SATA | UNIATA_AHCI               ),
     PCI_DEV_HW_SPEC_BM( 2922, 8086, 0x00, ATA_SA300, "Intel ICH9"       , UNIATA_SATA | UNIATA_AHCI               ),
 //    PCI_DEV_HW_SPEC_BM( 3200, 8086, 0x00, ATA_SA150, "Intel 31244"      , UNIATA_SATA                             ),
+/*    
+    PCI_DEV_HW_SPEC_BM( 5040, 11ab, 0x00, ATA_SA150, "Marvell 88SX5040" , UNIATA_SATA                             ),
+    PCI_DEV_HW_SPEC_BM( 5041, 11ab, 0x00, ATA_SA150, "Marvell 88SX5041" , UNIATA_SATA                             ),
+    PCI_DEV_HW_SPEC_BM( 5080, 11ab, 0x00, ATA_SA150, "Marvell 88SX5080" , UNIATA_SATA                             ),
+    PCI_DEV_HW_SPEC_BM( 5081, 11ab, 0x00, ATA_SA150, "Marvell 88SX5081" , UNIATA_SATA                             ),
+    PCI_DEV_HW_SPEC_BM( 6041, 11ab, 0x00, ATA_SA300, "Marvell 88SX6041" , UNIATA_SATA                             ),
+    PCI_DEV_HW_SPEC_BM( 6081, 11ab, 0x00, ATA_SA300, "Marvell 88SX6081" , UNIATA_SATA                             ),*/
+    PCI_DEV_HW_SPEC_BM( 6101, 11ab, 0x00, ATA_UDMA6, "Marvell 88SX6101" , 0                                       ),
+    PCI_DEV_HW_SPEC_BM( 6145, 11ab, 0x00, ATA_UDMA6, "Marvell 88SX6145" , 0                                       ),
 
     PCI_DEV_HW_SPEC_BM( 01bc, 10de, 0x00, ATA_UDMA5, "nVidia nForce"    , AMDNVIDIA                               ),
     PCI_DEV_HW_SPEC_BM( 0065, 10de, 0x00, ATA_UDMA6, "nVidia nForce2"   , AMDNVIDIA                               ),
@@ -553,6 +613,14 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 036e, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP55", AMDNVIDIA                             ),
     PCI_DEV_HW_SPEC_BM( 037e, 10de, 0x00, ATA_SA300, "nVidia nForce MCP55 S1",NV4OFF | NVQ | UNIATA_SATA          ),
     PCI_DEV_HW_SPEC_BM( 037f, 10de, 0x00, ATA_SA300, "nVidia nForce MCP55 S2",NV4OFF | NVQ | UNIATA_SATA          ),
+    PCI_DEV_HW_SPEC_BM( 03ec, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP61", AMDNVIDIA                             ),
+    PCI_DEV_HW_SPEC_BM( 03e7, 10de, 0x00, ATA_SA300, "nVidia nForce MCP61 S1",NV4OFF | NVQ | UNIATA_SATA          ),
+    PCI_DEV_HW_SPEC_BM( 03f6, 10de, 0x00, ATA_SA300, "nVidia nForce MCP61 S2",NV4OFF | NVQ | UNIATA_SATA          ),
+    PCI_DEV_HW_SPEC_BM( 03f7, 10de, 0x00, ATA_SA300, "nVidia nForce MCP61 S3",NV4OFF | NVQ | UNIATA_SATA          ),
+    PCI_DEV_HW_SPEC_BM( 0448, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP65", AMDNVIDIA                             ),
+    PCI_DEV_HW_SPEC_BM( 0560, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP67", AMDNVIDIA                             ),
+    PCI_DEV_HW_SPEC_BM( 056c, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP73", AMDNVIDIA                             ),
+    PCI_DEV_HW_SPEC_BM( 0759, 10de, 0x00, ATA_UDMA6, "nVidia nForce MCP77", AMDNVIDIA                             ),
 
     PCI_DEV_HW_SPEC_BM( 0502, 100b, 0x00, ATA_UDMA2, "National Geode SC1100", 0                                   ),
 
@@ -667,11 +735,12 @@ BUSMASTER_CONTROLLER_INFORMATION const BusMasterAdapters[] = {
     PCI_DEV_HW_SPEC_BM( 3149, 1106, 0x00, ATA_SA150, "VIA 6420"         , 0      | UNIATA_SATA                    ),
     PCI_DEV_HW_SPEC_BM( 3249, 1106, 0x00, ATA_SA150, "VIA 6421"         , VIABAR | UNIATA_SATA                    ),
     PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_SA150, "VIA 8237A"        , 0      | UNIATA_SATA                    ),
+    PCI_DEV_HW_SPEC_BM( 5337, 1106, 0x00, ATA_SA150, "VIA 8237S"        , 0      | UNIATA_SATA                    ),
     //PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_SA150, "VIA 8251"         , VIAAHCI| UNIATA_SATA                    ),
 
     PCI_DEV_HW_SPEC_BM( c693, 1080, 0x00, ATA_WDMA2, "Cypress 82C693"   ,0                                        ),
 
-/*
+/*                                                                                     
     PCI_DEV_HW_SPEC_BM( 4d68, 105a, 0, 0, "Promise TX2 ATA-100 controller",          UNIATA_RAID_CONTROLLER),
     PCI_DEV_HW_SPEC_BM( 6268, 105a, 0, 0, "Promise TX2 ATA-100 controller",          UNIATA_RAID_CONTROLLER),
 
index 781c0ed..993b6e0 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2005 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2008 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     bsmaster.h
@@ -31,7 +31,7 @@ Notes:
 Revision History:
 
     Code was created by
-         Alter, Copyright (c) 2002-2007
+         Alter, Copyright (c) 2002-2008
 
     Some definitions were taken from FreeBSD 4.3-4.6 ATA driver by
          Søren Schmidt, Copyright (c) 1998,1999,2000,2001
@@ -520,6 +520,8 @@ typedef struct _IDE_AHCI_PORT_REGISTERS {
 
 } IDE_AHCI_PORT_REGISTERS, *PIDE_AHCI_PORT_REGISTERS;
 
+#define IDX_AHCI_P_CLB                    (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CLB))
+#define IDX_AHCI_P_FB                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, FB))
 #define IDX_AHCI_P_IS                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, IS))
 #define IDX_AHCI_P_CI                     (FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, CI))
 
@@ -544,6 +546,7 @@ typedef struct _IDE_AHCI_PRD_ENTRY {
 } IDE_AHCI_PRD_ENTRY, *PIDE_AHCI_PRD_ENTRY;
 
 #define ATA_AHCI_DMA_ENTRIES           (PAGE_SIZE/2/sizeof(IDE_AHCI_PRD_ENTRY))   /* 128 */
+#define ATA_AHCI_MAX_TAGS              32
 
 typedef struct _IDE_AHCI_CMD {
     UCHAR              cfis[64];
@@ -557,8 +560,22 @@ typedef struct _IDE_AHCI_CMD_LIST {
     USHORT             prd_length;     /* PRD entries */
     ULONG              bytecount;
     ULONGLONG          cmd_table_phys; /* 128byte aligned */
+    ULONG              Reserved[4];
 } IDE_AHCI_CMD_LIST, *PIDE_AHCI_CMD_LIST;
 
+typedef struct _IDE_AHCI_RCV_FIS {
+    UCHAR              dsfis[28];
+    UCHAR              Reserved1[4];
+    UCHAR              psfis[24];
+    UCHAR              Reserved2[8];
+    UCHAR              rfis[24];
+    UCHAR              Reserved3[4];
+    ULONG              SDBFIS;
+    UCHAR              ufis[64];
+    UCHAR              Reserved4[96];
+} IDE_AHCI_RCV_FIS, *PIDE_AHCI_RCV_FIS;
+
+
 #define IsBusMaster(pciData) \
     ( ((pciData)->Command & (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/)) == \
           (PCI_ENABLE_BUS_MASTER/* | PCI_ENABLE_IO_SPACE*/))
@@ -892,7 +909,7 @@ typedef struct _HW_DEVICE_EXTENSION {
     ULONG NumberChannels;
     ULONG NumberLuns;
     ULONG FirstChannelToCheck;
-#if 1
+#if 0
     HW_LU_EXTENSION lun[IDE_MAX_LUN];
     HW_CHANNEL chan[AHCI_MAX_PORT/*IDE_MAX_CHAN*/];
 #else
@@ -1017,6 +1034,14 @@ UniataFindCompatBusMasterController2(
     OUT PBOOLEAN Again
     );
 
+#define UNIATA_ALLOCATE_NEW_LUNS  0x00
+
+extern BOOLEAN
+UniataAllocateLunExt(
+    PHW_DEVICE_EXTENSION  deviceExtension,
+    ULONG NewNumberChannels
+    );
+
 extern ULONG DDKAPI
 UniataFindBusMasterController(
     IN PVOID HwDeviceExtension,
@@ -1160,6 +1185,14 @@ AtapiInterrupt2(
 
 extern PDRIVER_OBJECT SavedDriverObject;
 
+extern BOOLEAN
+UniataChipDetectChannels(
+    IN PVOID HwDeviceExtension,
+    IN PPCI_COMMON_CONFIG pciData, // optional
+    IN ULONG DeviceNumber,
+    IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
+    );
+
 extern BOOLEAN
 UniataChipDetect(
     IN PVOID HwDeviceExtension,
index e0f58e2..e1fbe3b 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2007 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2008 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_ata.cpp
@@ -174,7 +174,7 @@ AtapiRegGetStringParameterValue(
     IN ULONG MaxLen
     )
 {
-#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched
+#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched 
     NTSTATUS          status;
     RTL_QUERY_REGISTRY_TABLE parameters[ITEMS_TO_QUERY];
     UNICODE_STRING ustr;
@@ -4553,7 +4553,7 @@ IntrPrepareResetController:
            }
         } else {
 
-            KdPrint2((PRINT_PREFIX
+            KdPrint3((PRINT_PREFIX
                         "AtapiInterrupt: Int reason %#x, but srb is for a write %#x.\n",
                         interruptReason,
                         srb));
@@ -5039,12 +5039,12 @@ PIO_wait_DRQ:
                                       CHECK_INTR_IDLE);
 
         // Sanity check that there is a current request.
-        if (srb != NULL) {
+        if(srb != NULL) {
             // Set status in SRB.
             srb->SrbStatus = (UCHAR)status;
 
             // Check for underflow.
-            if (AtaReq->WordsLeft) {
+            if(AtaReq->WordsLeft) {
 
                 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
                 // Subtract out residual words and update if filemark hit,
@@ -5424,7 +5424,7 @@ UniAtaCalculateLBARegs(
         (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack;
     } else {
         cylinder =    (USHORT)(startingSector / tmp);
-        drvSelect =   (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack);
+        drvSelect =   (UCHAR)((startingSector % tmp) / LunExt->IdentifyData.SectorsPerTrack); 
         sectorNumber = (UCHAR)(startingSector % LunExt->IdentifyData.SectorsPerTrack) + 1;
         (*max_bcount) = LunExt->IdentifyData.SectorsPerTrack - sectorNumber + 1;
         KdPrint2((PRINT_PREFIX "UniAtaCalculateLBARegs: C:H:S=%#x:%#x:%#x, max_bc %#x\n",
@@ -5642,7 +5642,9 @@ IdeReadWrite(
                      (USHORT)(AtaReq->bcount),
 //                     (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
                      0, ATA_IMMEDIATE);
-        GetStatus(chan, statusByte2);
+        if(statusByte2 != 0xff) {
+            GetStatus(chan, statusByte2);
+        }
         if(statusByte2 & IDE_STATUS_ERROR) {
             statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
             KdPrint2((PRINT_PREFIX "IdeReadWrite: status %#x, error %#x\n", statusByte2, statusByte));
@@ -5660,11 +5662,18 @@ IdeReadWrite(
 //                 (UCHAR)((wordCount*2 + DEV_BSIZE-1) / DEV_BSIZE),
                  0, ATA_WAIT_INTR);
 
-    if (!(statusByte & IDE_STATUS_DRQ)) {
+    if (!(statusByte & IDE_STATUS_DRQ) ||
+        statusByte == 0xff) {
 
-        KdPrint2((PRINT_PREFIX
-                   "IdeReadWrite: DRQ never asserted (%#x)\n",
-                   statusByte));
+        if(statusByte == 0xff) {
+            KdPrint2((PRINT_PREFIX 
+                       "IdeReadWrite: error sending command (%#x)\n",
+                       statusByte));
+        } else {
+            KdPrint2((PRINT_PREFIX 
+                       "IdeReadWrite: DRQ never asserted (%#x)\n",
+                       statusByte));
+        }
 
         AtaReq->WordsLeft = 0;
 
@@ -5676,7 +5685,7 @@ IdeReadWrite(
         // Clear current SRB.
         UniataRemoveRequest(chan, Srb);
 
-        return SRB_STATUS_TIMEOUT;
+        return (statusByte == 0xff) ? SRB_STATUS_ERROR : SRB_STATUS_TIMEOUT;
     }
 
     chan->ExpectingInterrupt = TRUE;
@@ -5756,7 +5765,7 @@ IdeVerify(
                   LunExt->IdentifyData.NumberOfCylinders;
     }
 
-    KdPrint2((PRINT_PREFIX
+    KdPrint2((PRINT_PREFIX 
                 "IdeVerify: Total sectors %#x\n",
                 sectors));
 
@@ -5764,21 +5773,21 @@ IdeVerify(
     MOV_DD_SWP(startingSector, ((PCDB)Srb->Cdb)->CDB10.LBA);
     MOV_DW_SWP(sectorCount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
 
-    KdPrint2((PRINT_PREFIX
+    KdPrint2((PRINT_PREFIX 
                 "IdeVerify: Starting sector %#x. Number of blocks %#x\n",
                 startingSector,
                 sectorCount));
 
     endSector = startingSector + sectorCount;
 
-    KdPrint2((PRINT_PREFIX
+    KdPrint2((PRINT_PREFIX 
                 "IdeVerify: Ending sector %#x\n",
                 endSector));
 
     if (endSector > sectors) {
 
         // Too big, round down.
-        KdPrint2((PRINT_PREFIX
+        KdPrint2((PRINT_PREFIX 
                     "IdeVerify: Truncating request to %#x blocks\n",
                     sectors - startingSector - 1));
 
@@ -6138,19 +6147,19 @@ call_dma_setup:
     
     // Make sure command is to ATAPI device.
     flags = deviceExtension->lun[ldev].DeviceFlags;
-    if (flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
-        if ((Srb->Lun) > (deviceExtension->lun[ldev].DiscsPresent - 1)) {
+    if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
+        if((Srb->Lun) > (deviceExtension->lun[ldev].DiscsPresent - 1)) {
 
             // Indicate no device found at this address.
             AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
             return SRB_STATUS_SELECTION_TIMEOUT;
         }
-    } else if (Srb->Lun > 0) {
+    } else if(Srb->Lun > 0) {
         AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
         return SRB_STATUS_SELECTION_TIMEOUT;
     }
 
-    if (!(flags & DFLAGS_ATAPI_DEVICE)) {
+    if(!(flags & DFLAGS_ATAPI_DEVICE)) {
         AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
         return SRB_STATUS_SELECTION_TIMEOUT;
     }
@@ -6162,11 +6171,11 @@ retry:
     GetStatus(chan, statusByte);
     KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
 
-    if (statusByte == 0xff) {
+    if(statusByte == 0xff) {
         KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n"));
         goto make_reset;
     }
-    if (statusByte & IDE_STATUS_BUSY) {
+    if(statusByte & IDE_STATUS_BUSY) {
         if(statusByte & IDE_STATUS_DSC) {
             KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte));
         } else {
@@ -6176,7 +6185,7 @@ retry:
             goto make_reset;
         }
     }
-    if (statusByte & IDE_STATUS_ERROR) {
+    if(statusByte & IDE_STATUS_ERROR) {
         if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
 
             KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
@@ -6189,7 +6198,7 @@ retry:
     }
     // If a tape drive doesn't have DSC set and the last command is restrictive, don't send
     // the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
-    if ((!(statusByte & IDE_STATUS_DSC)) &&
+    if((!(statusByte & IDE_STATUS_DSC)) &&
           (flags & (DFLAGS_TAPE_DEVICE | DFLAGS_ATAPI_DEVICE)) && chan->RDP) {
 
         AtapiStallExecution(200);
@@ -6198,13 +6207,13 @@ retry:
         return SRB_STATUS_PENDING;
     }
 
-    if (IS_RDP(Srb->Cdb[0])) {
+    if(IS_RDP(Srb->Cdb[0])) {
         chan->RDP = TRUE;
         KdPrint2((PRINT_PREFIX "AtapiSendCommand: %#x mapped as DSC restrictive\n", Srb->Cdb[0]));
     } else {
         chan->RDP = FALSE;
     }
-    if (statusByte & IDE_STATUS_DRQ) {
+    if(statusByte & IDE_STATUS_DRQ) {
 
         KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
                     statusByte));
@@ -6213,7 +6222,7 @@ retry:
         // in production devices.
         for (i = 0; i < 0x10000; i++) {
             GetStatus(chan, statusByte);
-            if (statusByte & IDE_STATUS_DRQ) {
+            if(statusByte & IDE_STATUS_DRQ) {
                 AtapiReadPort2(chan, IDX_IO1_i_Data);
             } else {
                 break;
@@ -6259,10 +6268,10 @@ make_reset:
         }
     }
 
-    if (flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
+    if(flags & (DFLAGS_SANYO_ATAPI_CHANGER | DFLAGS_ATAPI_CHANGER)) {
         // As the cdrom driver sets the LUN field in the cdb, it must be removed.
         Srb->Cdb[1] &= ~0xE0;
-        if ((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
+        if((Srb->Cdb[0] == SCSIOP_TEST_UNIT_READY) && (flags & DFLAGS_SANYO_ATAPI_CHANGER)) {
             // Torisan changer. TUR's are overloaded to be platter switches.
             Srb->Cdb[7] = Srb->Lun;
         }
@@ -6487,7 +6496,7 @@ IdeSendCommand(
     switch (Srb->Cdb[0]) {
     case SCSIOP_INQUIRY:
 
-        KdPrint2((PRINT_PREFIX
+        KdPrint2((PRINT_PREFIX 
                    "IdeSendCommand: SCSIOP_INQUIRY PATH:LUN:TID = %#x:%#x:%#x\n",
                    Srb->PathId, Srb->Lun, Srb->TargetId));
         // Filter out all TIDs but 0 and 1 since this is an IDE interface
@@ -6576,7 +6585,7 @@ IdeSendCommand(
 
     case SCSIOP_MODE_SENSE:
 
-        KdPrint2((PRINT_PREFIX
+        KdPrint2((PRINT_PREFIX 
                    "IdeSendCommand: SCSIOP_MODE_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
                    Srb->PathId, Srb->Lun, Srb->TargetId));
         // This is used to determine if the media is write-protected.
@@ -7296,7 +7305,7 @@ AtapiStartIo__(
 
 reject_srb:
             //if(!CheckDevice(HwDeviceExtension, lChannel, ldev & 1, FALSE)) {
-                KdPrint2((PRINT_PREFIX
+                KdPrint3((PRINT_PREFIX
                            "AtapiStartIo: SRB rejected\n"));
                 // Indicate no device found at this address.
                 KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
@@ -8160,9 +8169,16 @@ UniataInitAtaCommands()
 {
     int i;
     UCHAR command;
-    UCHAR flags = 0;
+    UCHAR flags;
+
+    KdPrint2((PRINT_PREFIX "UniataInitAtaCommands:\n"));
 
-    for(i=0, command=0; i<256; i++, command++) {
+    for(i=0; i<256; i++) {
+
+        flags = 0;
+        command = i;
+
+        KdPrint2((PRINT_PREFIX "cmd %2.2x: ", command));
 
         switch(command) {
         case IDE_COMMAND_READ_DMA48:
@@ -8183,6 +8199,7 @@ UniataInitAtaCommands()
         case IDE_COMMAND_WRITE_LOG_DMA48:
         case IDE_COMMAND_TRUSTED_RCV_DMA:
         case IDE_COMMAND_TRUSTED_SEND_DMA:
+            KdPrint2((PRINT_PREFIX "DMA "));
             flags |= ATA_CMD_FLAG_DMA;
         }
 
@@ -8205,6 +8222,7 @@ UniataInitAtaCommands()
         case IDE_COMMAND_FLUSH_CACHE48:
         case IDE_COMMAND_VERIFY48:
 
+            KdPrint2((PRINT_PREFIX "48 "));
             flags |= ATA_CMD_FLAG_48;
             /* FALL THROUGH */
 
@@ -8219,6 +8237,7 @@ UniataInitAtaCommands()
         case IDE_COMMAND_FLUSH_CACHE:
         case IDE_COMMAND_VERIFY:
 
+            KdPrint2((PRINT_PREFIX "LBA "));
             flags |= ATA_CMD_FLAG_LBAIOsupp;
         }
 
@@ -8250,9 +8269,11 @@ UniataInitAtaCommands()
         case IDE_COMMAND_VERIFY:
             command = IDE_COMMAND_VERIFY48; break;
         default:
+            KdPrint2((PRINT_PREFIX "!28->48 "));
             flags &= ~ATA_CMD_FLAG_48supp;
         }
 
+        KdPrint2((PRINT_PREFIX "\t -> %2.2x (%2.2x)\n", command, flags));
         AtaCommands48[i]   = command;
         AtaCommandFlags[i] = flags;
     }
@@ -8593,7 +8614,7 @@ DriverEntry(
 
 /*    KeBugCheckEx(0xc000000e,
                  i,
-                 c,
+                 c, 
                  newStatus, statusToReturn);*/
 
     // --------------
@@ -8924,7 +8945,7 @@ AtapiRegCheckParameterValue(
     IN ULONG Default
     )
 {
-#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched
+#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched 
 
 //    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     NTSTATUS          status;
@@ -8944,7 +8965,8 @@ AtapiRegCheckParameterValue(
 //    KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer));
 
     paramPath.Length = 0;
-    paramPath.MaximumLength = RegistryPath->Length + (wcslen(PathSuffix)+2)*sizeof(WCHAR);
+    paramPath.MaximumLength = RegistryPath->Length +
+        (wcslen(PathSuffix)+2)*sizeof(WCHAR);
     paramPath.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, paramPath.MaximumLength);
     if(!paramPath.Buffer) {
         KdPrint(("AtapiCheckRegValue: couldn't allocate paramPath\n"));
@@ -9051,7 +9073,7 @@ AtapiAdapterControl(
             status = UniataConnectIntr2(HwDeviceExtension);
             for (c = 0; c < numberChannels; c++) {
                 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, c);
-                FindDevices(HwDeviceExtension, FALSE, c);
+                FindDevices(HwDeviceExtension, 0, c);
                 AtapiEnableInterrupts(deviceExtension, c);
                 AtapiHwInitialize__(deviceExtension, c);
             }
index ae40fcd..0b1239f 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2007 Alexander A. Telyatnikov (Alter)
+Copyright (c) 2002-2008 Alexander A. Telyatnikov (Alter)
 
 Module Name:
     id_dma.cpp
@@ -31,7 +31,7 @@ Notes:
 Revision History:
 
     This module is a port from FreeBSD 4.3-6.1 ATA driver (ata-dma.c, ata-chipset.c) by
-         Søren Schmidt, Copyright (c) 1998-2007
+         Søren Schmidt, Copyright (c) 1998-2008
 
     Changed defaulting-to-generic-PIO/DMA policy
     Added PIO settings for VIA
@@ -176,24 +176,30 @@ err_1:
         }
     }
 #endif //USE_OWN_DMA
-/*
+
     if(deviceExtension->HwFlags & UNIATA_AHCI) {
-        chan->AHCI_CLP = MmAllocateContiguousMemory(sizeof(((PATA_REQ)NULL)->dma_tab), ph4gb);
-        if(chan->AHCI_CLP) {
-            chan->DB_PRD_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->DB_PRD), &i, &ph_addru);
-            if(!chan->DB_PRD_PhAddr || !i || ((LONG)(chan->DB_PRD_PhAddr) == -1)) {
-                KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD BASE\n" ));
-                chan->DB_PRD = NULL;
-                chan->DB_PRD_PhAddr = 0;
+        if(chan->AHCI_CL) {
+            return;
+        }
+        chan->AHCI_CL = (PIDE_AHCI_CMD_LIST)MmAllocateContiguousMemory(sizeof(IDE_AHCI_CMD_LIST)*ATA_AHCI_MAX_TAGS+sizeof(IDE_AHCI_RCV_FIS), ph4gb);
+        if(chan->AHCI_CL) {
+            chan->AHCI_CL_PhAddr = AtapiVirtToPhysAddr(HwDeviceExtension, NULL, (PUCHAR)(chan->AHCI_CL), &i, &ph_addru);
+            if(!chan->AHCI_CL_PhAddr || !i || ((LONG)(chan->AHCI_CL_PhAddr) == -1)) {
+                KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP BASE\n" ));
+                chan->AHCI_CL = NULL;
+                chan->AHCI_CL_PhAddr = 0;
                 return;
             }
             if(ph_addru) {
-                KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No DB PRD below 4Gb\n" ));
-                goto err_1;
+                KdPrint2((PRINT_PREFIX "AtapiDmaAlloc: No AHCI CLP below 4Gb\n" ));
+                MmFreeContiguousMemory(chan->AHCI_CL);
+                chan->AHCI_CL = NULL;
+                chan->AHCI_CL_PhAddr = 0;
+                return;
             }
         }
     }
-*/
+
     return;
 } // end AtapiDmaAlloc()
 
@@ -708,7 +714,7 @@ AtaSetTransferMode(
     IN ULONG mode
     )
 {
-    KdPrint2((PRINT_PREFIX
+    KdPrint3((PRINT_PREFIX 
                 "AtaSetTransferMode: Set %#x on Device %d/%d\n", mode, lChannel, DeviceNumber));
     LONG statusByte = 0;
     CHAR apiomode;
@@ -887,7 +893,7 @@ AtapiDmaInit(
         AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ModeByte);
         return;
     }
-    if (udmamode > 2 && !LunExt->IdentifyData.HwResCableId) {
+    if(udmamode > 2 && !LunExt->IdentifyData.HwResCableId) {
         KdPrint2((PRINT_PREFIX "AtapiDmaInit: DMA limited to UDMA33, non-ATA66 compliant cable\n"));
         udmamode = 2;
         apiomode = min( apiomode, (CHAR)(LunExt->LimitedTransferMode - ATA_PIO));
@@ -1124,6 +1130,29 @@ set_new_acard:
         }
         /* Use GENERIC PIO */
         break;
+    case ATA_MARVELL_ID:
+        /***********/
+        /* Marvell */
+        /***********/
+        for(i=udmamode; i>=0; i--) {
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
+                return;
+            }
+        }
+        for(i=wdmamode; i>=0; i--) {
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
+                return;
+            }
+        }
+        /* try generic DMA, use hpt_timing() */
+        if (wdmamode >= 0 && apiomode >= 4) {
+            if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_DMA)) {
+                return;
+            }
+        }
+        AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
+        return;
+        break;
     case ATA_NETCELL_ID:
         /***********/
         /* NetCell */
index ce49d9a..fe86d2b 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2004-2007 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2004-2008 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_init.cpp
@@ -43,6 +43,102 @@ Revision History:
 
 #include "stdafx.h"
 
+BOOLEAN
+UniataChipDetectChannels(
+    IN PVOID HwDeviceExtension,
+    IN PPCI_COMMON_CONFIG pciData, // optional
+    IN ULONG DeviceNumber,
+    IN PPORT_CONFIGURATION_INFORMATION ConfigInfo
+    )
+{
+    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
+    ULONG slotNumber = deviceExtension->slotNumber;
+    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+    ULONG VendorID =  deviceExtension->DevID        & 0xffff;
+    ULONG DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
+    ULONG RevID    =  deviceExtension->RevID;
+    ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
+    ULONG ChipFlags= deviceExtension->HwFlags & CHIPFLAG_MASK;
+
+    KdPrint2((PRINT_PREFIX "UniataChipDetectChannels:\n" ));
+    switch(VendorID) {
+    case ATA_ACER_LABS_ID:
+        switch(deviceExtension->DevID) {
+        case 0x528710b9:
+        case 0x528810b9:
+            deviceExtension->NumberChannels = 4;
+            KdPrint2((PRINT_PREFIX "Acer 4 chan\n"));
+        }
+        break;
+    case ATA_PROMISE_ID:
+
+        if(ChipType != PRMIO) {
+            break;
+        }
+        deviceExtension->NumberChannels = 4;
+        KdPrint2((PRINT_PREFIX "Promise 4 chan\n"));
+        break;
+    case ATA_MARVELL_ID:
+        KdPrint2((PRINT_PREFIX "Marvell\n"));
+        switch(deviceExtension->DevID) {
+        case 0x610111ab: 
+            /* 88SX6101 only have 1 PATA channel */
+            if(BMList[deviceExtension->DevIndex].channel) {
+                KdPrint2((PRINT_PREFIX "88SX6101 has no 2nd PATA chan\n"));
+                return FALSE;
+            }
+            deviceExtension->NumberChannels = 1;
+            KdPrint2((PRINT_PREFIX "88SX6101 PATA 1 chan\n"));
+            break;
+        }
+        break;
+    case ATA_ATI_ID:
+        KdPrint2((PRINT_PREFIX "ATI\n"));
+        switch(deviceExtension->DevID) {
+        case 0x438c1002: 
+        case 0x439c1002:
+            /* IXP600 & IXP700 only have 1 PATA channel */
+            if(BMList[deviceExtension->DevIndex].channel) {
+                KdPrint2((PRINT_PREFIX "New ATI no 2nd PATA chan\n"));
+                return FALSE;
+            }
+            deviceExtension->NumberChannels = 1;
+            KdPrint2((PRINT_PREFIX "New ATI PATA 1 chan\n"));
+            break;
+        }
+    case ATA_SILICON_IMAGE_ID:
+
+        if(ChipFlags & SIIBUG) {
+        }
+        if(ChipType != SIIMIO) {
+            break;
+        }
+        if(!pciData) {
+            break;
+        }
+
+        if(VendorID == ATA_SILICON_IMAGE_ID) {
+            KdPrint2((PRINT_PREFIX "New SII\n"));
+        } else {
+            KdPrint2((PRINT_PREFIX "ATI SATA\n"));
+        }
+        if(deviceExtension->HwFlags & SII4CH) {
+            deviceExtension->NumberChannels = 4;
+            KdPrint2((PRINT_PREFIX "4 chan\n"));
+        }
+        break;
+    case ATA_VIA_ID:
+        if((deviceExtension->DevID == 0x32491106) &&
+           ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[5].RangeStart)) {
+            deviceExtension->NumberChannels = 3;
+            KdPrint2((PRINT_PREFIX "VIA 3 chan\n"));
+        }
+        break;
+    } // end switch(VendorID)
+    return TRUE;
+
+} // end UniataChipDetectChannels()
+
 BOOLEAN
 UniataChipDetect(
     IN PVOID HwDeviceExtension,
@@ -81,12 +177,27 @@ UniataChipDetect(
         *simplexOnly = TRUE;
     }
 
+    // defaults
+    BaseIoAddressBM = pciData->u.type0.BaseAddresses[4] & ~0x07;
+    deviceExtension->MaxTransferMode = BaseIoAddressBM ? ATA_DMA : ATA_PIO4;
+    ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
+    deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
+
     KdPrint2((PRINT_PREFIX "i: %#x\n", i));
     if(i != BMLIST_TERMINATOR) {
         DevTypeInfo = (PBUSMASTER_CONTROLLER_INFORMATION)&BusMasterAdapters[i];
     } else {
+        KdPrint2((PRINT_PREFIX "  unknown dev, BM addr %#x", BaseIoAddressBM));
         DevTypeInfo = NULL;
-        deviceExtension->MaxTransferMode = deviceExtension->BaseIoAddressBM_0.Addr ? ATA_DMA : ATA_PIO4;
+        KdPrint2((PRINT_PREFIX "  MaxTransferMode %#x\n", deviceExtension->MaxTransferMode));
+
+        if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
+            return FALSE;
+        }
+        if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
+            return FALSE;
+        }
+
         return FALSE;
     }
 
@@ -105,7 +216,7 @@ UniataChipDetect(
         PCI_DEV_HW_SPEC_BM( 0730, 1039, 0x00, ATA_UDMA5, "SiS 730"  , SIS100OLD        ),
 
         PCI_DEV_HW_SPEC_BM( 0646, 1039, 0x00, ATA_UDMA6, "SiS 645DX", SIS133NEW        ),
-/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),*/
+/*        PCI_DEV_HW_SPEC_BM( 0645, 1039, 0x00, ATA_UDMA6, "SiS 645"  , SIS133NEW        ),
 /*        PCI_DEV_HW_SPEC_BM( 0640, 1039, 0x00, ATA_UDMA4, "SiS 640"  , SIS_SOUTH        ),*/
         PCI_DEV_HW_SPEC_BM( 0635, 1039, 0x00, ATA_UDMA5, "SiS 635"  , SIS100NEW        ),
         PCI_DEV_HW_SPEC_BM( 0633, 1039, 0x00, ATA_UDMA5, "SiS 633"  , SIS100NEW        ),
@@ -144,7 +255,8 @@ UniataChipDetect(
         PCI_DEV_HW_SPEC_BM( 3147, 1106, 0x00, ATA_UDMA6, "VIA 8233A"  , VIA133 | VIAAST ),
         PCI_DEV_HW_SPEC_BM( 3177, 1106, 0x00, ATA_UDMA6, "VIA 8235"   , VIA133 | VIAAST ),
         PCI_DEV_HW_SPEC_BM( 3227, 1106, 0x00, ATA_UDMA6, "VIA 8237"   , VIA133 | VIAAST ),
-        PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6, "VIA 8237"   , VIA133 | VIAAST ),
+        PCI_DEV_HW_SPEC_BM( 0591, 1106, 0x00, ATA_UDMA6, "VIA 8237A"  , VIA133 | VIAAST ),
+        PCI_DEV_HW_SPEC_BM( 3349, 1106, 0x00, ATA_UDMA6, "VIA 8251"   , VIA133 | VIAAST ),
         PCI_DEV_HW_SPEC_BM( ffff, ffff, 0xff, BMLIST_TERMINATOR       , NULL         , BMLIST_TERMINATOR )
         };
 
@@ -163,10 +275,13 @@ UniataChipDetect(
     case ATA_SIS_ID:
         KdPrint2((PRINT_PREFIX "ATA_SIS_ID\n"));
         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&SiSAdapters[0];
-        i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, -1, NULL);
+        i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL);
+        if(i != BMLIST_TERMINATOR) {
+            deviceExtension->FullDevName = SiSAdapters[i].FullDevName;
+        }
         goto for_ugly_chips;
 
-    case ATA_VIA_ID:
+    case ATA_VIA_ID: 
         KdPrint2((PRINT_PREFIX "ATA_VIA_ID\n"));
         // New chips have own DeviceId
         if(deviceExtension->DevID != ATA_VIA82C571)
@@ -175,12 +290,15 @@ UniataChipDetect(
         // only by SouthBridge DeviceId
         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaSouthAdapters[0];
         i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, slotNumber, NULL);
-        if(i != 0xFFFFFFFF) {
+        if(i != BMLIST_TERMINATOR) {
             KdPrint2((PRINT_PREFIX "VIASOUTH\n"));
             deviceExtension->HwFlags |= VIASOUTH;
         }
         DevTypeInfo = (BUSMASTER_CONTROLLER_INFORMATION*)&ViaAdapters[0];
         i = AtapiFindListedDev(DevTypeInfo, -1, HwDeviceExtension, SystemIoBusNumber, slotNumber, NULL);
+        if(i != BMLIST_TERMINATOR) {
+            deviceExtension->FullDevName = SiSAdapters[i].FullDevName;
+        }
         goto for_ugly_chips;
 
     default:
@@ -211,13 +329,13 @@ UniataChipDetect(
             deviceExtension->MaxTransferMode = ATA_UDMA2;
             break;
 
-        case 0x06401095:        /* CMD 640 known bad, no DMA */
+        case 0x06401039:        /* CMD 640 known bad, no DMA */
         case 0x06011039:
             *simplexOnly = TRUE; 
 
             /* FALLTHROUGH */
 
-        case 0x10001042:        /* RZ 100? known bad, no DMA */
+        case 0x10001042:        /* RZ 100x known bad, no DMA */
         case 0x10011042:
 
             if(deviceExtension->BaseIoAddressBM_0)
@@ -276,20 +394,22 @@ for_ugly_chips:
     if(deviceExtension->MaxTransferMode >= ATA_SA150) {
         deviceExtension->HwFlags |= UNIATA_SATA;
     }
-
+/*
     ConfigInfo->MaximumTransferLength = DEV_BSIZE*256;
     deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
-
+*/
     ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
     ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
 
+    if(!UniataChipDetectChannels(HwDeviceExtension, pciData, DeviceNumber, ConfigInfo)) {
+        return FALSE;
+    }
+    if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
+        return FALSE;
+    }
+
     switch(VendorID) {
     case ATA_ACER_LABS_ID:
-        switch(deviceExtension->DevID) {
-        case 0x528710b9:
-        case 0x528810b9:
-            deviceExtension->NumberChannels = 4;
-        }
         if(ChipFlags & UNIATA_SATA) {
             deviceExtension->AltRegMap = TRUE; // inform generic resource allocator
             BaseIoAddress1  = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
@@ -299,6 +419,7 @@ for_ugly_chips:
             BaseIoAddressBM = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
                                     4, 0, deviceExtension->NumberChannels*sizeof(IDE_BUSMASTER_REGISTERS));
             for(c=0; c<deviceExtension->NumberChannels; c++) {
+                ULONG unit01 = (c & 1);
                 ULONG unit10 = (c & 2);
                 chan = &deviceExtension->chan[c];
 
@@ -353,7 +474,6 @@ for_ugly_chips:
         if(ChipType != PRMIO) {
             break;
         }
-        deviceExtension->NumberChannels = 4;
         if(!pciData) {
             break;
         }
@@ -424,9 +544,6 @@ for_ugly_chips:
         }
         deviceExtension->BaseIoAddressSATA_0.Addr  = BaseMemAddress;
         deviceExtension->BaseIoAddressSATA_0.MemIo = MemIo;
-        if(deviceExtension->HwFlags & SII4CH) {
-            deviceExtension->NumberChannels = 4;
-        }
 
         for(c=0; c<deviceExtension->NumberChannels; c++) {
             ULONG unit01 = (c & 1);
@@ -512,9 +629,9 @@ for_ugly_chips:
             chan->RegTranslation[IDX_BM_PRD_Table].MemIo       = MemIo;
 
             chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + offs + 0x40;
-            chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
+            chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;               
             chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + offs + 0x44;
-            chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
+            chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;               
             chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + offs + 0x48;
             chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
 
@@ -555,14 +672,14 @@ for_ugly_chips:
             if(tmp32 == ATA_SIS5513 ||
                tmp32 == ATA_SIS5517) {
                 i = AtapiFindListedDev((BUSMASTER_CONTROLLER_INFORMATION*)&SiSSouthAdapters[0],
-                     -1, HwDeviceExtension, SystemIoBusNumber, -1, NULL);
+                     -1, HwDeviceExtension, SystemIoBusNumber, PCISLOTNUM_NOT_SPECIFIED, NULL); 
                 if(i != BMLIST_TERMINATOR) {
                     deviceExtension->HwFlags = (deviceExtension->HwFlags & ~CHIPTYPE_MASK) | SIS133OLD;
                     //deviceExtension->MaxTransferMode = ATA_UDMA6;
                     deviceExtension->MaxTransferMode = SiSSouthAdapters[i].MaxTransferMode;
                     if(SiSSouthAdapters[i].RaidFlags & UNIATA_SATA) {
                         deviceExtension->HwFlags |= UNIATA_SATA;
-                        if(SiSSouthAdapters[i].nDeviceId == 0x01182) {
+                        if(SiSSouthAdapters[i].nDeviceId == 0x1182) {
                             SIS_182 = TRUE;
                         }
                     }
@@ -617,16 +734,20 @@ for_ugly_chips:
         if(ChipFlags & UNIATA_SATA) {
 
             ULONG IoSize = 0;
+            ULONG BaseMemAddress = 0;
 
             switch(DeviceID) {
-            case 3149: // VIA 6420
+            case 0x3149: // VIA 6420
+                KdPrint2((PRINT_PREFIX "VIA 6420\n"));
                 IoSize = 0x80;
                 break;
-            case 3249: // VIA 6421
+            case 0x3249: // VIA 6421
+                KdPrint2((PRINT_PREFIX "VIA 6421\n"));
                 IoSize = 0x40;
                 break;
             }
             if(IoSize) {
+                KdPrint2((PRINT_PREFIX "IoSize %x\n", IoSize));
                 /*deviceExtension->*/BaseMemAddress = AtapiGetIoRange(HwDeviceExtension, ConfigInfo, pciData, SystemIoBusNumber,
                                         5, 0, IoSize * deviceExtension->NumberChannels);
                 if((*ConfigInfo->AccessRanges)[5].RangeInMemory) {
@@ -663,14 +784,18 @@ for_ugly_chips:
                         for (i=0; i<=IDX_BM_IO_SZ; i++) {
                             chan->RegTranslation[IDX_BM_IO+i].Addr         = BaseIoAddressBM_0 + sizeof(IDE_BUSMASTER_REGISTERS)*c + i;
                         }
-                        chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + (c * IoSize);
-                        chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
-                        chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 4 + (c * IoSize);
-                        chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
-                        chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 8 + (c * IoSize);
-                        chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
-
-                        chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
+                        if(c < 2) {
+                            // Do not setup SATA registers for PATA part
+                            chan->RegTranslation[IDX_SATA_SStatus].Addr        = BaseMemAddress + (c * IoSize);
+                            chan->RegTranslation[IDX_SATA_SStatus].MemIo       = MemIo;
+                            chan->RegTranslation[IDX_SATA_SError].Addr         = BaseMemAddress + 4 + (c * IoSize);
+                            chan->RegTranslation[IDX_SATA_SError].MemIo        = MemIo;
+                            chan->RegTranslation[IDX_SATA_SControl].Addr       = BaseMemAddress + 8 + (c * IoSize);
+                            chan->RegTranslation[IDX_SATA_SControl].MemIo      = MemIo;
+
+                            chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
+                        }
+
                     }
                 }
             }
@@ -862,6 +987,7 @@ AtapiRosbSouthBridgeFixup(
     IN ULONG  slotNumber
     )
 {
+    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PCI_COMMON_CONFIG     pciData;
     ULONG                 funcNumber;
     ULONG                 busDataRead;
@@ -913,6 +1039,7 @@ AtapiAliSouthBridgeFixup(
     IN ULONG  c
     )
 {
+    PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PCI_COMMON_CONFIG     pciData;
     ULONG                 funcNumber;
     ULONG                 busDataRead;
@@ -1024,7 +1151,7 @@ via_cable80(
     res = FALSE;
     for (j=0; j>=2; i -= 8) {
         i = (3-(channel*2+j))*8;
-        if (((reg50 >> (i & 16)) & 8) &&
+        if (((reg50 >> (i & 0x10)) & 8) &&
             ((reg50 >> i) & 0x20) &&
              (((reg50 >> i) & 7) < a)) {
 
@@ -1035,6 +1162,35 @@ via_cable80(
 
 } // end via_cable80()
 
+BOOLEAN
+generic_cable80(
+    IN PHW_DEVICE_EXTENSION deviceExtension,
+    IN ULONG channel,               // physical channel number (0-1)
+    IN ULONG pci_reg,
+    IN ULONG bit_offs
+    )
+{
+    PVOID HwDeviceExtension = (PVOID)deviceExtension;
+    ULONG slotNumber = deviceExtension->slotNumber;
+    ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
+
+    ULONG ChipType  = deviceExtension->HwFlags & CHIPTYPE_MASK;
+    PHW_CHANNEL chan;
+    ULONG  c; // logical channel (for Compatible Mode controllers)
+    UCHAR tmp8;
+
+    c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
+    chan = &deviceExtension->chan[c];
+
+    GetPciConfig1(pci_reg, tmp8);
+    if(!(tmp8 & (1 << (channel << bit_offs)))) {
+        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
+        return FALSE;
+    }
+
+    return TRUE;
+} // end generic_cable80()
+
 VOID
 UniAtaReadLunConfig(
     IN PHW_DEVICE_EXTENSION deviceExtension,
@@ -1065,12 +1221,22 @@ UniAtaReadLunConfig(
     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"PreferedTransferMode", 0xffffffff);
     LunExt->opt_PreferedTransferMode = tmp32;
 
+    tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"ReadOnly", 0);
+    if(tmp32 <= 2) {
+        LunExt->opt_ReadOnly = (UCHAR)tmp32;
+    }
+
     tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"GeomType", 0xffffffff);
     if(tmp32 > 2) {
         tmp32 = 0xffffffff;
     }
     LunExt->opt_GeomType = tmp32;
 
+    tmp32 = AtapiRegCheckDevValue(deviceExtension, channel, ldev, L"Hidden", 0);
+    if(tmp32) {
+        LunExt->DeviceFlags |= DFLAGS_HIDDEN;
+    }
+
     return;
 } // end UniAtaReadLunConfig()
 
@@ -1108,6 +1274,7 @@ AtapiReadChipConfig(
     }
 
     if(c == CHAN_NOT_SPECIFIED) {
+        KdPrint2((PRINT_PREFIX "MaxTransferMode (base): %#x\n", deviceExtension->MaxTransferMode));
         for(c=0; c<deviceExtension->NumberChannels; c++) {
             chan = &deviceExtension->chan[c];
             chan->MaxTransferMode = deviceExtension->MaxTransferMode;
@@ -1176,12 +1343,18 @@ AtapiChipInit(
     USHORT tmp16;
     ULONG  tmp32;
     ULONG  c; // logical channel (for Compatible Mode controllers)
+    BOOLEAN CheckCable = FALSE;
     //ULONG BaseIoAddress;
 
-    if(channel != CHAN_NOT_SPECIFIED) {
-        c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
-    } else {
+    switch(channel) {
+    case CHAN_NOT_SPECIFIED_CHECK_CABLE:
+        CheckCable = TRUE;
+        /* FALLTHROUGH */
+    case CHAN_NOT_SPECIFIED:
         c = CHAN_NOT_SPECIFIED;
+        break;
+    default:
+        c = channel - deviceExtension->Channel; // logical channel (for Compatible Mode controllers)
     }
 
     KdPrint2((PRINT_PREFIX "AtapiChipInit: dev %#x, ph chan %d\n", DeviceNumber, channel ));
@@ -1223,15 +1396,15 @@ AtapiChipInit(
 
                 /* enable ATAPI UDMA mode */
                 ChangePciConfig1(0x53, (a | 0x01));
+
+            } else {
+                // check 80-pin cable
+                generic_cable80(deviceExtension, channel, 0x4a, 0);
             }
         } else {
             if(c == CHAN_NOT_SPECIFIED) {
                 /* deactivate the ATAPI FIFO and enable ATAPI UDMA */
                 ChangePciConfig1(0x53, (a | 0x03));
-                // ATAPI DMA R/O
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    deviceExtension->chan[c].ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
-                }
             } else {
                 // ATAPI DMA R/O
                 deviceExtension->chan[c].ChannelCtrlFlags |= CTRFLAGS_DMA_RO;
@@ -1250,21 +1423,11 @@ AtapiChipInit(
         if(deviceExtension->MaxTransferMode < ATA_UDMA2)
             break;
         // check 80-pin cable
-        if(ChipFlags & AMDCABLE) {
+        if(!(ChipFlags & UNIATA_NO80CHK)) {
             if(c == CHAN_NOT_SPECIFIED) {
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    GetPciConfig1(0x42, tmp8);
-                    if(!(tmp8 & (1 << channel))) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
+                // do nothing
             } else {
-                chan = &deviceExtension->chan[c];
-                GetPciConfig1(0x42, tmp8);
-                if(!(tmp8 & (1 << channel))) {
-                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
+                generic_cable80(deviceExtension, channel, 0x42, 0);
             }
         }
         break;
@@ -1289,13 +1452,6 @@ AtapiChipInit(
                 }
             }
 
-            // check 80-pin cable
-            for(c=0; c<deviceExtension->NumberChannels; c++) {
-                chan = &deviceExtension->chan[c];
-                if(!hpt_cable80(deviceExtension, channel)) {
-                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
-            }
         } else {
             // check 80-pin cable
             chan = &deviceExtension->chan[c];
@@ -1337,14 +1493,9 @@ AtapiChipInit(
         }
         if(deviceExtension->MaxTransferMode < ATA_UDMA2)
             break;
+        // check 80-pin cable
         if(c == CHAN_NOT_SPECIFIED) {
-            for(c=0; c<deviceExtension->NumberChannels; c++) {
-                chan = &deviceExtension->chan[c];
-                GetPciConfig2(0x54, reg54);
-                if( ((reg54 >> (channel*2)) & 30) != 30) {
-                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
-            }
+            // do nothing
         } else {
             chan = &deviceExtension->chan[c];
             GetPciConfig2(0x54, reg54);
@@ -1366,7 +1517,7 @@ AtapiChipInit(
                     /* enable device and PHY state change interrupts */
                     AtapiWritePortEx4(NULL, (ULONG)(&deviceExtension->BaseIoAddressSATA_0),offs+4, 0x000d000d);
                     /* disable NCQ support */
-                    AtapiWritePortEx4(NULL, (ULONG)(&deviceExtension->BaseIoAddressSATA_0),0x0400,
+                    AtapiWritePortEx4(NULL, (ULONG)(&deviceExtension->BaseIoAddressSATA_0),0x0400, 
                         AtapiReadPortEx4(NULL, (ULONG)(&deviceExtension->BaseIoAddressSATA_0),0x0400) & 0xfffffff9);
                 } else {
                     /* clear interrupt status */
@@ -1380,27 +1531,19 @@ AtapiChipInit(
                 //UniataSataPhyEnable(HwDeviceExtension, c);
             }
         } else {
-            UCHAR reg52;
-
-            // check 80-pin cable
+            //UCHAR reg52;
+            
             if(c == CHAN_NOT_SPECIFIED) {
-
                 /* set prefetch, postwrite */
                 ChangePciConfig1(0x51, (a & 0x0f));
-
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    GetPciConfig1(0x52, reg52);
-                    if( !((reg52 >> (channel*2)) & 0x01)) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
             } else {
-                chan = &deviceExtension->chan[c];
+                // check 80-pin cable
+                generic_cable80(deviceExtension, channel, 0x52, 1);
+/*                chan = &deviceExtension->chan[c];
                 GetPciConfig1(0x52, reg52);
                 if( !((reg52 >> (channel*2)) & 0x01)) {
                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
+                }*/
             }
         }
         break; }
@@ -1411,7 +1554,7 @@ AtapiChipInit(
             /* setup clocks */
             if(c == CHAN_NOT_SPECIFIED) {
 //            ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
-                AtapiWritePortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x11,
+                AtapiWritePortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x11, 
                     AtapiReadPortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x11) | 0x0a );
             }
             /* FALLTHROUGH */
@@ -1419,16 +1562,10 @@ AtapiChipInit(
             /* enable burst mode */
 //            ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
             if(c == CHAN_NOT_SPECIFIED) {
-                AtapiWritePortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x1f,
+                AtapiWritePortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x1f, 
                     AtapiReadPortEx1(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x1f) | 0x01 );
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    GetPciConfig2(0x50, Reg50);
-                    if(Reg50 & (1 << (channel+10))) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
             } else {
+                // check 80-pin cable
                 chan = &deviceExtension->chan[c];
                 GetPciConfig2(0x50, Reg50);
                 if(Reg50 & (1 << (channel+10))) {
@@ -1438,14 +1575,9 @@ AtapiChipInit(
             break;
         case PRTX:
             if(c == CHAN_NOT_SPECIFIED) {
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
-                    if(AtapiReadPort1(chan, IDX_BM_DeviceSpecific1) & 0x04) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
+                // do nothing
             } else {
+                // check 80-pin cable
                 chan = &deviceExtension->chan[c];
                 AtapiWritePort1(chan, IDX_BM_DeviceSpecific0, 0x0b);
                 if(AtapiReadPort1(chan, IDX_BM_DeviceSpecific1) & 0x04) {
@@ -1458,21 +1590,12 @@ AtapiChipInit(
                 if(ChipFlags & PRSATA) {
                     AtapiWritePortEx4(NULL, (ULONG)(&deviceExtension->BaseIoAddressBM_0),0x6c, 0x000000ff);
                 }
-                for(c=0; c<4; c++) {
-                    chan = &deviceExtension->chan[c];
-                    AtapiWritePort4(chan, IDX_BM_Command,
-                        (AtapiReadPort4(chan, IDX_BM_Command) & ~0x00000f8f) | channel );
-                    AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
-                    if(chan->MaxTransferMode < ATA_SA150 &&
-                       (AtapiReadPort4(chan, IDX_BM_Command) & 0x01000000)) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
             } else {
                 chan = &deviceExtension->chan[c];
-                AtapiWritePort4(chan, IDX_BM_Command,
+                AtapiWritePort4(chan, IDX_BM_Command, 
                     (AtapiReadPort4(chan, IDX_BM_Command) & ~0x00000f8f) | channel );
                 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
+                // check 80-pin cable
                 if(chan->MaxTransferMode < ATA_SA150 &&
                    (AtapiReadPort4(chan, IDX_BM_Command) & 0x01000000)) {
                     chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
@@ -1507,7 +1630,7 @@ AtapiChipInit(
         case SIIMIO: {
 
             KdPrint2((PRINT_PREFIX "SII\n"));
-            UCHAR Reg79;
+            USHORT Reg79;
 
             if(c == CHAN_NOT_SPECIFIED) {
                 if(ChipFlags & SIISETCLK)  {
@@ -1523,16 +1646,11 @@ AtapiChipInit(
                 }
             }
             if(deviceExtension->MaxTransferMode < ATA_SA150) {
-                KdPrint2((PRINT_PREFIX "Check UDMA66 cable\n"));
+                // check 80-pin cable
                 if(c == CHAN_NOT_SPECIFIED) {
-                    for(c=0; c<deviceExtension->NumberChannels; c++) {
-                        chan = &deviceExtension->chan[c];
-                        GetPciConfig2(0x79, Reg79);
-                        if(Reg79 & (channel ? 0x02 : 0x01)) {
-                            chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                        }
-                    }
+                    // do nothing
                 } else {
+                    KdPrint2((PRINT_PREFIX "Check UDMA66 cable\n"));
                     chan = &deviceExtension->chan[c];
                     GetPciConfig2(0x79, Reg79);
                     if(Reg79 & (channel ? 0x02 : 0x01)) {
@@ -1647,14 +1765,9 @@ AtapiChipInit(
         }
         if(ChipType == SIS133NEW) {
             USHORT tmp16;
+            // check 80-pin cable
             if(c == CHAN_NOT_SPECIFIED) {
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    GetPciConfig2(channel ? 0x52 : 0x50, tmp16);
-                    if(tmp16 & 0x8000) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
+                // do nothing
             } else {
                 chan = &deviceExtension->chan[c];
                 GetPciConfig2(channel ? 0x52 : 0x50, tmp16);
@@ -1663,14 +1776,9 @@ AtapiChipInit(
                 }
             }
         } else {
+            // check 80-pin cable
             if(c == CHAN_NOT_SPECIFIED) {
-                for(c=0; c<deviceExtension->NumberChannels; c++) {
-                    chan = &deviceExtension->chan[c];
-                    GetPciConfig1(48, tmp8);
-                    if(tmp8 & (0x10 << channel)) {
-                        chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                    }
-                }
+                // do nothing
             } else {
                 chan = &deviceExtension->chan[c];
                 GetPciConfig1(48, tmp8);
@@ -1693,23 +1801,7 @@ AtapiChipInit(
                 ChangePciConfig2(/*PCIR_COMMAND*/0x04, (a & ~0x0400));
                 break;
             }
-        }
-        // check 80-pin cable
-        if(c == CHAN_NOT_SPECIFIED) {
-            for(c=0; c<deviceExtension->NumberChannels; c++) {
-                chan = &deviceExtension->chan[c];
-                if(!via_cable80(deviceExtension, channel)) {
-                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
-            }
-        } else {
-            chan = &deviceExtension->chan[c];
-            if(!via_cable80(deviceExtension, channel)) {
-                chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-            }
-        }
 
-        if(c == CHAN_NOT_SPECIFIED) {
             /* the southbridge might need the data corruption fix */
             if(ChipFlags & VIABUG) {
                 AtapiViaSouthBridgeFixup(HwDeviceExtension, PCIConfiguration,
@@ -1732,6 +1824,12 @@ AtapiChipInit(
             /* set sector size */
             SetPciConfig2(0x60, DEV_BSIZE);
             SetPciConfig2(0x68, DEV_BSIZE);
+        } else {
+            // check 80-pin cable
+            chan = &deviceExtension->chan[c];
+            if(!via_cable80(deviceExtension, channel)) {
+                chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
+            }
         }
 
         break;
@@ -1747,18 +1845,9 @@ AtapiChipInit(
             /* set default active & recover timings */
             SetPciConfig1(0x54, 0x31);
             SetPciConfig1(0x56, 0x31);
-        }
-
-        GetPciConfig2(0x40, tmp16);
-        // check 80-pin cable
-        if(c == CHAN_NOT_SPECIFIED) {
-            for(c=0; c<deviceExtension->NumberChannels; c++) {
-                chan = &deviceExtension->chan[c];
-                if(!(tmp16 & (channel ? 0x08 : 0x04))) {
-                    chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
-                }
-            }
         } else {
+            // check 80-pin cable
+            GetPciConfig2(0x40, tmp16);
             chan = &deviceExtension->chan[c];
             if(!(tmp16 & (channel ? 0x08 : 0x04))) {
                 chan->MaxTransferMode = min(deviceExtension->MaxTransferMode, ATA_UDMA2);
@@ -1766,6 +1855,23 @@ AtapiChipInit(
         }
 
         break;
+    default:
+        if(c != CHAN_NOT_SPECIFIED) {
+            // We don't know how to check for 80-pin cable on unknown controllers.
+            // Later we shall check bit in IDENTIFY structure, but it is not reliable way.
+            // So, leave this flag to use as hint in error recovery procedures
+            KdPrint2((PRINT_PREFIX "UNIATA_NO80CHK\n"));
+            deviceExtension->HwFlags |= UNIATA_NO80CHK;
+        }
+        break;
+    }
+
+    // In all places separate channels are inited after common controller init
+    // The only exception is probe. But there we may need info about 40/80 pin and MaxTransferRate
+    if(CheckCable && !(ChipFlags & (UNIATA_NO80CHK | UNIATA_SATA))) {
+        for(c=0; c<deviceExtension->NumberChannels; c++) {
+            AtapiChipInit(HwDeviceExtension, DeviceNumber, c);
+        }
     }
 
     return TRUE;
index 27ab0da..cfbb887 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 
-Copyright (c) 2002-2007 Alexandr A. Telyatnikov (Alter)
+Copyright (c) 2002-2008 Alexandr A. Telyatnikov (Alter)
 
 Module Name:
     id_probe.cpp
@@ -76,7 +76,7 @@ UniataEnumBusMasterController__(
 VOID
 AtapiDoNothing(VOID)
 {
-    //ULONG i = 0;
+    ULONG i = 0;
     return;
 } // end AtapiDoNothing()
 
@@ -504,8 +504,8 @@ UniataEnumBusMasterController__(
 /*                        if(known) {
                             RtlCopyMemory(newBMListPtr, (PVOID)&(BusMasterAdapters[i]), sizeof(BUSMASTER_CONTROLLER_INFORMATION));
                         } else {*/
-                        sprintf((PCHAR)vendorStrPtr, "%4.4x", (UINT32)VendorID);
-                        sprintf((PCHAR)deviceStrPtr, "%4.4x", (UINT32)DeviceID);
+                        sprintf((PCHAR)vendorStrPtr, "%4.4x", VendorID);
+                        sprintf((PCHAR)deviceStrPtr, "%4.4x", DeviceID);
 
                         RtlCopyMemory(&(newBMListPtr->VendorIdStr), (PCHAR)vendorStrPtr, 4);
                         RtlCopyMemory(&(newBMListPtr->DeviceIdStr), (PCHAR)deviceStrPtr, 4);
@@ -768,6 +768,44 @@ UniataFindCompatBusMasterController2(
         );
 } // end UniataFindCompatBusMasterController2()
 
+BOOLEAN
+UniataAllocateLunExt(
+    PHW_DEVICE_EXTENSION  deviceExtension,
+    ULONG NewNumberChannels
+    )
+{
+    PHW_LU_EXTENSION old_luns = NULL;
+    PHW_CHANNEL old_chans = NULL;
+
+    KdPrint2((PRINT_PREFIX "allocate Luns for %d channels\n", deviceExtension->NumberChannels));
+
+    old_luns = deviceExtension->lun;
+    old_chans = deviceExtension->chan;
+
+    if(old_luns || old_chans) {
+        if(NewNumberChannels == UNIATA_ALLOCATE_NEW_LUNS) {
+            KdPrint2((PRINT_PREFIX "already allocated!\n"));
+            return FALSE;
+        }
+    }
+
+    deviceExtension->lun = (PHW_LU_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * IDE_MAX_LUN_PER_CHAN);
+    if (!deviceExtension->lun) {
+        KdPrint2((PRINT_PREFIX "!deviceExtension->lun => SP_RETURN_ERROR\n"));
+        return FALSE;
+    }
+    RtlZeroMemory(deviceExtension->lun, sizeof(HW_LU_EXTENSION) * (deviceExtension->NumberChannels+1) * IDE_MAX_LUN_PER_CHAN);
+    
+    deviceExtension->chan = (PHW_CHANNEL)ExAllocatePool(NonPagedPool, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
+    if (!deviceExtension->chan) {
+        KdPrint2((PRINT_PREFIX "!deviceExtension->chan => SP_RETURN_ERROR\n"));
+        return FALSE;
+    }
+    RtlZeroMemory(deviceExtension->chan, sizeof(HW_CHANNEL) * (deviceExtension->NumberChannels+1));
+    return TRUE;
+} // end UniataAllocateLunExt()
+
+
 /*++
 
 Routine Description:
@@ -861,6 +899,8 @@ UniataFindBusMasterController(
 
     KdPrint2((PRINT_PREFIX "UniataFindBusMasterController: Context=%x, BMListLen=%d\n", Context, BMListLen));
 
+    KdPrint2((PRINT_PREFIX "ConfigInfo->Length %x\n", ConfigInfo->Length));
+
     if(ForceSimplex) {
         KdPrint2((PRINT_PREFIX "ForceSimplex (1)\n"));
         simplexOnly = TRUE;
@@ -893,7 +933,7 @@ UniataFindBusMasterController(
             i &= ~0x80000000;
             if(i >= BMListLen) {
                 KdPrint2((PRINT_PREFIX " => SP_RETURN_NOT_FOUND\n"));
-                return(SP_RETURN_NOT_FOUND);
+                goto exit_notfound;
             }
         }
         BMList[i].channel = (UCHAR)channel;
@@ -933,13 +973,13 @@ UniataFindBusMasterController(
 #ifndef UNIATA_CORE
     if (busDataRead < (ULONG)PCI_COMMON_HDR_LENGTH) {
         KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
-        return SP_RETURN_ERROR;
+        goto exit_error;
     }
 
     KdPrint2((PRINT_PREFIX "busDataRead\n"));
     if (pciData.VendorID == PCI_INVALID_VENDORID) {
         KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n"));
-        return SP_RETURN_ERROR;
+        goto exit_error;
     }
 #endif //UNIATA_CORE
 
@@ -964,7 +1004,7 @@ UniataFindBusMasterController(
 
     if(BaseClass != PCI_DEV_CLASS_STORAGE) {
         KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     KdPrint2((PRINT_PREFIX "Storage Class\n"));
@@ -973,13 +1013,13 @@ UniataFindBusMasterController(
     if(VendorID != BMList[i].nVendorId ||
        DeviceID != BMList[i].nDeviceId) {
         KdPrint2((PRINT_PREFIX "device not suitable\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     found = UniataCheckPCISubclass(BMList[i].Known, BMList[i].RaidFlags, SubClass);
     if(!found) {
         KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     ConfigInfo->AlignmentMask = 0x00000003;
@@ -1017,7 +1057,7 @@ UniataFindBusMasterController(
     KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags));
     if(!found) {
         KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags));
@@ -1050,11 +1090,11 @@ UniataFindBusMasterController(
         } else {
             if((channel==0) && ConfigInfo->AtdiskPrimaryClaimed) {
                 KdPrint2((PRINT_PREFIX "Error: Primary channel already claimed by another driver\n"));
-                return(SP_RETURN_NOT_FOUND);
+                goto exit_notfound;
             }
             if((channel==1) && ConfigInfo->AtdiskSecondaryClaimed) {
                 KdPrint2((PRINT_PREFIX "Error: Secondary channel already claimed by another driver\n"));
-                return(SP_RETURN_NOT_FOUND);
+                goto exit_notfound;
             }
         }
     }
@@ -1274,12 +1314,14 @@ UniataFindBusMasterController(
 
     if((WinVer_Id() >= WinVer_NT) ||
        (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4))) {
+        KdPrint2((PRINT_PREFIX "update ConfigInfo->nt4\n"));
         _ConfigInfo->nt4.DeviceExtensionSize         = sizeof(HW_DEVICE_EXTENSION);
         _ConfigInfo->nt4.SpecificLuExtensionSize     = sizeof(HW_LU_EXTENSION);
         _ConfigInfo->nt4.SrbExtensionSize            = sizeof(ATA_REQ);
     }
     if((WinVer_Id() > WinVer_2k) ||
        (ConfigInfo->Length >= sizeof(_ConfigInfo->comm) + sizeof(_ConfigInfo->nt4) + sizeof(_ConfigInfo->w2k))) {
+        KdPrint2((PRINT_PREFIX "update ConfigInfo->w2k\n"));
         _ConfigInfo->w2k.Dma64BitAddresses           = 0;
         _ConfigInfo->w2k.ResetTargetSupported        = TRUE;
         _ConfigInfo->w2k.MaximumNumberOfLogicalUnits = 2;
@@ -1317,7 +1359,7 @@ UniataFindBusMasterController(
 
         if(AltInit) {
             // I'm sorry, I have to do this
-            // when Win doesn't
+            // when Win doesn't 
 
             if(ConfigInfo->AdapterInterfaceType == Isa /*&&
 //               InDriverEntry*/) {
@@ -1526,7 +1568,7 @@ UniataFindBusMasterController(
             // Search for devices on this controller.
             if (!skip_find_dev &&
                 FindDevices(HwDeviceExtension,
-                        FALSE,
+                        0,
                         c)) {
                 KdPrint2((PRINT_PREFIX "Found some devices\n"));
                 found = TRUE;
@@ -1592,7 +1634,7 @@ exit_findbm:
                                    BaseIoAddressBM_0);
 
         KdPrint2((PRINT_PREFIX "return SP_RETURN_NOT_FOUND\n"));
-        return SP_RETURN_NOT_FOUND;
+        goto exit_notfound;
     } else {
 
         KdPrint2((PRINT_PREFIX "exit: init spinlock\n"));
@@ -1642,6 +1684,16 @@ exit_findbm:
     ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
     return SP_RETURN_FOUND;
 
+exit_error:
+    if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
+    if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
+    return SP_RETURN_ERROR;
+    
+exit_notfound:
+    ExFreePool(deviceExtension->lun);
+    ExFreePool(deviceExtension->chan);
+    return SP_RETURN_NOT_FOUND;
+
 } // end UniataFindBusMasterController()
 
 #ifndef UNIATA_CORE
@@ -1713,7 +1765,7 @@ UniataFindFakeBusMasterController(
         }
         if(i >= BMListLen) {
             KdPrint2((PRINT_PREFIX "unexpected device arrival => SP_RETURN_NOT_FOUND\n"));
-            return(SP_RETURN_NOT_FOUND);
+            goto exit_notfound;
         }
     }
 
@@ -1747,13 +1799,13 @@ UniataFindFakeBusMasterController(
 
     if (busDataRead < PCI_COMMON_HDR_LENGTH) {
         KdPrint2((PRINT_PREFIX "busDataRead < PCI_COMMON_HDR_LENGTH => SP_RETURN_ERROR\n"));
-        return SP_RETURN_ERROR;
+        goto exit_error;
     }
 
     KdPrint2((PRINT_PREFIX "busDataRead\n"));
     if (pciData.VendorID == PCI_INVALID_VENDORID) {
         KdPrint2((PRINT_PREFIX "PCI_INVALID_VENDORID\n"));
-        return SP_RETURN_ERROR;
+        goto exit_error;
     }
 
     VendorID  = pciData.VendorID;
@@ -1777,7 +1829,7 @@ UniataFindFakeBusMasterController(
 
     if(BaseClass != PCI_DEV_CLASS_STORAGE) {
         KdPrint2((PRINT_PREFIX "BaseClass != PCI_DEV_CLASS_STORAGE => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     KdPrint2((PRINT_PREFIX "Storage Class\n"));
@@ -1786,13 +1838,13 @@ UniataFindFakeBusMasterController(
     if(VendorID != BMList[i].nVendorId ||
        DeviceID != BMList[i].nDeviceId) {
         KdPrint2((PRINT_PREFIX "device not suitable\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     if((BMList[i].RaidFlags & UNIATA_RAID_CONTROLLER) &&
         SkipRaids) {
         KdPrint2((PRINT_PREFIX "RAID support disabled\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     switch(SubClass) {
@@ -1804,7 +1856,7 @@ UniataFindFakeBusMasterController(
         break;
     default:
         KdPrint2((PRINT_PREFIX "Subclass not supported\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     ConfigInfo->AlignmentMask = 0x00000003;
@@ -1842,7 +1894,7 @@ UniataFindFakeBusMasterController(
     KdPrint2((PRINT_PREFIX "HwFlags = %x\n (1)", deviceExtension->HwFlags));
     if(!found) {
         KdPrint2((PRINT_PREFIX "!found => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     KdPrint2((PRINT_PREFIX "HwFlags = %x\n (2)", deviceExtension->HwFlags));
@@ -1868,16 +1920,16 @@ UniataFindFakeBusMasterController(
         deviceExtension->NumberChannels = 1;
     } else {
         KdPrint2((PRINT_PREFIX "!MasterDev => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     if(deviceExtension->AltRegMap) {
         KdPrint2((PRINT_PREFIX "  Non-standard registers layout => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
     if(IsBusMaster(&pciData)) {
         KdPrint2((PRINT_PREFIX "  !BusMaster => SP_RETURN_NOT_FOUND\n"));
-        return(SP_RETURN_NOT_FOUND);
+        goto exit_notfound;
     }
 
     KdPrint2((PRINT_PREFIX "IsBusMaster == TRUE\n"));
@@ -1959,6 +2011,16 @@ exit_findbm:
     //PrintNtConsole("return SP_RETURN_FOUND, de %#x, c0.lun0 %#x\n", deviceExtension, deviceExtension->chan[0].lun[0]);
 
     return SP_RETURN_FOUND;
+    
+exit_error:
+    if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
+    if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
+    return SP_RETURN_ERROR;
+    
+exit_notfound:
+    ExFreePool(deviceExtension->lun);
+    ExFreePool(deviceExtension->chan);
+    return SP_RETURN_NOT_FOUND;
 
 } // end UniataFindFakeBusMasterController()
 
@@ -2143,7 +2205,7 @@ AtapiFindController(
     )
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    PHW_CHANNEL          chan = &(deviceExtension->chan[0]);
+    PHW_CHANNEL          chan;
     PULONG               adapterCount    = (PULONG)Context;
     PUCHAR               ioSpace;
     ULONG                i;
@@ -2177,6 +2239,12 @@ AtapiFindController(
     deviceExtension->MaxTransferMode = ATA_PIO4;
     deviceExtension->NumberChannels = 1;
 
+    if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
+        goto exit_error;
+    }
+
+    chan = &(deviceExtension->chan[0]);
+
     deviceExtension->AdapterInterfaceType =
     deviceExtension->OrigAdapterInterfaceType
                                         = ConfigInfo->AdapterInterfaceType;
@@ -2531,8 +2599,15 @@ not_found:
 
     KdPrint2((PRINT_PREFIX
                "AtapiFindController: return SP_RETURN_NOT_FOUND\n"));
+    ExFreePool(deviceExtension->lun);
+    ExFreePool(deviceExtension->chan);
     return(SP_RETURN_NOT_FOUND);
 
+exit_error:
+    if (deviceExtension->lun) ExFreePool(deviceExtension->lun);
+    if (deviceExtension->chan) ExFreePool(deviceExtension->chan);
+    return SP_RETURN_ERROR;
+    
 } // end AtapiFindController()
 
 BOOLEAN
index 0611cdc..3ebd999 100644 (file)
@@ -7,7 +7,7 @@ UniataSataConnect(
     )
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
-    //ULONG Channel = deviceExtension->Channel + lChannel;
+    ULONG Channel = deviceExtension->Channel + lChannel;
     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
     SATA_SSTATUS_REG SStatus;
     ULONG i;
@@ -126,7 +126,7 @@ UniataSataClearErr(
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     PHW_CHANNEL chan = &deviceExtension->chan[lChannel];
-    //ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
+    ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
     SATA_SSTATUS_REG SStatus;
     SATA_SERROR_REG  SError;
 
@@ -134,7 +134,7 @@ UniataSataClearErr(
     //if(ChipFlags & UNIATA_SATA) {
 
         SStatus.Reg = AtapiReadPort4(chan, IDX_SATA_SStatus);
-        SError.Reg  = AtapiReadPort4(chan, IDX_SATA_SError);
+        SError.Reg  = AtapiReadPort4(chan, IDX_SATA_SError); 
 
         if(SStatus.Reg) {
             KdPrint2((PRINT_PREFIX "  SStatus %x\n", SStatus.Reg));
@@ -203,13 +203,14 @@ UniataAhciInit(
 {
     PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
     ULONG version;
-    ULONG c;
+    ULONG c, i, n;
     PHW_CHANNEL chan;
     ULONG offs;
     ULONG BaseMemAddress;
     ULONG PI;
     ULONG CAP;
     BOOLEAN MemIo;
+    ULONGLONG base;
 
     /* reset AHCI controller */
     AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC,
@@ -225,9 +226,11 @@ UniataAhciInit(
         AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) | AHCI_GHC_AE);
 
     CAP = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_CAP);
+    PI = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_PI);
     /* get the number of HW channels */
+    for(i=PI, n=0; i; n++, i=i>>1);
     deviceExtension->NumberChannels =
-        (CAP & AHCI_CAP_NOP_MASK)+1;
+        max((CAP & AHCI_CAP_NOP_MASK)+1, n);
     if(CAP & AHCI_CAP_S64A) {
         KdPrint2((PRINT_PREFIX "  AHCI 64bit\n"));
         deviceExtension->Host64 = TRUE;
@@ -242,7 +245,6 @@ UniataAhciInit(
         AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_GHC) | AHCI_GHC_IE);
 
     version = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_VS);
-    PI = AtapiReadPortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, IDX_AHCI_PI);
     KdPrint2((PRINT_PREFIX "  AHCI version %x%x.%x%x controller with %d ports (mask %x) detected\n",
                  (version >> 24) & 0xff, (version >> 16) & 0xff,
                  (version >> 8) & 0xff, version & 0xff, deviceExtension->NumberChannels, PI));
@@ -281,6 +283,24 @@ UniataAhciInit(
         chan->RegTranslation[IDX_SATA_SActive].Addr   = BaseMemAddress + offs + FIELD_OFFSET(IDE_AHCI_PORT_REGISTERS, SACT);
         chan->RegTranslation[IDX_SATA_SActive].MemIo  = MemIo;
 
+        AtapiDmaAlloc(HwDeviceExtension, NULL, c);
+
+        base = chan->AHCI_CL_PhAddr;
+        if(!base) {
+            KdPrint2((PRINT_PREFIX "  AHCI buffer allocation failed\n"));
+            return FALSE;
+        }
+        AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, offs + IDX_AHCI_P_CLB,
+            (ULONG)(base & 0xffffffff));
+        AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, offs + IDX_AHCI_P_CLB + 4,
+            (ULONG)((base >> 32) & 0xffffffff));
+
+        base = chan->AHCI_CL_PhAddr + ATA_AHCI_MAX_TAGS;
+        AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, offs + IDX_AHCI_P_FB,
+            (ULONG)(base & 0xffffffff));
+        AtapiWritePortEx4(NULL, (ULONG)&deviceExtension->BaseIoAHCI_0, offs + IDX_AHCI_P_FB + 4,
+            (ULONG)((base >> 32) & 0xffffffff));
+
         chan->ChannelCtrlFlags |= CTRFLAGS_NO_SLAVE;
     }
 
@@ -367,6 +387,13 @@ UniataAhciSetupFIS(
     i = 0;
     plba = (PUCHAR)&lba;
 
+    if((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) &&
+       CheckIfBadBlock(&(deviceExtension->lun[ldev]), lba, count)) {
+        KdPrint3((PRINT_PREFIX ": artificial bad block, lba %#I64x count %#x\n", lba, count));
+        return IDE_STATUS_ERROR;
+        //return SRB_STATUS_ERROR;
+    }
+
     /* translate command into 48bit version */
     if ((lba >= ATA_MAX_LBA28 || count > 256) &&
         deviceExtension->lun[ldev].IdentifyData.FeaturesSupport.Address48) {
@@ -378,36 +405,36 @@ UniataAhciSetupFIS(
         }
     }
 
-    fis[i++] = 0x27;  /* host to device */
-    fis[i++] = 0x80;  /* command FIS (note PM goes here) */
-    fis[i++] = command;
-    fis[i++] = (UCHAR)feature;
+    fis[0] = 0x27;  /* host to device */
+    fis[1] = 0x80;  /* command FIS (note PM goes here) */
+    fis[2] = command;
+    fis[3] = (UCHAR)feature;
 
-    fis[i++] = plba[0];
-    fis[i++] = plba[1];
-    fis[i++] = plba[2];
-    fis[i] = IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1);
+    fis[4] = plba[0];
+    fis[5] = plba[1];
+    fis[6] = plba[2];
+    fis[7] = IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1);
     if ((lba >= ATA_MAX_LBA28 || count > 256) &&
         deviceExtension->lun[ldev].IdentifyData.FeaturesSupport.Address48) {
         i++;
     } else {
-        fis[i++] |= (plba[3] >> 24) & 0x0f;
+        fis[7] |= (plba[3] >> 24) & 0x0f;
     }
 
-    fis[i++] = plba[3];
-    fis[i++] = plba[4];
-    fis[i++] = plba[5]; 
-    fis[i++] = (UCHAR)(feature>>8) & 0xff;
-
-    fis[i++] = (UCHAR)count & 0xff;
-    fis[i++] = (UCHAR)(count>>8) & 0xff;
-    fis[i++] = 0x00;
-    fis[i++] = IDE_DC_A_4BIT;
-
-    fis[i++] = 0x00;
-    fis[i++] = 0x00;
-    fis[i++] = 0x00;
-    fis[i++] = 0x00;
-    return i;
+    fis[8] = plba[3];
+    fis[9] = plba[4];
+    fis[10] = plba[5]; 
+    fis[11] = (UCHAR)(feature>>8) & 0xff;
+
+    fis[12] = (UCHAR)count & 0xff;
+    fis[13] = (UCHAR)(count>>8) & 0xff;
+    fis[14] = 0x00;
+    fis[15] = IDE_DC_A_4BIT;
+
+    fis[16] = 0x00;
+    fis[17] = 0x00;
+    fis[18] = 0x00;
+    fis[19] = 0x00;
+    return 20;
 } // end UniataAhciSetupFIS()
 
index d64ec14..8553f0f 100644 (file)
@@ -12,7 +12,7 @@
 #define REACTOS_STR_FILE_VERSION        VERSION_STR
 #define REACTOS_STR_INTERNAL_NAME       "uniata.sys"
 #define REACTOS_STR_ORIGINAL_FILENAME   "uniata.sys"
-#define REACTOS_STR_LEGAL_COPYRIGHT     "Copyright 1999-2004 AlterWare, Copyright 2007 ReactOS Team"
+#define REACTOS_STR_LEGAL_COPYRIGHT     "Copyright 1999-2008 AlterWare, Copyright 2007 ReactOS Team"
 #define REACTOS_STR_PRODUCT_NAME        "UniATA Driver for ReactOS"
 #define REACTOS_STR_PRODUCT_VERSION     VERSION_STR
 
index 2e22649..12fbdec 100644 (file)
@@ -7,7 +7,7 @@ extern "C" {
 
 #if !defined(NT_INCLUDED)
 #include <ntddk.h>                  // various NT definitions
-#endif
+#endif 
 
 #include <stddef.h>
 #include <string.h>
index 0939fca..61f5267 100644 (file)
@@ -9,6 +9,11 @@
 #define ASSERT //(x) if (!(x)) {RtlAssert("#x",__FILE__,__LINE__, ""); }
 #endif //__REACTOS__
 
+
+#ifndef FILE_CHARACTERISTIC_PNP_DEVICE  // DDK 2003
+
+#define FILE_CHARACTERISTIC_PNP_DEVICE  0x00000800
+
 typedef enum _SYSTEM_INFORMATION_CLASS {
     SystemBasicInformation,
     SystemProcessorInformation,
@@ -125,6 +130,8 @@ typedef enum _SYSTEM_INFORMATION_CLASS {
 #endif //__REACTOS__
 } SYSTEM_INFORMATION_CLASS;
 
+#endif // !FILE_CHARACTERISTIC_PNP_DEVICE
+
 
 NTSYSAPI
 NTSTATUS
index e874386..f6e5b1c 100644 (file)
@@ -4,6 +4,7 @@
        <bootstrap installbase="$(CDOUTPUT)" />
        <include base="uniata">.</include>
        <include base="uniata">inc</include>
+       <define name="_DEBUG" />
        <library>ntoskrnl</library>
        <library>hal</library>
        <library>scsiport</library>
index 8494425..8c55047 100644 (file)
@@ -1,6 +1,6 @@
-#define UNIATA_VER_STR         "39f"
-#define UNIATA_VER_DOT         0.39.6.0
-#define UNIATA_VER_DOT_COMMA   0,39,6,0
-#define UNIATA_VER_DOT_STR     "0.39.6.0"
-#define UNIATA_VER_YEAR        2007
-#define UNIATA_VER_YEAR_STR    "2007"
+#define UNIATA_VER_STR         "39j"
+#define UNIATA_VER_DOT         0.39.10.0
+#define UNIATA_VER_DOT_COMMA   0,39,10,0
+#define UNIATA_VER_DOT_STR     "0.39.10.0"
+#define UNIATA_VER_YEAR        2008
+#define UNIATA_VER_YEAR_STR    "2008"