📄 promise_ide.c
字号:
sysOutByte(baseAddress[4] + 0x001a,primary_mode|1);
DbgPrint(("setting secondary_mode: 0x%x set to 0x%x\n",baseAddress[4]+0x1b,secondary_mode|1,0,0,0,0));
sysOutByte(baseAddress[4] + 0x001b,secondary_mode|1);
#if 0
// The statment below causes the promise controller to hang, unless a
// printf preceeds it. Ouch. Why?????
// However,It does not seem to be necessary. So I am commenting it out
// enable port0 device ???? to enable port 1 write offset 0x50 data 0x4 ?????
// I do not have a spec I am puzzling linux driver
status = pciConfigOutByte(
BusNo, /* bus number */
DeviceNo, /* device number */
FuncNo, /* function number */
0x50, /* offset into the configuration space */
0x02 /* data read from offset */
);
#if PROMISE_DEBUG
if (status != OK) {
printf("pciConfigOutByte error\n");
}
#endif /* PROMISE_DEBUG */
if (status != OK)
return status;
#endif /* 0 */
}
#else
int
ataInitPromise()
{
STATUS status;
int vector;
//unsigned char udma_speed_flag;
//unsigned char primary_mode;
//unsigned char secondary_mode;
int i;
//UINT32 romAddress;
// struct timespec waittime;
// volatile_noncached int *marker = 0xc0000010 + 0x18100000;
// printf("here\n");
// waittime.tv_sec = 0;
// waittime.tv_nsec = 50000;
// *marker = 0xDEADBEEF;
DbgPrint(("IN Promise initilization!\n",0,0,0,0,0,0));
//
// find PROMISE ultra-100 ide option card
// the logic here is that only one controller type can be
// present in the system. For LEAN_AND_MEAN, we only look
// for the 20265 (assumption here is that this is for the DVD
// system that only contains a 20265)
//
#if !(LEAN_AND_MEAN)
status = pciFindDevice(
PCI_VENDOR_ID_PROMISE, /* vendor ID */
PCI_DEVICE_ID_PROMISE_20262, /* device ID */
0, /* desired instance of device */
&BusNo, /* bus number */
&DeviceNo, /* device number */
&FuncNo /* function number */
);
if (status != OK) {
status = pciFindDevice(
PCI_VENDOR_ID_PROMISE, /* vendor ID */
PCI_DEVICE_ID_PROMISE_20267,/* device ID */
0, /* desired instance of device */
&BusNo, /* bus number */
&DeviceNo, /* device number */
&FuncNo /* function number */
);
}
if (status != OK)
#endif
{
status = pciFindDevice(
PCI_VENDOR_ID_PROMISE, /* vendor ID */
PCI_DEVICE_ID_PROMISE_20265, /* device ID */
0, /* desired instance of device */
&BusNo, /* bus number */
&DeviceNo, /* device number */
&FuncNo /* function number */
);
}
if (status != OK) {
DbgPrint(("ERROR: did not find promise card\n",0,0,0,0,0,0));
return status;
}
DbgPrint(("Found promise card\n",0,0,0,0,0,0));
/* load up the base address registers */
for(i=0; i<6; i++) {
int offset = 0x10 + (i*4);
status = pciConfigInLong(
BusNo, /* bus number */
DeviceNo, /* device number */
FuncNo, /* function number */
offset, /* offset into the configuration space */
&baseAddress[i]
);
if (status != OK) {
DbgPrint(("PCI 0x%x config failed\n", offset,0,0,0,0,0));
return status;
}
/* clear IO bit (bit 0 in all config registers) bit 1 is reserved */
baseAddress[i] &= ~3;
}
vector = sysPciIntPin(BusNo, DeviceNo );
/*
** fixup ataresources from syslib.c
*/
ataResources[0].resource.ioStart[0] = baseAddress[0];
ataResources[0].resource.ioStart[1] = baseAddress[1] + 2;
ataResources[1].resource.ioStart[0] = baseAddress[2];
ataResources[1].resource.ioStart[1] = baseAddress[3] + 2;
ataResources[0].intVector = vector;
ataResources[1].intVector = vector;
DbgPrint(("BAR[0]:0x%x\nBAR[1]:0x%x\n",baseAddress[0],baseAddress[1],0,0,0,0));
/******************************************/
/* reset drives */
/*****************************************/
#if 1
{
int i,count;
/* wait for reset, sysDelay is 6*63 cycles, and need to wait 6 milliseconds */
count = (6000*sysGetCPUMHz())/(6*63);
sysOutByte(0xC140 + 0x1F,0x10);
for (i=0;i<count;i++) {
sysDelay();
}
sysOutByte(0xC140 + 0x1F,0x00);
for (i=0;i<count;i++) {
sysDelay();
}
}
#endif
/*****************************************/
/*enable burst mode */
/****************************************/
sysOutByte(baseAddress[4] + 0x1F,0x01);
/**********************************************************************/
/* allow byte alignment and byte count transfer length in PRD entries */
/**********************************************************************/
sysOutByte(baseAddress[4] + 0x1A,0x01); /* primary channel */
sysOutByte(baseAddress[4] + 0x1B,0x01); /* secondary channel */
return status;
}
#endif
#if PROMISE_DEBUG
void ataPrintSpeed(char speed)
{
logMsg("Configured drive for \n",0,0,0,0,0,0);
switch(speed) {
case ATA_DMA_ULTRA_W_0:
logMsg("ultra DMA mode 0\n",0,0,0,0,0,0);
break;
case ATA_DMA_ULTRA_W_1:
logMsg("ultra DMA mode 1\n",0,0,0,0,0,0);
break;
case ATA_DMA_ULTRA_W_2:
logMsg("ultra DMA mode 2\n",0,0,0,0,0,0);
break;
case ATA_DMA_ULTRA_W_3:
logMsg("ultra DMA mode 3\n",0,0,0,0,0,0);
break;
case ATA_DMA_ULTRA_W_4:
logMsg("ultra DMA mode 4\n",0,0,0,0,0,0);
break;
case ATA_DMA_MULTI_W_0:
logMsg("multiword DMA mode 0\n",0,0,0,0,0,0);
break;
case ATA_DMA_MULTI_W_1:
logMsg("multiword DMA mode 1\n",0,0,0,0,0,0);
break;
case ATA_DMA_MULTI_W_2:
logMsg("multiword DMA mode 2\n",0,0,0,0,0,0);
break;
case ATA_DMA_SINGLE_W_0:
logMsg("singleword DMA mode 0\n",0,0,0,0,0,0);
break;
case ATA_DMA_SINGLE_W_1:
logMsg("singleword DMA mode 1\n",0,0,0,0,0,0);
break;
case ATA_DMA_SINGLE_W_2:
logMsg("singleword DMA mode 2\n",0,0,0,0,0,0);
break;
default:
logMsg("unknown speed\n",0,0,0,0,0,0);
}
}
#endif
void promiseideAtaInit(int ctrl)
{
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
// ATA_DRIVE *pDrive;
int drive;
char dev_name[5];
for (drive = 0; drive < pCtrl->drives; drive++)
{
//pDrive = &pCtrl->drive[drive];
//if (pDrive->okDma) {
//config_chipset_for_dma(ctrl,drive);
//}
sprintf(&dev_name[0], "dev%d:", drive);
/* mount the drive, assuming that the drive has
* been previously formated using a call to AtaFormat
*/
#ifdef FORMAT_IDE
printf("formating %s\n", &dev_name[0]);
AtaFormat(ctrl, drive, &dev_name[0]);
#else
AtaMount(ctrl, drive, &dev_name[0]);
#endif
}
}
int tune_chipset (int ctrl, int drive)
{
int err = 0;
unsigned char drive_pci, AP, BP, CP, DP;
unsigned char TA = 0, TB = 0, TC = 0;
int dn = ctrl*2+1;
ATA_CTRL *pCtrl = &ataCtrl[ctrl];
ATA_DRIVE *pDrive = &pCtrl->drive[drive];
STATUS status;
switch (dn) {
case 0: drive_pci = 0x60; break;
case 1: drive_pci = 0x64; break;
case 2: drive_pci = 0x68; break;
case 3: drive_pci = 0x6c; break;
default: return ERROR;
}
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci,&AP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x01,&BP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x02,&CP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x03,&DP);
if (pDrive->okDma) {
if ((BP & 0xF0) && (CP & 0x0F)) {
/* clear DMA modes of upper 842 bits of B Register */
/* clear PIO forced mode upper 1 bit of B Register */
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci|0x01,BP & ~0xF0);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x01,&BP);
/* clear DMA modes of lower 8421 bits of C Register */
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci|0x02,CP & ~0x0f);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x02,&CP);
}
}
if ((AP & 0x0F) || (BP & 0x07)) {
/* clear PIO modes of lower 8421 bits of A Register */
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci,AP & ~0x0F);
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci,AP);
/* clear PIO modes of lower 421 bits of B Register */
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci| 0x01,BP & ~0x07);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x1,&BP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci,&AP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x1,&BP);
}
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci,&AP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x01,&BP);
status = pciConfigInByte(BusNo,DeviceNo,FuncNo,drive_pci|0x02,&CP);
if (pDrive->okDma) {
switch(pDrive->rwDma) {
/* case XFER_UDMA_6: */
case ATA_DMA_ULTRA_W_5:
case ATA_DMA_ULTRA_W_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */
case ATA_DMA_ULTRA_W_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */
case ATA_DMA_ULTRA_W_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */
case ATA_DMA_ULTRA_W_1: TB = 0x40; TC = 0x02; break; /* speed 5 == UDMA mode 1 */
case ATA_DMA_ULTRA_W_0: TB = 0x60; TC = 0x03; break; /* speed 4 == UDMA mode 0 */
case ATA_DMA_MULTI_2: TB = 0x60; TC = 0x03; break; /* speed 4 == MDMA mode 2 */
case ATA_DMA_MULTI_1: TB = 0x60; TC = 0x04; break; /* speed 3 == MDMA mode 1 */
case ATA_DMA_MULTI_0: TB = 0x60; TC = 0x05; break; /* speed 2 == MDMA mode 0 */
}
}
switch(pDrive->rwMode) {
case ATA_PIO_4: TA = 0x01; TB |= 0x04; break;
case ATA_PIO_3: TA = 0x02; TB |= 0x06; break;
case ATA_PIO_2: TA = 0x03; TB |= 0x08; break;
case ATA_PIO_1: TA = 0x05; TB |= 0x0C; break;
case ATA_PIO_0:
default: TA = 0x09; TB = 0x13; break;
}
if (pDrive->okDma) {
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci|0x1,BP|TB);
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci|0x2,CP|TC);
} else {
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci,AP|TA);
status = pciConfigOutByte(BusNo,DeviceNo,FuncNo,drive_pci|0x1,BP|TB);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -