Changes in / [e5792d1:a71c158] in mainline
- Location:
- uspace/srv/bd/ata_bd
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
re5792d1 ra71c158 50 50 #include <as.h> 51 51 #include <fibril_sync.h> 52 #include <string.h>53 52 #include <devmap.h> 54 53 #include <sys/types.h> … … 86 85 static int ata_bd_write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 87 86 const void *buf); 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); 87 static int drive_identify(int drive_id, disk_t *d); 91 88 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 92 89 unsigned timeout); … … 109 106 fflush(stdout); 110 107 111 rc = d isk_init(&disk[i], i);108 rc = drive_identify(i, &disk[i]); 112 109 113 110 if (rc == EOK) { 114 disk_print_summary(&disk[i]); 111 printf("%u cylinders, %u heads, %u sectors\n", 112 disk[i].cylinders, disk[i].heads, disk[i].sectors); 115 113 } else { 116 114 printf("Not found.\n"); … … 149 147 } 150 148 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 }173 149 174 150 /** Register driver and enable device I/O. */ … … 275 251 } 276 252 277 /** Initialize a disk.278 *279 * Probes for a disk, determines its parameters and initializes280 * 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 348 253 /** Transfer a logical block from/to the device. 349 254 * … … 389 294 /** Issue IDENTIFY command. 390 295 * 391 * Reads @c identify data into the provided buffer. This is used to detect392 * whether an ATA device is present and if so, to determine its parameters.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. 393 298 * 394 299 * @param disk_id Device ID, 0 or 1. 395 * @param buf Pointer to a 512-byte buffer.396 */ 397 static int drive_identify(int disk_id, void *buf)300 * @param d Device structure to store parameters in. 301 */ 302 static int drive_identify(int disk_id, disk_t *d) 398 303 { 399 304 uint16_t data; … … 403 308 404 309 drv_head = ((disk_id != 0) ? DHR_DRV : 0); 310 d->present = false; 405 311 406 312 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) … … 424 330 425 331 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 426 337 for (i = 0; i < block_size / 2; i++) { 427 338 data = pio_read_16(&cmd->data_port); 428 ((uint16_t *) buf)[i] = data; 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 } 429 345 } 430 346 } … … 432 348 if ((status & SR_ERR) != 0) 433 349 return EIO; 350 351 d->blocks = d->cylinders * d->heads * d->sectors; 352 353 d->present = true; 354 fibril_mutex_initialize(&d->lock); 434 355 435 356 return EOK; … … 462 383 return EINVAL; 463 384 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 } 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); 477 391 478 392 /* New value for Drive/Head register */ 479 393 drv_head = 480 394 ((disk_id != 0) ? DHR_DRV : 0) | 481 ((d->amode != am_chs) ? DHR_LBA : 0) |482 395 (h & 0x0f); 483 396 … … 551 464 return EINVAL; 552 465 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 } 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); 566 472 567 473 /* New value for Drive/Head register */ 568 474 drv_head = 569 475 ((disk_id != 0) ? DHR_DRV : 0) | 570 ((d->amode != am_chs) ? DHR_LBA : 0) |571 476 (h & 0x0f); 572 477 -
uspace/srv/bd/ata_bd/ata_bd.h
re5792d1 ra71c158 38 38 #include <sys/types.h> 39 39 #include <fibril_sync.h> 40 #include <string.h>41 40 42 41 enum { … … 116 115 117 116 enum drive_head_bits { 118 DHR_LBA = 0x40, /**< Use LBA addressing mode */ 119 DHR_DRV = 0x10 /**< Select device 1 */ 117 DHR_DRV = 0x10 120 118 }; 121 119 … … 144 142 }; 145 143 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 = 0x0100198 };199 200 /** Block addressing mode. */201 enum addr_mode {202 am_chs,203 am_lba28204 };205 206 144 typedef struct { 207 145 bool present; 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 146 unsigned heads; 147 unsigned cylinders; 148 unsigned sectors; 219 149 uint64_t blocks; 220 221 char model[STR_BOUNDS(40) + 1];222 150 223 151 fibril_mutex_t lock;
Note:
See TracChangeset
for help on using the changeset viewer.