00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <pci/hd.h>
00031 #include <sys/video.h>
00032 #include <sys/device.h>
00033 #include <sys/io.h>
00034 #include <lib/kmalloc.h>
00035 #include <lib/kprintf.h>
00036 #include <devfs/devfs.h>
00037 #include <string.h>
00038
00039 int initHardDisk() {
00040 int i = 0x0;
00041 int x = 0x0;
00042 int minor = 0x0;
00043 struct device_interface *devInfo = 0x0;
00044 struct device_interface *devInfo2 = 0x0;
00045 struct dos_partition *d = 0x0;
00046 struct driveInfo *hdd = 0x0;
00047 struct driveInfo *hdd2 = 0x0;
00048 char *data = 0x0;
00049 char *data2 = 0x0;
00050 char name[16];
00051 struct bsd_disklabel *bsdd = 0x0;
00052
00053 hdd = (struct driveInfo *)kmalloc(sizeof(struct driveInfo));
00054 hdd->hdPort = 0x1F0;
00055 hdd->hdDev = 0x40;
00056 hdd->parOffset = 0x0;
00057
00058
00059
00060 devInfo = (struct device_interface *)kmalloc(sizeof(struct device_interface));
00061 devInfo->read = (void *)&hdRead;
00062 devInfo->write = (void *)&hdWrite;
00063 devInfo->reset = (void *)&hdReset;
00064 devInfo->init = (void *)&hdInit;
00065 devInfo->ioctl = (void *)&hdIoctl;
00066 devInfo->stop = (void *)&hdStop;
00067 devInfo->start = (void *)&hdStart;
00068 devInfo->standby = (void *)&hdStandby;
00069 devInfo->info = hdd;
00070
00071 devInfo->major = 0x1;
00072
00073 data = (char *)kmalloc(512);
00074 d = (struct dos_partition *)(data + 0x1BE);
00075
00076 data2 = (char *)kmalloc(512);
00077 bsdd = (struct bsd_disklabel *)data2;
00078
00079 if (device_add(0,'c',devInfo) == 0x0) {
00080 kprintf("ad0 - Start: [0x0], Size: [0x%x/0x%X]\n",hdd->hdSize,hdd->hdSize*512);
00081 devfs_makeNode("ad0",'b',0x1,0x0);
00082 hdRead(devInfo->info,data,0x0,0x1);
00083 for (i = 0x0;i < 0x4;i++) {
00084 if (d[i].dp_type != 0x0) {
00085 devInfo2 = (struct device_interface *)kmalloc(sizeof(struct device_interface));
00086 hdd2 = (struct driveInfo *)kmalloc(sizeof(struct driveInfo));
00087 memcpy(devInfo2,devInfo,sizeof(struct device_interface));
00088 memcpy(hdd2,hdd,sizeof(struct driveInfo));
00089 hdd2->parOffset = d[i].dp_start;
00090 devInfo2->info = hdd2;
00091 minor++;
00092 if (device_add(minor,'c',devInfo2) == 0x0) {
00093 sprintf(name,"ad0s%i",i + 1);
00094 kprintf("%s - Type: [0x%X], Start: [0x%X], Size: [0x%X]\n",name,d[i].dp_type,d[i].dp_start,d[i].dp_size);
00095 devfs_makeNode(name,'c',0x1,minor);
00096 if (d[i].dp_type == 0xA5) {
00097
00098 hdRead(devInfo->info,data2,d[i].dp_start + 1,0x1);
00099 for (x = 0;x < bsdd->d_npartitions;x++) {
00100 if (bsdd->d_partitions[x].p_size > 0) {
00101 sprintf(name,"ad0s%i%c",i + 1,'a' + x);
00102
00103 devInfo2 = (struct device_interface *)kmalloc(sizeof(struct device_interface));
00104 hdd2 = (struct driveInfo *)kmalloc(sizeof(struct driveInfo));
00105 memcpy(devInfo2,devInfo,sizeof(struct device_interface));
00106 memcpy(hdd2,hdd,sizeof(struct driveInfo));
00107
00108 hdd2->parOffset = bsdd->d_partitions[x].p_offset;
00109 devInfo2->info = hdd2;
00110 minor++;
00111 device_add(minor,'c',devInfo2);
00112 devfs_makeNode(name,'c',0x1,minor);
00113 kprintf("%s - Type: [%s], Start: [0x%X], Size: [0x%X], MM: [%i:%i]\n",name,fstypenames[bsdd->d_partitions[x].p_fstype],bsdd->d_partitions[x].p_offset,bsdd->d_partitions[x].p_size,devInfo->major,minor);
00114 }
00115 }
00116 }
00117 }
00118 }
00119 }
00120 }
00121 kfree(data);
00122 return(0x0);
00123 }
00124
00125 int hdStandby() {
00126 return(0x0);
00127 }
00128
00129 int hdStart() {
00130 return(0x0);
00131 }
00132
00133 int hdStop() {
00134 return(0x0);
00135 }
00136
00137 int hdIoctl() {
00138 return(0x0);
00139 }
00140
00141 int hdReset() {
00142 return(0x0);
00143 }
00144
00145 int hdInit(struct device_node *dev) {
00146 char retVal = 0x0;
00147 long counter = 0x0;
00148 short *tmp = 0x0;
00149 struct driveInfo *hdd = dev->devInfo->info;
00150 for (counter = 1000000;counter >= 0;counter--) {
00151 retVal = inportByte(hdd->hdPort + hdStat) & 0x80;
00152 if (!retVal) goto ready;
00153 }
00154 kprintf("Error Initializing Drive\n");
00155 return(1);
00156 ready:
00157 outportByte(hdd->hdPort + hdHead,hdd->hdDev);
00158 outportByte(hdd->hdPort + hdCmd,0xEC);
00159 for (counter = 1000000;counter >= 0;counter--) {
00160 retVal = inportByte(hdd->hdPort + hdStat);
00161 if ((retVal & 1) != 0x0) {
00162 kprintf("Error Drive Not Available\n");
00163 return(1);
00164 }
00165 if ((retVal & 8) != 0x0) {
00166 goto go;
00167 }
00168 }
00169 kprintf("Time Out Waiting On Drive\n");
00170 return(1);
00171 go:
00172 tmp = (short *)hdd->hdSector;
00173 for (counter = 0;counter < (512/2);counter++) {
00174 tmp[counter] = inportWord(hdd->hdPort + hdData);
00175 }
00176 retVal = tmp[0x2F] & 0xFF;
00177 switch (retVal) {
00178 case 0:
00179 hdd->hdShift = 0;
00180 hdd->hdMulti = 1;
00181 break;
00182 case 2:
00183 hdd->hdShift = 1;
00184 hdd->hdMulti = retVal;
00185 break;
00186 case 4:
00187 hdd->hdShift = 2;
00188 hdd->hdMulti = retVal;
00189 break;
00190 case 8:
00191 hdd->hdShift = 3;
00192 hdd->hdMulti = retVal;
00193 break;
00194 case 16:
00195 hdd->hdShift = 4;
00196 hdd->hdMulti = retVal;
00197 break;
00198 case 32:
00199 hdd->hdShift = 5;
00200 hdd->hdMulti = retVal;
00201 break;
00202 case 64:
00203 hdd->hdShift = 6;
00204 hdd->hdMulti = retVal;
00205 break;
00206 default:
00207 kprintf("Error BLOCK Mode Unavailable: [%i]\n",retVal);
00208 return(1);
00209 }
00210 outportByte(hdd->hdPort + hdSecCount,retVal);
00211 outportByte(hdd->hdPort + hdHead,hdd->hdDev);
00212 outportByte(hdd->hdPort + hdCmd,0xC6);
00213 hdd->hdMask = retVal;
00214 hdd->hdSize = (hdd->hdSector[0x7B] * 256 * 256 * 256) + (hdd->hdSector[0x7A] * 256 * 256) + (hdd->hdSector[0x79] * 256) + hdd->hdSector[0x78];
00215 hdd->hdEnable = 1;
00216 kprintf("Drive: [0x%X/0x%X], Size: [%iSectors/%iKBytes]\n",hdd->hdPort,hdd->hdDev,hdd->hdSize,((hdd->hdSize*512)/1024));
00217 dev->devInfo->size = hdd->hdSize*512;
00218 dev->devInfo->initialized = 0x1;
00219 return(0x0);
00220 }
00221
00222 void hdWrite(struct driveInfo *hdd,void *baseAddr,uInt32 startSector,uInt32 sectorCount) {
00223 long counter = 0x0;
00224 long retVal = 0x0;
00225 short transactionCount = 0x0;
00226 short *tmp = (short *)baseAddr;
00227 startSector += hdd->parOffset;
00228 if (hdd->hdEnable == 0x0) {
00229 kprintf("Invalid Drive\n");
00230 return;
00231 }
00232 if ((sectorCount >> hdd->hdShift) == 0x0) {
00233 hdd->hdCalc = sectorCount;
00234 transactionCount = 1;
00235 }
00236 else {
00237 hdd->hdCalc = hdd->hdMulti;
00238 transactionCount = sectorCount >> hdd->hdShift;
00239 }
00240 for (;transactionCount > 0;transactionCount--) {
00241 for (counter = 1000000;counter >= 0;counter--) {
00242 retVal = inportByte(hdd->hdPort + hdStat) & 0x80;
00243 if (!retVal) goto ready;
00244 }
00245 kprintf("Time Out Waiting On Drive\n");
00246 return;
00247 ready:
00248 outportByte(hdd->hdPort + hdSecCount,hdd->hdCalc);
00249 outportByte(hdd->hdPort + hdSecNum,(startSector & 0xFF));
00250 retVal = startSector >> 8;
00251 outportByte(hdd->hdPort + hdCylLow,(retVal & 0xFF));
00252 retVal >>= 8;
00253 outportByte(hdd->hdPort + hdCylHi,(retVal & 0xFF));
00254 retVal >>= 8;
00255 retVal &= 0x0F;
00256 retVal |= (hdd->hdDev | 0xA0);
00257 outportByte(hdd->hdPort + hdHead,(retVal & 0xFF));
00258 if (hdd->hdShift > 0)
00259 outportByte(hdd->hdPort + hdCmd,0xC5);
00260 else
00261 outportByte(hdd->hdPort + hdCmd,0x30);
00262 for (counter = 1000000;counter >= 0;counter--) {
00263 retVal = inportByte(hdd->hdPort + hdStat);
00264 if ((retVal & 1) != 0x0) {
00265 kprintf("HD Write Error\n");
00266 return;
00267 }
00268 if ((retVal & 8) != 0x0) {
00269 goto go;
00270 }
00271 }
00272 kprintf("Time Out Waiting On Drive\n");
00273 return;
00274 go:
00275 for (counter = 0;counter < (hdd->hdCalc << 8);counter++) {
00276 outportWord(hdd->hdPort + hdData,(short)tmp[counter]);
00277 }
00278 tmp += (counter + 0);
00279 startSector += hdd->hdCalc;
00280 }
00281 return;
00282 }
00283
00284 void hdRead(struct driveInfo *hdd,void *baseAddr,uInt32 startSector,uInt32 sectorCount) {
00285 long counter = 0x0;
00286 long retVal = 0x0;
00287 short transactionCount = 0x0;
00288 short *tmp = (short *)baseAddr;
00289 startSector += hdd->parOffset;
00290
00291 if (hdd->hdEnable == 0x0) {
00292 kprintf("Invalid Drive\n");
00293 return;
00294 }
00295 if ((sectorCount >> hdd->hdShift) == 0x0) {
00296 hdd->hdCalc = sectorCount;
00297 transactionCount = 1;
00298 }
00299 else {
00300 hdd->hdCalc = hdd->hdMulti;
00301 transactionCount = sectorCount >> hdd->hdShift;
00302 }
00303 for (;transactionCount > 0;transactionCount--) {
00304 for (counter = 1000000;counter >= 0;counter--) {
00305 retVal = inportByte(hdd->hdPort + hdStat) & 0x80;
00306 if (!retVal) goto ready;
00307 }
00308 kprintf("Time Out Waiting On Drive\n");
00309 return;
00310 ready:
00311 outportByte(hdd->hdPort + hdSecCount,hdd->hdCalc);
00312 outportByte(hdd->hdPort + hdSecNum,(startSector & 0xFF));
00313 retVal = startSector >> 8;
00314 outportByte(hdd->hdPort + hdCylLow,(retVal & 0xFF));
00315 retVal >>= 8;
00316 outportByte(hdd->hdPort + hdCylHi,(retVal & 0xFF));
00317 retVal >>= 8;
00318 retVal &= 0x0F;
00319 retVal |= (hdd->hdDev | 0xA0);
00320
00321 outportByte(hdd->hdPort + hdHead,(retVal & 0xFF));
00322 if (hdd->hdShift > 0)
00323 outportByte(hdd->hdPort + hdCmd,0xC4);
00324 else
00325 outportByte(hdd->hdPort + hdCmd,0x20);
00326 for (counter = 1000000;counter >= 0;counter--) {
00327 retVal = inportByte(hdd->hdPort + hdStat);
00328 if ((retVal & 1) != 0x0) {
00329 kprintf("HD Read Error: [%i:0x%X:%i]\n",counter,(uInt32)baseAddr,startSector);
00330 return;
00331 }
00332 if ((retVal & 8) != 0x0) {
00333 goto go;
00334 }
00335 }
00336 kprintf("Error: Time Out Waiting On Drive\n");
00337 return;
00338 go:
00339 for (counter = 0;counter < (hdd->hdCalc << 8);counter++) {
00340 tmp[counter] = inportWord(hdd->hdPort + hdData);
00341 }
00342 tmp += (counter + 0);
00343 startSector += hdd->hdCalc;
00344 }
00345 return;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445