Changeset 1787e527 in mainline for uspace/srv
- Timestamp:
- 2009-11-16T21:22:54Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5ebdf94
- Parents:
- fcbd1be (diff), 9c70ed6 (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
- Files:
-
- 42 added
- 47 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = ata_bd 44 SOURCES = \ 45 ata_bd.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/bd/ata_bd/ata_bd.c
rfcbd1be r1787e527 35 35 * @brief ATA disk driver 36 36 * 37 * This driver currently works only with CHS addressing and uses PIO. 38 * Currently based on the (now obsolete) ATA-1, ATA-2 standards. 37 * This driver supports CHS, 28-bit and 48-bit LBA addressing. It only uses 38 * PIO transfers. There is no support DMA, the PACKET feature set or any other 39 * fancy features such as S.M.A.R.T, removable devices, etc. 40 * 41 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7 42 * standards, as published by the ANSI, NCITS and INCITS standards bodies, 43 * which are freely available. This driver contains no vendor-specific 44 * code at this moment. 39 45 * 40 46 * The driver services a single controller which can have up to two disks … … 50 56 #include <as.h> 51 57 #include <fibril_sync.h> 58 #include <string.h> 52 59 #include <devmap.h> 53 60 #include <sys/types.h> … … 55 62 #include <bool.h> 56 63 #include <task.h> 64 #include <macros.h> 57 65 58 66 #include "ata_bd.h" … … 79 87 static int ata_bd_init(void); 80 88 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall); 81 static int ata_bd_r dwr(int disk_id, ipcarg_t method, off_t offset, size_t size,89 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 82 90 void *buf); 83 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt, 91 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 92 const void *buf); 93 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t cnt, 84 94 void *buf); 85 static int ata_bd_write_block(int disk_id, uint64_t b lk_idx, size_t blk_cnt,95 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 86 96 const void *buf); 87 static int drive_identify(int drive_id, disk_t *d); 97 static int disk_init(disk_t *d, int disk_id); 98 static int drive_identify(int drive_id, void *buf); 99 static void disk_print_summary(disk_t *d); 100 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); 101 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt); 88 102 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 89 103 unsigned timeout); … … 97 111 printf(NAME ": ATA disk driver\n"); 98 112 99 printf("I/O address 0x% x\n", cmd_physical);113 printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical); 100 114 101 115 if (ata_bd_init() != EOK) … … 106 120 fflush(stdout); 107 121 108 rc = d rive_identify(i, &disk[i]);122 rc = disk_init(&disk[i], i); 109 123 110 124 if (rc == EOK) { 111 printf("%u cylinders, %u heads, %u sectors\n", 112 disk[i].cylinders, disk[i].heads, disk[i].sectors); 125 disk_print_summary(&disk[i]); 113 126 } else { 114 127 printf("Not found.\n"); … … 147 160 } 148 161 162 /** Print one-line device summary. */ 163 static void disk_print_summary(disk_t *d) 164 { 165 uint64_t mbytes; 166 167 printf("%s: ", d->model); 168 169 switch (d->amode) { 170 case am_chs: 171 printf("CHS %u cylinders, %u heads, %u sectors", 172 disk->geom.cylinders, disk->geom.heads, disk->geom.sectors); 173 break; 174 case am_lba28: 175 printf("LBA-28"); 176 break; 177 case am_lba48: 178 printf("LBA-48"); 179 break; 180 } 181 182 printf(" %llu blocks", d->blocks, d->blocks / (2 * 1024)); 183 184 mbytes = d->blocks / (2 * 1024); 185 if (mbytes > 0) 186 printf(" %llu MB.", mbytes); 187 188 printf("\n"); 189 } 149 190 150 191 /** Register driver and enable device I/O. */ … … 190 231 int flags; 191 232 int retval; 192 off_t idx;193 size_t size;233 uint64_t ba; 234 size_t cnt; 194 235 int disk_id, i; 195 236 … … 211 252 ipc_answer_0(iid, EOK); 212 253 213 if (! ipc_share_out_receive(&callid, &comm_size, &flags)) {254 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 214 255 ipc_answer_0(callid, EHANGUP); 215 256 return; … … 222 263 } 223 264 224 (void) ipc_share_out_finalize(callid, fs_va);265 (void) async_share_out_finalize(callid, fs_va); 225 266 226 267 while (1) { … … 232 273 ipc_answer_0(callid, EOK); 233 274 return; 234 case BD_READ_BLOCK :235 case BD_WRITE_BLOCK:236 idx = IPC_GET_ARG1(call);237 size = IPC_GET_ARG2(call);238 if ( size > comm_size) {239 retval = E INVAL;275 case BD_READ_BLOCKS: 276 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 277 IPC_GET_ARG2(call)); 278 cnt = IPC_GET_ARG3(call); 279 if (cnt * block_size > comm_size) { 280 retval = ELIMIT; 240 281 break; 241 282 } 242 retval = ata_bd_rdwr(disk_id, method, idx, 243 size, fs_va); 283 retval = ata_bd_read_blocks(disk_id, ba, cnt, fs_va); 244 284 break; 285 case BD_WRITE_BLOCKS: 286 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 287 IPC_GET_ARG2(call)); 288 cnt = IPC_GET_ARG3(call); 289 if (cnt * block_size > comm_size) { 290 retval = ELIMIT; 291 break; 292 } 293 retval = ata_bd_write_blocks(disk_id, ba, cnt, fs_va); 294 break; 295 case BD_GET_BLOCK_SIZE: 296 ipc_answer_1(callid, EOK, block_size); 297 continue; 245 298 default: 246 299 retval = EINVAL; … … 251 304 } 252 305 253 /** Transfer a logical block from/to the device. 254 * 255 * @param disk_id Device index (0 or 1) 256 * @param method @c BD_READ_BLOCK or @c BD_WRITE_BLOCK 257 * @param blk_idx Index of the first block. 258 * @param size Size of the logical block. 259 * @param buf Data buffer. 260 * 261 * @return EOK on success, EIO on error. 262 */ 263 static int ata_bd_rdwr(int disk_id, ipcarg_t method, off_t blk_idx, size_t size, 264 void *buf) 265 { 306 /** Initialize a disk. 307 * 308 * Probes for a disk, determines its parameters and initializes 309 * the disk structure. 310 */ 311 static int disk_init(disk_t *d, int disk_id) 312 { 313 identify_data_t idata; 314 uint8_t model[40]; 315 uint16_t w; 316 uint8_t c; 317 size_t pos, len; 266 318 int rc; 267 size_t now; 268 269 while (size > 0) { 270 now = size < block_size ? size : block_size; 271 if (now != block_size) 272 return EINVAL; 273 274 if (method == BD_READ_BLOCK) 275 rc = ata_bd_read_block(disk_id, blk_idx, 1, buf); 276 else 277 rc = ata_bd_write_block(disk_id, blk_idx, 1, buf); 278 319 unsigned i; 320 321 rc = drive_identify(disk_id, &idata); 322 if (rc != EOK) { 323 d->present = false; 324 return rc; 325 } 326 327 if ((idata.caps & cap_lba) == 0) { 328 /* Device only supports CHS addressing. */ 329 d->amode = am_chs; 330 331 d->geom.cylinders = idata.cylinders; 332 d->geom.heads = idata.heads; 333 d->geom.sectors = idata.sectors; 334 335 d->blocks = d->geom.cylinders * d->geom.heads * d->geom.sectors; 336 } else if ((idata.cmd_set1 & cs1_addr48) == 0) { 337 /* Device only supports LBA-28 addressing. */ 338 d->amode = am_lba28; 339 340 d->geom.cylinders = 0; 341 d->geom.heads = 0; 342 d->geom.sectors = 0; 343 344 d->blocks = 345 (uint32_t) idata.total_lba28_0 | 346 ((uint32_t) idata.total_lba28_1 << 16); 347 } else { 348 /* Device supports LBA-48 addressing. */ 349 d->amode = am_lba48; 350 351 d->geom.cylinders = 0; 352 d->geom.heads = 0; 353 d->geom.sectors = 0; 354 355 d->blocks = 356 (uint64_t) idata.total_lba48_0 | 357 ((uint64_t) idata.total_lba48_1 << 16) | 358 ((uint64_t) idata.total_lba48_2 << 32) | 359 ((uint64_t) idata.total_lba48_3 << 48); 360 } 361 362 /* 363 * Convert model name to string representation. 364 */ 365 for (i = 0; i < 20; i++) { 366 w = idata.model_name[i]; 367 model[2 * i] = w >> 8; 368 model[2 * i + 1] = w & 0x00ff; 369 } 370 371 len = 40; 372 while (len > 0 && model[len - 1] == 0x20) 373 --len; 374 375 pos = 0; 376 for (i = 0; i < len; ++i) { 377 c = model[i]; 378 if (c >= 0x80) c = '?'; 379 380 chr_encode(c, d->model, &pos, 40); 381 } 382 d->model[pos] = '\0'; 383 384 d->present = true; 385 fibril_mutex_initialize(&d->lock); 386 387 return EOK; 388 } 389 390 /** Read multiple blocks from the device. */ 391 static int ata_bd_read_blocks(int disk_id, uint64_t ba, size_t cnt, 392 void *buf) { 393 394 int rc; 395 396 while (cnt > 0) { 397 rc = ata_bd_read_block(disk_id, ba, 1, buf); 279 398 if (rc != EOK) 280 399 return rc; 281 400 401 ++ba; 402 --cnt; 282 403 buf += block_size; 283 blk_idx++; 284 285 if (size > block_size) 286 size -= block_size; 287 else 288 size = 0; 404 } 405 406 return EOK; 407 } 408 409 /** Write multiple blocks to the device. */ 410 static int ata_bd_write_blocks(int disk_id, uint64_t ba, size_t cnt, 411 const void *buf) { 412 413 int rc; 414 415 while (cnt > 0) { 416 rc = ata_bd_write_block(disk_id, ba, 1, buf); 417 if (rc != EOK) 418 return rc; 419 420 ++ba; 421 --cnt; 422 buf += block_size; 289 423 } 290 424 … … 294 428 /** Issue IDENTIFY command. 295 429 * 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.430 * Reads @c identify data into the provided buffer. This is used to detect 431 * whether an ATA device is present and if so, to determine its parameters. 298 432 * 299 433 * @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)434 * @param buf Pointer to a 512-byte buffer. 435 */ 436 static int drive_identify(int disk_id, void *buf) 303 437 { 304 438 uint16_t data; … … 308 442 309 443 drv_head = ((disk_id != 0) ? DHR_DRV : 0); 310 d->present = false;311 444 312 445 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) … … 330 463 331 464 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 for (i = 0; i < block_size / 2; i++) {338 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 }345 }346 }347 348 if ((status & SR_ERR) != 0)349 return EIO;350 351 d->blocks = d->cylinders * d->heads * d->sectors;352 353 d->present = true;354 fibril_mutex_initialize(&d->lock);355 356 return EOK;357 }358 359 /** Read a physical from the device.360 *361 * @param disk_id Device index (0 or 1)362 * @param blk_idx Index of the first block.363 * @param blk_cnt Number of blocks to transfer.364 * @param buf Buffer for holding the data.365 *366 * @return EOK on success, EIO on error.367 */368 static int ata_bd_read_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,369 void *buf)370 {371 size_t i;372 uint16_t data;373 uint8_t status;374 uint64_t c, h, s;375 uint64_t idx;376 uint8_t drv_head;377 disk_t *d;378 379 d = &disk[disk_id];380 381 /* Check device bounds. */382 if (blk_idx >= d->blocks)383 return EINVAL;384 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);391 392 /* New value for Drive/Head register */393 drv_head =394 ((disk_id != 0) ? DHR_DRV : 0) |395 (h & 0x0f);396 397 fibril_mutex_lock(&d->lock);398 399 /* Program a Read Sectors operation. */400 401 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {402 fibril_mutex_unlock(&d->lock);403 return EIO;404 }405 406 pio_write_8(&cmd->drive_head, drv_head);407 408 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {409 fibril_mutex_unlock(&d->lock);410 return EIO;411 }412 413 pio_write_8(&cmd->sector_count, 1);414 pio_write_8(&cmd->sector_number, s);415 pio_write_8(&cmd->cylinder_low, c & 0xff);416 pio_write_8(&cmd->cylinder_high, c >> 16);417 418 pio_write_8(&cmd->command, CMD_READ_SECTORS);419 420 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {421 fibril_mutex_unlock(&d->lock);422 return EIO;423 }424 425 if ((status & SR_DRQ) != 0) {426 /* Read data from the device buffer. */427 428 465 for (i = 0; i < block_size / 2; i++) { 429 466 data = pio_read_16(&cmd->data_port); … … 435 472 return EIO; 436 473 437 fibril_mutex_unlock(&d->lock); 438 return EOK; 439 } 440 441 /** Write a physical block to the device. 474 return EOK; 475 } 476 477 /** Read a physical from the device. 442 478 * 443 479 * @param disk_id Device index (0 or 1) 444 * @param b lk_idx Index ofthe first block.445 * @param blk_cntNumber of blocks to transfer.446 * @param buf Buffer holding the data to write.480 * @param ba Address the first block. 481 * @param cnt Number of blocks to transfer. 482 * @param buf Buffer for holding the data. 447 483 * 448 484 * @return EOK on success, EIO on error. 449 485 */ 450 static int ata_bd_ write_block(int disk_id, uint64_t blk_idx, size_t blk_cnt,451 constvoid *buf)486 static int ata_bd_read_block(int disk_id, uint64_t ba, size_t blk_cnt, 487 void *buf) 452 488 { 453 489 size_t i; 490 uint16_t data; 454 491 uint8_t status; 455 uint64_t c, h, s;456 uint64_t idx;457 492 uint8_t drv_head; 458 493 disk_t *d; 494 block_coord_t bc; 459 495 460 496 d = &disk[disk_id]; 461 462 /* Check device bounds. */ 463 if (blk_idx >= d->blocks) 497 bc.h = 0; /* Silence warning. */ 498 499 /* Compute block coordinates. */ 500 if (coord_calc(d, ba, &bc) != EOK) 464 501 return EINVAL; 465 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);472 502 473 503 /* New value for Drive/Head register */ 474 504 drv_head = 475 505 ((disk_id != 0) ? DHR_DRV : 0) | 476 (h & 0x0f); 506 ((d->amode != am_chs) ? DHR_LBA : 0) | 507 (bc.h & 0x0f); 477 508 478 509 fibril_mutex_lock(&d->lock); 479 510 480 /* Program a WriteSectors operation. */511 /* Program a Read Sectors operation. */ 481 512 482 513 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { … … 492 523 } 493 524 494 pio_write_8(&cmd->sector_count, 1); 495 pio_write_8(&cmd->sector_number, s); 496 pio_write_8(&cmd->cylinder_low, c & 0xff); 497 pio_write_8(&cmd->cylinder_high, c >> 16); 498 499 pio_write_8(&cmd->command, CMD_WRITE_SECTORS); 525 /* Program block coordinates into the device. */ 526 coord_sc_program(&bc, 1); 527 528 pio_write_8(&cmd->command, d->amode == am_lba48 ? 529 CMD_READ_SECTORS_EXT : CMD_READ_SECTORS); 530 531 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 532 fibril_mutex_unlock(&d->lock); 533 return EIO; 534 } 535 536 if ((status & SR_DRQ) != 0) { 537 /* Read data from the device buffer. */ 538 539 for (i = 0; i < block_size / 2; i++) { 540 data = pio_read_16(&cmd->data_port); 541 ((uint16_t *) buf)[i] = data; 542 } 543 } 544 545 if ((status & SR_ERR) != 0) 546 return EIO; 547 548 fibril_mutex_unlock(&d->lock); 549 return EOK; 550 } 551 552 /** Write a physical block to the device. 553 * 554 * @param disk_id Device index (0 or 1) 555 * @param ba Address of the first block. 556 * @param cnt Number of blocks to transfer. 557 * @param buf Buffer holding the data to write. 558 * 559 * @return EOK on success, EIO on error. 560 */ 561 static int ata_bd_write_block(int disk_id, uint64_t ba, size_t cnt, 562 const void *buf) 563 { 564 size_t i; 565 uint8_t status; 566 uint8_t drv_head; 567 disk_t *d; 568 block_coord_t bc; 569 570 d = &disk[disk_id]; 571 bc.h = 0; /* Silence warning. */ 572 573 /* Compute block coordinates. */ 574 if (coord_calc(d, ba, &bc) != EOK) 575 return EINVAL; 576 577 /* New value for Drive/Head register */ 578 drv_head = 579 ((disk_id != 0) ? DHR_DRV : 0) | 580 ((d->amode != am_chs) ? DHR_LBA : 0) | 581 (bc.h & 0x0f); 582 583 fibril_mutex_lock(&d->lock); 584 585 /* Program a Write Sectors operation. */ 586 587 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 588 fibril_mutex_unlock(&d->lock); 589 return EIO; 590 } 591 592 pio_write_8(&cmd->drive_head, drv_head); 593 594 if (wait_status(SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 595 fibril_mutex_unlock(&d->lock); 596 return EIO; 597 } 598 599 /* Program block coordinates into the device. */ 600 coord_sc_program(&bc, 1); 601 602 pio_write_8(&cmd->command, d->amode == am_lba48 ? 603 CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS); 500 604 501 605 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { … … 518 622 519 623 return EOK; 624 } 625 626 /** Calculate block coordinates. 627 * 628 * Calculates block coordinates in the best coordinate system supported 629 * by the device. These can be later programmed into the device using 630 * @c coord_sc_program(). 631 * 632 * @return EOK on success or EINVAL if block index is past end of device. 633 */ 634 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc) 635 { 636 uint64_t c; 637 uint64_t idx; 638 639 /* Check device bounds. */ 640 if (ba >= d->blocks) 641 return EINVAL; 642 643 bc->amode = d->amode; 644 645 switch (d->amode) { 646 case am_chs: 647 /* Compute CHS coordinates. */ 648 c = ba / (d->geom.heads * d->geom.sectors); 649 idx = ba % (d->geom.heads * d->geom.sectors); 650 651 bc->cyl_lo = c & 0xff; 652 bc->cyl_hi = (c >> 8) & 0xff; 653 bc->h = (idx / d->geom.sectors) & 0x0f; 654 bc->sector = (1 + (idx % d->geom.sectors)) & 0xff; 655 break; 656 657 case am_lba28: 658 /* Compute LBA-28 coordinates. */ 659 bc->c0 = ba & 0xff; /* bits 0-7 */ 660 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */ 661 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */ 662 bc->h = (ba >> 24) & 0x0f; /* bits 24-27 */ 663 break; 664 665 case am_lba48: 666 /* Compute LBA-48 coordinates. */ 667 bc->c0 = ba & 0xff; /* bits 0-7 */ 668 bc->c1 = (ba >> 8) & 0xff; /* bits 8-15 */ 669 bc->c2 = (ba >> 16) & 0xff; /* bits 16-23 */ 670 bc->c3 = (ba >> 24) & 0xff; /* bits 24-31 */ 671 bc->c4 = (ba >> 32) & 0xff; /* bits 32-39 */ 672 bc->c5 = (ba >> 40) & 0xff; /* bits 40-47 */ 673 bc->h = 0; 674 break; 675 } 676 677 return EOK; 678 } 679 680 /** Program block coordinates and sector count into ATA registers. 681 * 682 * Note that bc->h must be programmed separately into the device/head register. 683 */ 684 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt) 685 { 686 if (bc->amode == am_lba48) { 687 /* Write high-order bits. */ 688 pio_write_8(&cmd->sector_count, scnt >> 8); 689 pio_write_8(&cmd->sector_number, bc->c3); 690 pio_write_8(&cmd->cylinder_low, bc->c4); 691 pio_write_8(&cmd->cylinder_high, bc->c5); 692 } 693 694 /* Write low-order bits. */ 695 pio_write_8(&cmd->sector_count, scnt & 0x00ff); 696 pio_write_8(&cmd->sector_number, bc->c0); 697 pio_write_8(&cmd->cylinder_low, bc->c1); 698 pio_write_8(&cmd->cylinder_high, bc->c2); 520 699 } 521 700 -
uspace/srv/bd/ata_bd/ata_bd.h
rfcbd1be r1787e527 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 … … 130 132 131 133 enum ata_command { 132 CMD_IDENTIFY_DRIVE = 0xEC,133 134 CMD_READ_SECTORS = 0x20, 134 CMD_WRITE_SECTORS = 0x30 135 CMD_READ_SECTORS_EXT = 0x24, 136 CMD_WRITE_SECTORS = 0x30, 137 CMD_WRITE_SECTORS_EXT = 0x34, 138 CMD_IDENTIFY_DRIVE = 0xEC 135 139 }; 136 140 … … 142 146 }; 143 147 148 /** Data returned from @c identify command. */ 149 typedef struct { 150 uint16_t gen_conf; 151 uint16_t cylinders; 152 uint16_t _res2; 153 uint16_t heads; 154 uint16_t _vs4; 155 uint16_t _vs5; 156 uint16_t sectors; 157 uint16_t _vs7; 158 uint16_t _vs8; 159 uint16_t _vs9; 160 161 uint16_t serial_number[10]; 162 uint16_t _vs20; 163 uint16_t _vs21; 164 uint16_t vs_bytes; 165 uint16_t firmware_rev[4]; 166 uint16_t model_name[20]; 167 168 uint16_t max_rw_multiple; 169 uint16_t _res48; 170 uint16_t caps; 171 uint16_t _res50; 172 uint16_t pio_timing; 173 uint16_t dma_timing; 174 175 uint16_t validity; 176 uint16_t cur_cyl; 177 uint16_t cur_heads; 178 uint16_t cur_sectors; 179 uint16_t cur_capacity0; 180 uint16_t cur_capacity1; 181 uint16_t mss; 182 uint16_t total_lba28_0; 183 uint16_t total_lba28_1; 184 uint16_t sw_dma; 185 uint16_t mw_dma; 186 uint16_t pio_modes; 187 uint16_t min_mw_dma_cycle; 188 uint16_t rec_mw_dma_cycle; 189 uint16_t min_raw_pio_cycle; 190 uint16_t min_iordy_pio_cycle; 191 192 uint16_t _res69; 193 uint16_t _res70; 194 uint16_t _res71; 195 uint16_t _res72; 196 uint16_t _res73; 197 uint16_t _res74; 198 199 uint16_t queue_depth; 200 uint16_t _res76[1 + 79 - 76]; 201 uint16_t version_maj; 202 uint16_t version_min; 203 uint16_t cmd_set0; 204 uint16_t cmd_set1; 205 uint16_t csf_sup_ext; 206 uint16_t csf_enabled0; 207 uint16_t csf_enabled1; 208 uint16_t csf_default; 209 uint16_t udma; 210 211 uint16_t _res89[1 + 99 - 89]; 212 213 /* Total number of blocks in LBA-48 addressing */ 214 uint16_t total_lba48_0; 215 uint16_t total_lba48_1; 216 uint16_t total_lba48_2; 217 uint16_t total_lba48_3; 218 219 /* Note: more fields are defined in ATA/ATAPI-7 */ 220 uint16_t _res104[1 + 127 - 104]; 221 uint16_t _vs128[1 + 159 - 128]; 222 uint16_t _res160[1 + 255 - 160]; 223 } identify_data_t; 224 225 enum ata_caps { 226 cap_iordy = 0x0800, 227 cap_iordy_cbd = 0x0400, 228 cap_lba = 0x0200, 229 cap_dma = 0x0100 230 }; 231 232 /** Bits of @c identify_data_t.cmd_set1 */ 233 enum ata_cs1 { 234 cs1_addr48 = 0x0400 /**< 48-bit address feature set */ 235 }; 236 237 /** Block addressing mode. */ 238 enum addr_mode { 239 am_chs, /**< CHS block addressing */ 240 am_lba28, /**< LBA-28 block addressing */ 241 am_lba48 /**< LBA-48 block addressing */ 242 }; 243 244 /** Block coordinates */ 245 typedef struct { 246 /** Addressing mode used */ 247 enum addr_mode amode; 248 249 union { 250 /** CHS coordinates */ 251 struct { 252 uint8_t sector; 253 uint8_t cyl_lo; 254 uint8_t cyl_hi; 255 }; 256 /** LBA coordinates */ 257 struct { 258 uint8_t c0; 259 uint8_t c1; 260 uint8_t c2; 261 uint8_t c3; 262 uint8_t c4; 263 uint8_t c5; 264 }; 265 }; 266 267 /** Lower 4 bits for device/head register */ 268 uint8_t h; 269 } block_coord_t; 270 144 271 typedef struct { 145 272 bool present; 146 unsigned heads; 147 unsigned cylinders; 148 unsigned sectors; 273 enum addr_mode amode; 274 275 /* 276 * Geometry. Only valid if operating in CHS mode. 277 */ 278 struct { 279 unsigned heads; 280 unsigned cylinders; 281 unsigned sectors; 282 } geom; 283 149 284 uint64_t blocks; 285 286 char model[STR_BOUNDS(40) + 1]; 150 287 151 288 fibril_mutex_t lock; -
uspace/srv/bd/file_bd/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = file_bd 44 SOURCES = \ 45 file_bd.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/bd/file_bd/file_bd.c
rfcbd1be r1787e527 51 51 #include <bool.h> 52 52 #include <task.h> 53 #include <macros.h> 53 54 54 55 #define NAME "file_bd" 55 56 56 static size_t comm_size;57 static const size_t block_size = 512; 57 58 static FILE *img; 58 59 … … 62 63 static int file_bd_init(const char *fname); 63 64 static void file_bd_connection(ipc_callid_t iid, ipc_call_t *icall); 64 static int file_bd_read (off_t blk_idx, size_t size, void *buf);65 static int file_bd_write (off_t blk_idx, size_t size,void *buf);65 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf); 66 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf); 66 67 67 68 int main(int argc, char **argv) … … 120 121 ipc_call_t call; 121 122 ipcarg_t method; 123 size_t comm_size; 122 124 int flags; 123 125 int retval; 124 off_t idx;125 size_t size;126 uint64_t ba; 127 size_t cnt; 126 128 127 129 /* Answer the IPC_M_CONNECT_ME_TO call. */ 128 130 ipc_answer_0(iid, EOK); 129 131 130 if (! ipc_share_out_receive(&callid, &comm_size, &flags)) {132 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 131 133 ipc_answer_0(callid, EHANGUP); 132 134 return; … … 139 141 } 140 142 141 (void) ipc_share_out_finalize(callid, fs_va);143 (void) async_share_out_finalize(callid, fs_va); 142 144 143 145 while (1) { … … 149 151 ipc_answer_0(callid, EOK); 150 152 return; 151 case BD_READ_BLOCK :152 case BD_WRITE_BLOCK:153 idx = IPC_GET_ARG1(call);154 size = IPC_GET_ARG2(call);155 if ( size > comm_size) {156 retval = E INVAL;153 case BD_READ_BLOCKS: 154 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 155 IPC_GET_ARG2(call)); 156 cnt = IPC_GET_ARG3(call); 157 if (cnt * block_size > comm_size) { 158 retval = ELIMIT; 157 159 break; 158 160 } 159 if (method == BD_READ_BLOCK) 160 retval = file_bd_read(idx, size, fs_va); 161 else 162 retval = file_bd_write(idx, size, fs_va); 161 retval = file_bd_read_blocks(ba, cnt, fs_va); 163 162 break; 163 case BD_WRITE_BLOCKS: 164 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 165 IPC_GET_ARG2(call)); 166 cnt = IPC_GET_ARG3(call); 167 if (cnt * block_size > comm_size) { 168 retval = ELIMIT; 169 break; 170 } 171 retval = file_bd_write_blocks(ba, cnt, fs_va); 172 break; 173 case BD_GET_BLOCK_SIZE: 174 ipc_answer_1(callid, EOK, block_size); 175 continue; 164 176 default: 165 177 retval = EINVAL; … … 170 182 } 171 183 172 static int file_bd_read(off_t blk_idx, size_t size, void *buf) 184 /** Read blocks from the device. */ 185 static int file_bd_read_blocks(uint64_t ba, size_t cnt, void *buf) 173 186 { 174 187 size_t n_rd; … … 176 189 fibril_mutex_lock(&dev_lock); 177 190 178 fseek(img, b lk_idx *size, SEEK_SET);179 n_rd = fread(buf, 1, size, img);191 fseek(img, ba * block_size, SEEK_SET); 192 n_rd = fread(buf, block_size, cnt, img); 180 193 181 194 if (ferror(img)) { … … 186 199 fibril_mutex_unlock(&dev_lock); 187 200 188 if (n_rd < size)189 return EINVAL; /* Read beyond end of d isk*/201 if (n_rd < cnt) 202 return EINVAL; /* Read beyond end of device */ 190 203 191 204 return EOK; 192 205 } 193 206 194 static int file_bd_write(off_t blk_idx, size_t size, void *buf) 207 /** Write blocks to the device. */ 208 static int file_bd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 195 209 { 196 210 size_t n_wr; … … 198 212 fibril_mutex_lock(&dev_lock); 199 213 200 fseek(img, b lk_idx *size, SEEK_SET);201 n_wr = fread(buf, 1, size, img);202 203 if (ferror(img) || n_wr < size) {214 fseek(img, ba * block_size, SEEK_SET); 215 n_wr = fread(buf, block_size, cnt, img); 216 217 if (ferror(img) || n_wr < cnt) { 204 218 fibril_mutex_unlock(&dev_lock); 205 219 return EIO; /* Write error */ -
uspace/srv/bd/gxe_bd/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = gxe_bd 44 SOURCES = \ 45 gxe_bd.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/bd/gxe_bd/gxe_bd.c
rfcbd1be r1787e527 47 47 #include <sys/types.h> 48 48 #include <errno.h> 49 #include <macros.h> 49 50 #include <task.h> 50 51 … … 97 98 static int gxe_bd_init(void); 98 99 static void gxe_bd_connection(ipc_callid_t iid, ipc_call_t *icall); 99 static int gx _bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size,100 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 100 101 void *buf); 101 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size, 102 void *buf); 103 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size, 102 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 104 103 const void *buf); 104 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf); 105 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf); 105 106 106 107 int main(int argc, char **argv) … … 163 164 int flags; 164 165 int retval; 165 off_t idx;166 size_t size;166 uint64_t ba; 167 unsigned cnt; 167 168 int disk_id, i; 168 169 … … 184 185 ipc_answer_0(iid, EOK); 185 186 186 if (!ipc_share_out_receive(&callid, &comm_size, &flags)) { 187 if (!async_share_out_receive(&callid, &comm_size, &flags)) { 188 ipc_answer_0(callid, EHANGUP); 189 return; 190 } 191 192 if (comm_size < block_size) { 187 193 ipc_answer_0(callid, EHANGUP); 188 194 return; … … 195 201 } 196 202 197 (void) ipc_share_out_finalize(callid, fs_va);203 (void) async_share_out_finalize(callid, fs_va); 198 204 199 205 while (1) { … … 205 211 ipc_answer_0(callid, EOK); 206 212 return; 207 case BD_READ_BLOCK :208 case BD_WRITE_BLOCK:209 idx = IPC_GET_ARG1(call);210 size = IPC_GET_ARG2(call);211 if ( size > comm_size) {212 retval = E INVAL;213 case BD_READ_BLOCKS: 214 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 215 IPC_GET_ARG2(call)); 216 cnt = IPC_GET_ARG3(call); 217 if (cnt * block_size > comm_size) { 218 retval = ELIMIT; 213 219 break; 214 220 } 215 retval = gx_bd_rdwr(disk_id, method, idx * size, 216 size, fs_va); 221 retval = gxe_bd_read_blocks(disk_id, ba, cnt, fs_va); 217 222 break; 223 case BD_WRITE_BLOCKS: 224 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 225 IPC_GET_ARG2(call)); 226 cnt = IPC_GET_ARG3(call); 227 if (cnt * block_size > comm_size) { 228 retval = ELIMIT; 229 break; 230 } 231 retval = gxe_bd_write_blocks(disk_id, ba, cnt, fs_va); 232 break; 233 case BD_GET_BLOCK_SIZE: 234 ipc_answer_1(callid, EOK, block_size); 235 continue; 218 236 default: 219 237 retval = EINVAL; … … 224 242 } 225 243 226 static int gx_bd_rdwr(int disk_id, ipcarg_t method, off_t offset, size_t size, 227 void *buf) 228 { 244 /** Read multiple blocks from the device. */ 245 static int gxe_bd_read_blocks(int disk_id, uint64_t ba, unsigned cnt, 246 void *buf) { 247 229 248 int rc; 230 size_t now; 231 232 while (size > 0) { 233 now = size < block_size ? size : block_size; 234 235 if (method == BD_READ_BLOCK) 236 rc = gxe_bd_read_block(disk_id, offset, now, buf); 237 else 238 rc = gxe_bd_write_block(disk_id, offset, now, buf); 239 249 250 while (cnt > 0) { 251 rc = gxe_bd_read_block(disk_id, ba, buf); 240 252 if (rc != EOK) 241 253 return rc; 242 254 255 ++ba; 256 --cnt; 243 257 buf += block_size; 244 offset += block_size; 245 246 if (size > block_size) 247 size -= block_size; 248 else 249 size = 0; 250 } 251 252 return EOK; 253 } 254 255 static int gxe_bd_read_block(int disk_id, uint64_t offset, size_t size, 256 void *buf) 258 } 259 260 return EOK; 261 } 262 263 /** Write multiple blocks to the device. */ 264 static int gxe_bd_write_blocks(int disk_id, uint64_t ba, unsigned cnt, 265 const void *buf) { 266 267 int rc; 268 269 while (cnt > 0) { 270 rc = gxe_bd_write_block(disk_id, ba, buf); 271 if (rc != EOK) 272 return rc; 273 274 ++ba; 275 --cnt; 276 buf += block_size; 277 } 278 279 return EOK; 280 } 281 282 /** Read a block from the device. */ 283 static int gxe_bd_read_block(int disk_id, uint64_t ba, void *buf) 257 284 { 258 285 uint32_t status; 286 uint64_t byte_addr; 259 287 size_t i; 260 288 uint32_t w; 261 289 290 byte_addr = ba * block_size; 291 262 292 fibril_mutex_lock(&dev_lock[disk_id]); 263 pio_write_32(&dev->offset_lo, (uint32_t) offset);264 pio_write_32(&dev->offset_hi, offset>> 32);293 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 294 pio_write_32(&dev->offset_hi, byte_addr >> 32); 265 295 pio_write_32(&dev->disk_id, disk_id); 266 296 pio_write_32(&dev->control, CTL_READ_START); … … 272 302 } 273 303 274 for (i = 0; i < size; i++) {304 for (i = 0; i < block_size; i++) { 275 305 ((uint8_t *) buf)[i] = w = pio_read_8(&dev->buffer[i]); 276 306 } … … 280 310 } 281 311 282 static int gxe_bd_write_block(int disk_id, uint64_t offset, size_t size, 283 312 /** Write a block to the device. */ 313 static int gxe_bd_write_block(int disk_id, uint64_t ba, const void *buf) 284 314 { 285 315 uint32_t status; 316 uint64_t byte_addr; 286 317 size_t i; 287 318 288 for (i = 0; i < size; i++) { 319 byte_addr = ba * block_size; 320 321 fibril_mutex_lock(&dev_lock[disk_id]); 322 323 for (i = 0; i < block_size; i++) { 289 324 pio_write_8(&dev->buffer[i], ((const uint8_t *) buf)[i]); 290 325 } 291 326 292 fibril_mutex_lock(&dev_lock[disk_id]); 293 pio_write_32(&dev->offset_lo, (uint32_t) offset); 294 pio_write_32(&dev->offset_hi, offset >> 32); 327 pio_write_32(&dev->offset_lo, (uint32_t) byte_addr); 328 pio_write_32(&dev->offset_hi, byte_addr >> 32); 295 329 pio_write_32(&dev->disk_id, disk_id); 296 330 pio_write_32(&dev->control, CTL_WRITE_START); -
uspace/srv/bd/rd/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = rd 44 SOURCES = \ 45 rd.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/bd/rd/rd.c
rfcbd1be r1787e527 55 55 #include <devmap.h> 56 56 #include <ipc/bd.h> 57 #include <macros.h> 57 58 58 59 #define NAME "rd" 59 60 60 /** Pointer to the ramdisk's image .*/61 /** Pointer to the ramdisk's image */ 61 62 static void *rd_addr; 62 /** Size of the ramdisk .*/63 /** Size of the ramdisk */ 63 64 static size_t rd_size; 65 66 /** Block size */ 67 static const size_t block_size = 512; 68 69 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf); 70 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf); 64 71 65 72 /** … … 82 89 int retval; 83 90 void *fs_va = NULL; 84 off_t offset;85 size_t block_size;86 size_t maxblock_size;91 uint64_t ba; 92 size_t cnt; 93 size_t comm_size; 87 94 88 95 /* … … 95 102 */ 96 103 int flags; 97 if ( ipc_share_out_receive(&callid, &maxblock_size, &flags)) {98 fs_va = as_get_mappable_page( maxblock_size);104 if (async_share_out_receive(&callid, &comm_size, &flags)) { 105 fs_va = as_get_mappable_page(comm_size); 99 106 if (fs_va) { 100 (void) ipc_share_out_finalize(callid, fs_va);107 (void) async_share_out_finalize(callid, fs_va); 101 108 } else { 102 109 ipc_answer_0(callid, EHANGUP); … … 123 130 ipc_answer_0(callid, EOK); 124 131 return; 125 case BD_READ_BLOCK: 126 offset = IPC_GET_ARG1(call); 127 block_size = IPC_GET_ARG2(call); 128 if (block_size > maxblock_size) { 129 /* 130 * Maximum block size exceeded. 131 */ 132 case BD_READ_BLOCKS: 133 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 134 IPC_GET_ARG2(call)); 135 cnt = IPC_GET_ARG3(call); 136 if (cnt * block_size > comm_size) { 132 137 retval = ELIMIT; 133 138 break; 134 139 } 135 if (offset * block_size > rd_size - block_size) { 136 /* 137 * Reading past the end of the device. 138 */ 140 retval = rd_read_blocks(ba, cnt, fs_va); 141 break; 142 case BD_WRITE_BLOCKS: 143 ba = MERGE_LOUP32(IPC_GET_ARG1(call), 144 IPC_GET_ARG2(call)); 145 cnt = IPC_GET_ARG3(call); 146 if (cnt * block_size > comm_size) { 139 147 retval = ELIMIT; 140 148 break; 141 149 } 142 fibril_rwlock_read_lock(&rd_lock); 143 memcpy(fs_va, rd_addr + offset * block_size, block_size); 144 fibril_rwlock_read_unlock(&rd_lock); 145 retval = EOK; 150 retval = rd_write_blocks(ba, cnt, fs_va); 146 151 break; 147 case BD_WRITE_BLOCK: 148 offset = IPC_GET_ARG1(call); 149 block_size = IPC_GET_ARG2(call); 150 if (block_size > maxblock_size) { 151 /* 152 * Maximum block size exceeded. 153 */ 154 retval = ELIMIT; 155 break; 156 } 157 if (offset * block_size > rd_size - block_size) { 158 /* 159 * Writing past the end of the device. 160 */ 161 retval = ELIMIT; 162 break; 163 } 164 fibril_rwlock_write_lock(&rd_lock); 165 memcpy(rd_addr + offset * block_size, fs_va, block_size); 166 fibril_rwlock_write_unlock(&rd_lock); 167 retval = EOK; 168 break; 152 case BD_GET_BLOCK_SIZE: 153 ipc_answer_1(callid, EOK, block_size); 154 continue; 169 155 default: 170 156 /* … … 181 167 } 182 168 169 /** Read blocks from the device. */ 170 static int rd_read_blocks(uint64_t ba, size_t cnt, void *buf) 171 { 172 if ((ba + cnt) * block_size > rd_size) { 173 /* Reading past the end of the device. */ 174 return ELIMIT; 175 } 176 177 fibril_rwlock_read_lock(&rd_lock); 178 memcpy(buf, rd_addr + ba * block_size, block_size * cnt); 179 fibril_rwlock_read_unlock(&rd_lock); 180 181 return EOK; 182 } 183 184 /** Write blocks to the device. */ 185 static int rd_write_blocks(uint64_t ba, size_t cnt, const void *buf) 186 { 187 if ((ba + cnt) * block_size > rd_size) { 188 /* Writing past the end of the device. */ 189 return ELIMIT; 190 } 191 192 fibril_rwlock_write_lock(&rd_lock); 193 memcpy(rd_addr + ba * block_size, buf, block_size * cnt); 194 fibril_rwlock_write_unlock(&rd_lock); 195 196 return EOK; 197 } 198 183 199 /** Prepare the ramdisk image for operation. */ 184 200 static bool rd_init(void) -
uspace/srv/cir/fhc/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = fhc 44 SOURCES = \ 45 fhc.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/cir/obio/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 .PHONY: all clean 32 33 33 LIBC_PREFIX = ../../../lib/libc 34 SOFTINT_PREFIX = ../../../lib/softint 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = obio 44 SOURCES = \ 45 obio.c 46 47 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 48 49 .PHONY: all clean depend disasm 50 51 all: $(OUTPUT) $(OUTPUT).disasm 52 53 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 54 37 55 38 clean: 56 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 57 58 depend: 59 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 60 61 $(OUTPUT): $(OBJECTS) $(LIBS) 62 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 63 64 disasm: $(OUTPUT).disasm 65 66 $(OUTPUT).disasm: $(OUTPUT) 67 $(OBJDUMP) -d $< > $@ 68 69 %.o: %.S 70 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 71 72 %.o: %.s 73 $(AS) $(AFLAGS) $< -o $@ 74 75 %.o: %.c 76 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/console/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 34 33 35 include $(LIBC_PREFIX)/Makefile.toolchain 36 37 CFLAGS += -I. 38 39 LIBS = $(LIBC_PREFIX)/libc.a 40 41 ## Sources 42 # 43 44 OUTPUT = console 45 46 GENERIC_SOURCES = \ 47 console.c \ 48 screenbuffer.c \ 49 keybuffer.c \ 50 gcons.c 51 52 IMAGES = \ 53 gfx/helenos.ppm \ 54 gfx/nameic.ppm \ 55 gfx/cons_selected.ppm \ 56 gfx/cons_idle.ppm \ 57 gfx/cons_has_data.ppm \ 58 gfx/cons_kernel.ppm \ 59 gfx/anim_1.ppm \ 60 gfx/anim_2.ppm \ 61 gfx/anim_3.ppm \ 62 gfx/anim_4.ppm 63 64 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) \ 65 $(addsuffix .o,$(basename $(IMAGES))) 66 67 OBJECTS := $(GENERIC_OBJECTS) 68 69 .PHONY: all clean depend disasm 70 71 all: $(OUTPUT) $(OUTPUT).disasm 72 73 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 74 37 75 38 clean: 76 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 77 78 depend: 79 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 80 81 $(OUTPUT): $(OBJECTS) $(LIBS) 82 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 83 84 disasm: $(OUTPUT).disasm 85 86 $(OUTPUT).disasm: $(OUTPUT) 87 $(OBJDUMP) -d $< > $@ 88 89 %.o: %.S 90 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 91 92 %.o: %.s 93 $(AS) $(AFLAGS) $< -o $@ 94 95 %.o: %.c 96 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 97 98 %.o: %.ppm 99 $(OBJCOPY) -I binary -O $(BFD_NAME) -B $(BFD_ARCH) $< $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/console/console.c
rfcbd1be r1787e527 40 40 #include <ipc/services.h> 41 41 #include <errno.h> 42 #include <keybuffer.h>43 42 #include <ipc/console.h> 44 43 #include <unistd.h> … … 55 54 #include "console.h" 56 55 #include "gcons.h" 56 #include "keybuffer.h" 57 57 #include "screenbuffer.h" 58 58 … … 429 429 ipc_callid_t callid; 430 430 size_t size; 431 if (! ipc_data_write_receive(&callid, &size)) {431 if (!async_data_write_receive(&callid, &size)) { 432 432 ipc_answer_0(callid, EINVAL); 433 433 ipc_answer_0(rid, EINVAL); … … 442 442 } 443 443 444 (void) ipc_data_write_finalize(callid, buf, size);444 (void) async_data_write_finalize(callid, buf, size); 445 445 446 446 async_serialize_start(); … … 464 464 ipc_callid_t callid; 465 465 size_t size; 466 if (! ipc_data_read_receive(&callid, &size)) {466 if (!async_data_read_receive(&callid, &size)) { 467 467 ipc_answer_0(callid, EINVAL); 468 468 ipc_answer_0(rid, EINVAL); … … 489 489 490 490 if (pos == size) { 491 (void) ipc_data_read_finalize(callid, buf, size);491 (void) async_data_read_finalize(callid, buf, size); 492 492 ipc_answer_1(rid, EOK, size); 493 493 free(buf); … … 713 713 714 714 if (interbuffer) { 715 if ( ipc_share_out_start(fb_info.phone, interbuffer,715 if (async_share_out_start(fb_info.phone, interbuffer, 716 716 AS_AREA_READ) != EOK) { 717 717 as_area_destroy(interbuffer); -
uspace/srv/console/gcons.c
rfcbd1be r1787e527 339 339 goto exit; 340 340 341 rc = ipc_share_out_start(fbphone, shm, PROTO_READ);341 rc = async_share_out_start(fbphone, shm, PROTO_READ); 342 342 if (rc) 343 343 goto drop; … … 409 409 goto exit; 410 410 411 rc = ipc_share_out_start(fbphone, shm, PROTO_READ);411 rc = async_share_out_start(fbphone, shm, PROTO_READ); 412 412 if (rc) 413 413 goto drop; -
uspace/srv/console/keybuffer.c
rfcbd1be r1787e527 35 35 */ 36 36 37 #include <keybuffer.h>38 37 #include <futex.h> 38 #include "keybuffer.h" 39 39 40 40 atomic_t keybuffer_futex = FUTEX_INITIALIZER; -
uspace/srv/console/screenbuffer.c
rfcbd1be r1787e527 33 33 */ 34 34 35 #include <screenbuffer.h>36 35 #include <io/style.h> 37 36 #include <malloc.h> 38 37 #include <unistd.h> 38 #include "screenbuffer.h" 39 39 40 40 /** Store one character to screenbuffer. -
uspace/srv/devmap/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 34 33 35 include $(LIBC_PREFIX)/Makefile.toolchain 36 37 LIBS = $(LIBC_PREFIX)/libc.a 38 39 ## Sources 40 # 41 42 OUTPUT = devmap 43 SOURCES = \ 44 devmap.c 45 46 CFLAGS += -D$(UARCH) 47 48 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 49 50 .PHONY: all clean depend disasm 51 52 all: $(OUTPUT) $(OUTPUT).disasm 53 54 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 55 37 56 38 clean: 57 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 58 59 depend: 60 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 61 62 $(OUTPUT): $(OBJECTS) $(LIBS) 63 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 64 65 disasm: $(OUTPUT).disasm 66 67 $(OUTPUT).disasm: $(OUTPUT) 68 $(OBJDUMP) -d $< > $@ 69 70 %.o: %.S 71 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 72 73 %.o: %.s 74 $(AS) $(AFLAGS) $< -o $@ 75 76 %.o: %.c 77 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/devmap/devmap.c
rfcbd1be r1787e527 213 213 ipc_callid_t callid; 214 214 size_t name_size; 215 if (! ipc_data_write_receive(&callid, &name_size)) {215 if (!async_data_write_receive(&callid, &name_size)) { 216 216 free(driver); 217 217 ipc_answer_0(callid, EREFUSED); … … 241 241 * Send confirmation to sender and get data into buffer. 242 242 */ 243 if ( ipc_data_write_finalize(callid, driver->name, name_size) != EOK) {243 if (async_data_write_finalize(callid, driver->name, name_size) != EOK) { 244 244 free(driver->name); 245 245 free(driver); … … 358 358 ipc_callid_t callid; 359 359 size_t size; 360 if (! ipc_data_write_receive(&callid, &size)) {360 if (!async_data_write_receive(&callid, &size)) { 361 361 free(device); 362 362 ipc_answer_0(iid, EREFUSED); … … 381 381 } 382 382 383 ipc_data_write_finalize(callid, device->name, size);383 async_data_write_finalize(callid, device->name, size); 384 384 device->name[size] = 0; 385 385 … … 466 466 ipc_callid_t callid; 467 467 size_t size; 468 if (! ipc_data_write_receive(&callid, &size)) {468 if (!async_data_write_receive(&callid, &size)) { 469 469 ipc_answer_0(callid, EREFUSED); 470 470 ipc_answer_0(iid, EREFUSED); … … 491 491 * Send confirmation to sender and get data into buffer. 492 492 */ 493 ipcarg_t retval = ipc_data_write_finalize(callid, name, size);493 ipcarg_t retval = async_data_write_finalize(callid, name, size); 494 494 if (retval != EOK) { 495 495 ipc_answer_0(iid, EREFUSED); … … 553 553 * size_t name_size = str_size(device->name); 554 554 * 555 * int rc = ipc_data_write_send(phone, device->name, name_size);555 * int rc = async_data_write_send(phone, device->name, name_size); 556 556 * if (rc != EOK) { 557 557 * async_wait_for(req, NULL); … … 576 576 ipc_callid_t callid; 577 577 size_t size; 578 if (! ipc_data_read_receive(&callid, &size)) {578 if (!async_data_read_receive(&callid, &size)) { 579 579 ipc_answer_0(callid, EREFUSED); 580 580 ipc_answer_0(iid, EREFUSED); … … 608 608 } 609 609 610 ipcarg_t retval = ipc_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t));610 ipcarg_t retval = async_data_read_finalize(callid, desc, pos * sizeof(dev_desc_t)); 611 611 if (retval != EOK) { 612 612 ipc_answer_0(iid, EREFUSED); -
uspace/srv/fb/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 34 33 35 include $(LIBC_PREFIX)/Makefile.toolchain 36 37 LIBS = $(LIBC_PREFIX)/libc.a 38 39 ## Sources 40 # 41 42 OUTPUT = fb 43 SOURCES = \ 44 main.c \ 45 ppm.c 46 47 ifneq ($(UARCH),ia64) 48 SOURCES += fb.c \ 49 font-8x16.c 50 CFLAGS += -DFB_ENABLED 51 endif 52 53 ifeq ($(UARCH),ia32) 54 SOURCES += ega.c 55 CFLAGS += -DEGA_ENABLED 56 endif 57 58 ifeq ($(UARCH),ia64) 59 SOURCES += ega.c \ 60 ski.c \ 61 serial_console.c 62 CFLAGS += -DSKI_ENABLED 63 CFLAGS += -DEGA_ENABLED 64 endif 65 66 ifeq ($(UARCH),amd64) 67 SOURCES += ega.c 68 CFLAGS += -DEGA_ENABLED 69 endif 70 71 ifeq ($(UARCH),mips32) 72 SOURCES += msim.c \ 73 serial_console.c 74 CFLAGS += -DMSIM_ENABLED 75 endif 76 77 ifeq ($(UARCH),sparc64) 78 SOURCES += sgcn.c \ 79 serial_console.c 80 CFLAGS += -DSGCN_ENABLED 81 endif 82 83 CFLAGS += -D$(UARCH) 84 85 86 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 87 88 .PHONY: all clean depend disasm 89 90 all: $(OUTPUT) $(OUTPUT).disasm 91 92 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 93 37 94 38 clean: 95 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 96 97 depend: 98 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 99 100 $(OUTPUT): $(OBJECTS) $(LIBS) 101 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 102 103 disasm: $(OUTPUT).disasm 104 105 $(OUTPUT).disasm: $(OUTPUT) 106 $(OBJDUMP) -d $< > $@ 107 108 %.o: %.S 109 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 110 111 %.o: %.s 112 $(AS) $(AFLAGS) $< -o $@ 113 114 %.o: %.c 115 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/fs/devfs/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../../lib/libc 33 LIBFS_PREFIX = ../../../lib/libfs 34 SOFTINT_PREFIX = ../../../lib/softint 32 .PHONY: all clean 35 33 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 CFLAGS += -I $(LIBFS_PREFIX) 39 40 LIBS = \ 41 $(LIBFS_PREFIX)/libfs.a \ 42 $(LIBC_PREFIX)/libc.a 43 44 ## Sources 45 # 46 47 OUTPUT = devfs 48 SOURCES = \ 49 devfs.c \ 50 devfs_ops.c 51 52 53 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 54 55 .PHONY: all clean depend disasm 56 57 all: $(OUTPUT) $(OUTPUT).disasm 58 59 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 60 37 61 38 clean: 62 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 63 64 depend: 65 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 66 67 $(OUTPUT): $(OBJECTS) $(LIBS) 68 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 69 70 disasm: $(OUTPUT).disasm 71 72 $(OUTPUT).disasm: $(OUTPUT) 73 $(OBJDUMP) -d $< > $@ 74 75 %.o: %.S 76 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 77 78 %.o: %.s 79 $(AS) $(AFLAGS) $< -o $@ 80 81 %.o: %.c 82 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/fs/devfs/devfs.c
rfcbd1be r1787e527 44 44 #include <async.h> 45 45 #include <errno.h> 46 #include <task.h> 46 47 #include <libfs.h> 47 48 #include "devfs.h" … … 51 52 52 53 static vfs_info_t devfs_vfs_info = { 53 .name = "devfs",54 .name = NAME, 54 55 }; 55 56 … … 131 132 132 133 printf(NAME ": Accepting connections\n"); 134 task_retval(0); 133 135 async_manager(); 134 136 -
uspace/srv/fs/devfs/devfs_ops.c
rfcbd1be r1787e527 108 108 ipc_callid_t callid; 109 109 size_t size; 110 if (! ipc_data_write_receive(&callid, &size)) {110 if (!async_data_write_receive(&callid, &size)) { 111 111 ipc_answer_0(callid, EINVAL); 112 112 ipc_answer_0(rid, EINVAL); … … 121 121 } 122 122 123 ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);123 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 124 124 if (retval != EOK) { 125 125 ipc_answer_0(rid, retval); … … 286 286 ipc_callid_t callid; 287 287 size_t size; 288 if (! ipc_data_read_receive(&callid, &size) ||288 if (!async_data_read_receive(&callid, &size) || 289 289 size != sizeof(struct stat)) { 290 290 ipc_answer_0(callid, EINVAL); … … 315 315 } 316 316 317 ipc_data_read_finalize(callid, &stat, sizeof(struct stat));317 async_data_read_finalize(callid, &stat, sizeof(struct stat)); 318 318 ipc_answer_0(rid, EOK); 319 319 } … … 340 340 341 341 ipc_callid_t callid; 342 if (! ipc_data_read_receive(&callid, NULL)) {342 if (!async_data_read_receive(&callid, NULL)) { 343 343 fibril_mutex_unlock(&devices_mutex); 344 344 ipc_answer_0(callid, EINVAL); … … 367 367 ipc_callid_t callid; 368 368 size_t size; 369 if (! ipc_data_read_receive(&callid, &size)) {369 if (!async_data_read_receive(&callid, &size)) { 370 370 ipc_answer_0(callid, EINVAL); 371 371 ipc_answer_0(rid, EINVAL); … … 384 384 385 385 if (pos < max) { 386 ipc_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);386 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 387 387 } else { 388 388 ipc_answer_0(callid, ENOENT); … … 418 418 419 419 ipc_callid_t callid; 420 if (! ipc_data_write_receive(&callid, NULL)) {420 if (!async_data_write_receive(&callid, NULL)) { 421 421 fibril_mutex_unlock(&devices_mutex); 422 422 ipc_answer_0(callid, EINVAL); -
uspace/srv/fs/fat/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../../lib/libc 33 LIBFS_PREFIX = ../../../lib/libfs 34 LIBBLOCK_PREFIX = ../../../lib/libblock 35 SOFTINT_PREFIX = ../../../lib/softint 32 .PHONY: all clean 36 33 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) 40 41 LIBS = \ 42 $(LIBFS_PREFIX)/libfs.a \ 43 $(LIBBLOCK_PREFIX)/libblock.a \ 44 $(LIBC_PREFIX)/libc.a 45 46 ## Sources 47 # 48 49 OUTPUT = fat 50 SOURCES = \ 51 fat.c \ 52 fat_ops.c \ 53 fat_idx.c \ 54 fat_dentry.c \ 55 fat_fat.c 56 57 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 58 59 .PHONY: all clean depend disasm 60 61 all: $(OUTPUT) $(OUTPUT).disasm 62 63 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 64 37 65 38 clean: 66 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 67 68 depend: 69 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 70 71 $(OUTPUT): $(OBJECTS) $(LIBS) 72 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 73 74 disasm: $(OUTPUT).disasm 75 76 $(OUTPUT).disasm: $(OUTPUT) 77 $(OBJDUMP) -d $< > $@ 78 79 %.o: %.S 80 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 81 82 %.o: %.s 83 $(AS) $(AFLAGS) $< -o $@ 84 85 %.o: %.c 86 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/fs/fat/fat.c
rfcbd1be r1787e527 43 43 #include <errno.h> 44 44 #include <unistd.h> 45 #include <task.h> 45 46 #include <stdio.h> 46 47 #include <libfs.h> 47 48 #include "../../vfs/vfs.h" 48 49 50 #define NAME "fat" 49 51 50 52 vfs_info_t fat_vfs_info = { 51 .name = "fat",53 .name = NAME, 52 54 }; 53 55 … … 83 85 } 84 86 85 dprintf( "VFS-FAT connection established.\n");87 dprintf(NAME ": connection opened\n"); 86 88 while (1) { 87 89 ipc_callid_t callid; … … 137 139 int rc; 138 140 139 printf( "fat: HelenOS FAT file system server.\n");141 printf(NAME ": HelenOS FAT file system server\n"); 140 142 141 143 rc = fat_idx_init(); … … 145 147 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); 146 148 if (vfs_phone < EOK) { 147 printf( "fat: failed to connect to VFS\n");149 printf(NAME ": failed to connect to VFS\n"); 148 150 return -1; 149 151 } … … 155 157 } 156 158 157 dprintf("FAT filesystem registered, fs_handle=%d.\n", 158 fat_reg.fs_handle); 159 159 printf(NAME ": Accepting connections\n"); 160 task_retval(0); 160 161 async_manager(); 161 162 /* not reached */ … … 163 164 164 165 err: 165 printf( "Failed to register the FATfile system (%d)\n", rc);166 printf(NAME ": Failed to register file system (%d)\n", rc); 166 167 return rc; 167 168 } -
uspace/srv/fs/fat/fat.h
rfcbd1be r1787e527 89 89 uint16_t signature; 90 90 } __attribute__ ((packed)); 91 struct {91 struct fat32 { 92 92 /* FAT32 only */ 93 93 /** Sectors per FAT. */ … … 215 215 extern void fat_sync(ipc_callid_t, ipc_call_t *); 216 216 217 extern fat_idx_t *fat_idx_get_new(dev_handle_t);217 extern int fat_idx_get_new(fat_idx_t **, dev_handle_t); 218 218 extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned); 219 219 extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t); -
uspace/srv/fs/fat/fat_fat.c
rfcbd1be r1787e527 61 61 * @param dev_handle Device handle of the device with the file. 62 62 * @param firstc First cluster to start the walk with. 63 * @param lastc If non-NULL, output argument hodling the last cluster number visited. 63 * @param lastc If non-NULL, output argument hodling the last cluster 64 * number visited. 65 * @param numc If non-NULL, output argument holding the number of 66 * clusters seen during the walk. 64 67 * @param max_clusters Maximum number of clusters to visit. 65 68 * 66 * @return Number of clusters seen during the walk.67 */ 68 uint16_t69 * @return EOK on success or a negative error code. 70 */ 71 int 69 72 fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 70 fat_cluster_t *lastc, uint16_t max_clusters)73 fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters) 71 74 { 72 75 block_t *b; … … 75 78 uint16_t clusters = 0; 76 79 fat_cluster_t clst = firstc; 80 int rc; 77 81 78 82 bps = uint16_t_le2host(bs->bps); … … 83 87 if (lastc) 84 88 *lastc = firstc; 85 return 0; 89 if (numc) 90 *numc = 0; 91 return EOK; 86 92 } 87 93 … … 96 102 fidx = clst % (bps / sizeof(fat_cluster_t)); 97 103 /* read FAT1 */ 98 b = block_get(dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); 104 rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); 105 if (rc != EOK) 106 return rc; 99 107 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); 100 108 assert(clst != FAT_CLST_BAD); 101 block_put(b); 109 rc = block_put(b); 110 if (rc != EOK) 111 return rc; 102 112 clusters++; 103 113 } … … 105 115 if (lastc && clst < FAT_CLST_LAST1) 106 116 *lastc = clst; 107 108 return clusters; 117 if (numc) 118 *numc = clusters; 119 120 return EOK; 109 121 } 110 122 111 123 /** Read block from file located on a FAT file system. 112 124 * 125 * @param block Pointer to a block pointer for storing result. 113 126 * @param bs Buffer holding the boot sector of the file system. 114 127 * @param dev_handle Device handle of the file system. … … 118 131 * @param flags Flags passed to libblock. 119 132 * 120 * @return Block structure holding the requested block. 121 */ 122 block_t * 123 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 124 bn_t bn, int flags) 125 { 126 block_t *b; 133 * @return EOK on success or a negative error code. 134 */ 135 int 136 _fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle, 137 fat_cluster_t firstc, bn_t bn, int flags) 138 { 127 139 unsigned bps; 128 140 unsigned rscnt; /* block address of the first FAT */ … … 131 143 unsigned sf; 132 144 unsigned ssa; /* size of the system area */ 133 unsigned clusters, max_clusters; 145 uint16_t clusters; 146 unsigned max_clusters; 134 147 fat_cluster_t lastc; 148 int rc; 135 149 136 150 bps = uint16_t_le2host(bs->bps); … … 146 160 /* root directory special case */ 147 161 assert(bn < rds); 148 b = block_get(dev_handle, rscnt + bs->fatcnt * sf + bn, flags); 149 return b; 162 rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn, 163 flags); 164 return rc; 150 165 } 151 166 152 167 max_clusters = bn / bs->spc; 153 clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,168 rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters, 154 169 max_clusters); 170 if (rc != EOK) 171 return rc; 155 172 assert(clusters == max_clusters); 156 173 157 b = block_get(dev_handle, ssa + (lastc - FAT_CLST_FIRST) * bs->spc +158 bn % bs->spc, flags);159 160 return b;174 rc = block_get(block, dev_handle, 175 ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 176 177 return rc; 161 178 } 162 179 … … 170 187 * this argument is ignored. 171 188 * @param pos Position in the last node block. 172 */ 173 void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 189 * 190 * @return EOK on success or a negative error code. 191 */ 192 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 174 193 { 175 194 uint16_t bps; … … 177 196 block_t *b; 178 197 off_t o, boundary; 198 int rc; 179 199 180 200 bps = uint16_t_le2host(bs->bps); … … 188 208 int flags = (o % bps == 0) ? 189 209 BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE; 190 b = fat_block_get(bs, nodep, o / bps, flags); 210 rc = fat_block_get(&b, bs, nodep, o / bps, flags); 211 if (rc != EOK) 212 return rc; 191 213 memset(b->data + o % bps, 0, bps - o % bps); 192 214 b->dirty = true; /* need to sync node */ 193 block_put(b); 215 rc = block_put(b); 216 if (rc != EOK) 217 return rc; 194 218 } 195 219 196 220 if (o >= pos) 197 return ;221 return EOK; 198 222 199 223 /* zero out the initial part of the new cluster chain */ 200 224 for (o = boundary; o < pos; o += bps) { 201 b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,225 rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl, 202 226 (o - boundary) / bps, BLOCK_FLAGS_NOREAD); 227 if (rc != EOK) 228 return rc; 203 229 memset(b->data, 0, min(bps, pos - o)); 204 230 b->dirty = true; /* need to sync node */ 205 block_put(b); 206 } 231 rc = block_put(b); 232 if (rc != EOK) 233 return rc; 234 } 235 236 return EOK; 207 237 } 208 238 … … 212 242 * @param dev_handle Device handle for the file system. 213 243 * @param clst Cluster which to get. 214 * 215 * @return Value found in the cluster. 216 */ 217 fat_cluster_t 218 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst) 244 * @param value Output argument holding the value of the cluster. 245 * 246 * @return EOK or a negative error code. 247 */ 248 int 249 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst, 250 fat_cluster_t *value) 219 251 { 220 252 block_t *b; 221 253 uint16_t bps; 222 254 uint16_t rscnt; 223 fat_cluster_t *cp, value; 255 fat_cluster_t *cp; 256 int rc; 224 257 225 258 bps = uint16_t_le2host(bs->bps); 226 259 rscnt = uint16_t_le2host(bs->rscnt); 227 260 228 b = block_get(dev_handle, rscnt + (clst * sizeof(fat_cluster_t)) / bps, 229 BLOCK_FLAGS_NONE); 261 rc = block_get(&b, dev_handle, rscnt + 262 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 263 if (rc != EOK) 264 return rc; 230 265 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 231 value = uint16_t_le2host(*cp);232 block_put(b);233 234 return value;266 *value = uint16_t_le2host(*cp); 267 rc = block_put(b); 268 269 return rc; 235 270 } 236 271 … … 242 277 * @param clst Cluster which is to be set. 243 278 * @param value Value to set the cluster with. 244 */ 245 void 279 * 280 * @return EOK on success or a negative error code. 281 */ 282 int 246 283 fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno, 247 284 fat_cluster_t clst, fat_cluster_t value) … … 252 289 uint16_t sf; 253 290 fat_cluster_t *cp; 291 int rc; 254 292 255 293 bps = uint16_t_le2host(bs->bps); … … 258 296 259 297 assert(fatno < bs->fatcnt); 260 b = block_get(dev_handle, rscnt + sf * fatno +298 rc = block_get(&b, dev_handle, rscnt + sf * fatno + 261 299 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 300 if (rc != EOK) 301 return rc; 262 302 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 263 303 *cp = host2uint16_t_le(value); 264 304 b->dirty = true; /* need to sync block */ 265 block_put(b); 305 rc = block_put(b); 306 return rc; 266 307 } 267 308 … … 272 313 * @param lifo Chain of allocated clusters. 273 314 * @param nclsts Number of clusters in the lifo chain. 274 */ 275 void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 315 * 316 * @return EOK on success or a negative error code. 317 */ 318 int fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 276 319 fat_cluster_t *lifo, unsigned nclsts) 277 320 { 278 321 uint8_t fatno; 279 322 unsigned c; 323 int rc; 280 324 281 325 for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) { 282 326 for (c = 0; c < nclsts; c++) { 283 fat_set_cluster(bs, dev_handle, fatno, lifo[c],327 rc = fat_set_cluster(bs, dev_handle, fatno, lifo[c], 284 328 c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]); 329 if (rc != EOK) 330 return rc; 285 331 } 286 332 } 333 334 return EOK; 287 335 } 288 336 … … 311 359 uint16_t rscnt; 312 360 uint16_t sf; 361 uint16_t ts; 362 unsigned rde; 363 unsigned rds; 364 unsigned ssa; 313 365 block_t *blk; 314 366 fat_cluster_t *lifo; /* stack for storing free cluster numbers */ 315 367 unsigned found = 0; /* top of the free cluster number stack */ 316 368 unsigned b, c, cl; 369 int rc; 317 370 318 371 lifo = (fat_cluster_t *) malloc(nclsts * sizeof(fat_cluster_t)); … … 323 376 rscnt = uint16_t_le2host(bs->rscnt); 324 377 sf = uint16_t_le2host(bs->sec_per_fat); 378 rde = uint16_t_le2host(bs->root_ent_max); 379 ts = uint16_t_le2host(bs->totsec16); 380 381 rds = (sizeof(fat_dentry_t) * rde) / bps; 382 rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); 383 ssa = rscnt + bs->fatcnt * sf + rds; 325 384 326 385 /* … … 329 388 fibril_mutex_lock(&fat_alloc_lock); 330 389 for (b = 0, cl = 0; b < sf; b++) { 331 blk = block_get(dev_handle, rscnt + b, BLOCK_FLAGS_NONE); 390 rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE); 391 if (rc != EOK) 392 goto error; 332 393 for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) { 394 /* 395 * Check if the cluster is physically there. This check 396 * becomes necessary when the file system is created 397 * with fewer total sectors than how many is inferred 398 * from the size of the file allocation table. 399 */ 400 if ((cl - 2) * bs->spc + ssa >= ts) { 401 rc = block_put(blk); 402 if (rc != EOK) 403 goto error; 404 goto out; 405 } 406 333 407 fat_cluster_t *clst = (fat_cluster_t *)blk->data + c; 334 408 if (uint16_t_le2host(*clst) == FAT_CLST_RES0) { … … 344 418 if (++found == nclsts) { 345 419 /* we are almost done */ 346 block_put(blk); 420 rc = block_put(blk); 421 if (rc != EOK) 422 goto error; 347 423 /* update the shadow copies of FAT */ 348 fat_alloc_shadow_clusters(bs,424 rc = fat_alloc_shadow_clusters(bs, 349 425 dev_handle, lifo, nclsts); 426 if (rc != EOK) 427 goto error; 350 428 *mcl = lifo[found - 1]; 351 429 *lcl = lifo[0]; … … 356 434 } 357 435 } 358 block_put(blk); 359 } 436 rc = block_put(blk); 437 if (rc != EOK) { 438 error: 439 fibril_mutex_unlock(&fat_alloc_lock); 440 free(lifo); 441 return rc; 442 } 443 } 444 out: 360 445 fibril_mutex_unlock(&fat_alloc_lock); 361 446 … … 365 450 */ 366 451 while (found--) { 367 fat_set_cluster(bs, dev_handle, FAT1, lifo[found],452 rc = fat_set_cluster(bs, dev_handle, FAT1, lifo[found], 368 453 FAT_CLST_RES0); 454 if (rc != EOK) { 455 free(lifo); 456 return rc; 457 } 369 458 } 370 459 … … 378 467 * @param dev_handle Device handle of the file system. 379 468 * @param firstc First cluster in the chain which is to be freed. 380 */ 381 void 469 * 470 * @return EOK on success or a negative return code. 471 */ 472 int 382 473 fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc) 383 474 { 384 475 unsigned fatno; 385 476 fat_cluster_t nextc; 477 int rc; 386 478 387 479 /* Mark all clusters in the chain as free in all copies of FAT. */ 388 480 while (firstc < FAT_CLST_LAST1) { 389 481 assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD); 390 nextc = fat_get_cluster(bs, dev_handle, firstc); 391 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 392 fat_set_cluster(bs, dev_handle, fatno, firstc, 482 rc = fat_get_cluster(bs, dev_handle, firstc, &nextc); 483 if (rc != EOK) 484 return rc; 485 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 486 rc = fat_set_cluster(bs, dev_handle, fatno, firstc, 393 487 FAT_CLST_RES0); 488 if (rc != EOK) 489 return rc; 490 } 491 394 492 firstc = nextc; 395 493 } 494 495 return EOK; 396 496 } 397 497 … … 401 501 * @param nodep Node representing the file. 402 502 * @param mcl First cluster of the cluster chain to append. 403 */ 404 void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 503 * 504 * @return EOK on success or a negative error code. 505 */ 506 int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 405 507 { 406 508 dev_handle_t dev_handle = nodep->idx->dev_handle; 407 509 fat_cluster_t lcl; 510 uint16_t numc; 408 511 uint8_t fatno; 409 410 if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, 411 (uint16_t) -1) == 0) { 512 int rc; 513 514 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc, 515 (uint16_t) -1); 516 if (rc != EOK) 517 return rc; 518 519 if (numc == 0) { 412 520 /* No clusters allocated to the node yet. */ 413 521 nodep->firstc = mcl; 414 522 nodep->dirty = true; /* need to sync node */ 415 return; 416 } 417 418 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 419 fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl); 523 return EOK; 524 } 525 526 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 527 rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, 528 mcl); 529 if (rc != EOK) 530 return rc; 531 } 532 533 return EOK; 420 534 } 421 535 … … 427 541 * argument is FAT_CLST_RES0, then all clusters will 428 542 * be chopped off. 429 */ 430 void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 431 { 543 * 544 * @return EOK on success or a negative return code. 545 */ 546 int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 547 { 548 int rc; 549 432 550 dev_handle_t dev_handle = nodep->idx->dev_handle; 433 551 if (lastc == FAT_CLST_RES0) { 434 552 /* The node will have zero size and no clusters allocated. */ 435 fat_free_clusters(bs, dev_handle, nodep->firstc); 553 rc = fat_free_clusters(bs, dev_handle, nodep->firstc); 554 if (rc != EOK) 555 return rc; 436 556 nodep->firstc = FAT_CLST_RES0; 437 557 nodep->dirty = true; /* need to sync node */ … … 440 560 unsigned fatno; 441 561 442 nextc = fat_get_cluster(bs, dev_handle, lastc); 562 rc = fat_get_cluster(bs, dev_handle, lastc, &nextc); 563 if (rc != EOK) 564 return rc; 443 565 444 566 /* Terminate the cluster chain in all copies of FAT. */ 445 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 446 fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1); 567 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 568 rc = fat_set_cluster(bs, dev_handle, fatno, lastc, 569 FAT_CLST_LAST1); 570 if (rc != EOK) 571 return rc; 572 } 447 573 448 574 /* Free all following clusters. */ 449 fat_free_clusters(bs, dev_handle, nextc); 450 } 451 } 452 453 void 575 rc = fat_free_clusters(bs, dev_handle, nextc); 576 if (rc != EOK) 577 return rc; 578 } 579 580 return EOK; 581 } 582 583 int 454 584 fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c) 455 585 { … … 457 587 block_t *b; 458 588 unsigned bps; 589 int rc; 459 590 460 591 bps = uint16_t_le2host(bs->bps); 461 592 462 593 for (i = 0; i < bs->spc; i++) { 463 b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD); 594 rc = _fat_block_get(&b, bs, dev_handle, c, i, 595 BLOCK_FLAGS_NOREAD); 596 if (rc != EOK) 597 return rc; 464 598 memset(b->data, 0, bps); 465 599 b->dirty = true; 466 block_put(b); 467 } 600 rc = block_put(b); 601 if (rc != EOK) 602 return rc; 603 } 604 605 return EOK; 468 606 } 469 607 -
uspace/srv/fs/fat/fat_fat.h
rfcbd1be r1787e527 59 59 typedef uint16_t fat_cluster_t; 60 60 61 #define fat_clusters_get( bs, dh, fc) \62 fat_cluster_walk((bs), (dh), (fc), NULL, ( uint16_t) -1)63 extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,64 fat_cluster_t *, uint16_t );61 #define fat_clusters_get(numc, bs, dh, fc) \ 62 fat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint16_t) -1) 63 extern int fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t, 64 fat_cluster_t *, uint16_t *, uint16_t); 65 65 66 #define fat_block_get(bs, np, bn, flags) \ 67 _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags)) 66 #define fat_block_get(b, bs, np, bn, flags) \ 67 _fat_block_get((b), (bs), (np)->idx->dev_handle, (np)->firstc, (bn), \ 68 (flags)) 68 69 69 extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,70 extern int _fat_block_get(block_t **, struct fat_bs *, dev_handle_t, 70 71 fat_cluster_t, bn_t, int); 71 72 72 extern voidfat_append_clusters(struct fat_bs *, struct fat_node *,73 extern int fat_append_clusters(struct fat_bs *, struct fat_node *, 73 74 fat_cluster_t); 74 extern voidfat_chop_clusters(struct fat_bs *, struct fat_node *,75 extern int fat_chop_clusters(struct fat_bs *, struct fat_node *, 75 76 fat_cluster_t); 76 77 extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned, 77 78 fat_cluster_t *, fat_cluster_t *); 78 extern voidfat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);79 extern voidfat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,79 extern int fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t); 80 extern int fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t, 80 81 fat_cluster_t *, unsigned); 81 extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t); 82 extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned, 82 extern int fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t, 83 fat_cluster_t *); 84 extern int fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned, 83 85 fat_cluster_t, fat_cluster_t); 84 extern voidfat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,86 extern int fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t, 85 87 off_t); 86 extern voidfat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);88 extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t); 87 89 88 90 #endif -
uspace/srv/fs/fat/fat_idx.c
rfcbd1be r1787e527 339 339 } 340 340 341 static fat_idx_t *fat_idx_create(dev_handle_t dev_handle)341 static int fat_idx_create(fat_idx_t **fidxp, dev_handle_t dev_handle) 342 342 { 343 343 fat_idx_t *fidx; … … 345 345 fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); 346 346 if (!fidx) 347 return NULL;347 return ENOMEM; 348 348 if (!fat_index_alloc(dev_handle, &fidx->index)) { 349 349 free(fidx); 350 return NULL;350 return ENOSPC; 351 351 } 352 352 … … 359 359 fidx->nodep = NULL; 360 360 361 return fidx; 362 } 363 364 fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle) 361 *fidxp = fidx; 362 return EOK; 363 } 364 365 int fat_idx_get_new(fat_idx_t **fidxp, dev_handle_t dev_handle) 365 366 { 366 367 fat_idx_t *fidx; 368 int rc; 367 369 368 370 fibril_mutex_lock(&used_lock); 369 fidx = fat_idx_create(dev_handle);370 if ( !fidx) {371 rc = fat_idx_create(&fidx, dev_handle); 372 if (rc != EOK) { 371 373 fibril_mutex_unlock(&used_lock); 372 return NULL;374 return rc; 373 375 } 374 376 … … 382 384 fibril_mutex_unlock(&used_lock); 383 385 384 return fidx; 386 *fidxp = fidx; 387 return EOK; 385 388 } 386 389 … … 401 404 fidx = hash_table_get_instance(l, fat_idx_t, uph_link); 402 405 } else { 403 fidx = fat_idx_create(dev_handle); 404 if (!fidx) { 406 int rc; 407 408 rc = fat_idx_create(&fidx, dev_handle); 409 if (rc != EOK) { 405 410 fibril_mutex_unlock(&used_lock); 406 411 return NULL; -
uspace/srv/fs/fat/fat_ops.c
rfcbd1be r1787e527 65 65 static LIST_INITIALIZE(ffn_head); 66 66 67 /* 68 * Forward declarations of FAT libfs operations. 69 */ 70 static int fat_root_get(fs_node_t **, dev_handle_t); 71 static int fat_match(fs_node_t **, fs_node_t *, const char *); 72 static int fat_node_get(fs_node_t **, dev_handle_t, fs_index_t); 73 static int fat_node_put(fs_node_t *); 74 static int fat_create_node(fs_node_t **, dev_handle_t, int); 75 static int fat_destroy_node(fs_node_t *); 76 static int fat_link(fs_node_t *, fs_node_t *, const char *); 77 static int fat_unlink(fs_node_t *, fs_node_t *, const char *); 78 static int fat_has_children(bool *, fs_node_t *); 79 static fs_index_t fat_index_get(fs_node_t *); 80 static size_t fat_size_get(fs_node_t *); 81 static unsigned fat_lnkcnt_get(fs_node_t *); 82 static char fat_plb_get_char(unsigned); 83 static bool fat_is_directory(fs_node_t *); 84 static bool fat_is_file(fs_node_t *node); 85 86 /* 87 * Helper functions. 88 */ 67 89 static void fat_node_initialize(fat_node_t *node) 68 90 { … … 78 100 } 79 101 80 static voidfat_node_sync(fat_node_t *node)102 static int fat_node_sync(fat_node_t *node) 81 103 { 82 104 block_t *b; … … 85 107 uint16_t bps; 86 108 unsigned dps; 109 int rc; 87 110 88 111 assert(node->dirty); … … 93 116 94 117 /* Read the block that contains the dentry of interest. */ 95 b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,118 rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc, 96 119 (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); 120 if (rc != EOK) 121 return rc; 97 122 98 123 d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps); … … 108 133 109 134 b->dirty = true; /* need to sync block */ 110 block_put(b); 111 } 112 113 static fat_node_t *fat_node_get_new(void) 135 rc = block_put(b); 136 return rc; 137 } 138 139 static int fat_node_get_new(fat_node_t **nodepp) 114 140 { 115 141 fs_node_t *fn; 116 142 fat_node_t *nodep; 143 int rc; 117 144 118 145 fibril_mutex_lock(&ffn_mutex); … … 130 157 list_remove(&nodep->ffn_link); 131 158 fibril_mutex_unlock(&ffn_mutex); 132 if (nodep->dirty) 133 fat_node_sync(nodep); 159 if (nodep->dirty) { 160 rc = fat_node_sync(nodep); 161 if (rc != EOK) { 162 idxp_tmp->nodep = NULL; 163 fibril_mutex_unlock(&nodep->lock); 164 fibril_mutex_unlock(&idxp_tmp->lock); 165 free(nodep->bp); 166 free(nodep); 167 return rc; 168 } 169 } 134 170 idxp_tmp->nodep = NULL; 135 171 fibril_mutex_unlock(&nodep->lock); … … 142 178 fn = (fs_node_t *)malloc(sizeof(fs_node_t)); 143 179 if (!fn) 144 return NULL;180 return ENOMEM; 145 181 nodep = (fat_node_t *)malloc(sizeof(fat_node_t)); 146 182 if (!nodep) { 147 183 free(fn); 148 return NULL;184 return ENOMEM; 149 185 } 150 186 } … … 154 190 nodep->bp = fn; 155 191 156 return nodep; 192 *nodepp = nodep; 193 return EOK; 157 194 } 158 195 … … 161 198 * @param idxp Locked index structure. 162 199 */ 163 static fat_node_t *fat_node_get_core(fat_idx_t *idxp)200 static int fat_node_get_core(fat_node_t **nodepp, fat_idx_t *idxp) 164 201 { 165 202 block_t *b; … … 170 207 unsigned spc; 171 208 unsigned dps; 209 int rc; 172 210 173 211 if (idxp->nodep) { … … 177 215 */ 178 216 fibril_mutex_lock(&idxp->nodep->lock); 179 if (!idxp->nodep->refcnt++) 217 if (!idxp->nodep->refcnt++) { 218 fibril_mutex_lock(&ffn_mutex); 180 219 list_remove(&idxp->nodep->ffn_link); 220 fibril_mutex_unlock(&ffn_mutex); 221 } 181 222 fibril_mutex_unlock(&idxp->nodep->lock); 182 return idxp->nodep; 223 *nodepp = idxp->nodep; 224 return EOK; 183 225 } 184 226 … … 189 231 assert(idxp->pfc); 190 232 191 nodep = fat_node_get_new();192 if ( !nodep)193 return NULL;233 rc = fat_node_get_new(&nodep); 234 if (rc != EOK) 235 return rc; 194 236 195 237 bs = block_bb_get(idxp->dev_handle); … … 199 241 200 242 /* Read the block that contains the dentry of interest. */ 201 b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,243 rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, 202 244 (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); 203 assert(b); 245 if (rc != EOK) { 246 (void) fat_node_put(FS_NODE(nodep)); 247 return rc; 248 } 204 249 205 250 d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps); … … 216 261 * size of the directory by walking the FAT. 217 262 */ 218 nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle, 263 uint16_t clusters; 264 rc = fat_clusters_get(&clusters, bs, idxp->dev_handle, 219 265 uint16_t_le2host(d->firstc)); 266 if (rc != EOK) { 267 (void) fat_node_put(FS_NODE(nodep)); 268 return rc; 269 } 270 nodep->size = bps * spc * clusters; 220 271 } else { 221 272 nodep->type = FAT_FILE; … … 226 277 nodep->refcnt = 1; 227 278 228 block_put(b); 279 rc = block_put(b); 280 if (rc != EOK) { 281 (void) fat_node_put(FS_NODE(nodep)); 282 return rc; 283 } 229 284 230 285 /* Link the idx structure with the node structure. */ … … 232 287 idxp->nodep = nodep; 233 288 234 return nodep; 235 } 236 237 /* 238 * Forward declarations of FAT libfs operations. 239 */ 240 static fs_node_t *fat_node_get(dev_handle_t, fs_index_t); 241 static void fat_node_put(fs_node_t *); 242 static fs_node_t *fat_create_node(dev_handle_t, int); 243 static int fat_destroy_node(fs_node_t *); 244 static int fat_link(fs_node_t *, fs_node_t *, const char *); 245 static int fat_unlink(fs_node_t *, fs_node_t *, const char *); 246 static fs_node_t *fat_match(fs_node_t *, const char *); 247 static fs_index_t fat_index_get(fs_node_t *); 248 static size_t fat_size_get(fs_node_t *); 249 static unsigned fat_lnkcnt_get(fs_node_t *); 250 static bool fat_has_children(fs_node_t *); 251 static fs_node_t *fat_root_get(dev_handle_t); 252 static char fat_plb_get_char(unsigned); 253 static bool fat_is_directory(fs_node_t *); 254 static bool fat_is_file(fs_node_t *node); 289 *nodepp = nodep; 290 return EOK; 291 } 255 292 256 293 /* … … 258 295 */ 259 296 260 /** Instantiate a FAT in-core node. */ 261 fs_node_t *fat_node_get(dev_handle_t dev_handle, fs_index_t index) 262 { 263 fat_node_t *nodep; 264 fat_idx_t *idxp; 265 266 idxp = fat_idx_get_by_index(dev_handle, index); 267 if (!idxp) 268 return NULL; 269 /* idxp->lock held */ 270 nodep = fat_node_get_core(idxp); 271 fibril_mutex_unlock(&idxp->lock); 272 return FS_NODE(nodep); 273 } 274 275 void fat_node_put(fs_node_t *fn) 276 { 277 fat_node_t *nodep = FAT_NODE(fn); 278 bool destroy = false; 279 280 fibril_mutex_lock(&nodep->lock); 281 if (!--nodep->refcnt) { 282 if (nodep->idx) { 283 fibril_mutex_lock(&ffn_mutex); 284 list_append(&nodep->ffn_link, &ffn_head); 285 fibril_mutex_unlock(&ffn_mutex); 286 } else { 287 /* 288 * The node does not have any index structure associated 289 * with itself. This can only mean that we are releasing 290 * the node after a failed attempt to allocate the index 291 * structure for it. 292 */ 293 destroy = true; 294 } 295 } 296 fibril_mutex_unlock(&nodep->lock); 297 if (destroy) { 298 free(nodep->bp); 299 free(nodep); 300 } 301 } 302 303 fs_node_t *fat_create_node(dev_handle_t dev_handle, int flags) 304 { 305 fat_idx_t *idxp; 306 fat_node_t *nodep; 307 fat_bs_t *bs; 308 fat_cluster_t mcl, lcl; 309 uint16_t bps; 310 int rc; 311 312 bs = block_bb_get(dev_handle); 313 bps = uint16_t_le2host(bs->bps); 314 if (flags & L_DIRECTORY) { 315 /* allocate a cluster */ 316 rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl); 317 if (rc != EOK) 318 return NULL; 319 } 320 321 nodep = fat_node_get_new(); 322 if (!nodep) { 323 fat_free_clusters(bs, dev_handle, mcl); 324 return NULL; 325 } 326 idxp = fat_idx_get_new(dev_handle); 327 if (!idxp) { 328 fat_free_clusters(bs, dev_handle, mcl); 329 fat_node_put(FS_NODE(nodep)); 330 return NULL; 331 } 332 /* idxp->lock held */ 333 if (flags & L_DIRECTORY) { 334 /* Populate the new cluster with unused dentries. */ 335 fat_zero_cluster(bs, dev_handle, mcl); 336 nodep->type = FAT_DIRECTORY; 337 nodep->firstc = mcl; 338 nodep->size = bps * bs->spc; 339 } else { 340 nodep->type = FAT_FILE; 341 nodep->firstc = FAT_CLST_RES0; 342 nodep->size = 0; 343 } 344 nodep->lnkcnt = 0; /* not linked anywhere */ 345 nodep->refcnt = 1; 346 nodep->dirty = true; 347 348 nodep->idx = idxp; 349 idxp->nodep = nodep; 350 351 fibril_mutex_unlock(&idxp->lock); 352 return FS_NODE(nodep); 353 } 354 355 int fat_destroy_node(fs_node_t *fn) 356 { 357 fat_node_t *nodep = FAT_NODE(fn); 358 fat_bs_t *bs; 359 360 /* 361 * The node is not reachable from the file system. This means that the 362 * link count should be zero and that the index structure cannot be 363 * found in the position hash. Obviously, we don't need to lock the node 364 * nor its index structure. 365 */ 366 assert(nodep->lnkcnt == 0); 367 368 /* 369 * The node may not have any children. 370 */ 371 assert(fat_has_children(fn) == false); 372 373 bs = block_bb_get(nodep->idx->dev_handle); 374 if (nodep->firstc != FAT_CLST_RES0) { 375 assert(nodep->size); 376 /* Free all clusters allocated to the node. */ 377 fat_free_clusters(bs, nodep->idx->dev_handle, nodep->firstc); 378 } 379 380 fat_idx_destroy(nodep->idx); 381 free(nodep->bp); 382 free(nodep); 383 return EOK; 384 } 385 386 int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 387 { 388 fat_node_t *parentp = FAT_NODE(pfn); 389 fat_node_t *childp = FAT_NODE(cfn); 390 fat_dentry_t *d; 391 fat_bs_t *bs; 392 block_t *b; 393 unsigned i, j; 394 uint16_t bps; 395 unsigned dps; 396 unsigned blocks; 397 fat_cluster_t mcl, lcl; 398 int rc; 399 400 fibril_mutex_lock(&childp->lock); 401 if (childp->lnkcnt == 1) { 402 /* 403 * On FAT, we don't support multiple hard links. 404 */ 405 fibril_mutex_unlock(&childp->lock); 406 return EMLINK; 407 } 408 assert(childp->lnkcnt == 0); 409 fibril_mutex_unlock(&childp->lock); 410 411 if (!fat_dentry_name_verify(name)) { 412 /* 413 * Attempt to create unsupported name. 414 */ 415 return ENOTSUP; 416 } 417 418 /* 419 * Get us an unused parent node's dentry or grow the parent and allocate 420 * a new one. 421 */ 422 423 fibril_mutex_lock(&parentp->idx->lock); 424 bs = block_bb_get(parentp->idx->dev_handle); 425 bps = uint16_t_le2host(bs->bps); 426 dps = bps / sizeof(fat_dentry_t); 427 428 blocks = parentp->size / bps; 429 430 for (i = 0; i < blocks; i++) { 431 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 432 for (j = 0; j < dps; j++) { 433 d = ((fat_dentry_t *)b->data) + j; 434 switch (fat_classify_dentry(d)) { 435 case FAT_DENTRY_SKIP: 436 case FAT_DENTRY_VALID: 437 /* skipping used and meta entries */ 438 continue; 439 case FAT_DENTRY_FREE: 440 case FAT_DENTRY_LAST: 441 /* found an empty slot */ 442 goto hit; 443 } 444 } 445 block_put(b); 446 } 447 j = 0; 448 449 /* 450 * We need to grow the parent in order to create a new unused dentry. 451 */ 452 if (parentp->firstc == FAT_CLST_ROOT) { 453 /* Can't grow the root directory. */ 454 fibril_mutex_unlock(&parentp->idx->lock); 455 return ENOSPC; 456 } 457 rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl); 458 if (rc != EOK) { 459 fibril_mutex_unlock(&parentp->idx->lock); 460 return rc; 461 } 462 fat_zero_cluster(bs, parentp->idx->dev_handle, mcl); 463 fat_append_clusters(bs, parentp, mcl); 464 parentp->size += bps * bs->spc; 465 parentp->dirty = true; /* need to sync node */ 466 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 467 d = (fat_dentry_t *)b->data; 468 469 hit: 470 /* 471 * At this point we only establish the link between the parent and the 472 * child. The dentry, except of the name and the extension, will remain 473 * uninitialized until the corresponding node is synced. Thus the valid 474 * dentry data is kept in the child node structure. 475 */ 476 memset(d, 0, sizeof(fat_dentry_t)); 477 fat_dentry_name_set(d, name); 478 b->dirty = true; /* need to sync block */ 479 block_put(b); 480 fibril_mutex_unlock(&parentp->idx->lock); 481 482 fibril_mutex_lock(&childp->idx->lock); 483 484 /* 485 * If possible, create the Sub-directory Identifier Entry and the 486 * Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries 487 * are not mandatory according to Standard ECMA-107 and HelenOS VFS does 488 * not use them anyway, so this is rather a sign of our good will. 489 */ 490 b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE); 491 d = (fat_dentry_t *)b->data; 492 if (fat_classify_dentry(d) == FAT_DENTRY_LAST || 493 str_cmp(d->name, FAT_NAME_DOT) == 0) { 494 memset(d, 0, sizeof(fat_dentry_t)); 495 str_cpy(d->name, 8, FAT_NAME_DOT); 496 str_cpy(d->ext, 3, FAT_EXT_PAD); 497 d->attr = FAT_ATTR_SUBDIR; 498 d->firstc = host2uint16_t_le(childp->firstc); 499 /* TODO: initialize also the date/time members. */ 500 } 501 d++; 502 if (fat_classify_dentry(d) == FAT_DENTRY_LAST || 503 str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) { 504 memset(d, 0, sizeof(fat_dentry_t)); 505 str_cpy(d->name, 8, FAT_NAME_DOT_DOT); 506 str_cpy(d->ext, 3, FAT_EXT_PAD); 507 d->attr = FAT_ATTR_SUBDIR; 508 d->firstc = (parentp->firstc == FAT_CLST_ROOT) ? 509 host2uint16_t_le(FAT_CLST_RES0) : 510 host2uint16_t_le(parentp->firstc); 511 /* TODO: initialize also the date/time members. */ 512 } 513 b->dirty = true; /* need to sync block */ 514 block_put(b); 515 516 childp->idx->pfc = parentp->firstc; 517 childp->idx->pdi = i * dps + j; 518 fibril_mutex_unlock(&childp->idx->lock); 519 520 fibril_mutex_lock(&childp->lock); 521 childp->lnkcnt = 1; 522 childp->dirty = true; /* need to sync node */ 523 fibril_mutex_unlock(&childp->lock); 524 525 /* 526 * Hash in the index structure into the position hash. 527 */ 528 fat_idx_hashin(childp->idx); 529 530 return EOK; 531 } 532 533 int fat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm) 534 { 535 fat_node_t *parentp = FAT_NODE(pfn); 536 fat_node_t *childp = FAT_NODE(cfn); 537 fat_bs_t *bs; 538 fat_dentry_t *d; 539 uint16_t bps; 540 block_t *b; 541 542 if (!parentp) 543 return EBUSY; 544 545 if (fat_has_children(cfn)) 546 return ENOTEMPTY; 547 548 fibril_mutex_lock(&parentp->lock); 549 fibril_mutex_lock(&childp->lock); 550 assert(childp->lnkcnt == 1); 551 fibril_mutex_lock(&childp->idx->lock); 552 bs = block_bb_get(childp->idx->dev_handle); 553 bps = uint16_t_le2host(bs->bps); 554 555 b = _fat_block_get(bs, childp->idx->dev_handle, childp->idx->pfc, 556 (childp->idx->pdi * sizeof(fat_dentry_t)) / bps, 557 BLOCK_FLAGS_NONE); 558 d = (fat_dentry_t *)b->data + 559 (childp->idx->pdi % (bps / sizeof(fat_dentry_t))); 560 /* mark the dentry as not-currently-used */ 561 d->name[0] = FAT_DENTRY_ERASED; 562 b->dirty = true; /* need to sync block */ 563 block_put(b); 564 565 /* remove the index structure from the position hash */ 566 fat_idx_hashout(childp->idx); 567 /* clear position information */ 568 childp->idx->pfc = FAT_CLST_RES0; 569 childp->idx->pdi = 0; 570 fibril_mutex_unlock(&childp->idx->lock); 571 childp->lnkcnt = 0; 572 childp->dirty = true; 573 fibril_mutex_unlock(&childp->lock); 574 fibril_mutex_unlock(&parentp->lock); 575 576 return EOK; 577 } 578 579 fs_node_t *fat_match(fs_node_t *pfn, const char *component) 297 int fat_root_get(fs_node_t **rfn, dev_handle_t dev_handle) 298 { 299 return fat_node_get(rfn, dev_handle, 0); 300 } 301 302 int fat_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 580 303 { 581 304 fat_bs_t *bs; … … 588 311 fat_dentry_t *d; 589 312 block_t *b; 313 int rc; 590 314 591 315 fibril_mutex_lock(&parentp->idx->lock); … … 595 319 blocks = parentp->size / bps; 596 320 for (i = 0; i < blocks; i++) { 597 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 321 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 322 if (rc != EOK) { 323 fibril_mutex_unlock(&parentp->idx->lock); 324 return rc; 325 } 598 326 for (j = 0; j < dps; j++) { 599 327 d = ((fat_dentry_t *)b->data) + j; … … 603 331 continue; 604 332 case FAT_DENTRY_LAST: 605 block_put(b); 333 /* miss */ 334 rc = block_put(b); 606 335 fibril_mutex_unlock(&parentp->idx->lock); 607 return NULL; 336 *rfn = NULL; 337 return rc; 608 338 default: 609 339 case FAT_DENTRY_VALID: … … 629 359 * run out of 32-bit indices. 630 360 */ 631 block_put(b);632 return NULL;361 rc = block_put(b); 362 return (rc == EOK) ? ENOMEM : rc; 633 363 } 634 nodep = fat_node_get_core(idx);364 rc = fat_node_get_core(&nodep, idx); 635 365 fibril_mutex_unlock(&idx->lock); 636 block_put(b); 637 return FS_NODE(nodep); 366 if (rc != EOK) { 367 (void) block_put(b); 368 return rc; 369 } 370 *rfn = FS_NODE(nodep); 371 rc = block_put(b); 372 if (rc != EOK) 373 (void) fat_node_put(*rfn); 374 return rc; 638 375 } 639 376 } 640 block_put(b); 377 rc = block_put(b); 378 if (rc != EOK) { 379 fibril_mutex_unlock(&parentp->idx->lock); 380 return rc; 381 } 641 382 } 642 383 643 384 fibril_mutex_unlock(&parentp->idx->lock); 644 return NULL; 645 } 646 647 fs_index_t fat_index_get(fs_node_t *fn) 648 { 649 return FAT_NODE(fn)->idx->index; 650 } 651 652 size_t fat_size_get(fs_node_t *fn) 653 { 654 return FAT_NODE(fn)->size; 655 } 656 657 unsigned fat_lnkcnt_get(fs_node_t *fn) 658 { 659 return FAT_NODE(fn)->lnkcnt; 660 } 661 662 bool fat_has_children(fs_node_t *fn) 385 *rfn = NULL; 386 return EOK; 387 } 388 389 /** Instantiate a FAT in-core node. */ 390 int fat_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index) 391 { 392 fat_node_t *nodep; 393 fat_idx_t *idxp; 394 int rc; 395 396 idxp = fat_idx_get_by_index(dev_handle, index); 397 if (!idxp) { 398 *rfn = NULL; 399 return EOK; 400 } 401 /* idxp->lock held */ 402 rc = fat_node_get_core(&nodep, idxp); 403 fibril_mutex_unlock(&idxp->lock); 404 if (rc == EOK) 405 *rfn = FS_NODE(nodep); 406 return rc; 407 } 408 409 int fat_node_put(fs_node_t *fn) 410 { 411 fat_node_t *nodep = FAT_NODE(fn); 412 bool destroy = false; 413 414 fibril_mutex_lock(&nodep->lock); 415 if (!--nodep->refcnt) { 416 if (nodep->idx) { 417 fibril_mutex_lock(&ffn_mutex); 418 list_append(&nodep->ffn_link, &ffn_head); 419 fibril_mutex_unlock(&ffn_mutex); 420 } else { 421 /* 422 * The node does not have any index structure associated 423 * with itself. This can only mean that we are releasing 424 * the node after a failed attempt to allocate the index 425 * structure for it. 426 */ 427 destroy = true; 428 } 429 } 430 fibril_mutex_unlock(&nodep->lock); 431 if (destroy) { 432 free(nodep->bp); 433 free(nodep); 434 } 435 return EOK; 436 } 437 438 int fat_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int flags) 439 { 440 fat_idx_t *idxp; 441 fat_node_t *nodep; 442 fat_bs_t *bs; 443 fat_cluster_t mcl, lcl; 444 uint16_t bps; 445 int rc; 446 447 bs = block_bb_get(dev_handle); 448 bps = uint16_t_le2host(bs->bps); 449 if (flags & L_DIRECTORY) { 450 /* allocate a cluster */ 451 rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl); 452 if (rc != EOK) 453 return rc; 454 /* populate the new cluster with unused dentries */ 455 rc = fat_zero_cluster(bs, dev_handle, mcl); 456 if (rc != EOK) { 457 (void) fat_free_clusters(bs, dev_handle, mcl); 458 return rc; 459 } 460 } 461 462 rc = fat_node_get_new(&nodep); 463 if (rc != EOK) { 464 (void) fat_free_clusters(bs, dev_handle, mcl); 465 return rc; 466 } 467 rc = fat_idx_get_new(&idxp, dev_handle); 468 if (rc != EOK) { 469 (void) fat_free_clusters(bs, dev_handle, mcl); 470 (void) fat_node_put(FS_NODE(nodep)); 471 return rc; 472 } 473 /* idxp->lock held */ 474 if (flags & L_DIRECTORY) { 475 nodep->type = FAT_DIRECTORY; 476 nodep->firstc = mcl; 477 nodep->size = bps * bs->spc; 478 } else { 479 nodep->type = FAT_FILE; 480 nodep->firstc = FAT_CLST_RES0; 481 nodep->size = 0; 482 } 483 nodep->lnkcnt = 0; /* not linked anywhere */ 484 nodep->refcnt = 1; 485 nodep->dirty = true; 486 487 nodep->idx = idxp; 488 idxp->nodep = nodep; 489 490 fibril_mutex_unlock(&idxp->lock); 491 *rfn = FS_NODE(nodep); 492 return EOK; 493 } 494 495 int fat_destroy_node(fs_node_t *fn) 496 { 497 fat_node_t *nodep = FAT_NODE(fn); 498 fat_bs_t *bs; 499 bool has_children; 500 int rc; 501 502 /* 503 * The node is not reachable from the file system. This means that the 504 * link count should be zero and that the index structure cannot be 505 * found in the position hash. Obviously, we don't need to lock the node 506 * nor its index structure. 507 */ 508 assert(nodep->lnkcnt == 0); 509 510 /* 511 * The node may not have any children. 512 */ 513 rc = fat_has_children(&has_children, fn); 514 if (rc != EOK) 515 return rc; 516 assert(!has_children); 517 518 bs = block_bb_get(nodep->idx->dev_handle); 519 if (nodep->firstc != FAT_CLST_RES0) { 520 assert(nodep->size); 521 /* Free all clusters allocated to the node. */ 522 rc = fat_free_clusters(bs, nodep->idx->dev_handle, 523 nodep->firstc); 524 } 525 526 fat_idx_destroy(nodep->idx); 527 free(nodep->bp); 528 free(nodep); 529 return rc; 530 } 531 532 int fat_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 533 { 534 fat_node_t *parentp = FAT_NODE(pfn); 535 fat_node_t *childp = FAT_NODE(cfn); 536 fat_dentry_t *d; 537 fat_bs_t *bs; 538 block_t *b; 539 unsigned i, j; 540 uint16_t bps; 541 unsigned dps; 542 unsigned blocks; 543 fat_cluster_t mcl, lcl; 544 int rc; 545 546 fibril_mutex_lock(&childp->lock); 547 if (childp->lnkcnt == 1) { 548 /* 549 * On FAT, we don't support multiple hard links. 550 */ 551 fibril_mutex_unlock(&childp->lock); 552 return EMLINK; 553 } 554 assert(childp->lnkcnt == 0); 555 fibril_mutex_unlock(&childp->lock); 556 557 if (!fat_dentry_name_verify(name)) { 558 /* 559 * Attempt to create unsupported name. 560 */ 561 return ENOTSUP; 562 } 563 564 /* 565 * Get us an unused parent node's dentry or grow the parent and allocate 566 * a new one. 567 */ 568 569 fibril_mutex_lock(&parentp->idx->lock); 570 bs = block_bb_get(parentp->idx->dev_handle); 571 bps = uint16_t_le2host(bs->bps); 572 dps = bps / sizeof(fat_dentry_t); 573 574 blocks = parentp->size / bps; 575 576 for (i = 0; i < blocks; i++) { 577 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 578 if (rc != EOK) { 579 fibril_mutex_unlock(&parentp->idx->lock); 580 return rc; 581 } 582 for (j = 0; j < dps; j++) { 583 d = ((fat_dentry_t *)b->data) + j; 584 switch (fat_classify_dentry(d)) { 585 case FAT_DENTRY_SKIP: 586 case FAT_DENTRY_VALID: 587 /* skipping used and meta entries */ 588 continue; 589 case FAT_DENTRY_FREE: 590 case FAT_DENTRY_LAST: 591 /* found an empty slot */ 592 goto hit; 593 } 594 } 595 rc = block_put(b); 596 if (rc != EOK) { 597 fibril_mutex_unlock(&parentp->idx->lock); 598 return rc; 599 } 600 } 601 j = 0; 602 603 /* 604 * We need to grow the parent in order to create a new unused dentry. 605 */ 606 if (parentp->firstc == FAT_CLST_ROOT) { 607 /* Can't grow the root directory. */ 608 fibril_mutex_unlock(&parentp->idx->lock); 609 return ENOSPC; 610 } 611 rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl); 612 if (rc != EOK) { 613 fibril_mutex_unlock(&parentp->idx->lock); 614 return rc; 615 } 616 rc = fat_zero_cluster(bs, parentp->idx->dev_handle, mcl); 617 if (rc != EOK) { 618 (void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl); 619 fibril_mutex_unlock(&parentp->idx->lock); 620 return rc; 621 } 622 rc = fat_append_clusters(bs, parentp, mcl); 623 if (rc != EOK) { 624 (void) fat_free_clusters(bs, parentp->idx->dev_handle, mcl); 625 fibril_mutex_unlock(&parentp->idx->lock); 626 return rc; 627 } 628 parentp->size += bps * bs->spc; 629 parentp->dirty = true; /* need to sync node */ 630 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 631 if (rc != EOK) { 632 fibril_mutex_unlock(&parentp->idx->lock); 633 return rc; 634 } 635 d = (fat_dentry_t *)b->data; 636 637 hit: 638 /* 639 * At this point we only establish the link between the parent and the 640 * child. The dentry, except of the name and the extension, will remain 641 * uninitialized until the corresponding node is synced. Thus the valid 642 * dentry data is kept in the child node structure. 643 */ 644 memset(d, 0, sizeof(fat_dentry_t)); 645 fat_dentry_name_set(d, name); 646 b->dirty = true; /* need to sync block */ 647 rc = block_put(b); 648 fibril_mutex_unlock(&parentp->idx->lock); 649 if (rc != EOK) 650 return rc; 651 652 fibril_mutex_lock(&childp->idx->lock); 653 654 /* 655 * If possible, create the Sub-directory Identifier Entry and the 656 * Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries 657 * are not mandatory according to Standard ECMA-107 and HelenOS VFS does 658 * not use them anyway, so this is rather a sign of our good will. 659 */ 660 rc = fat_block_get(&b, bs, childp, 0, BLOCK_FLAGS_NONE); 661 if (rc != EOK) { 662 /* 663 * Rather than returning an error, simply skip the creation of 664 * these two entries. 665 */ 666 goto skip_dots; 667 } 668 d = (fat_dentry_t *)b->data; 669 if (fat_classify_dentry(d) == FAT_DENTRY_LAST || 670 str_cmp(d->name, FAT_NAME_DOT) == 0) { 671 memset(d, 0, sizeof(fat_dentry_t)); 672 str_cpy(d->name, 8, FAT_NAME_DOT); 673 str_cpy(d->ext, 3, FAT_EXT_PAD); 674 d->attr = FAT_ATTR_SUBDIR; 675 d->firstc = host2uint16_t_le(childp->firstc); 676 /* TODO: initialize also the date/time members. */ 677 } 678 d++; 679 if (fat_classify_dentry(d) == FAT_DENTRY_LAST || 680 str_cmp(d->name, FAT_NAME_DOT_DOT) == 0) { 681 memset(d, 0, sizeof(fat_dentry_t)); 682 str_cpy(d->name, 8, FAT_NAME_DOT_DOT); 683 str_cpy(d->ext, 3, FAT_EXT_PAD); 684 d->attr = FAT_ATTR_SUBDIR; 685 d->firstc = (parentp->firstc == FAT_CLST_ROOT) ? 686 host2uint16_t_le(FAT_CLST_RES0) : 687 host2uint16_t_le(parentp->firstc); 688 /* TODO: initialize also the date/time members. */ 689 } 690 b->dirty = true; /* need to sync block */ 691 /* 692 * Ignore the return value as we would have fallen through on error 693 * anyway. 694 */ 695 (void) block_put(b); 696 skip_dots: 697 698 childp->idx->pfc = parentp->firstc; 699 childp->idx->pdi = i * dps + j; 700 fibril_mutex_unlock(&childp->idx->lock); 701 702 fibril_mutex_lock(&childp->lock); 703 childp->lnkcnt = 1; 704 childp->dirty = true; /* need to sync node */ 705 fibril_mutex_unlock(&childp->lock); 706 707 /* 708 * Hash in the index structure into the position hash. 709 */ 710 fat_idx_hashin(childp->idx); 711 712 return EOK; 713 } 714 715 int fat_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *nm) 716 { 717 fat_node_t *parentp = FAT_NODE(pfn); 718 fat_node_t *childp = FAT_NODE(cfn); 719 fat_bs_t *bs; 720 fat_dentry_t *d; 721 uint16_t bps; 722 block_t *b; 723 bool has_children; 724 int rc; 725 726 if (!parentp) 727 return EBUSY; 728 729 rc = fat_has_children(&has_children, cfn); 730 if (rc != EOK) 731 return rc; 732 if (has_children) 733 return ENOTEMPTY; 734 735 fibril_mutex_lock(&parentp->lock); 736 fibril_mutex_lock(&childp->lock); 737 assert(childp->lnkcnt == 1); 738 fibril_mutex_lock(&childp->idx->lock); 739 bs = block_bb_get(childp->idx->dev_handle); 740 bps = uint16_t_le2host(bs->bps); 741 742 rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc, 743 (childp->idx->pdi * sizeof(fat_dentry_t)) / bps, 744 BLOCK_FLAGS_NONE); 745 if (rc != EOK) 746 goto error; 747 d = (fat_dentry_t *)b->data + 748 (childp->idx->pdi % (bps / sizeof(fat_dentry_t))); 749 /* mark the dentry as not-currently-used */ 750 d->name[0] = FAT_DENTRY_ERASED; 751 b->dirty = true; /* need to sync block */ 752 rc = block_put(b); 753 if (rc != EOK) 754 goto error; 755 756 /* remove the index structure from the position hash */ 757 fat_idx_hashout(childp->idx); 758 /* clear position information */ 759 childp->idx->pfc = FAT_CLST_RES0; 760 childp->idx->pdi = 0; 761 fibril_mutex_unlock(&childp->idx->lock); 762 childp->lnkcnt = 0; 763 childp->dirty = true; 764 fibril_mutex_unlock(&childp->lock); 765 fibril_mutex_unlock(&parentp->lock); 766 767 return EOK; 768 769 error: 770 fibril_mutex_unlock(&parentp->idx->lock); 771 fibril_mutex_unlock(&childp->lock); 772 fibril_mutex_unlock(&childp->idx->lock); 773 return rc; 774 } 775 776 int fat_has_children(bool *has_children, fs_node_t *fn) 663 777 { 664 778 fat_bs_t *bs; … … 669 783 block_t *b; 670 784 unsigned i, j; 671 672 if (nodep->type != FAT_DIRECTORY) 673 return false; 785 int rc; 786 787 if (nodep->type != FAT_DIRECTORY) { 788 *has_children = false; 789 return EOK; 790 } 674 791 675 792 fibril_mutex_lock(&nodep->idx->lock); … … 683 800 fat_dentry_t *d; 684 801 685 b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE); 802 rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE); 803 if (rc != EOK) { 804 fibril_mutex_unlock(&nodep->idx->lock); 805 return rc; 806 } 686 807 for (j = 0; j < dps; j++) { 687 808 d = ((fat_dentry_t *)b->data) + j; … … 691 812 continue; 692 813 case FAT_DENTRY_LAST: 693 block_put(b);814 rc = block_put(b); 694 815 fibril_mutex_unlock(&nodep->idx->lock); 695 return false; 816 *has_children = false; 817 return rc; 696 818 default: 697 819 case FAT_DENTRY_VALID: 698 block_put(b);820 rc = block_put(b); 699 821 fibril_mutex_unlock(&nodep->idx->lock); 700 return true; 822 *has_children = true; 823 return rc; 701 824 } 702 block_put(b); 825 } 826 rc = block_put(b); 827 if (rc != EOK) { 703 828 fibril_mutex_unlock(&nodep->idx->lock); 704 return true; 705 } 706 block_put(b); 829 return rc; 830 } 707 831 } 708 832 709 833 fibril_mutex_unlock(&nodep->idx->lock); 710 return false; 711 } 712 713 fs_node_t *fat_root_get(dev_handle_t dev_handle) 714 { 715 return fat_node_get(dev_handle, 0); 834 *has_children = false; 835 return EOK; 836 } 837 838 839 fs_index_t fat_index_get(fs_node_t *fn) 840 { 841 return FAT_NODE(fn)->idx->index; 842 } 843 844 size_t fat_size_get(fs_node_t *fn) 845 { 846 return FAT_NODE(fn)->size; 847 } 848 849 unsigned fat_lnkcnt_get(fs_node_t *fn) 850 { 851 return FAT_NODE(fn)->lnkcnt; 716 852 } 717 853 … … 733 869 /** libfs operations */ 734 870 libfs_ops_t fat_libfs_ops = { 871 .root_get = fat_root_get, 735 872 .match = fat_match, 736 873 .node_get = fat_node_get, … … 740 877 .link = fat_link, 741 878 .unlink = fat_unlink, 879 .has_children = fat_has_children, 742 880 .index_get = fat_index_get, 743 881 .size_get = fat_size_get, 744 882 .lnkcnt_get = fat_lnkcnt_get, 745 .has_children = fat_has_children,746 .root_get = fat_root_get,747 883 .plb_get_char = fat_plb_get_char, 748 884 .is_directory = fat_is_directory, … … 766 902 ipc_callid_t callid; 767 903 size_t size; 768 if (! ipc_data_write_receive(&callid, &size)) {904 if (!async_data_write_receive(&callid, &size)) { 769 905 ipc_answer_0(callid, EINVAL); 770 906 ipc_answer_0(rid, EINVAL); … … 777 913 return; 778 914 } 779 ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);915 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 780 916 if (retval != EOK) { 781 917 ipc_answer_0(rid, retval); … … 799 935 800 936 /* prepare the boot block */ 801 rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE);937 rc = block_bb_read(dev_handle, BS_BLOCK); 802 938 if (rc != EOK) { 803 939 block_fini(dev_handle); … … 895 1031 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 896 1032 off_t pos = (off_t)IPC_GET_ARG3(*request); 897 fs_node_t *fn = fat_node_get(dev_handle, index);1033 fs_node_t *fn; 898 1034 fat_node_t *nodep; 899 1035 fat_bs_t *bs; … … 901 1037 size_t bytes; 902 1038 block_t *b; 903 1039 int rc; 1040 1041 rc = fat_node_get(&fn, dev_handle, index); 1042 if (rc != EOK) { 1043 ipc_answer_0(rid, rc); 1044 return; 1045 } 904 1046 if (!fn) { 905 1047 ipc_answer_0(rid, ENOENT); … … 910 1052 ipc_callid_t callid; 911 1053 size_t len; 912 if (! ipc_data_read_receive(&callid, &len)) {1054 if (!async_data_read_receive(&callid, &len)) { 913 1055 fat_node_put(fn); 914 1056 ipc_answer_0(callid, EINVAL); … … 929 1071 /* reading beyond the EOF */ 930 1072 bytes = 0; 931 (void) ipc_data_read_finalize(callid, NULL, 0);1073 (void) async_data_read_finalize(callid, NULL, 0); 932 1074 } else { 933 1075 bytes = min(len, bps - pos % bps); 934 1076 bytes = min(bytes, nodep->size - pos); 935 b = fat_block_get(bs, nodep, pos / bps,1077 rc = fat_block_get(&b, bs, nodep, pos / bps, 936 1078 BLOCK_FLAGS_NONE); 937 (void) ipc_data_read_finalize(callid, b->data + pos % bps, 1079 if (rc != EOK) { 1080 fat_node_put(fn); 1081 ipc_answer_0(callid, rc); 1082 ipc_answer_0(rid, rc); 1083 return; 1084 } 1085 (void) async_data_read_finalize(callid, b->data + pos % bps, 938 1086 bytes); 939 block_put(b); 1087 rc = block_put(b); 1088 if (rc != EOK) { 1089 fat_node_put(fn); 1090 ipc_answer_0(rid, rc); 1091 return; 1092 } 940 1093 } 941 1094 } else { … … 959 1112 off_t o; 960 1113 961 b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE); 1114 rc = fat_block_get(&b, bs, nodep, bnum, 1115 BLOCK_FLAGS_NONE); 1116 if (rc != EOK) 1117 goto err; 962 1118 for (o = pos % (bps / sizeof(fat_dentry_t)); 963 1119 o < bps / sizeof(fat_dentry_t); … … 969 1125 continue; 970 1126 case FAT_DENTRY_LAST: 971 block_put(b); 1127 rc = block_put(b); 1128 if (rc != EOK) 1129 goto err; 972 1130 goto miss; 973 1131 default: 974 1132 case FAT_DENTRY_VALID: 975 1133 fat_dentry_name_get(d, name); 976 block_put(b); 1134 rc = block_put(b); 1135 if (rc != EOK) 1136 goto err; 977 1137 goto hit; 978 1138 } 979 1139 } 980 block_put(b); 1140 rc = block_put(b); 1141 if (rc != EOK) 1142 goto err; 981 1143 bnum++; 982 1144 } 983 1145 miss: 984 fat_node_put(fn); 985 ipc_answer_0(callid, ENOENT); 986 ipc_answer_1(rid, ENOENT, 0); 987 return; 1146 rc = fat_node_put(fn); 1147 ipc_answer_0(callid, rc != EOK ? rc : ENOENT); 1148 ipc_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1149 return; 1150 1151 err: 1152 (void) fat_node_put(fn); 1153 ipc_answer_0(callid, rc); 1154 ipc_answer_0(rid, rc); 1155 return; 1156 988 1157 hit: 989 (void) ipc_data_read_finalize(callid, name, str_size(name) + 1);1158 (void) async_data_read_finalize(callid, name, str_size(name) + 1); 990 1159 bytes = (pos - spos) + 1; 991 1160 } 992 1161 993 fat_node_put(fn);994 ipc_answer_1(rid, EOK, (ipcarg_t)bytes);1162 rc = fat_node_put(fn); 1163 ipc_answer_1(rid, rc, (ipcarg_t)bytes); 995 1164 } 996 1165 … … 1000 1169 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1001 1170 off_t pos = (off_t)IPC_GET_ARG3(*request); 1002 fs_node_t *fn = fat_node_get(dev_handle, index);1171 fs_node_t *fn; 1003 1172 fat_node_t *nodep; 1004 1173 fat_bs_t *bs; 1005 size_t bytes ;1174 size_t bytes, size; 1006 1175 block_t *b; 1007 1176 uint16_t bps; … … 1010 1179 off_t boundary; 1011 1180 int flags = BLOCK_FLAGS_NONE; 1012 1181 int rc; 1182 1183 rc = fat_node_get(&fn, dev_handle, index); 1184 if (rc != EOK) { 1185 ipc_answer_0(rid, rc); 1186 return; 1187 } 1013 1188 if (!fn) { 1014 1189 ipc_answer_0(rid, ENOENT); … … 1019 1194 ipc_callid_t callid; 1020 1195 size_t len; 1021 if (! ipc_data_write_receive(&callid, &len)) {1022 fat_node_put(fn);1196 if (!async_data_write_receive(&callid, &len)) { 1197 (void) fat_node_put(fn); 1023 1198 ipc_answer_0(callid, EINVAL); 1024 1199 ipc_answer_0(rid, EINVAL); … … 1050 1225 * next block size boundary. 1051 1226 */ 1052 fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); 1053 b = fat_block_get(bs, nodep, pos / bps, flags); 1054 (void) ipc_data_write_finalize(callid, b->data + pos % bps, 1227 rc = fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); 1228 if (rc != EOK) { 1229 (void) fat_node_put(fn); 1230 ipc_answer_0(callid, rc); 1231 ipc_answer_0(rid, rc); 1232 return; 1233 } 1234 rc = fat_block_get(&b, bs, nodep, pos / bps, flags); 1235 if (rc != EOK) { 1236 (void) fat_node_put(fn); 1237 ipc_answer_0(callid, rc); 1238 ipc_answer_0(rid, rc); 1239 return; 1240 } 1241 (void) async_data_write_finalize(callid, b->data + pos % bps, 1055 1242 bytes); 1056 1243 b->dirty = true; /* need to sync block */ 1057 block_put(b); 1244 rc = block_put(b); 1245 if (rc != EOK) { 1246 (void) fat_node_put(fn); 1247 ipc_answer_0(rid, rc); 1248 return; 1249 } 1058 1250 if (pos + bytes > nodep->size) { 1059 1251 nodep->size = pos + bytes; 1060 1252 nodep->dirty = true; /* need to sync node */ 1061 1253 } 1062 ipc_answer_2(rid, EOK, bytes, nodep->size); 1063 fat_node_put(fn); 1254 size = nodep->size; 1255 rc = fat_node_put(fn); 1256 ipc_answer_2(rid, rc, bytes, nodep->size); 1064 1257 return; 1065 1258 } else { … … 1068 1261 * clusters for the node and zero them out. 1069 1262 */ 1070 int status;1071 1263 unsigned nclsts; 1072 1264 fat_cluster_t mcl, lcl; … … 1074 1266 nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc; 1075 1267 /* create an independent chain of nclsts clusters in all FATs */ 1076 status= fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl);1077 if ( status!= EOK) {1268 rc = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl); 1269 if (rc != EOK) { 1078 1270 /* could not allocate a chain of nclsts clusters */ 1079 fat_node_put(fn);1080 ipc_answer_0(callid, status);1081 ipc_answer_0(rid, status);1271 (void) fat_node_put(fn); 1272 ipc_answer_0(callid, rc); 1273 ipc_answer_0(rid, rc); 1082 1274 return; 1083 1275 } 1084 1276 /* zero fill any gaps */ 1085 fat_fill_gap(bs, nodep, mcl, pos); 1086 b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc, 1277 rc = fat_fill_gap(bs, nodep, mcl, pos); 1278 if (rc != EOK) { 1279 (void) fat_free_clusters(bs, dev_handle, mcl); 1280 (void) fat_node_put(fn); 1281 ipc_answer_0(callid, rc); 1282 ipc_answer_0(rid, rc); 1283 return; 1284 } 1285 rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc, 1087 1286 flags); 1088 (void) ipc_data_write_finalize(callid, b->data + pos % bps, 1287 if (rc != EOK) { 1288 (void) fat_free_clusters(bs, dev_handle, mcl); 1289 (void) fat_node_put(fn); 1290 ipc_answer_0(callid, rc); 1291 ipc_answer_0(rid, rc); 1292 return; 1293 } 1294 (void) async_data_write_finalize(callid, b->data + pos % bps, 1089 1295 bytes); 1090 1296 b->dirty = true; /* need to sync block */ 1091 block_put(b); 1297 rc = block_put(b); 1298 if (rc != EOK) { 1299 (void) fat_free_clusters(bs, dev_handle, mcl); 1300 (void) fat_node_put(fn); 1301 ipc_answer_0(rid, rc); 1302 return; 1303 } 1092 1304 /* 1093 1305 * Append the cluster chain starting in mcl to the end of the 1094 1306 * node's cluster chain. 1095 1307 */ 1096 fat_append_clusters(bs, nodep, mcl); 1097 nodep->size = pos + bytes; 1308 rc = fat_append_clusters(bs, nodep, mcl); 1309 if (rc != EOK) { 1310 (void) fat_free_clusters(bs, dev_handle, mcl); 1311 (void) fat_node_put(fn); 1312 ipc_answer_0(rid, rc); 1313 return; 1314 } 1315 nodep->size = size = pos + bytes; 1098 1316 nodep->dirty = true; /* need to sync node */ 1099 ipc_answer_2(rid, EOK, bytes, nodep->size);1100 fat_node_put(fn);1317 rc = fat_node_put(fn); 1318 ipc_answer_2(rid, rc, bytes, size); 1101 1319 return; 1102 1320 } … … 1108 1326 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1109 1327 size_t size = (off_t)IPC_GET_ARG3(*request); 1110 fs_node_t *fn = fat_node_get(dev_handle, index);1328 fs_node_t *fn; 1111 1329 fat_node_t *nodep; 1112 1330 fat_bs_t *bs; … … 1116 1334 int rc; 1117 1335 1336 rc = fat_node_get(&fn, dev_handle, index); 1337 if (rc != EOK) { 1338 ipc_answer_0(rid, rc); 1339 return; 1340 } 1118 1341 if (!fn) { 1119 1342 ipc_answer_0(rid, ENOENT); … … 1147 1370 */ 1148 1371 if (size == 0) { 1149 fat_chop_clusters(bs, nodep, FAT_CLST_RES0); 1372 rc = fat_chop_clusters(bs, nodep, FAT_CLST_RES0); 1373 if (rc != EOK) 1374 goto out; 1150 1375 } else { 1151 1376 fat_cluster_t lastc; 1152 (void) fat_cluster_walk(bs, dev_handle, nodep->firstc, 1153 &lastc, (size - 1) / bpc); 1154 fat_chop_clusters(bs, nodep, lastc); 1377 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, 1378 &lastc, NULL, (size - 1) / bpc); 1379 if (rc != EOK) 1380 goto out; 1381 rc = fat_chop_clusters(bs, nodep, lastc); 1382 if (rc != EOK) 1383 goto out; 1155 1384 } 1156 1385 nodep->size = size; … … 1158 1387 rc = EOK; 1159 1388 } 1389 out: 1160 1390 fat_node_put(fn); 1161 1391 ipc_answer_0(rid, rc); … … 1172 1402 dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); 1173 1403 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1404 fs_node_t *fn; 1174 1405 int rc; 1175 1406 1176 fs_node_t *fn = fat_node_get(dev_handle, index); 1407 rc = fat_node_get(&fn, dev_handle, index); 1408 if (rc != EOK) { 1409 ipc_answer_0(rid, rc); 1410 return; 1411 } 1177 1412 if (!fn) { 1178 1413 ipc_answer_0(rid, ENOENT); -
uspace/srv/fs/tmpfs/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 2006 Martin Decky 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../../lib/libc 33 LIBFS_PREFIX = ../../../lib/libfs 34 LIBBLOCK_PREFIX = ../../../lib/libblock 35 SOFTINT_PREFIX = ../../../lib/softint 32 .PHONY: all clean 36 33 37 include $(LIBC_PREFIX)/Makefile.toolchain 38 39 CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) 40 41 LIBS = \ 42 $(LIBFS_PREFIX)/libfs.a \ 43 $(LIBBLOCK_PREFIX)/libblock.a \ 44 $(LIBC_PREFIX)/libc.a 45 46 ## Sources 47 # 48 49 OUTPUT = tmpfs 50 SOURCES = \ 51 tmpfs.c \ 52 tmpfs_ops.c \ 53 tmpfs_dump.c 54 55 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 56 57 .PHONY: all clean depend disasm 58 59 all: $(OUTPUT) $(OUTPUT).disasm 60 61 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 62 37 63 38 clean: 64 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 65 66 depend: 67 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 68 69 $(OUTPUT): $(OBJECTS) $(LIBS) 70 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 71 72 disasm: $(OUTPUT).disasm 73 74 $(OUTPUT).disasm: $(OUTPUT) 75 $(OBJDUMP) -d $< > $@ 76 77 %.o: %.S 78 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 79 80 %.o: %.s 81 $(AS) $(AFLAGS) $< -o $@ 82 83 %.o: %.c 84 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/fs/tmpfs/tmpfs.c
rfcbd1be r1787e527 48 48 #include <unistd.h> 49 49 #include <stdio.h> 50 #include <task.h> 50 51 #include <libfs.h> 51 52 #include "../../vfs/vfs.h" … … 55 56 56 57 vfs_info_t tmpfs_vfs_info = { 57 .name = "tmpfs",58 .name = NAME, 58 59 }; 59 60 … … 90 91 } 91 92 92 dprintf( "VFS-TMPFS connection established.\n");93 dprintf(NAME ": connection opened\n"); 93 94 while (1) { 94 95 ipc_callid_t callid; … … 162 163 163 164 printf(NAME ": Accepting connections\n"); 165 task_retval(0); 164 166 async_manager(); 165 167 /* not reached */ -
uspace/srv/fs/tmpfs/tmpfs_dump.c
rfcbd1be r1787e527 47 47 #include <byteorder.h> 48 48 49 #define TMPFS_ BLOCK_SIZE102449 #define TMPFS_COMM_SIZE 1024 50 50 51 51 struct rdentry { … … 69 69 70 70 if (block_seqread(dev, bufpos, buflen, pos, &entry, 71 sizeof(entry) , TMPFS_BLOCK_SIZE) != EOK)71 sizeof(entry)) != EOK) 72 72 return false; 73 73 … … 82 82 return false; 83 83 84 fn = ops->create(dev, L_FILE);85 if ( fn == NULL) {84 rc = ops->create(&fn, dev, L_FILE); 85 if (rc != EOK || fn == NULL) { 86 86 free(fname); 87 87 return false; … … 89 89 90 90 if (block_seqread(dev, bufpos, buflen, pos, fname, 91 entry.len , TMPFS_BLOCK_SIZE) != EOK) {92 ops->destroy(fn);91 entry.len) != EOK) { 92 (void) ops->destroy(fn); 93 93 free(fname); 94 94 return false; … … 98 98 rc = ops->link(pfn, fn, fname); 99 99 if (rc != EOK) { 100 ops->destroy(fn);100 (void) ops->destroy(fn); 101 101 free(fname); 102 102 return false; … … 105 105 106 106 if (block_seqread(dev, bufpos, buflen, pos, &size, 107 sizeof(size) , TMPFS_BLOCK_SIZE) != EOK)107 sizeof(size)) != EOK) 108 108 return false; 109 109 … … 117 117 nodep->size = size; 118 118 if (block_seqread(dev, bufpos, buflen, pos, nodep->data, 119 size , TMPFS_BLOCK_SIZE) != EOK)119 size) != EOK) 120 120 return false; 121 121 … … 126 126 return false; 127 127 128 fn = ops->create(dev, L_DIRECTORY);129 if ( fn == NULL) {128 rc = ops->create(&fn, dev, L_DIRECTORY); 129 if (rc != EOK || fn == NULL) { 130 130 free(fname); 131 131 return false; … … 133 133 134 134 if (block_seqread(dev, bufpos, buflen, pos, fname, 135 entry.len , TMPFS_BLOCK_SIZE) != EOK) {136 ops->destroy(fn);135 entry.len) != EOK) { 136 (void) ops->destroy(fn); 137 137 free(fname); 138 138 return false; … … 142 142 rc = ops->link(pfn, fn, fname); 143 143 if (rc != EOK) { 144 ops->destroy(fn);144 (void) ops->destroy(fn); 145 145 free(fname); 146 146 return false; … … 164 164 { 165 165 libfs_ops_t *ops = &tmpfs_libfs_ops; 166 fs_node_t *fn; 166 167 int rc; 167 168 168 rc = block_init(dev, TMPFS_ BLOCK_SIZE);169 rc = block_init(dev, TMPFS_COMM_SIZE); 169 170 if (rc != EOK) 170 171 return false; … … 175 176 176 177 char tag[6]; 177 if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5, 178 TMPFS_BLOCK_SIZE) != EOK) 178 if (block_seqread(dev, &bufpos, &buflen, &pos, tag, 5) != EOK) 179 179 goto error; 180 180 … … 183 183 goto error; 184 184 185 if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos, 186 ops->root_get(dev))) 185 rc = ops->root_get(&fn, dev); 186 if (rc != EOK) 187 goto error; 188 189 if (!tmpfs_restore_recursion(dev, &bufpos, &buflen, &pos, fn)) 187 190 goto error; 188 191 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
rfcbd1be r1787e527 67 67 68 68 /* Forward declarations of static functions. */ 69 static fs_node_t *tmpfs_match(fs_node_t *, const char *); 70 static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t); 71 static void tmpfs_node_put(fs_node_t *); 72 static fs_node_t *tmpfs_create_node(dev_handle_t, int); 69 static int tmpfs_match(fs_node_t **, fs_node_t *, const char *); 70 static int tmpfs_node_get(fs_node_t **, dev_handle_t, fs_index_t); 71 static int tmpfs_node_put(fs_node_t *); 72 static int tmpfs_create_node(fs_node_t **, dev_handle_t, int); 73 static int tmpfs_destroy_node(fs_node_t *); 73 74 static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *); 74 75 static int tmpfs_unlink_node(fs_node_t *, fs_node_t *, const char *); 75 static int tmpfs_destroy_node(fs_node_t *);76 76 77 77 /* Implementation of helper functions. */ 78 static int tmpfs_root_get(fs_node_t **rfn, dev_handle_t dev_handle) 79 { 80 return tmpfs_node_get(rfn, dev_handle, TMPFS_SOME_ROOT); 81 } 82 83 static int tmpfs_has_children(bool *has_children, fs_node_t *fn) 84 { 85 *has_children = !list_empty(&TMPFS_NODE(fn)->cs_head); 86 return EOK; 87 } 88 78 89 static fs_index_t tmpfs_index_get(fs_node_t *fn) 79 90 { … … 89 100 { 90 101 return TMPFS_NODE(fn)->lnkcnt; 91 }92 93 static bool tmpfs_has_children(fs_node_t *fn)94 {95 return !list_empty(&TMPFS_NODE(fn)->cs_head);96 }97 98 static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)99 {100 return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);101 102 } 102 103 … … 118 119 /** libfs operations */ 119 120 libfs_ops_t tmpfs_libfs_ops = { 121 .root_get = tmpfs_root_get, 120 122 .match = tmpfs_match, 121 123 .node_get = tmpfs_node_get, … … 125 127 .link = tmpfs_link_node, 126 128 .unlink = tmpfs_unlink_node, 129 .has_children = tmpfs_has_children, 127 130 .index_get = tmpfs_index_get, 128 131 .size_get = tmpfs_size_get, 129 132 .lnkcnt_get = tmpfs_lnkcnt_get, 130 .has_children = tmpfs_has_children,131 .root_get = tmpfs_root_get,132 133 .plb_get_char = tmpfs_plb_get_char, 133 134 .is_directory = tmpfs_is_directory, … … 197 198 { 198 199 fs_node_t *rfn; 200 int rc; 199 201 200 r fn = tmpfs_create_node(dev_handle, L_DIRECTORY);201 if ( !rfn)202 rc = tmpfs_create_node(&rfn, dev_handle, L_DIRECTORY); 203 if (rc != EOK || !rfn) 202 204 return false; 203 205 TMPFS_NODE(rfn)->lnkcnt = 0; /* FS root is not linked */ … … 205 207 } 206 208 207 fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component)209 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 208 210 { 209 211 tmpfs_node_t *parentp = TMPFS_NODE(pfn); … … 212 214 for (lnk = parentp->cs_head.next; lnk != &parentp->cs_head; 213 215 lnk = lnk->next) { 214 tmpfs_dentry_t *dentryp = list_get_instance(lnk, tmpfs_dentry_t, 215 link); 216 if (!str_cmp(dentryp->name, component)) 217 return FS_NODE(dentryp->node); 218 } 219 220 return NULL; 221 } 222 223 fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index) 216 tmpfs_dentry_t *dentryp; 217 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 218 if (!str_cmp(dentryp->name, component)) { 219 *rfn = FS_NODE(dentryp->node); 220 return EOK; 221 } 222 } 223 224 *rfn = NULL; 225 return EOK; 226 } 227 228 int tmpfs_node_get(fs_node_t **rfn, dev_handle_t dev_handle, fs_index_t index) 224 229 { 225 230 unsigned long key[] = { … … 228 233 }; 229 234 link_t *lnk = hash_table_find(&nodes, key); 230 if (!lnk) 231 return NULL; 232 return FS_NODE(hash_table_get_instance(lnk, tmpfs_node_t, nh_link)); 233 } 234 235 void tmpfs_node_put(fs_node_t *fn) 235 if (lnk) { 236 tmpfs_node_t *nodep; 237 nodep = hash_table_get_instance(lnk, tmpfs_node_t, nh_link); 238 *rfn = FS_NODE(nodep); 239 } else { 240 *rfn = NULL; 241 } 242 return EOK; 243 } 244 245 int tmpfs_node_put(fs_node_t *fn) 236 246 { 237 247 /* nothing to do */ 238 } 239 240 fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag) 241 { 248 return EOK; 249 } 250 251 int tmpfs_create_node(fs_node_t **rfn, dev_handle_t dev_handle, int lflag) 252 { 253 fs_node_t *rootfn; 254 int rc; 255 242 256 assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); 243 257 244 258 tmpfs_node_t *nodep = malloc(sizeof(tmpfs_node_t)); 245 259 if (!nodep) 246 return NULL;260 return ENOMEM; 247 261 tmpfs_node_initialize(nodep); 248 262 nodep->bp = malloc(sizeof(fs_node_t)); 249 263 if (!nodep->bp) { 250 264 free(nodep); 251 return NULL;265 return ENOMEM; 252 266 } 253 267 fs_node_initialize(nodep->bp); 254 268 nodep->bp->data = nodep; /* link the FS and TMPFS nodes */ 255 if (!tmpfs_root_get(dev_handle)) 269 270 rc = tmpfs_root_get(&rootfn, dev_handle); 271 assert(rc == EOK); 272 if (!rootfn) 256 273 nodep->index = TMPFS_SOME_ROOT; 257 274 else … … 269 286 }; 270 287 hash_table_insert(&nodes, key, &nodep->nh_link); 271 return FS_NODE(nodep); 288 *rfn = FS_NODE(nodep); 289 return EOK; 290 } 291 292 int tmpfs_destroy_node(fs_node_t *fn) 293 { 294 tmpfs_node_t *nodep = TMPFS_NODE(fn); 295 296 assert(!nodep->lnkcnt); 297 assert(list_empty(&nodep->cs_head)); 298 299 unsigned long key[] = { 300 [NODES_KEY_INDEX] = nodep->index, 301 [NODES_KEY_DEV] = nodep->dev_handle 302 }; 303 hash_table_remove(&nodes, key, 2); 304 305 if (nodep->type == TMPFS_FILE) 306 free(nodep->data); 307 free(nodep->bp); 308 free(nodep); 309 return EOK; 272 310 } 273 311 … … 343 381 } 344 382 345 int tmpfs_destroy_node(fs_node_t *fn)346 {347 tmpfs_node_t *nodep = TMPFS_NODE(fn);348 349 assert(!nodep->lnkcnt);350 assert(list_empty(&nodep->cs_head));351 352 unsigned long key[] = {353 [NODES_KEY_INDEX] = nodep->index,354 [NODES_KEY_DEV] = nodep->dev_handle355 };356 hash_table_remove(&nodes, key, 2);357 358 if (nodep->type == TMPFS_FILE)359 free(nodep->data);360 free(nodep->bp);361 free(nodep);362 return EOK;363 }364 365 383 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 366 384 { 367 385 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 386 int rc; 368 387 369 388 /* accept the mount options */ 370 389 ipc_callid_t callid; 371 390 size_t size; 372 if (! ipc_data_write_receive(&callid, &size)) {391 if (!async_data_write_receive(&callid, &size)) { 373 392 ipc_answer_0(callid, EINVAL); 374 393 ipc_answer_0(rid, EINVAL); … … 381 400 return; 382 401 } 383 ipcarg_t retval = ipc_data_write_finalize(callid, opts, size);402 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 384 403 if (retval != EOK) { 385 404 ipc_answer_0(rid, retval); … … 395 414 } 396 415 397 tmpfs_node_t *rootp = TMPFS_NODE(tmpfs_root_get(dev_handle)); 416 fs_node_t *rootfn; 417 rc = tmpfs_root_get(&rootfn, dev_handle); 418 assert(rc == EOK); 419 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 398 420 if (str_cmp(opts, "restore") == 0) { 399 421 if (tmpfs_restore(dev_handle)) … … 445 467 ipc_callid_t callid; 446 468 size_t size; 447 if (! ipc_data_read_receive(&callid, &size)) {469 if (!async_data_read_receive(&callid, &size)) { 448 470 ipc_answer_0(callid, EINVAL); 449 471 ipc_answer_0(rid, EINVAL); … … 454 476 if (nodep->type == TMPFS_FILE) { 455 477 bytes = max(0, min(nodep->size - pos, size)); 456 (void) ipc_data_read_finalize(callid, nodep->data + pos,478 (void) async_data_read_finalize(callid, nodep->data + pos, 457 479 bytes); 458 480 } else { … … 481 503 dentryp = list_get_instance(lnk, tmpfs_dentry_t, link); 482 504 483 (void) ipc_data_read_finalize(callid, dentryp->name,505 (void) async_data_read_finalize(callid, dentryp->name, 484 506 str_size(dentryp->name) + 1); 485 507 bytes = 1; … … 519 541 ipc_callid_t callid; 520 542 size_t size; 521 if (! ipc_data_write_receive(&callid, &size)) {543 if (!async_data_write_receive(&callid, &size)) { 522 544 ipc_answer_0(callid, EINVAL); 523 545 ipc_answer_0(rid, EINVAL); … … 530 552 if (pos + size <= nodep->size) { 531 553 /* The file size is not changing. */ 532 (void) ipc_data_write_finalize(callid, nodep->data + pos, size);554 (void) async_data_write_finalize(callid, nodep->data + pos, size); 533 555 ipc_answer_2(rid, EOK, size, nodep->size); 534 556 return; … … 552 574 nodep->size += delta; 553 575 nodep->data = newdata; 554 (void) ipc_data_write_finalize(callid, nodep->data + pos, size);576 (void) async_data_write_finalize(callid, nodep->data + pos, size); 555 577 ipc_answer_2(rid, EOK, size, nodep->size); 556 578 } -
uspace/srv/kbd/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 34 33 35 include $(LIBC_PREFIX)/Makefile.toolchain 36 37 CFLAGS += -Iinclude 38 39 LIBS = $(LIBC_PREFIX)/libc.a 40 41 ## Sources 42 # 43 44 OUTPUT = kbd 45 GENERIC_SOURCES = \ 46 generic/kbd.c \ 47 genarch/gsp.c \ 48 genarch/stroke.c 49 50 ARCH_SOURCES = 51 GENARCH_SOURCES = \ 52 layout/cz.c \ 53 layout/us_qwerty.c \ 54 layout/us_dvorak.c 55 56 ifeq ($(UARCH), amd64) 57 GENARCH_SOURCES += \ 58 port/i8042.c \ 59 ctl/pc.c 60 endif 61 62 ifeq ($(UARCH), arm32) 63 ifeq ($(MACHINE), testarm) 64 GENARCH_SOURCES += \ 65 port/gxemul.c 66 67 ifeq ($(CONFIG_FB), y) 68 GENARCH_SOURCES += \ 69 ctl/gxe_fb.c 70 else 71 GENARCH_SOURCES += \ 72 ctl/stty.c 73 endif 74 endif 75 ifeq ($(MACHINE), integratorcp) 76 GENARCH_SOURCES += \ 77 port/pl050.c \ 78 ctl/pl050.c 79 endif 80 endif 81 82 ifeq ($(UARCH), ia32) 83 GENARCH_SOURCES += \ 84 port/i8042.c \ 85 ctl/pc.c 86 endif 87 88 ifeq ($(MACHINE), i460GX) 89 GENARCH_SOURCES += \ 90 port/i8042.c \ 91 ctl/pc.c 92 endif 93 94 ifeq ($(MACHINE), ski) 95 GENARCH_SOURCES += \ 96 port/ski.c \ 97 ctl/stty.c 98 endif 99 100 ifeq ($(MACHINE), msim) 101 GENARCH_SOURCES += \ 102 port/msim.c \ 103 ctl/stty.c 104 endif 105 106 ifeq ($(MACHINE), lgxemul) 107 GENARCH_SOURCES += \ 108 port/gxemul.c 109 110 ifeq ($(CONFIG_FB), y) 111 GENARCH_SOURCES += \ 112 ctl/gxe_fb.c 113 else 114 GENARCH_SOURCES += \ 115 ctl/stty.c 116 endif 117 endif 118 119 ifeq ($(MACHINE), bgxemul) 120 GENARCH_SOURCES += \ 121 port/gxemul.c 122 123 ifeq ($(CONFIG_FB), y) 124 GENARCH_SOURCES += \ 125 ctl/gxe_fb.c 126 else 127 GENARCH_SOURCES += \ 128 ctl/stty.c 129 endif 130 endif 131 132 ifeq ($(UARCH), ppc32) 133 GENARCH_SOURCES += \ 134 port/dummy.c \ 135 ctl/stty.c 136 endif 137 138 ifeq ($(UARCH), sparc64) 139 ifeq ($(MACHINE),serengeti) 140 GENARCH_SOURCES += \ 141 port/sgcn.c \ 142 ctl/stty.c 143 else 144 GENARCH_SOURCES += \ 145 port/sun.c \ 146 port/z8530.c \ 147 port/ns16550.c \ 148 ctl/sun.c 149 endif 150 endif 151 152 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) 153 ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) 154 GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES))) 155 156 OBJECTS := $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS) 157 158 .PHONY: all clean depend disasm links 159 160 all: $(OUTPUT) $(OUTPUT).disasm 161 162 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 163 37 164 38 clean: 165 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 166 167 depend: 168 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 169 170 $(OUTPUT): $(OBJECTS) $(LIBS) 171 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 172 173 disasm: $(OUTPUT).disasm 174 175 $(OUTPUT).disasm: $(OUTPUT) 176 $(OBJDUMP) -d $< > $@ 177 178 %.o: %.S 179 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 180 181 %.o: %.s 182 $(AS) $(AFLAGS) $< -o $@ 183 184 %.o: %.c 185 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/loader/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 200 8 Jiri Svoboda3 # Copyright (c) 2007 Jakub Jermar 4 4 # All rights reserved. 5 5 # … … 28 28 # 29 29 30 ## Setup toolchain 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../../lib/libc 34 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 35 33 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 include arch/$(UARCH)/Makefile.inc 38 39 CFLAGS += -Iinclude 40 41 LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a 42 43 ## Sources 44 # 45 46 OUTPUT = loader 47 GENERIC_SOURCES = \ 48 main.c \ 49 elf_load.c \ 50 interp.s 51 52 SOURCES := $(GENERIC_SOURCES) $(ARCH_SOURCES) 53 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 54 55 .PHONY: all clean depend disasm 56 57 all: $(OUTPUT) disasm 58 59 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 60 37 61 38 clean: 62 -rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(UARCH)/_link.ld Makefile.depend 63 64 depend: 65 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 66 67 $(OUTPUT): $(OBJECTS) $(LIBS) arch/$(UARCH)/_link.ld 68 $(LD) -T arch/$(UARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map 69 70 disasm: 71 $(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm 72 73 arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in 74 $(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ 75 76 %.o: %.S 77 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 78 79 %.o: %.s 80 $(AS) $(AFLAGS) $< -o $@ 81 82 %.o: %.c 83 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm arch/*/_link.ld 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/loader/arch/ia32/_link.ld.in
rfcbd1be r1787e527 8 8 PHDRS { 9 9 interp PT_INTERP; 10 10 text PT_LOAD FILEHDR PHDRS FLAGS(5); 11 11 data PT_LOAD FLAGS(6); 12 12 } … … 16 16 *(.interp); 17 17 } :interp 18 18 19 19 . = 0x70001000; 20 20 21 21 .init ALIGN(0x1000) : SUBALIGN(0x1000) { 22 22 *(.init); 23 23 } :text 24 24 25 .text : { 25 26 *(.text); 26 27 *(.rodata*); 27 28 } :text 28 29 … … 30 31 *(.data); 31 32 } :data 33 32 34 .tdata : { 33 35 _tdata_start = .; 34 36 *(.tdata); 37 *(.gnu.linkonce.tb.*); 35 38 _tdata_end = .; 36 39 } :data 40 37 41 .tbss : { 38 42 _tbss_start = .; … … 40 44 _tbss_end = .; 41 45 } :data 46 42 47 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 48 43 49 .bss : { 44 45 50 *(COMMON); 51 *(.bss); 46 52 } :data 47 53 48 54 . = ALIGN(0x1000); 55 49 56 _heap = .; 50 57 … … 52 59 *(*); 53 60 } 54 55 61 } -
uspace/srv/loader/arch/ia32/ia32.s
rfcbd1be r1787e527 40 40 movl 0x8(%ebp), %eax 41 41 42 # %e bx:= pcb43 # pcb is passed to the entry point in t %ebx44 mov 0xc(%ebp), %e bx42 # %edi := pcb 43 # pcb is passed to the entry point in %edi 44 mov 0xc(%ebp), %edi 45 45 46 46 # Save a tiny bit of stack space -
uspace/srv/loader/main.c
rfcbd1be r1787e527 72 72 static pcb_t pcb; 73 73 74 /** Current working directory */ 75 static char *cwd = NULL; 76 74 77 /** Number of arguments */ 75 78 static int argc = 0; … … 102 105 task_id = task_get_id(); 103 106 104 if (! ipc_data_read_receive(&callid, &len)) {107 if (!async_data_read_receive(&callid, &len)) { 105 108 ipc_answer_0(callid, EINVAL); 106 109 ipc_answer_0(rid, EINVAL); … … 111 114 len = sizeof(task_id); 112 115 113 ipc_data_read_finalize(callid, &task_id, len);116 async_data_read_finalize(callid, &task_id, len); 114 117 ipc_answer_0(rid, EOK); 115 118 } 116 119 120 /** Receive a call setting the current working directory. 121 * 122 * @param rid 123 * @param request 124 */ 125 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request) 126 { 127 ipc_callid_t callid; 128 size_t len; 129 130 if (!async_data_write_receive(&callid, &len)) { 131 ipc_answer_0(callid, EINVAL); 132 ipc_answer_0(rid, EINVAL); 133 return; 134 } 135 136 cwd = malloc(len + 1); 137 if (!cwd) { 138 ipc_answer_0(callid, ENOMEM); 139 ipc_answer_0(rid, ENOMEM); 140 return; 141 } 142 143 async_data_write_finalize(callid, cwd, len); 144 cwd[len] = '\0'; 145 146 ipc_answer_0(rid, EOK); 147 } 117 148 118 149 /** Receive a call setting pathname of the program to execute. … … 127 158 char *name_buf; 128 159 129 if (! ipc_data_write_receive(&callid, &len)) {160 if (!async_data_write_receive(&callid, &len)) { 130 161 ipc_answer_0(callid, EINVAL); 131 162 ipc_answer_0(rid, EINVAL); … … 140 171 } 141 172 142 ipc_data_write_finalize(callid, name_buf, len);173 async_data_write_finalize(callid, name_buf, len); 143 174 ipc_answer_0(rid, EOK); 144 175 … … 164 195 int n; 165 196 166 if (! ipc_data_write_receive(&callid, &buf_size)) {197 if (!async_data_write_receive(&callid, &buf_size)) { 167 198 ipc_answer_0(callid, EINVAL); 168 199 ipc_answer_0(rid, EINVAL); … … 187 218 } 188 219 189 ipc_data_write_finalize(callid, arg_buf, buf_size);220 async_data_write_finalize(callid, arg_buf, buf_size); 190 221 191 222 arg_buf[buf_size] = '\0'; … … 239 270 ipc_callid_t callid; 240 271 size_t buf_size; 241 if (! ipc_data_write_receive(&callid, &buf_size)) {272 if (!async_data_write_receive(&callid, &buf_size)) { 242 273 ipc_answer_0(callid, EINVAL); 243 274 ipc_answer_0(rid, EINVAL); … … 268 299 } 269 300 270 ipc_data_write_finalize(callid, fil_buf, buf_size);301 async_data_write_finalize(callid, fil_buf, buf_size); 271 302 272 303 int count = buf_size / sizeof(fdi_node_t); … … 312 343 313 344 elf_create_pcb(&prog_info, &pcb); 345 346 pcb.cwd = cwd; 314 347 315 348 pcb.argc = argc; … … 406 439 case LOADER_GET_TASKID: 407 440 ldr_get_taskid(callid, &call); 441 continue; 442 case LOADER_SET_CWD: 443 ldr_set_cwd(callid, &call); 408 444 continue; 409 445 case LOADER_SET_PATHNAME: -
uspace/srv/ns/Makefile
rfcbd1be r1787e527 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 3 4 # All rights reserved. 4 5 # … … 27 28 # 28 29 29 ## Setup toolchain 30 # 30 include Makefile.common 31 31 32 LIBC_PREFIX = ../../lib/libc 33 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 34 33 35 include $(LIBC_PREFIX)/Makefile.toolchain 36 37 LIBS = $(LIBC_PREFIX)/libc.a 38 39 ## Sources 40 # 41 42 OUTPUT = ns 43 SOURCES = \ 44 ns.c \ 45 service.c \ 46 clonable.c \ 47 task.c 48 49 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 50 51 .PHONY: all clean depend disasm 52 53 all: $(OUTPUT) $(OUTPUT).disasm 54 55 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 56 37 57 38 clean: 58 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 59 60 depend: 61 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 62 63 $(OUTPUT): $(OBJECTS) $(LIBS) 64 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 65 66 disasm: $(OUTPUT).disasm 67 68 $(OUTPUT).disasm: $(OUTPUT) 69 $(OBJDUMP) -d $< > $@ 70 71 %.o: %.S 72 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 73 74 %.o: %.s 75 $(AS) $(AFLAGS) $< -o $@ 76 77 %.o: %.c 78 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/ns/service.c
rfcbd1be r1787e527 156 156 157 157 hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); 158 ipcarg_t retval = ipc_forward_fast(pr->callid, hs->phone, 159 pr->arg2, pr->arg3, 0, IPC_FF_NONE); 160 161 if (!(pr->callid & IPC_CALLID_NOTIFICATION)) 162 ipc_answer_0(pr->callid, retval); 158 (void) ipc_forward_fast(pr->callid, hs->phone, pr->arg2, 159 pr->arg3, 0, IPC_FF_NONE); 163 160 164 161 list_remove(cur); … … 242 239 243 240 hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); 244 retval =ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call),241 (void) ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 245 242 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 243 return; 246 244 247 245 out: -
uspace/srv/vfs/Makefile
rfcbd1be r1787e527 1 1 # 2 # Copyright (c) 200 6Martin Decky3 # Copyright (c) 200 8Jakub Jermar2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 2007 Jakub Jermar 4 4 # All rights reserved. 5 5 # … … 28 28 # 29 29 30 ## Setup toolchain 31 # 30 include Makefile.common 32 31 33 LIBC_PREFIX = ../../lib/libc 34 SOFTINT_PREFIX = ../../lib/softint 32 .PHONY: all clean 35 33 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 38 LIBS = $(LIBC_PREFIX)/libc.a 39 40 ## Sources 41 # 42 43 OUTPUT = vfs 44 SOURCES = \ 45 vfs.c \ 46 vfs_node.c \ 47 vfs_file.c \ 48 vfs_ops.c \ 49 vfs_lookup.c \ 50 vfs_register.c 51 52 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 53 54 .PHONY: all clean depend disasm 55 56 all: $(OUTPUT) $(OUTPUT).disasm 57 58 -include Makefile.depend 34 all: $(LIBC_PREFIX)/../../../Makefile.config $(LIBC_PREFIX)/../../../config.h $(LIBC_PREFIX)/../../../config.defs $(LIBS) 35 -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV) 36 $(MAKE) -f Makefile.build 59 37 60 38 clean: 61 -rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) 62 63 depend: 64 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 65 66 $(OUTPUT): $(OBJECTS) $(LIBS) 67 $(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map 68 69 disasm: $(OUTPUT).disasm 70 71 $(OUTPUT).disasm: $(OUTPUT) 72 $(OBJDUMP) -d $< > $@ 73 74 %.o: %.S 75 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 76 77 %.o: %.s 78 $(AS) $(AFLAGS) $< -o $@ 79 80 %.o: %.c 81 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 39 rm -f $(DEPEND) $(DEPEND_PREV) $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm 40 find . -name '*.o' -follow -exec rm \{\} \; -
uspace/srv/vfs/vfs.c
rfcbd1be r1787e527 126 126 vfs_sync(callid, &call); 127 127 break; 128 case VFS_IN_DUP: 129 vfs_dup(callid, &call); 128 130 default: 129 131 ipc_answer_0(callid, ENOTSUP); -
uspace/srv/vfs/vfs.h
rfcbd1be r1787e527 186 186 extern bool vfs_files_init(void); 187 187 extern vfs_file_t *vfs_file_get(int); 188 extern int vfs_fd_alloc(void); 188 extern int vfs_fd_assign(vfs_file_t *file, int fd); 189 extern int vfs_fd_alloc(bool desc); 189 190 extern int vfs_fd_free(int); 190 191 … … 200 201 extern void vfs_open_node(ipc_callid_t, ipc_call_t *); 201 202 extern void vfs_sync(ipc_callid_t, ipc_call_t *); 203 extern void vfs_dup(ipc_callid_t, ipc_call_t *); 202 204 extern void vfs_close(ipc_callid_t, ipc_call_t *); 203 205 extern void vfs_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/vfs/vfs_file.c
rfcbd1be r1787e527 76 76 /** Allocate a file descriptor. 77 77 * 78 * @return First available file descriptor or a negative error 79 * code. 80 */ 81 int vfs_fd_alloc(void) 78 * @param desc If true, look for an available file descriptor 79 * in a descending order. 80 * 81 * @return First available file descriptor or a negative error 82 * code. 83 */ 84 int vfs_fd_alloc(bool desc) 82 85 { 83 86 if (!vfs_files_init()) … … 85 88 86 89 unsigned int i; 87 for (i = 0; i < MAX_OPEN_FILES; i++) { 90 if (desc) 91 i = MAX_OPEN_FILES - 1; 92 else 93 i = 0; 94 95 while (true) { 88 96 if (!files[i]) { 89 97 files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t)); … … 96 104 return (int) i; 97 105 } 106 107 if (desc) { 108 if (i == 0) 109 break; 110 111 i--; 112 } else { 113 if (i == MAX_OPEN_FILES - 1) 114 break; 115 116 i++; 117 } 98 118 } 99 119 … … 118 138 vfs_file_delref(files[fd]); 119 139 files[fd] = NULL; 140 141 return EOK; 142 } 143 144 /** Assign a file to a file descriptor. 145 * 146 * @param file File to assign. 147 * @param fd File descriptor to assign to. 148 * 149 * @return EOK on success or EINVAL if fd is an invalid or already 150 * used file descriptor. 151 * 152 */ 153 int vfs_fd_assign(vfs_file_t *file, int fd) 154 { 155 if (!vfs_files_init()) 156 return ENOMEM; 157 158 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (files[fd] != NULL)) 159 return EINVAL; 160 161 files[fd] = file; 162 vfs_file_addref(files[fd]); 120 163 121 164 return EOK; -
uspace/srv/vfs/vfs_lookup.c
rfcbd1be r1787e527 209 209 (ipcarg_t) result->triplet.index, &answer); 210 210 211 212 211 ipcarg_t rc; 213 212 async_wait_for(req, &rc); -
uspace/srv/vfs/vfs_ops.c
rfcbd1be r1787e527 125 125 (ipcarg_t) dev_handle, &answer); 126 126 /* send the mount options */ 127 rc = ipc_data_write_start(phone, (void *)opts,127 rc = async_data_write_start(phone, (void *)opts, 128 128 str_size(opts)); 129 129 if (rc != EOK) { … … 207 207 208 208 /* send the mount options */ 209 rc = ipc_data_write_start(phone, (void *)opts, str_size(opts));209 rc = async_data_write_start(phone, (void *)opts, str_size(opts)); 210 210 if (rc != EOK) { 211 211 async_wait_for(msg, NULL); … … 268 268 ipc_callid_t callid; 269 269 size_t size; 270 if (! ipc_data_write_receive(&callid, &size)) {270 if (!async_data_write_receive(&callid, &size)) { 271 271 ipc_answer_0(callid, EINVAL); 272 272 ipc_answer_0(rid, EINVAL); … … 290 290 291 291 /* Deliver the mount point. */ 292 ipcarg_t retval = ipc_data_write_finalize(callid, mp, size);292 ipcarg_t retval = async_data_write_finalize(callid, mp, size); 293 293 if (retval != EOK) { 294 294 ipc_answer_0(rid, retval); … … 299 299 300 300 /* Now we expect to receive the mount options. */ 301 if (! ipc_data_write_receive(&callid, &size)) {301 if (!async_data_write_receive(&callid, &size)) { 302 302 ipc_answer_0(callid, EINVAL); 303 303 ipc_answer_0(rid, EINVAL); … … 324 324 325 325 /* Deliver the mount options. */ 326 retval = ipc_data_write_finalize(callid, opts, size);326 retval = async_data_write_finalize(callid, opts, size); 327 327 if (retval != EOK) { 328 328 ipc_answer_0(rid, retval); … … 337 337 * system. 338 338 */ 339 if (! ipc_data_write_receive(&callid, &size)) {339 if (!async_data_write_receive(&callid, &size)) { 340 340 ipc_answer_0(callid, EINVAL); 341 341 ipc_answer_0(rid, EINVAL); … … 370 370 371 371 /* Deliver the file system name. */ 372 retval = ipc_data_write_finalize(callid, fs_name, size);372 retval = async_data_write_finalize(callid, fs_name, size); 373 373 if (retval != EOK) { 374 374 ipc_answer_0(rid, retval); … … 469 469 470 470 ipc_callid_t callid; 471 if (! ipc_data_write_receive(&callid, &len)) {471 if (!async_data_write_receive(&callid, &len)) { 472 472 ipc_answer_0(callid, EINVAL); 473 473 ipc_answer_0(rid, EINVAL); … … 483 483 484 484 int rc; 485 if ((rc = ipc_data_write_finalize(callid, path, len))) {485 if ((rc = async_data_write_finalize(callid, path, len))) { 486 486 ipc_answer_0(rid, rc); 487 487 free(path); … … 543 543 * structure. 544 544 */ 545 int fd = vfs_fd_alloc( );545 int fd = vfs_fd_alloc((oflag & O_DESC) != 0); 546 546 if (fd < 0) { 547 547 vfs_node_put(node); … … 620 620 * structure. 621 621 */ 622 int fd = vfs_fd_alloc( );622 int fd = vfs_fd_alloc((oflag & O_DESC) != 0); 623 623 if (fd < 0) { 624 624 vfs_node_put(node); … … 679 679 } 680 680 681 static int vfs_close_internal(vfs_file_t *file) 682 { 683 /* 684 * Lock the open file structure so that no other thread can manipulate 685 * the same open file at a time. 686 */ 687 fibril_mutex_lock(&file->lock); 688 689 if (file->refcnt <= 1) { 690 /* Only close the file on the destination FS server 691 if there are no more file descriptors (except the 692 present one) pointing to this file. */ 693 694 int fs_phone = vfs_grab_phone(file->node->fs_handle); 695 696 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 697 aid_t msg; 698 ipc_call_t answer; 699 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle, 700 file->node->index, &answer); 701 702 /* Wait for reply from the FS server. */ 703 ipcarg_t rc; 704 async_wait_for(msg, &rc); 705 706 vfs_release_phone(fs_phone); 707 fibril_mutex_unlock(&file->lock); 708 709 return IPC_GET_ARG1(answer); 710 } 711 712 fibril_mutex_unlock(&file->lock); 713 return EOK; 714 } 715 681 716 void vfs_close(ipc_callid_t rid, ipc_call_t *request) 682 717 { … … 690 725 } 691 726 692 /* 693 * Lock the open file structure so that no other thread can manipulate 694 * the same open file at a time. 695 */ 696 fibril_mutex_lock(&file->lock); 697 int fs_phone = vfs_grab_phone(file->node->fs_handle); 698 699 /* Make a VFS_OUT_CLOSE request at the destination FS server. */ 700 aid_t msg; 701 ipc_call_t answer; 702 msg = async_send_2(fs_phone, VFS_OUT_CLOSE, file->node->dev_handle, 703 file->node->index, &answer); 704 705 /* Wait for reply from the FS server. */ 706 ipcarg_t rc; 707 async_wait_for(msg, &rc); 708 709 vfs_release_phone(fs_phone); 710 fibril_mutex_unlock(&file->lock); 711 712 int retval = IPC_GET_ARG1(answer); 713 if (retval != EOK) 714 ipc_answer_0(rid, retval); 715 716 retval = vfs_fd_free(fd); 717 ipc_answer_0(rid, retval); 727 int ret = vfs_close_internal(file); 728 if (ret != EOK) 729 ipc_answer_0(rid, ret); 730 731 ret = vfs_fd_free(fd); 732 ipc_answer_0(rid, ret); 718 733 } 719 734 … … 747 762 int res; 748 763 if (read) 749 res = ipc_data_read_receive(&callid, NULL);764 res = async_data_read_receive(&callid, NULL); 750 765 else 751 res = ipc_data_write_receive(&callid, NULL);766 res = async_data_write_receive(&callid, NULL); 752 767 if (!res) { 753 768 ipc_answer_0(callid, EINVAL); … … 934 949 { 935 950 int fd = IPC_GET_ARG1(*request); 936 size_t size = IPC_GET_ARG2(*request);937 951 ipcarg_t rc; 938 952 … … 944 958 945 959 ipc_callid_t callid; 946 if (! ipc_data_read_receive(&callid, NULL)) {960 if (!async_data_read_receive(&callid, NULL)) { 947 961 ipc_answer_0(callid, EINVAL); 948 962 ipc_answer_0(rid, EINVAL); … … 970 984 ipc_callid_t callid; 971 985 972 if (! ipc_data_write_receive(&callid, &len)) {986 if (!async_data_write_receive(&callid, &len)) { 973 987 ipc_answer_0(callid, EINVAL); 974 988 ipc_answer_0(rid, EINVAL); … … 982 996 } 983 997 int rc; 984 if ((rc = ipc_data_write_finalize(callid, path, len))) {998 if ((rc = async_data_write_finalize(callid, path, len))) { 985 999 ipc_answer_0(rid, rc); 986 1000 free(path); … … 989 1003 path[len] = '\0'; 990 1004 991 if (! ipc_data_read_receive(&callid, NULL)) {1005 if (!async_data_read_receive(&callid, NULL)) { 992 1006 free(path); 993 1007 ipc_answer_0(callid, EINVAL); … … 1038 1052 ipc_callid_t callid; 1039 1053 1040 if (! ipc_data_write_receive(&callid, &len)) {1054 if (!async_data_write_receive(&callid, &len)) { 1041 1055 ipc_answer_0(callid, EINVAL); 1042 1056 ipc_answer_0(rid, EINVAL); … … 1050 1064 } 1051 1065 int rc; 1052 if ((rc = ipc_data_write_finalize(callid, path, len))) {1066 if ((rc = async_data_write_finalize(callid, path, len))) { 1053 1067 ipc_answer_0(rid, rc); 1054 1068 free(path); … … 1075 1089 ipc_callid_t callid; 1076 1090 1077 if (! ipc_data_write_receive(&callid, &len)) {1091 if (!async_data_write_receive(&callid, &len)) { 1078 1092 ipc_answer_0(callid, EINVAL); 1079 1093 ipc_answer_0(rid, EINVAL); … … 1087 1101 } 1088 1102 int rc; 1089 if ((rc = ipc_data_write_finalize(callid, path, len))) {1103 if ((rc = async_data_write_finalize(callid, path, len))) { 1090 1104 ipc_answer_0(rid, rc); 1091 1105 free(path); … … 1126 1140 1127 1141 /* Retrieve the old path. */ 1128 if (! ipc_data_write_receive(&callid, &olen)) {1142 if (!async_data_write_receive(&callid, &olen)) { 1129 1143 ipc_answer_0(callid, EINVAL); 1130 1144 ipc_answer_0(rid, EINVAL); … … 1137 1151 return; 1138 1152 } 1139 if ((rc = ipc_data_write_finalize(callid, old, olen))) {1153 if ((rc = async_data_write_finalize(callid, old, olen))) { 1140 1154 ipc_answer_0(rid, rc); 1141 1155 free(old); … … 1145 1159 1146 1160 /* Retrieve the new path. */ 1147 if (! ipc_data_write_receive(&callid, &nlen)) {1161 if (!async_data_write_receive(&callid, &nlen)) { 1148 1162 ipc_answer_0(callid, EINVAL); 1149 1163 ipc_answer_0(rid, EINVAL); … … 1158 1172 return; 1159 1173 } 1160 if ((rc = ipc_data_write_finalize(callid, new, nlen))) {1174 if ((rc = async_data_write_finalize(callid, new, nlen))) { 1161 1175 ipc_answer_0(rid, rc); 1162 1176 free(old); … … 1311 1325 } 1312 1326 1327 void vfs_dup(ipc_callid_t rid, ipc_call_t *request) 1328 { 1329 int oldfd = IPC_GET_ARG1(*request); 1330 int newfd = IPC_GET_ARG2(*request); 1331 1332 /* Lookup the file structure corresponding to oldfd. */ 1333 vfs_file_t *oldfile = vfs_file_get(oldfd); 1334 if (!oldfile) { 1335 ipc_answer_0(rid, EBADF); 1336 return; 1337 } 1338 1339 /* If the file descriptors are the same, do nothing. */ 1340 if (oldfd == newfd) { 1341 ipc_answer_1(rid, EOK, newfd); 1342 return; 1343 } 1344 1345 /* 1346 * Lock the open file structure so that no other thread can manipulate 1347 * the same open file at a time. 1348 */ 1349 fibril_mutex_lock(&oldfile->lock); 1350 1351 /* Lookup an open file structure possibly corresponding to newfd. */ 1352 vfs_file_t *newfile = vfs_file_get(newfd); 1353 if (newfile) { 1354 /* Close the originally opened file. */ 1355 int ret = vfs_close_internal(newfile); 1356 if (ret != EOK) { 1357 ipc_answer_0(rid, ret); 1358 return; 1359 } 1360 1361 ret = vfs_fd_free(newfd); 1362 if (ret != EOK) { 1363 ipc_answer_0(rid, ret); 1364 return; 1365 } 1366 } 1367 1368 /* Assign the old file to newfd. */ 1369 int ret = vfs_fd_assign(oldfile, newfd); 1370 fibril_mutex_unlock(&oldfile->lock); 1371 1372 if (ret != EOK) 1373 ipc_answer_0(rid, ret); 1374 else 1375 ipc_answer_1(rid, EOK, newfd); 1376 } 1377 1313 1378 /** 1314 1379 * @} -
uspace/srv/vfs/vfs_register.c
rfcbd1be r1787e527 122 122 * VFS info structure from the client FS. 123 123 */ 124 if (! ipc_data_write_receive(&callid, &size)) {124 if (!async_data_write_receive(&callid, &size)) { 125 125 /* 126 126 * The client doesn't obey the same protocol as we do. … … 163 163 fibril_mutex_initialize(&fs_info->phone_lock); 164 164 165 rc = ipc_data_write_finalize(callid, &fs_info->vfs_info, size);165 rc = async_data_write_finalize(callid, &fs_info->vfs_info, size); 166 166 if (rc != EOK) { 167 167 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n", … … 229 229 */ 230 230 231 if (! ipc_share_in_receive(&callid, &size)) {231 if (!async_share_in_receive(&callid, &size)) { 232 232 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); 233 233 list_remove(&fs_info->fs_link); … … 257 257 * Commit to read-only sharing the PLB with the client. 258 258 */ 259 (void) ipc_share_in_finalize(callid, plb,259 (void) async_share_in_finalize(callid, plb, 260 260 AS_AREA_READ | AS_AREA_CACHEABLE); 261 261
Note:
See TracChangeset
for help on using the changeset viewer.