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