openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

identify.c (4784B)


      1 /* $Id: //depot/blt/srv/ide/identify.c#6 $
      2 **
      3 ** Copyright 1999 Sidney Cammeresi
      4 ** All rights reserved.
      5 **
      6 ** Redistribution and use in source and binary forms, with or without
      7 ** modification, are permitted provided that the following conditions
      8 ** are met:
      9 ** 1. Redistributions of source code must retain the above copyright
     10 **    notice, this list of conditions, and the following disclaimer.
     11 ** 2. Redistributions in binary form must reproduce the above copyright
     12 **    notice, this list of conditions, and the following disclaimer in the
     13 **    documentation and/or other materials provided with the distribution.
     14 ** 3. The name of the author may not be used to endorse or promote products
     15 **    derived from this software without specific prior written permission.
     16 **
     17 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #include <stdio.h>
     30 #include <string.h>
     31 #include <stdlib.h>
     32 #include <blt/syscall.h>
     33 #include <blt/types.h>
     34 #include <blt/disk.h>
     35 #include <blt/blkdev.h>
     36 #include <i386/io.h>
     37 #include "ide-int.h"
     38 
     39 int total_busses = 0;
     40 ide_dev_t **ide_dev;
     41 
     42 static void ide_string_conv (char *str, int len)
     43 {
     44 	int i;
     45 	unsigned short *w;
     46 
     47 	w = (unsigned short *) str;
     48 	for (i = 0; i < len / sizeof (unsigned short); i++)
     49 		w[i] = ntohs (w[i]);
     50 
     51 	str[len - 1] = 0;
     52 	for (i = len - 1; (i >= 0) && ((str[i] == ' ') || !str[i]); i--)
     53 		str[i] = 0;
     54 }
     55 
     56 int ide_reset (int bus, int device)
     57 {
     58 	int i, base, fail = 0;
     59 
     60 	outb (6, IDE_DIGITAL_OUTPUT);
     61 	for (i = 0; i < 1000000; i++) ; /* XXX */
     62 	outb (0, IDE_DIGITAL_OUTPUT);
     63 	//IDE_WAIT_1 (STATUS, 6);
     64 
     65 	base = ide_base (bus);
     66 	IDE_WAIT_0 (STATUS, 7);
     67 	IDE_SEL_DH (bus, device, 0);
     68 	IDE_WAIT_0 (STATUS, 7);
     69 	IDE_WAITFAIL_1 (STATUS, 6);
     70 	if (fail)
     71 		return 1;
     72 
     73 	outb (0, IDE_REG_CYLLSB);
     74 	outb (0, IDE_REG_CYLMSB);
     75 	outb (0, IDE_REG_SECNUM);
     76 	outb (0, IDE_REG_SECCNT);
     77 	outb (IDE_OP_RECALIBRATE, IDE_REG_COMMAND);
     78 	return 0;
     79 }
     80 
     81 const ide_hw_id_t *ide_identify_device (int bus, int device)
     82 {
     83 	short *buf;
     84 	int i, base, fail, mb;
     85 	ide_hw_id_t *hwdev;
     86 
     87 	if ((base = ide_base (bus)) < 0)
     88 		return NULL;
     89 	if ((device < 0) || (device > 1))
     90 		return NULL;
     91 
     92 	fail = 0;
     93 	buf = (short *) hwdev = malloc (sizeof (ide_hw_id_t));
     94 	IDE_WAIT_0 (STATUS, 7);
     95 
     96 	IDE_SEL_DH (bus, device, 0);
     97 	IDE_WAIT_0 (STATUS, 7);
     98 	IDE_WAITFAIL_1 (STATUS, 6);
     99 	if (fail)
    100 		return NULL;
    101 
    102 	outb (IDE_OP_IDENTIFY_DEVICE, IDE_REG_COMMAND);
    103 	IDE_WAIT_1 (STATUS, 3);
    104 
    105 	for (i = 0; i < sizeof (ide_hw_id_t) / sizeof (short); i++)
    106 		buf[i] = inw (IDE_REG_DATA);
    107 
    108 	ide_string_conv (hwdev->serial, sizeof (hwdev->serial));
    109 	ide_string_conv (hwdev->firmware, sizeof (hwdev->firmware));
    110 	ide_string_conv (hwdev->model, sizeof (hwdev->model));
    111 	mb = hwdev->cyls * hwdev->heads * hwdev->sectors * 512 / 1024 / 1024;
    112 
    113 	printf ("ide: disk at bus %d, device %d, <%s>\n", bus, device,
    114 		hwdev->model);
    115 	printf ("ide/%d/%d: %dMB; %d cyl, %d head, %d sec, 512 bytes/sec\n",
    116 		bus, device, mb, hwdev->cyls, hwdev->heads, hwdev->sectors);
    117 	return hwdev;
    118 }
    119 
    120 int ide_attach_bus (int io, int irq)
    121 {
    122 	total_busses++;
    123 	return 0;
    124 }
    125 
    126 int ide_attach_device (int bus, int device)
    127 {
    128 	char name[9];
    129 	int i;
    130 	blkdev_t *bdev;
    131 	disk_t *disk;
    132 	const ide_hw_id_t *hwdev;
    133 	ide_dev_t *dev;
    134 
    135 	if ((hwdev = ide_identify_device (bus, device)) == NULL)
    136 		return 0;
    137 
    138 	dev = ide_dev[bus * 2 + device] = malloc (sizeof (ide_dev_t));
    139 	dev->hwdev = hwdev;
    140 	dev->iobase = ide_base (bus);
    141 	dev->read = ide_disk_read;
    142 	dev->write = ide_disk_write;
    143 
    144 	snprintf (name, sizeof (name), "ide/%d/%d", bus, device);
    145 	printf ("%s: partitions:", name);
    146 	blk_open (name, 0, &bdev);
    147 	dev->disk = disk = disk_alloc (bdev);
    148 	for (i = 0; i < disk->numparts; i++)
    149 		printf (" %s", disk_partition_name (disk, i));
    150 	printf ("\n");
    151 	blk_close (bdev);
    152 	return 1;
    153 }
    154 
    155 int ide_probe_devices (void)
    156 {
    157 	int i, found;
    158 
    159 	found = 0;
    160 	os_handle_irq (14);
    161 	ide_attach_bus (0x1f0, 14); /* XXX find this properly */
    162 	ide_dev = malloc (sizeof (ide_dev_t *) * total_busses * 2);
    163 
    164 	for (i = 0; i < total_busses; i++)
    165 	{
    166 		//if (!ide_reset (i, 0))
    167 			found += ide_attach_device (i, 0);
    168 		//if (!ide_reset (i, 1))
    169 			found += ide_attach_device (i, 1);
    170 	}
    171 	return found;
    172 }
    173