Changeset 1806e5d in mainline
- Timestamp:
- 2009-06-12T21:27:58Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4f5caea
- Parents:
- 26360f7
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r26360f7 r1806e5d 51 51 #include <sys/types.h> 52 52 #include <errno.h> 53 #include <bool.h> 53 54 54 55 #define NAME "ata_bd" … … 134 135 }; 135 136 137 typedef struct { 138 bool present; 139 unsigned heads; 140 unsigned cylinders; 141 unsigned sectors; 142 uint64_t blocks; 143 } disk_t; 144 136 145 static const size_t block_size = 512; 137 146 static size_t comm_size; … … 146 155 static atomic_t dev_futex = FUTEX_INITIALIZER; 147 156 148 static unsigned heads, cylinders, sectors; 149 static uint64_t disk_blocks; 157 static disk_t disk[2]; 150 158 151 159 static int ata_bd_init(void); … … 155 163 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 156 164 void *buf); 165 static int drive_identify(int drive_id, disk_t *d); 157 166 158 167 int main(int argc, char **argv) 159 168 { 160 169 uint8_t status; 161 uint16_t data; 162 int i; 170 char name[16]; 171 int i, rc; 172 int n_disks; 163 173 164 174 printf(NAME ": ATA disk driver\n"); … … 188 198 printf("Status = 0x%x\n", pio_read_8(&cmd->status)); 189 199 190 printf("Issue drive_identify command\n"); 191 pio_write_8(&cmd->drive_head, 0x00); 192 async_usleep(100); 193 pio_write_8(&cmd->command, 0xEC); 194 195 printf("Status = 0x%x\n", pio_read_8(&cmd->status)); 196 197 for (i = 0; i < 256; i++) { 198 do { 199 status = pio_read_8(&cmd->status); 200 } while ((status & SR_DRDY) == 0); 201 202 data = pio_read_16(&cmd->data_port); 203 204 switch (i) { 205 case 1: cylinders = data; break; 206 case 3: heads = data; break; 207 case 6: sectors = data; break; 208 } 209 } 210 211 printf("\n\nStatus = 0x%x\n", pio_read_8(&cmd->status)); 212 213 printf("Geometry: %u cylinders, %u heads, %u sectors\n", 214 cylinders, heads, sectors); 215 disk_blocks = cylinders * heads * sectors; 216 217 printf(NAME ": Accepting connections\n"); 218 async_manager(); 219 220 /* Not reached */ 221 return 0; 222 } 223 224 static int ata_bd_init(void) 225 { 226 void *vaddr; 227 int rc, i; 228 char name[16]; 229 230 rc = devmap_driver_register(NAME, ata_bd_connection); 231 if (rc < 0) { 232 printf(NAME ": Unable to register driver.\n"); 233 return rc; 234 } 235 236 rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr); 237 if (rc != EOK) { 238 printf(NAME ": Could not initialize device I/O space.\n"); 239 return rc; 240 } 241 242 cmd = vaddr; 243 244 rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr); 245 if (rc != EOK) { 246 printf(NAME ": Could not initialize device I/O space.\n"); 247 return rc; 248 } 249 250 ctl = vaddr; 200 (void) drive_identify(0, &disk[0]); 201 (void) drive_identify(1, &disk[1]); 202 203 n_disks = 0; 251 204 252 205 for (i = 0; i < MAX_DISKS; i++) { 206 /* Skip unattached drives. */ 207 if (disk[i].present == false) 208 continue; 209 253 210 snprintf(name, 16, "disk%d", i); 254 211 rc = devmap_device_register(name, &dev_handle[i]); … … 259 216 return rc; 260 217 } 261 } 218 ++n_disks; 219 } 220 221 if (n_disks == 0) { 222 printf("No disks detected.\n"); 223 return -1; 224 } 225 226 printf(NAME ": Accepting connections\n"); 227 async_manager(); 228 229 /* Not reached */ 230 return 0; 231 } 232 233 static int drive_identify(int disk_id, disk_t *d) 234 { 235 uint16_t data; 236 uint8_t status; 237 int i; 238 239 printf("Identify drive %d\n", disk_id); 240 pio_write_8(&cmd->drive_head, ((disk_id != 0) ? DHR_DRV : 0)); 241 async_usleep(100); 242 pio_write_8(&cmd->command, 0xEC); 243 244 status = pio_read_8(&cmd->status); 245 printf("Status = 0x%x\n", status); 246 247 d->present = false; 248 249 /* 250 * Detect if drive is present. This is Qemu only! Need to 251 * do the right thing to work with real drives. 252 */ 253 if ((status & SR_DRDY) == 0) { 254 printf("None attached.\n"); 255 return ENOENT; 256 } 257 258 for (i = 0; i < 256; i++) { 259 do { 260 status = pio_read_8(&cmd->status); 261 } while ((status & SR_DRDY) == 0); 262 263 data = pio_read_16(&cmd->data_port); 264 265 switch (i) { 266 case 1: d->cylinders = data; break; 267 case 3: d->heads = data; break; 268 case 6: d->sectors = data; break; 269 } 270 } 271 272 printf("\n\nStatus = 0x%x\n", pio_read_8(&cmd->status)); 273 274 d->blocks = d->cylinders * d->heads * d->sectors; 275 276 printf("Geometry: %u cylinders, %u heads, %u sectors\n", 277 d->cylinders, d->heads, d->sectors); 278 279 d->present = true; 280 281 return EOK; 282 } 283 284 static int ata_bd_init(void) 285 { 286 void *vaddr; 287 int rc; 288 289 rc = devmap_driver_register(NAME, ata_bd_connection); 290 if (rc < 0) { 291 printf(NAME ": Unable to register driver.\n"); 292 return rc; 293 } 294 295 rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr); 296 if (rc != EOK) { 297 printf(NAME ": Could not initialize device I/O space.\n"); 298 return rc; 299 } 300 301 cmd = vaddr; 302 303 rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr); 304 if (rc != EOK) { 305 printf(NAME ": Could not initialize device I/O space.\n"); 306 return rc; 307 } 308 309 ctl = vaddr; 310 262 311 263 312 return EOK; … … 286 335 disk_id = i; 287 336 288 if (disk_id < 0 ) {337 if (disk_id < 0 || disk[disk_id].present == false) { 289 338 ipc_answer_0(iid, EINVAL); 290 339 return; … … 375 424 uint64_t idx; 376 425 uint8_t drv_head; 426 disk_t *d; 427 428 d = &disk[disk_id]; 377 429 378 430 /* Check device bounds. */ 379 if (blk_idx >= d isk_blocks)431 if (blk_idx >= d->blocks) 380 432 return EINVAL; 381 433 382 434 /* Compute CHS. */ 383 c = blk_idx / ( heads *sectors);384 idx = blk_idx % ( heads *sectors);385 386 h = idx / sectors;387 s = 1 + (idx % sectors);435 c = blk_idx / (d->heads * d->sectors); 436 idx = blk_idx % (d->heads * d->sectors); 437 438 h = idx / d->sectors; 439 s = 1 + (idx % d->sectors); 388 440 389 441 /* New value for Drive/Head register */
Note:
See TracChangeset
for help on using the changeset viewer.