Changeset e5792d1 in mainline
- Timestamp:
- 2009-08-22T15:20:01Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 22af3af
- Parents:
- a71c158 (diff), 4ef117f8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/srv/bd/ata_bd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
ra71c158 re5792d1 50 50 #include <as.h> 51 51 #include <fibril_sync.h> 52 #include <string.h> 52 53 #include <devmap.h> 53 54 #include <sys/types.h> … … 85 86 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 86 87 const void *buf); 87 static int drive_identify(int drive_id, disk_t *d); 88 static int disk_init(disk_t *d, int disk_id); 89 static int drive_identify(int drive_id, void *buf); 90 static void disk_print_summary(disk_t *d); 88 91 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 89 92 unsigned timeout); … … 106 109 fflush(stdout); 107 110 108 rc = d rive_identify(i, &disk[i]);111 rc = disk_init(&disk[i], i); 109 112 110 113 if (rc == EOK) { 111 printf("%u cylinders, %u heads, %u sectors\n", 112 disk[i].cylinders, disk[i].heads, disk[i].sectors); 114 disk_print_summary(&disk[i]); 113 115 } else { 114 116 printf("Not found.\n"); … … 147 149 } 148 150 151 /** Print one-line device summary. */ 152 static void disk_print_summary(disk_t *d) 153 { 154 uint64_t mbytes; 155 156 printf("%s: ", d->model); 157 158 if (d->amode == am_chs) { 159 printf("CHS %u cylinders, %u heads, %u sectors", 160 disk->geom.cylinders, disk->geom.heads, disk->geom.sectors); 161 } else { 162 printf("LBA-28"); 163 } 164 165 printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024)); 166 167 mbytes = d->blocks / (2 * 1024); 168 if (mbytes > 0) 169 printf(" %llu MB.", mbytes); 170 171 printf("\n"); 172 } 149 173 150 174 /** Register driver and enable device I/O. */ … … 251 275 } 252 276 277 /** Initialize a disk. 278 * 279 * Probes for a disk, determines its parameters and initializes 280 * the disk structure. 281 */ 282 static int disk_init(disk_t *d, int disk_id) 283 { 284 identify_data_t idata; 285 uint8_t model[40]; 286 uint16_t w; 287 uint8_t c; 288 size_t pos, len; 289 int rc; 290 int i; 291 292 rc = drive_identify(disk_id, &idata); 293 if (rc != EOK) { 294 d->present = false; 295 return rc; 296 } 297 298 if ((idata.caps & cap_lba) == 0) { 299 /* Device only supports CHS addressing. */ 300 d->amode = am_chs; 301 302 d->geom.cylinders = idata.cylinders; 303 d->geom.heads = idata.heads; 304 d->geom.sectors = idata.sectors; 305 306 d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors; 307 } else { 308 /* Device supports LBA-28. */ 309 d->amode = am_lba28; 310 311 d->geom.cylinders = 0; 312 d->geom.heads = 0; 313 d->geom.sectors = 0; 314 315 d->blocks = 316 (uint32_t) idata.total_lba_sec0 | 317 ((uint32_t) idata.total_lba_sec1 << 16); 318 } 319 320 /* 321 * Convert model name to string representation. 322 */ 323 for (i = 0; i < 20; i++) { 324 w = idata.model_name[i]; 325 model[2 * i] = w >> 8; 326 model[2 * i + 1] = w & 0x00ff; 327 } 328 329 len = 40; 330 while (len > 0 && model[len - 1] == 0x20) 331 --len; 332 333 pos = 0; 334 for (i = 0; i < len; ++i) { 335 c = model[i]; 336 if (c >= 0x80) c = '?'; 337 338 chr_encode(c, d->model, &pos, 40); 339 } 340 d->model[pos] = '\0'; 341 342 d->present = true; 343 fibril_mutex_initialize(&d->lock); 344 345 return EOK; 346 } 347 253 348 /** Transfer a logical block from/to the device. 254 349 * … … 294 389 /** Issue IDENTIFY command. 295 390 * 296 * This is used to detect whether an ATA device is present and if so,297 * to determine its parameters. The parameters are written to @a d.391 * Reads @c identify data into the provided buffer. This is used to detect 392 * whether an ATA device is present and if so, to determine its parameters. 298 393 * 299 394 * @param disk_id Device ID, 0 or 1. 300 * @param d Device structure to store parameters in.301 */ 302 static int drive_identify(int disk_id, disk_t *d)395 * @param buf Pointer to a 512-byte buffer. 396 */ 397 static int drive_identify(int disk_id, void *buf) 303 398 { 304 399 uint16_t data; … … 308 403 309 404 drv_head = ((disk_id != 0) ? DHR_DRV : 0); 310 d->present = false;311 405 312 406 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) … … 330 424 331 425 if ((status & SR_DRQ) != 0) { 332 // for (i = 0; i < block_size / 2; i++) {333 // data = pio_read_16(&cmd->data_port);334 // ((uint16_t *) buf)[i] = data;335 // }336 337 426 for (i = 0; i < block_size / 2; i++) { 338 427 data = pio_read_16(&cmd->data_port); 339 340 switch (i) { 341 case 1: d->cylinders = data; break; 342 case 3: d->heads = data; break; 343 case 6: d->sectors = data; break; 344 } 428 ((uint16_t *) buf)[i] = data; 345 429 } 346 430 } … … 348 432 if ((status & SR_ERR) != 0) 349 433 return EIO; 350 351 d->blocks = d->cylinders * d->heads * d->sectors;352 353 d->present = true;354 fibril_mutex_initialize(&d->lock);355 434 356 435 return EOK; … … 383 462 return EINVAL; 384 463 385 /* Compute CHS. */ 386 c = blk_idx / (d->heads * d->sectors); 387 idx = blk_idx % (d->heads * d->sectors); 388 389 h = idx / d->sectors; 390 s = 1 + (idx % d->sectors); 464 if (d->amode == am_chs) { 465 /* Compute CHS coordinates. */ 466 c = blk_idx / (d->geom.heads * d->geom.sectors); 467 idx = blk_idx % (d->geom.heads * d->geom.sectors); 468 469 h = idx / d->geom.sectors; 470 s = 1 + (idx % d->geom.sectors); 471 } else { 472 /* Compute LBA-28 coordinates. */ 473 s = blk_idx & 0xff; /* bits 0-7 */ 474 c = (blk_idx >> 8) & 0xffff; /* bits 8-23 */ 475 h = (blk_idx >> 24) & 0x0f; /* bits 24-27 */ 476 } 391 477 392 478 /* New value for Drive/Head register */ 393 479 drv_head = 394 480 ((disk_id != 0) ? DHR_DRV : 0) | 481 ((d->amode != am_chs) ? DHR_LBA : 0) | 395 482 (h & 0x0f); 396 483 … … 464 551 return EINVAL; 465 552 466 /* Compute CHS. */ 467 c = blk_idx / (d->heads * d->sectors); 468 idx = blk_idx % (d->heads * d->sectors); 469 470 h = idx / d->sectors; 471 s = 1 + (idx % d->sectors); 553 if (d->amode == am_chs) { 554 /* Compute CHS coordinates. */ 555 c = blk_idx / (d->geom.heads * d->geom.sectors); 556 idx = blk_idx % (d->geom.heads * d->geom.sectors); 557 558 h = idx / d->geom.sectors; 559 s = 1 + (idx % d->geom.sectors); 560 } else { 561 /* Compute LBA-28 coordinates. */ 562 s = blk_idx & 0xff; /* bits 0-7 */ 563 c = (blk_idx >> 8) & 0xffff; /* bits 8-23 */ 564 h = (blk_idx >> 24) & 0x0f; /* bits 24-27 */ 565 } 472 566 473 567 /* New value for Drive/Head register */ 474 568 drv_head = 475 569 ((disk_id != 0) ? DHR_DRV : 0) | 570 ((d->amode != am_chs) ? DHR_LBA : 0) | 476 571 (h & 0x0f); 477 572 -
uspace/srv/bd/ata_bd/ata_bd.h
ra71c158 re5792d1 38 38 #include <sys/types.h> 39 39 #include <fibril_sync.h> 40 #include <string.h> 40 41 41 42 enum { … … 115 116 116 117 enum drive_head_bits { 117 DHR_DRV = 0x10 118 DHR_LBA = 0x40, /**< Use LBA addressing mode */ 119 DHR_DRV = 0x10 /**< Select device 1 */ 118 120 }; 119 121 … … 142 144 }; 143 145 146 /** Data returned from @c identify command. */ 147 typedef struct { 148 uint16_t gen_conf; 149 uint16_t cylinders; 150 uint16_t _res2; 151 uint16_t heads; 152 uint16_t _vs4; 153 uint16_t _vs5; 154 uint16_t sectors; 155 uint16_t _vs7; 156 uint16_t _vs8; 157 uint16_t _vs9; 158 uint16_t serial_number[10]; 159 uint16_t _vs20; 160 uint16_t _vs21; 161 uint16_t vs_bytes; 162 uint16_t firmware_rev[4]; 163 uint16_t model_name[20]; 164 uint16_t max_rw_multiple; 165 uint16_t _res48; 166 uint16_t caps; 167 uint16_t _res50; 168 uint16_t pio_timing; 169 uint16_t dma_timing; 170 uint16_t validity; 171 uint16_t cur_cyl; 172 uint16_t cur_heads; 173 uint16_t cur_sectors; 174 uint16_t cur_capacity0; 175 uint16_t cur_capacity1; 176 uint16_t mss; 177 uint16_t total_lba_sec0; 178 uint16_t total_lba_sec1; 179 uint16_t sw_dma; 180 uint16_t mw_dma; 181 uint16_t pio_modes; 182 uint16_t min_mw_dma_cycle; 183 uint16_t rec_mw_dma_cycle; 184 uint16_t min_raw_pio_cycle; 185 uint16_t min_iordy_pio_cycle; 186 uint16_t _res69; 187 uint16_t _res70; 188 uint16_t _res71[1 + 127 - 71]; 189 uint16_t _vs128[1 + 159 - 128]; 190 uint16_t _res160[1 + 255 - 160]; 191 } identify_data_t; 192 193 enum ata_caps { 194 cap_iordy = 0x0800, 195 cap_iordy_cbd = 0x0400, 196 cap_lba = 0x0200, 197 cap_dma = 0x0100 198 }; 199 200 /** Block addressing mode. */ 201 enum addr_mode { 202 am_chs, 203 am_lba28 204 }; 205 144 206 typedef struct { 145 207 bool present; 146 unsigned heads; 147 unsigned cylinders; 148 unsigned sectors; 208 enum addr_mode amode; 209 210 /* 211 * Geometry. Only valid if operating in CHS mode. 212 */ 213 struct { 214 unsigned heads; 215 unsigned cylinders; 216 unsigned sectors; 217 } geom; 218 149 219 uint64_t blocks; 220 221 char model[STR_BOUNDS(40) + 1]; 150 222 151 223 fibril_mutex_t lock;
Note:
See TracChangeset
for help on using the changeset viewer.