Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/drivers/ata/diskio.c need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 
0019 
0020 #include "arch/i386.h"
0021 #include "drivers/ata/ata.h"
0022 #include "util/printf.h"
0023 
0024 /*
0025 
0026 ;  Technical Information on the ports:
0027 ;      Port    Read/Write   Misc
0028 ;     ------  ------------ -------------------------------------------------
0029 ;       1f0       r/w       data register, the bytes are written/read here
0030 ;       1f1       r         error register  (look these values up yourself)
0031 ;       1f2       r/w       sector count, how many sectors to read/write
0032 ;       1f3       r/w       sector number, the actual sector wanted
0033 ;       1f4       r/w       cylinder low, cylinders is 0-1024
0034 ;       1f5       r/w       cylinder high, this makes up the rest of the 1024
0035 ;       1f6       r/w       drive/head 
0036 ;                              bit 7 = 1
0037 ;                              bit 6 = 0
0038 ;                              bit 5 = 1
0039 ;                              bit 4 = 0  drive 0 select
0040 ;                                    = 1  drive 1 select
0041 ;                              bit 3-0    head select bits
0042 ;       1f7       r         status register
0043 ;                              bit 7 = 1  controller is executing a command
0044 ;                              bit 6 = 1  drive is ready
0045 ;                              bit 5 = 1  write fault
0046 ;                              bit 4 = 1  seek complete
0047 ;                              bit 3 = 1  sector buffer requires servicing
0048 ;                              bit 2 = 1  disk data read corrected
0049 ;                              bit 1 = 1  index - set to 1 each revolution
0050 ;                              bit 0 = 1  previous command ended in an error
0051 ;       1f7       w         command register
0052 ;                            commands:
0053 ;                              50h format track
0054 ;                              20h read sectors with retry
0055 ;                              21h read sectors without retry
0056 ;                              22h read long with retry
0057 ;                              23h read long without retry
0058 ;                              30h write sectors with retry
0059 ;                              31h write sectors without retry
0060 ;                              32h write long with retry
0061 ;                              33h write long without retry
0062 
0063 */
0064 
0065 /* Read a sector using CHS geometry information */
0066 void
0067 ReadSector (void *offset, int cylinder, int head, int sector)
0068 {
0069 
0070   /* Setup drive 0, head 0 */
0071   outb (0xa0 + head, 0x1f6);
0072 
0073   /* Setup count of sectors to read -- here one sector */
0074   outb (0x1, 0x1f2);
0075 
0076   /* Read from selected sector */
0077   outb (sector, 0x1f3);
0078 
0079   /* Specify cylinder 0 -- using low port for cylinder */
0080   outb (cylinder & 0xFF, 0x1f4);
0081 
0082   /* Specify cylinder 0 -- using high port */
0083   outb (cylinder >> 8, 0x1f5);
0084 
0085   /* Issue read sectors with retry command to command register */
0086   outb (0x20, 0x1f7);
0087 
0088   while (!(inb (0x1f7) & 0x8)); /* Wait until sector buffer requires 
0089                                    servicing */
0090 
0091   /* Read a sector of 512 bytes as 256 short words */
0092   insw (0x1f0, offset, 256);
0093 
0094 }
0095 
0096 /* Write a sector using CHS geometry information */
0097 void
0098 WriteSector (void *offset, int cylinder, int head, int sector)
0099 {
0100 
0101   /* Setup drive 0, head 0 */
0102   outb (0xa0 + head, 0x1f6);
0103 
0104   /* Setup count of sectors to write -- here one sector */
0105   outb (0x1, 0x1f2);
0106 
0107   /* Write to selected sector */
0108   outb (sector, 0x1f3);
0109 
0110   /* Specify cylinder 0 -- using low port for cylinder */
0111   outb (cylinder & 0xFF, 0x1f4);
0112 
0113   /* Specify cylinder 0 -- using high port */
0114   outb (cylinder >> 8, 0x1f5);
0115 
0116   /* Issue write sectors with retry command to command register */
0117   outb (0x30, 0x1f7);
0118 
0119   while (!(inb (0x1f7) & 0x8)); /* Wait until sector buffer requires 
0120                                    servicing */
0121 
0122   /* Write a sector of 512 bytes as 256 short words */
0123   outsw (0x1f0, offset, 256);
0124 
0125 }
0126 
0127 /* Read a sector using LBA information */
0128 void
0129 ReadSectorLBA (void *offset, uint32 lba)
0130 {
0131   ata_drive_read_sector (ATA_BUS_PRIMARY, ATA_DRIVE_MASTER, lba,
0132                          (uint8 *) offset);
0133 }
0134 
0135 /* Write a sector using LBA information */
0136 void
0137 WriteSectorLBA (void *offset, uint32 lba)
0138 {
0139   ata_drive_write_sector (ATA_BUS_PRIMARY, ATA_DRIVE_MASTER, lba,
0140                           (uint8 *) offset);
0141 }
0142 
0143 /* 
0144  * Local Variables:
0145  * indent-tabs-mode: nil
0146  * mode: C
0147  * c-file-style: "gnu"
0148  * c-basic-offset: 2
0149  * End: 
0150  */
0151 
0152 /* vi: set et sw=2 sts=2: */