Changeset 03c971f in mainline for uspace/drv
- Timestamp:
- 2013-08-15T14:20:16Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bb2a5b2
- Parents:
- f2c19b0 (diff), 2921602 (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/drv
- Files:
-
- 4 added
- 21 edited
- 3 moved
-
block/ata_bd/Makefile (added)
-
block/ata_bd/ata_bd.c (moved) (moved from uspace/srv/bd/ata_bd/ata_bd.c ) (37 diffs)
-
block/ata_bd/ata_bd.h (moved) (moved from uspace/srv/bd/ata_bd/ata_bd.h ) (3 diffs)
-
block/ata_bd/ata_bd.ma (added)
-
block/ata_bd/ata_hw.h (moved) (moved from uspace/srv/bd/ata_bd/ata_hw.h )
-
block/ata_bd/main.c (added)
-
block/ata_bd/main.h (added)
-
bus/isa/isa.dev (modified) (1 diff)
-
bus/usb/ehci/main.c (modified) (4 diffs)
-
bus/usb/ehci/res.c (modified) (9 diffs)
-
bus/usb/ohci/hc.c (modified) (8 diffs)
-
bus/usb/ohci/hc.h (modified) (2 diffs)
-
bus/usb/ohci/ohci.c (modified) (4 diffs)
-
bus/usb/uhci/hc.c (modified) (5 diffs)
-
bus/usb/uhci/hc.h (modified) (2 diffs)
-
bus/usb/uhci/uhci.c (modified) (5 diffs)
-
bus/usb/uhcirh/main.c (modified) (1 diff)
-
bus/usb/uhcirh/port.c (modified) (3 diffs)
-
bus/usb/vhc/hub/virthubops.c (modified) (1 diff)
-
char/i8042/i8042.c (modified) (1 diff)
-
char/i8042/main.c (modified) (2 diffs)
-
char/ns8250/ns8250.c (modified) (11 diffs)
-
char/ps2mouse/main.c (modified) (1 diff)
-
char/ps2mouse/ps2mouse.c (modified) (2 diffs)
-
char/xtkbd/main.c (modified) (1 diff)
-
infrastructure/rootamdm37x/rootamdm37x.c (modified) (5 diffs)
-
infrastructure/rootamdm37x/uhh.h (modified) (1 diff)
-
nic/rtl8139/driver.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/block/ata_bd/ata_bd.c
rf2c19b0 r03c971f 1 1 /* 2 * Copyright (c) 20 09Jiri Svoboda2 * Copyright (c) 2013 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 35 35 * @brief ATA disk driver 36 36 * 37 * This driver supports CHS, 28-bit and 48-bit LBA addressing . It only uses38 * P IO transfers. There is no support DMA, the PACKET feature set or any other39 * fancy features such as S.M.A.R.T, removable devices, etc.37 * This driver supports CHS, 28-bit and 48-bit LBA addressing, as well as 38 * PACKET devices. It only uses PIO transfers. There is no support DMA 39 * or any other fancy features such as S.M.A.R.T, removable devices, etc. 40 40 * 41 41 * This driver is based on the ATA-1, ATA-2, ATA-3 and ATA/ATAPI-4 through 7 … … 48 48 */ 49 49 50 #include <stdio.h>51 50 #include <ddi.h> 51 #include <ddf/log.h> 52 52 #include <async.h> 53 53 #include <as.h> … … 61 61 #include <errno.h> 62 62 #include <stdbool.h> 63 #include <stdio.h> 63 64 #include <byteorder.h> 64 65 #include <task.h> … … 67 68 #include "ata_hw.h" 68 69 #include "ata_bd.h" 70 #include "main.h" 69 71 70 72 #define NAME "ata_bd" … … 80 82 static const size_t identify_data_size = 512; 81 83 82 /** I/O base address of the command registers. */ 83 static uintptr_t cmd_physical; 84 /** I/O base address of the control registers. */ 85 static uintptr_t ctl_physical; 86 87 /** I/O base addresses for legacy (ISA-compatible) controllers. */ 88 static ata_base_t legacy_base[LEGACY_CTLS] = { 89 { 0x1f0, 0x3f0 }, 90 { 0x170, 0x370 }, 91 { 0x1e8, 0x3e8 }, 92 { 0x168, 0x368 } 93 }; 94 95 static ata_cmd_t *cmd; 96 static ata_ctl_t *ctl; 97 98 /** Per-disk state. */ 99 static disk_t ata_disk[MAX_DISKS]; 100 101 static void print_syntax(void); 102 static int ata_bd_init(void); 103 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *); 84 static int ata_bd_init_io(ata_ctrl_t *ctrl); 85 static void ata_bd_fini_io(ata_ctrl_t *ctrl); 104 86 105 87 static int ata_bd_open(bd_srvs_t *, bd_srv_t *); … … 117 99 static int ata_rcmd_write(disk_t *disk, uint64_t ba, size_t cnt, 118 100 const void *buf); 119 static int disk_init( disk_t *d, int disk_id);120 static int drive_identify(disk_t *disk, void *buf);121 static int identify_pkt_dev(disk_t *disk, void *buf);101 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id); 102 static int ata_identify_dev(disk_t *disk, void *buf); 103 static int ata_identify_pkt_dev(disk_t *disk, void *buf); 122 104 static int ata_cmd_packet(disk_t *disk, const void *cpkt, size_t cpkt_size, 123 105 void *obuf, size_t obuf_size); … … 129 111 static void disk_print_summary(disk_t *d); 130 112 static int coord_calc(disk_t *d, uint64_t ba, block_coord_t *bc); 131 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt); 132 static int wait_status(unsigned set, unsigned n_reset, uint8_t *pstatus, 133 unsigned timeout); 134 135 static bd_ops_t ata_bd_ops = { 113 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc, 114 uint16_t scnt); 115 static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset, 116 uint8_t *pstatus, unsigned timeout); 117 118 bd_ops_t ata_bd_ops = { 136 119 .open = ata_bd_open, 137 120 .close = ata_bd_close, … … 153 136 } 154 137 155 int main(int argc, char **argv) 156 { 157 char name[16]; 138 /** Initialize ATA controller. */ 139 int ata_ctrl_init(ata_ctrl_t *ctrl, ata_base_t *res) 140 { 158 141 int i, rc; 159 142 int n_disks; 160 unsigned ctl_num; 161 char *eptr; 162 163 printf(NAME ": ATA disk driver\n"); 164 165 if (argc > 1) { 166 ctl_num = strtoul(argv[1], &eptr, 0); 167 if (*eptr != '\0' || ctl_num == 0 || ctl_num > 4) { 168 printf("Invalid argument.\n"); 169 print_syntax(); 170 return -1; 171 } 172 } else { 173 ctl_num = 1; 174 } 175 176 cmd_physical = legacy_base[ctl_num - 1].cmd; 177 ctl_physical = legacy_base[ctl_num - 1].ctl; 178 179 printf("I/O address %p/%p\n", (void *) cmd_physical, 180 (void *) ctl_physical); 181 182 if (ata_bd_init() != EOK) 183 return -1; 143 144 ddf_msg(LVL_DEBUG, "ata_ctrl_init()"); 145 146 fibril_mutex_initialize(&ctrl->lock); 147 ctrl->cmd_physical = res->cmd; 148 ctrl->ctl_physical = res->ctl; 149 150 ddf_msg(LVL_NOTE, "I/O address %p/%p", (void *) ctrl->cmd_physical, 151 (void *) ctrl->ctl_physical); 152 153 rc = ata_bd_init_io(ctrl); 154 if (rc != EOK) 155 return rc; 184 156 185 157 for (i = 0; i < MAX_DISKS; i++) { 186 printf("Identify drive %d... ", i); 187 fflush(stdout); 188 189 rc = disk_init(&ata_disk[i], i); 158 ddf_msg(LVL_NOTE, "Identify drive %d...", i); 159 160 rc = disk_init(ctrl, &ctrl->disk[i], i); 190 161 191 162 if (rc == EOK) { 192 disk_print_summary(& ata_disk[i]);163 disk_print_summary(&ctrl->disk[i]); 193 164 } else { 194 printf("Not found.\n");165 ddf_msg(LVL_NOTE, "Not found."); 195 166 } 196 167 } … … 200 171 for (i = 0; i < MAX_DISKS; i++) { 201 172 /* Skip unattached drives. */ 202 if ( ata_disk[i].present == false)173 if (ctrl->disk[i].present == false) 203 174 continue; 204 205 snprintf(name, 16, "%s/ata%udisk%d", NAMESPACE, ctl_num, i); 206 rc = loc_service_register(name, &ata_disk[i].service_id); 175 176 rc = ata_fun_create(&ctrl->disk[i]); 207 177 if (rc != EOK) { 208 printf(NAME ": Unable to register device %s.\n", name); 178 ddf_msg(LVL_ERROR, "Unable to create function for " 179 "disk %d.", i); 180 goto error; 181 } 182 ++n_disks; 183 } 184 185 if (n_disks == 0) { 186 ddf_msg(LVL_WARN, "No disks detected."); 187 rc = EIO; 188 goto error; 189 } 190 191 return EOK; 192 error: 193 for (i = 0; i < MAX_DISKS; i++) { 194 if (ata_fun_remove(&ctrl->disk[i]) != EOK) { 195 ddf_msg(LVL_ERROR, "Unable to clean up function for " 196 "disk %d.", i); 197 } 198 } 199 ata_bd_fini_io(ctrl); 200 return rc; 201 } 202 203 /** Remove ATA controller. */ 204 int ata_ctrl_remove(ata_ctrl_t *ctrl) 205 { 206 int i, rc; 207 208 ddf_msg(LVL_DEBUG, ": ata_ctrl_remove()"); 209 210 fibril_mutex_lock(&ctrl->lock); 211 212 for (i = 0; i < MAX_DISKS; i++) { 213 rc = ata_fun_remove(&ctrl->disk[i]); 214 if (rc != EOK) { 215 ddf_msg(LVL_ERROR, "Unable to clean up function for " 216 "disk %d.", i); 209 217 return rc; 210 218 } 211 ++n_disks; 212 } 213 214 if (n_disks == 0) { 215 printf("No disks detected.\n"); 216 return -1; 217 } 218 219 printf("%s: Accepting connections\n", NAME); 220 task_retval(0); 221 async_manager(); 222 223 /* Not reached */ 224 return 0; 225 } 226 227 228 static void print_syntax(void) 229 { 230 printf("Syntax: " NAME " <controller_number>\n"); 231 printf("Controller number = 1..4\n"); 219 } 220 221 ata_bd_fini_io(ctrl); 222 fibril_mutex_unlock(&ctrl->lock); 223 224 return EOK; 225 } 226 227 /** Surprise removal of ATA controller. */ 228 int ata_ctrl_gone(ata_ctrl_t *ctrl) 229 { 230 int i, rc; 231 232 ddf_msg(LVL_DEBUG, "ata_ctrl_gone()"); 233 234 fibril_mutex_lock(&ctrl->lock); 235 236 for (i = 0; i < MAX_DISKS; i++) { 237 rc = ata_fun_unbind(&ctrl->disk[i]); 238 if (rc != EOK) { 239 ddf_msg(LVL_ERROR, "Unable to clean up function for " 240 "disk %d.", i); 241 return rc; 242 } 243 } 244 245 ata_bd_fini_io(ctrl); 246 fibril_mutex_unlock(&ctrl->lock); 247 248 return EOK; 232 249 } 233 250 … … 236 253 { 237 254 uint64_t mbytes; 238 239 printf("%s: ", d->model); 255 char *atype = NULL; 256 char *cap = NULL; 257 int rc; 240 258 241 259 if (d->dev_type == ata_reg_dev) { 242 260 switch (d->amode) { 243 261 case am_chs: 244 printf("CHS %u cylinders, %u heads, %u sectors",245 d->geom.cylinders, d->geom.heads,262 rc = asprintf(&atype, "CHS %u cylinders, %u heads, " 263 "%u sectors", d->geom.cylinders, d->geom.heads, 246 264 d->geom.sectors); 265 if (rc < 0) { 266 /* Out of memory */ 267 atype = NULL; 268 } 247 269 break; 248 270 case am_lba28: 249 printf("LBA-28");271 atype = str_dup("LBA-28"); 250 272 break; 251 273 case am_lba48: 252 printf("LBA-48");274 atype = str_dup("LBA-48"); 253 275 break; 254 276 } 255 277 } else { 256 printf("PACKET"); 257 } 258 259 printf(" %" PRIu64 " blocks", d->blocks); 278 atype = str_dup("PACKET"); 279 } 280 281 if (atype == NULL) 282 return; 260 283 261 284 mbytes = d->blocks / (2 * 1024); 262 if (mbytes > 0) 263 printf(" %" PRIu64 " MB.", mbytes); 264 265 printf("\n"); 266 } 267 268 /** Register driver and enable device I/O. */ 269 static int ata_bd_init(void) 270 { 271 async_set_client_connection(ata_bd_connection); 272 int rc = loc_server_register(NAME); 285 if (mbytes > 0) { 286 rc = asprintf(&cap, " %" PRIu64 " MB.", mbytes); 287 if (rc < 0) { 288 cap = NULL; 289 goto cleanup; 290 } 291 } 292 293 ddf_msg(LVL_NOTE, "%s: %s %" PRIu64 " blocks%s", d->model, atype, 294 d->blocks, cap); 295 cleanup: 296 free(atype); 297 free(cap); 298 } 299 300 /** Enable device I/O. */ 301 static int ata_bd_init_io(ata_ctrl_t *ctrl) 302 { 303 int rc; 304 void *vaddr; 305 306 rc = pio_enable((void *) ctrl->cmd_physical, sizeof(ata_cmd_t), &vaddr); 273 307 if (rc != EOK) { 274 printf("%s: Unable to register driver.\n", NAME);308 ddf_msg(LVL_ERROR, "Cannot initialize device I/O space."); 275 309 return rc; 276 310 } 277 278 void *vaddr; 279 rc = pio_enable((void *) cmd_physical, sizeof(ata_cmd_t), &vaddr); 311 312 ctrl->cmd = vaddr; 313 314 rc = pio_enable((void *) ctrl->ctl_physical, sizeof(ata_ctl_t), &vaddr); 280 315 if (rc != EOK) { 281 printf("%s: Could not initialize device I/O space.\n", NAME);316 ddf_msg(LVL_ERROR, "Cannot initialize device I/O space."); 282 317 return rc; 283 318 } 284 285 cmd = vaddr; 286 287 rc = pio_enable((void *) ctl_physical, sizeof(ata_ctl_t), &vaddr); 288 if (rc != EOK) { 289 printf("%s: Could not initialize device I/O space.\n", NAME); 290 return rc; 291 } 292 293 ctl = vaddr; 294 295 return EOK; 296 } 297 298 /** Block device connection handler */ 299 static void ata_bd_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 300 { 301 service_id_t dsid; 302 int i; 303 disk_t *disk; 304 305 /* Get the device service ID. */ 306 dsid = IPC_GET_ARG1(*icall); 307 308 /* Determine which disk device is the client connecting to. */ 309 disk = NULL; 310 for (i = 0; i < MAX_DISKS; i++) 311 if (ata_disk[i].service_id == dsid) 312 disk = &ata_disk[i]; 313 314 if (disk == NULL || disk->present == false) { 315 async_answer_0(iid, EINVAL); 316 return; 317 } 318 319 bd_conn(iid, icall, &disk->bds); 319 320 ctrl->ctl = vaddr; 321 322 return EOK; 323 } 324 325 /** Clean up device I/O. */ 326 static void ata_bd_fini_io(ata_ctrl_t *ctrl) 327 { 328 (void) ctrl; 329 /* XXX TODO */ 320 330 } 321 331 … … 325 335 * the disk structure. 326 336 */ 327 static int disk_init( disk_t *d, int disk_id)337 static int disk_init(ata_ctrl_t *ctrl, disk_t *d, int disk_id) 328 338 { 329 339 identify_data_t idata; … … 337 347 unsigned i; 338 348 349 d->ctrl = ctrl; 339 350 d->disk_id = disk_id; 340 351 d->present = false; 341 fibril_mutex_initialize(&d->lock); 342 343 bd_srvs_init(&d->bds); 344 d->bds.ops = &ata_bd_ops; 345 d->bds.sarg = d; 352 d->afun = NULL; 346 353 347 354 /* Try identify command. */ 348 rc = drive_identify(d, &idata);355 rc = ata_identify_dev(d, &idata); 349 356 if (rc == EOK) { 350 357 /* Success. It's a register (non-packet) device. */ 351 printf("ATA register-only device found.\n");358 ddf_msg(LVL_NOTE, "ATA register-only device found."); 352 359 d->dev_type = ata_reg_dev; 353 360 } else if (rc == EIO) { … … 362 369 * the byte count registers. So, only check these. 363 370 */ 364 bc = ((uint16_t)pio_read_8(&c md->cylinder_high) << 8) |365 pio_read_8(&c md->cylinder_low);371 bc = ((uint16_t)pio_read_8(&ctrl->cmd->cylinder_high) << 8) | 372 pio_read_8(&ctrl->cmd->cylinder_low); 366 373 367 374 if (bc == PDEV_SIGNATURE_BC) { 368 rc = identify_pkt_dev(d, &idata);375 rc = ata_identify_pkt_dev(d, &idata); 369 376 if (rc == EOK) { 370 377 /* We have a packet device. */ … … 452 459 rc = ata_pcmd_inquiry(d, &inq_data, sizeof(inq_data)); 453 460 if (rc != EOK) { 454 printf("Device inquiry failed.\n");461 ddf_msg(LVL_ERROR, "Device inquiry failed."); 455 462 d->present = false; 456 463 return EIO; … … 459 466 /* Check device type. */ 460 467 if (INQUIRY_PDEV_TYPE(inq_data.pdev_type) != PDEV_TYPE_CDROM) 461 printf("Warning: Peripheral device type is not CD-ROM.\n");468 ddf_msg(LVL_WARN, "Peripheral device type is not CD-ROM."); 462 469 463 470 /* Assume 2k block size for now. */ … … 563 570 } 564 571 565 /** Issue IDENTIFY command. 572 /** PIO data-in command protocol. */ 573 static int ata_pio_data_in(disk_t *disk, void *obuf, size_t obuf_size, 574 size_t blk_size, size_t nblocks) 575 { 576 ata_ctrl_t *ctrl = disk->ctrl; 577 uint16_t data; 578 size_t i; 579 uint8_t status; 580 581 /* XXX Support multiple blocks */ 582 assert(nblocks == 1); 583 assert(blk_size % 2 == 0); 584 585 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 586 return EIO; 587 588 if ((status & SR_DRQ) != 0) { 589 /* Read data from the device buffer. */ 590 591 for (i = 0; i < blk_size / 2; i++) { 592 data = pio_read_16(&ctrl->cmd->data_port); 593 ((uint16_t *) obuf)[i] = data; 594 } 595 } 596 597 if ((status & SR_ERR) != 0) 598 return EIO; 599 600 return EOK; 601 } 602 603 /** PIO data-out command protocol. */ 604 static int ata_pio_data_out(disk_t *disk, const void *buf, size_t buf_size, 605 size_t blk_size, size_t nblocks) 606 { 607 ata_ctrl_t *ctrl = disk->ctrl; 608 size_t i; 609 uint8_t status; 610 611 /* XXX Support multiple blocks */ 612 assert(nblocks == 1); 613 assert(blk_size % 2 == 0); 614 615 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 616 return EIO; 617 618 if ((status & SR_DRQ) != 0) { 619 /* Write data to the device buffer. */ 620 621 for (i = 0; i < blk_size / 2; i++) { 622 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) buf)[i]); 623 } 624 } 625 626 if (status & SR_ERR) 627 return EIO; 628 629 return EOK; 630 } 631 632 /** Issue IDENTIFY DEVICE command. 566 633 * 567 634 * Reads @c identify data into the provided buffer. This is used to detect … … 574 641 * not present). EIO if device responds with error. 575 642 */ 576 static int drive_identify(disk_t *disk, void *buf)577 { 578 uint16_t data;643 static int ata_identify_dev(disk_t *disk, void *buf) 644 { 645 ata_ctrl_t *ctrl = disk->ctrl; 579 646 uint8_t status; 580 647 uint8_t drv_head; 581 size_t i;582 648 583 649 drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 584 650 585 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)651 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 586 652 return ETIMEOUT; 587 653 588 pio_write_8(&c md->drive_head, drv_head);654 pio_write_8(&ctrl->cmd->drive_head, drv_head); 589 655 590 656 /* … … 593 659 * set after issuing the command. 594 660 */ 595 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)661 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 596 662 return ETIMEOUT; 597 663 598 pio_write_8(&c md->command, CMD_IDENTIFY_DRIVE);599 600 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK)664 pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_DRIVE); 665 666 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 601 667 return ETIMEOUT; 602 668 … … 605 671 * the caller to check for one. 606 672 */ 607 if ((status & SR_ERR) != 0) { 608 return EIO; 609 } 610 611 if (wait_status(SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 673 if ((status & SR_ERR) != 0) 674 return EIO; 675 676 /* 677 * For probing purposes we need to wait for some status bit to become 678 * active - otherwise we could be fooled just by receiving all zeroes. 679 */ 680 if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_PROBE) != EOK) 612 681 return ETIMEOUT; 613 682 614 /* Read data from the disk buffer. */ 615 616 for (i = 0; i < identify_data_size / 2; i++) { 617 data = pio_read_16(&cmd->data_port); 618 ((uint16_t *) buf)[i] = data; 619 } 620 621 return EOK; 683 return ata_pio_data_in(disk, buf, identify_data_size, 684 identify_data_size, 1); 622 685 } 623 686 … … 630 693 * @param buf Pointer to a 512-byte buffer. 631 694 */ 632 static int identify_pkt_dev(disk_t *disk, void *buf) 633 { 634 uint16_t data; 635 uint8_t status; 695 static int ata_identify_pkt_dev(disk_t *disk, void *buf) 696 { 697 ata_ctrl_t *ctrl = disk->ctrl; 636 698 uint8_t drv_head; 637 size_t i;638 699 639 700 drv_head = ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 640 701 641 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK)642 return EIO; 643 644 pio_write_8(&c md->drive_head, drv_head);702 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 703 return EIO; 704 705 pio_write_8(&ctrl->cmd->drive_head, drv_head); 645 706 646 707 /* For ATAPI commands we do not need to wait for DRDY. */ 647 if (wait_status(0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 648 return EIO; 649 650 pio_write_8(&cmd->command, CMD_IDENTIFY_PKT_DEV); 651 652 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) 653 return EIO; 654 655 /* Read data from the device buffer. */ 656 657 if ((status & SR_DRQ) != 0) { 658 for (i = 0; i < identify_data_size / 2; i++) { 659 data = pio_read_16(&cmd->data_port); 660 ((uint16_t *) buf)[i] = data; 661 } 662 } 663 664 if ((status & SR_ERR) != 0) 665 return EIO; 666 667 return EOK; 708 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) 709 return EIO; 710 711 pio_write_8(&ctrl->cmd->command, CMD_IDENTIFY_PKT_DEV); 712 713 return ata_pio_data_in(disk, buf, identify_data_size, 714 identify_data_size, 1); 668 715 } 669 716 … … 681 728 void *obuf, size_t obuf_size) 682 729 { 730 ata_ctrl_t *ctrl = disk->ctrl; 683 731 size_t i; 684 732 uint8_t status; … … 687 735 uint16_t val; 688 736 689 fibril_mutex_lock(& disk->lock);737 fibril_mutex_lock(&ctrl->lock); 690 738 691 739 /* New value for Drive/Head register */ … … 693 741 ((disk_dev_idx(disk) != 0) ? DHR_DRV : 0); 694 742 695 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) {696 fibril_mutex_unlock(& disk->lock);697 return EIO; 698 } 699 700 pio_write_8(&c md->drive_head, drv_head);701 702 if (wait_status( 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) {703 fibril_mutex_unlock(& disk->lock);743 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_PROBE) != EOK) { 744 fibril_mutex_unlock(&ctrl->lock); 745 return EIO; 746 } 747 748 pio_write_8(&ctrl->cmd->drive_head, drv_head); 749 750 if (wait_status(ctrl, 0, ~(SR_BSY|SR_DRQ), NULL, TIMEOUT_BSY) != EOK) { 751 fibril_mutex_unlock(&ctrl->lock); 704 752 return EIO; 705 753 } 706 754 707 755 /* Byte count <- max. number of bytes we can read in one transfer. */ 708 pio_write_8(&c md->cylinder_low, 0xfe);709 pio_write_8(&c md->cylinder_high, 0xff);710 711 pio_write_8(&c md->command, CMD_PACKET);712 713 if (wait_status( SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {714 fibril_mutex_unlock(& disk->lock);756 pio_write_8(&ctrl->cmd->cylinder_low, 0xfe); 757 pio_write_8(&ctrl->cmd->cylinder_high, 0xff); 758 759 pio_write_8(&ctrl->cmd->command, CMD_PACKET); 760 761 if (wait_status(ctrl, SR_DRQ, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 762 fibril_mutex_unlock(&ctrl->lock); 715 763 return EIO; 716 764 } … … 718 766 /* Write command packet. */ 719 767 for (i = 0; i < (cpkt_size + 1) / 2; i++) 720 pio_write_16(&c md->data_port, ((uint16_t *) cpkt)[i]);721 722 if (wait_status( 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) {723 fibril_mutex_unlock(& disk->lock);768 pio_write_16(&ctrl->cmd->data_port, ((uint16_t *) cpkt)[i]); 769 770 if (wait_status(ctrl, 0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 771 fibril_mutex_unlock(&ctrl->lock); 724 772 return EIO; 725 773 } 726 774 727 775 if ((status & SR_DRQ) == 0) { 728 fibril_mutex_unlock(& disk->lock);776 fibril_mutex_unlock(&ctrl->lock); 729 777 return EIO; 730 778 } 731 779 732 780 /* Read byte count. */ 733 data_size = (uint16_t) pio_read_8(&c md->cylinder_low) +734 ((uint16_t) pio_read_8(&c md->cylinder_high) << 8);781 data_size = (uint16_t) pio_read_8(&ctrl->cmd->cylinder_low) + 782 ((uint16_t) pio_read_8(&ctrl->cmd->cylinder_high) << 8); 735 783 736 784 /* Check whether data fits into output buffer. */ 737 785 if (data_size > obuf_size) { 738 786 /* Output buffer is too small to store data. */ 739 fibril_mutex_unlock(& disk->lock);787 fibril_mutex_unlock(&ctrl->lock); 740 788 return EIO; 741 789 } … … 743 791 /* Read data from the device buffer. */ 744 792 for (i = 0; i < (data_size + 1) / 2; i++) { 745 val = pio_read_16(&c md->data_port);793 val = pio_read_16(&ctrl->cmd->data_port); 746 794 ((uint16_t *) obuf)[i] = val; 747 795 } 748 796 749 if (status & SR_ERR) { 750 fibril_mutex_unlock(&disk->lock); 751 return EIO; 752 } 753 754 fibril_mutex_unlock(&disk->lock); 797 fibril_mutex_unlock(&ctrl->lock); 798 799 if (status & SR_ERR) 800 return EIO; 755 801 756 802 return EOK; … … 849 895 cp.oldformat = 0x40; /* 0x01 = multi-session mode (shifted to MSB) */ 850 896 851 rc = ata_cmd_packet( 0, &cp, sizeof(cp), obuf, obuf_size);897 rc = ata_cmd_packet(disk, &cp, sizeof(cp), obuf, obuf_size); 852 898 if (rc != EOK) 853 899 return rc; … … 856 902 } 857 903 858 /** Read a physical from the device.904 /** Read a physical block from the device. 859 905 * 860 906 * @param disk Disk … … 868 914 void *buf) 869 915 { 870 size_t i; 871 uint16_t data; 872 uint8_t status; 916 ata_ctrl_t *ctrl = disk->ctrl; 873 917 uint8_t drv_head; 874 918 block_coord_t bc; 919 int rc; 875 920 876 921 /* Silence warning. */ … … 887 932 (bc.h & 0x0f); 888 933 889 fibril_mutex_lock(& disk->lock);934 fibril_mutex_lock(&ctrl->lock); 890 935 891 936 /* Program a Read Sectors operation. */ 892 937 893 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {894 fibril_mutex_unlock(& disk->lock);895 return EIO; 896 } 897 898 pio_write_8(&c md->drive_head, drv_head);899 900 if (wait_status( SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {901 fibril_mutex_unlock(& disk->lock);938 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 939 fibril_mutex_unlock(&ctrl->lock); 940 return EIO; 941 } 942 943 pio_write_8(&ctrl->cmd->drive_head, drv_head); 944 945 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 946 fibril_mutex_unlock(&ctrl->lock); 902 947 return EIO; 903 948 } 904 949 905 950 /* Program block coordinates into the device. */ 906 coord_sc_program( &bc, 1);907 908 pio_write_8(&c md->command, disk->amode == am_lba48 ?951 coord_sc_program(ctrl, &bc, 1); 952 953 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? 909 954 CMD_READ_SECTORS_EXT : CMD_READ_SECTORS); 910 955 911 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 912 fibril_mutex_unlock(&disk->lock); 913 return EIO; 914 } 915 916 if ((status & SR_DRQ) != 0) { 917 /* Read data from the device buffer. */ 918 919 for (i = 0; i < disk->block_size / 2; i++) { 920 data = pio_read_16(&cmd->data_port); 921 ((uint16_t *) buf)[i] = data; 922 } 923 } 924 925 if ((status & SR_ERR) != 0) 926 return EIO; 927 928 fibril_mutex_unlock(&disk->lock); 929 return EOK; 956 rc = ata_pio_data_in(disk, buf, blk_cnt * disk->block_size, 957 disk->block_size, blk_cnt); 958 959 fibril_mutex_unlock(&ctrl->lock); 960 961 return rc; 930 962 } 931 963 … … 942 974 const void *buf) 943 975 { 944 size_t i; 945 uint8_t status; 976 ata_ctrl_t *ctrl = disk->ctrl; 946 977 uint8_t drv_head; 947 978 block_coord_t bc; 979 int rc; 948 980 949 981 /* Silence warning. */ … … 960 992 (bc.h & 0x0f); 961 993 962 fibril_mutex_lock(& disk->lock);994 fibril_mutex_lock(&ctrl->lock); 963 995 964 996 /* Program a Write Sectors operation. */ 965 997 966 if (wait_status( 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) {967 fibril_mutex_unlock(& disk->lock);968 return EIO; 969 } 970 971 pio_write_8(&c md->drive_head, drv_head);972 973 if (wait_status( SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) {974 fibril_mutex_unlock(& disk->lock);998 if (wait_status(ctrl, 0, ~SR_BSY, NULL, TIMEOUT_BSY) != EOK) { 999 fibril_mutex_unlock(&ctrl->lock); 1000 return EIO; 1001 } 1002 1003 pio_write_8(&ctrl->cmd->drive_head, drv_head); 1004 1005 if (wait_status(ctrl, SR_DRDY, ~SR_BSY, NULL, TIMEOUT_DRDY) != EOK) { 1006 fibril_mutex_unlock(&ctrl->lock); 975 1007 return EIO; 976 1008 } 977 1009 978 1010 /* Program block coordinates into the device. */ 979 coord_sc_program( &bc, 1);980 981 pio_write_8(&c md->command, disk->amode == am_lba48 ?1011 coord_sc_program(ctrl, &bc, 1); 1012 1013 pio_write_8(&ctrl->cmd->command, disk->amode == am_lba48 ? 982 1014 CMD_WRITE_SECTORS_EXT : CMD_WRITE_SECTORS); 983 1015 984 if (wait_status(0, ~SR_BSY, &status, TIMEOUT_BSY) != EOK) { 985 fibril_mutex_unlock(&disk->lock); 986 return EIO; 987 } 988 989 if ((status & SR_DRQ) != 0) { 990 /* Write data to the device buffer. */ 991 992 for (i = 0; i < disk->block_size / 2; i++) { 993 pio_write_16(&cmd->data_port, ((uint16_t *) buf)[i]); 994 } 995 } 996 997 fibril_mutex_unlock(&disk->lock); 998 999 if (status & SR_ERR) 1000 return EIO; 1001 1002 return EOK; 1016 rc = ata_pio_data_out(disk, buf, cnt * disk->block_size, 1017 disk->block_size, cnt); 1018 1019 fibril_mutex_unlock(&ctrl->lock); 1020 return rc; 1003 1021 } 1004 1022 … … 1060 1078 * 1061 1079 * Note that bc->h must be programmed separately into the device/head register. 1062 */ 1063 static void coord_sc_program(const block_coord_t *bc, uint16_t scnt) 1064 { 1080 * 1081 * @param ctrl Controller 1082 * @param bc Block coordinates 1083 * @param scnt Sector count 1084 */ 1085 static void coord_sc_program(ata_ctrl_t *ctrl, const block_coord_t *bc, 1086 uint16_t scnt) 1087 { 1088 ata_cmd_t *cmd = ctrl->cmd; 1089 1065 1090 if (bc->amode == am_lba48) { 1066 1091 /* Write high-order bits. */ … … 1080 1105 /** Wait until some status bits are set and some are reset. 1081 1106 * 1082 * Example: wait_status( SR_DRDY, ~SR_BSY) waits for SR_DRDY to become1107 * Example: wait_status(ctrl, SR_DRDY, ~SR_BSY, ...) waits for SR_DRDY to become 1083 1108 * set and SR_BSY to become reset. 1084 1109 * 1110 * @param ctrl Controller 1085 1111 * @param set Combination if bits which must be all set. 1086 1112 * @param n_reset Negated combination of bits which must be all reset. … … 1090 1116 * @return EOK on success, EIO on timeout. 1091 1117 */ 1092 static int wait_status( unsigned set, unsigned n_reset, uint8_t *pstatus,1093 u nsigned timeout)1118 static int wait_status(ata_ctrl_t *ctrl, unsigned set, unsigned n_reset, 1119 uint8_t *pstatus, unsigned timeout) 1094 1120 { 1095 1121 uint8_t status; 1096 1122 int cnt; 1097 1123 1098 status = pio_read_8(&c md->status);1124 status = pio_read_8(&ctrl->cmd->status); 1099 1125 1100 1126 /* … … 1110 1136 if (cnt <= 0) break; 1111 1137 1112 status = pio_read_8(&c md->status);1138 status = pio_read_8(&ctrl->cmd->status); 1113 1139 } 1114 1140 … … 1119 1145 if (cnt <= 0) break; 1120 1146 1121 status = pio_read_8(&c md->status);1147 status = pio_read_8(&ctrl->cmd->status); 1122 1148 } 1123 1149 -
uspace/drv/block/ata_bd/ata_bd.h
rf2c19b0 r03c971f 36 36 #define __ATA_BD_H__ 37 37 38 #include <async.h> 38 39 #include <bd_srv.h> 40 #include <ddf/driver.h> 39 41 #include <sys/types.h> 40 42 #include <fibril_synch.h> 41 43 #include <str.h> 44 #include "ata_hw.h" 45 46 #define NAME "ata_bd" 42 47 43 48 /** Base addresses for ATA I/O blocks. */ … … 95 100 typedef struct { 96 101 bool present; 102 struct ata_ctrl *ctrl; 103 struct ata_fun *afun; 97 104 98 105 /** Device type */ … … 116 123 char model[STR_BOUNDS(40) + 1]; 117 124 125 int disk_id; 126 } disk_t; 127 128 /** ATA controller */ 129 typedef struct ata_ctrl { 130 /** DDF device */ 131 ddf_dev_t *dev; 132 /** I/O base address of the command registers */ 133 uintptr_t cmd_physical; 134 /** I/O base address of the control registers */ 135 uintptr_t ctl_physical; 136 137 /** Command registers */ 138 ata_cmd_t *cmd; 139 /** Control registers */ 140 ata_ctl_t *ctl; 141 142 /** Per-disk state. */ 143 disk_t disk[MAX_DISKS]; 144 118 145 fibril_mutex_t lock; 119 service_id_t service_id; 120 int disk_id; 146 } ata_ctrl_t; 147 148 typedef struct ata_fun { 149 ddf_fun_t *fun; 150 disk_t *disk; 121 151 bd_srvs_t bds; 122 } disk_t; 152 } ata_fun_t; 153 154 extern int ata_ctrl_init(ata_ctrl_t *, ata_base_t *); 155 extern int ata_ctrl_remove(ata_ctrl_t *); 156 extern int ata_ctrl_gone(ata_ctrl_t *); 157 158 extern bd_ops_t ata_bd_ops; 123 159 124 160 #endif -
uspace/drv/bus/isa/isa.dev
rf2c19b0 r03c971f 31 31 match 100 isa/cmos-rtc 32 32 io_range 70 2 33 34 ata-c1: 35 match 100 isa/ata_bd 36 io_range 0x1f0 8 37 io_range 0x3f0 8 38 39 ata-c2: 40 match 100 isa/ata_bd 41 io_range 0x170 8 42 io_range 0x370 8 43 44 ata-c3: 45 match 100 isa/ata_bd 46 io_range 0x1e8 8 47 io_range 0x3e8 8 48 49 ata-c4: 50 match 100 isa/ata_bd 51 io_range 0x168 8 52 io_range 0x368 8 -
uspace/drv/bus/usb/ehci/main.c
rf2c19b0 r03c971f 33 33 * Main routines of EHCI driver. 34 34 */ 35 35 36 #include <ddf/driver.h> 36 37 #include <ddf/interrupt.h> 37 38 #include <device/hw_res.h> 38 39 #include <errno.h> 40 #include <stdbool.h> 39 41 #include <str_error.h> 40 42 … … 70 72 static int ehci_dev_add(ddf_dev_t *device) 71 73 { 74 ddf_fun_t *hc_fun = NULL; 75 bool fun_bound = false; 76 72 77 assert(device); 73 #define CHECK_RET_RETURN(ret, message...) \74 if (ret != EOK) { \75 usb_log_error(message); \76 return ret; \77 }78 78 79 79 uintptr_t reg_base = 0; … … 81 81 int irq = 0; 82 82 83 int ret = get_my_registers(device, ®_base, ®_size, &irq); 84 CHECK_RET_RETURN(ret, 85 "Failed to get memory addresses for %" PRIun ": %s.\n", 86 ddf_dev_get_handle(device), str_error(ret)); 83 int rc = get_my_registers(device, ®_base, ®_size, &irq); 84 if (rc != EOK) { 85 usb_log_error("Failed to get memory addresses for %" PRIun 86 ": %s.\n", ddf_dev_get_handle(device), str_error(rc)); 87 goto error; 88 } 89 87 90 usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n", 88 91 reg_base, reg_size, irq); 89 92 90 ret = disable_legacy(device, reg_base, reg_size); 91 CHECK_RET_RETURN(ret, 92 "Failed to disable legacy USB: %s.\n", str_error(ret)); 93 rc = disable_legacy(device, reg_base, reg_size); 94 if (rc != EOK) { 95 usb_log_error("Failed to disable legacy USB: %s.\n", 96 str_error(rc)); 97 goto error; 98 } 93 99 94 ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");100 hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc"); 95 101 if (hc_fun == NULL) { 96 102 usb_log_error("Failed to create EHCI function.\n"); 97 return ENOMEM; 103 rc = ENOMEM; 104 goto error; 98 105 } 106 99 107 hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t)); 100 108 if (ehci_hc == NULL) { 101 109 usb_log_error("Failed to alloc generic HC driver.\n"); 102 return ENOMEM; 110 rc = ENOMEM; 111 goto error; 103 112 } 113 104 114 /* High Speed, no bandwidth */ 105 115 hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL); 106 116 ddf_fun_set_ops(hc_fun, &hc_ops); 107 117 108 ret = ddf_fun_bind(hc_fun); 109 CHECK_RET_RETURN(ret, 110 "Failed to bind EHCI function: %s.\n", 111 str_error(ret)); 112 ret = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY); 113 CHECK_RET_RETURN(ret, 114 "Failed to add EHCI to HC class: %s.\n", 115 str_error(ret)); 118 rc = ddf_fun_bind(hc_fun); 119 if (rc != EOK) { 120 usb_log_error("Failed to bind EHCI function: %s.\n", 121 str_error(rc)); 122 goto error; 123 } 124 125 fun_bound = true; 126 127 rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY); 128 if (rc != EOK) { 129 usb_log_error("Failed to add EHCI to HC class: %s.\n", 130 str_error(rc)); 131 goto error; 132 } 116 133 117 134 usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n", … … 119 136 120 137 return EOK; 121 #undef CHECK_RET_RETURN 138 error: 139 if (fun_bound) 140 ddf_fun_unbind(hc_fun); 141 if (hc_fun != NULL) 142 ddf_fun_destroy(hc_fun); 143 return rc; 122 144 } 123 145 -
uspace/drv/bus/usb/ehci/res.c
rf2c19b0 r03c971f 145 145 return ENOMEM; 146 146 147 #define CHECK_RET_HANGUP_RETURN(ret, message...) \148 if (ret != EOK) { \149 usb_log_error(message); \150 async_hangup(parent_sess); \151 return ret; \152 } else (void)0153 154 147 /* Read the first EEC. i.e. Legacy Support register */ 155 148 uint32_t usblegsup; 156 int r et= pci_config_space_read_32(parent_sess,149 int rc = pci_config_space_read_32(parent_sess, 157 150 eecp + USBLEGSUP_OFFSET, &usblegsup); 158 CHECK_RET_HANGUP_RETURN(ret, 159 "Failed to read USBLEGSUP: %s.\n", str_error(ret)); 151 if (rc != EOK) { 152 usb_log_error("Failed to read USBLEGSUP: %s.\n", 153 str_error(rc)); 154 goto error; 155 } 156 160 157 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 161 158 … … 163 160 * byte. (OS Control semaphore)*/ 164 161 usb_log_debug("Requesting OS control.\n"); 165 r et= pci_config_space_write_8(parent_sess,162 rc = pci_config_space_write_8(parent_sess, 166 163 eecp + USBLEGSUP_OFFSET + 3, 1); 167 CHECK_RET_HANGUP_RETURN(ret, "Failed to request OS EHCI control: %s.\n", 168 str_error(ret)); 164 if (rc != EOK) { 165 usb_log_error("Failed to request OS EHCI control: %s.\n", 166 str_error(rc)); 167 goto error; 168 } 169 169 170 170 size_t wait = 0; 171 171 /* Wait for BIOS to release control. */ 172 r et= pci_config_space_read_32(172 rc = pci_config_space_read_32( 173 173 parent_sess, eecp + USBLEGSUP_OFFSET, &usblegsup); 174 if (rc != EOK) { 175 usb_log_error("Failed reading PCI config space: %s.\n", 176 str_error(rc)); 177 goto error; 178 } 179 174 180 while ((wait < DEFAULT_WAIT) && (usblegsup & USBLEGSUP_BIOS_CONTROL)) { 175 181 async_usleep(WAIT_STEP); 176 r et= pci_config_space_read_32(parent_sess,182 rc = pci_config_space_read_32(parent_sess, 177 183 eecp + USBLEGSUP_OFFSET, &usblegsup); 184 if (rc != EOK) { 185 usb_log_error("Failed reading PCI config space: %s.\n", 186 str_error(rc)); 187 goto error; 188 } 178 189 wait += WAIT_STEP; 179 190 } … … 188 199 usb_log_warning( "BIOS failed to release control after " 189 200 "%zu usecs, force it.\n", wait); 190 r et= pci_config_space_write_32(parent_sess,201 rc = pci_config_space_write_32(parent_sess, 191 202 eecp + USBLEGSUP_OFFSET, USBLEGSUP_OS_CONTROL); 192 CHECK_RET_HANGUP_RETURN(ret, "Failed to force OS control: " 193 "%s.\n", str_error(ret)); 203 if (rc != EOK) { 204 usb_log_error("Failed to force OS control: " 205 "%s.\n", str_error(rc)); 206 goto error; 207 } 208 194 209 /* 195 210 * Check capability type here, value of 01h identifies the capability … … 201 216 /* Read the second EEC Legacy Support and Control register */ 202 217 uint32_t usblegctlsts; 203 r et= pci_config_space_read_32(parent_sess,218 rc = pci_config_space_read_32(parent_sess, 204 219 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 205 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS: %s.\n", 206 str_error(ret)); 220 if (rc != EOK) { 221 usb_log_error("Failed to get USBLEGCTLSTS: %s.\n", 222 str_error(rc)); 223 goto error; 224 } 225 207 226 usb_log_debug("USBLEGCTLSTS: %" PRIx32 ".\n", usblegctlsts); 208 227 /* … … 211 230 * interfering. NOTE: Three upper bits are WC 212 231 */ 213 r et= pci_config_space_write_32(parent_sess,232 rc = pci_config_space_write_32(parent_sess, 214 233 eecp + USBLEGCTLSTS_OFFSET, 0xe0000000); 215 CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) zero USBLEGCTLSTS.\n", ret); 234 if (rc != EOK) { 235 usb_log_error("Failed(%d) zero USBLEGCTLSTS.\n", rc); 236 goto error; 237 } 238 216 239 udelay(10); 217 r et= pci_config_space_read_32(parent_sess,240 rc = pci_config_space_read_32(parent_sess, 218 241 eecp + USBLEGCTLSTS_OFFSET, &usblegctlsts); 219 CHECK_RET_HANGUP_RETURN(ret, "Failed to get USBLEGCTLSTS 2: %s.\n", 220 str_error(ret)); 242 if (rc != EOK) { 243 usb_log_error("Failed to get USBLEGCTLSTS 2: %s.\n", 244 str_error(rc)); 245 goto error; 246 } 247 221 248 usb_log_debug("Zeroed USBLEGCTLSTS: %" PRIx32 ".\n", 222 249 usblegctlsts); … … 224 251 225 252 /* Read again Legacy Support register */ 226 r et= pci_config_space_read_32(parent_sess,253 rc = pci_config_space_read_32(parent_sess, 227 254 eecp + USBLEGSUP_OFFSET, &usblegsup); 228 CHECK_RET_HANGUP_RETURN(ret, "Failed to read USBLEGSUP: %s.\n", 229 str_error(ret)); 255 if (rc != EOK) { 256 usb_log_error("Failed to read USBLEGSUP: %s.\n", 257 str_error(rc)); 258 goto error; 259 } 260 230 261 usb_log_debug("USBLEGSUP: %" PRIx32 ".\n", usblegsup); 231 262 async_hangup(parent_sess); 232 263 return EOK; 233 #undef CHECK_RET_HANGUP_RETURN 264 error: 265 async_hangup(parent_sess); 266 return rc; 234 267 } 235 268 … … 239 272 usb_log_debug("Disabling EHCI legacy support.\n"); 240 273 241 #define CHECK_RET_RETURN(ret, message...) \242 if (ret != EOK) { \243 usb_log_error(message); \244 return ret; \245 } else (void)0246 247 274 /* Map EHCI registers */ 248 275 void *regs = NULL; 249 int ret = pio_enable((void*)reg_base, reg_size, ®s); 250 CHECK_RET_RETURN(ret, "Failed to map registers %p: %s.\n", 251 (void *) reg_base, str_error(ret)); 276 int rc = pio_enable((void*)reg_base, reg_size, ®s); 277 if (rc != EOK) { 278 usb_log_error("Failed to map registers %p: %s.\n", 279 (void *) reg_base, str_error(rc)); 280 return rc; 281 } 252 282 253 283 usb_log_debug2("Registers mapped at: %p.\n", regs); … … 263 293 usb_log_debug("Value of EECP: %x.\n", eecp); 264 294 265 ret = disable_extended_caps(device, eecp); 266 CHECK_RET_RETURN(ret, "Failed to disable extended capabilities: %s.\n", 267 str_error(ret)); 268 269 #undef CHECK_RET_RETURN 295 rc = disable_extended_caps(device, eecp); 296 if (rc != EOK) { 297 usb_log_error("Failed to disable extended capabilities: %s.\n", 298 str_error(rc)); 299 return rc; 300 } 270 301 271 302 /* … … 306 337 usbcmd, *usbcmd, usbsts, *usbsts, usbint, *usbint, usbconf,*usbconf); 307 338 308 return r et;339 return rc; 309 340 } 310 341 -
uspace/drv/bus/usb/ohci/hc.c
rf2c19b0 r03c971f 35 35 36 36 #include <errno.h> 37 #include <stdbool.h> 37 38 #include <str_error.h> 38 39 #include <adt/list.h> … … 83 84 }; 84 85 86 enum { 87 /** Number of PIO ranges used in IRQ code */ 88 hc_irq_pio_range_count = 89 sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t), 90 91 /** Number of commands used in IRQ code */ 92 hc_irq_cmd_count = 93 sizeof(ohci_irq_commands) / sizeof(irq_cmd_t) 94 }; 95 85 96 static void hc_gain_control(hc_t *instance); 86 97 static void hc_start(hc_t *instance); … … 89 100 static int interrupt_emulator(hc_t *instance); 90 101 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 91 92 /** Get number of PIO ranges used in IRQ code.93 * @return Number of ranges.94 */95 size_t hc_irq_pio_range_count(void)96 {97 return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);98 }99 100 /** Get number of commands used in IRQ code.101 * @return Number of commands.102 */103 size_t hc_irq_cmd_count(void)104 {105 return sizeof(ohci_irq_commands) / sizeof(irq_cmd_t);106 }107 102 108 103 /** Generate IRQ code. … … 137 132 } 138 133 134 /** Register interrupt handler. 135 * 136 * @param[in] device Host controller DDF device 137 * @param[in] reg_base Register range base 138 * @param[in] reg_size Register range size 139 * @param[in] irq Interrupt number 140 * @paran[in] handler Interrupt handler 141 * 142 * @return EOK on success or negative error code 143 */ 144 int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, 145 int irq, interrupt_handler_t handler) 146 { 147 int rc; 148 149 irq_pio_range_t irq_ranges[hc_irq_pio_range_count]; 150 irq_cmd_t irq_cmds[hc_irq_cmd_count]; 151 152 irq_code_t irq_code = { 153 .rangecount = hc_irq_pio_range_count, 154 .ranges = irq_ranges, 155 .cmdcount = hc_irq_cmd_count, 156 .cmds = irq_cmds 157 }; 158 159 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 160 sizeof(irq_cmds), reg_base, reg_size); 161 if (rc != EOK) { 162 usb_log_error("Failed to generate IRQ code: %s.\n", 163 str_error(rc)); 164 return rc; 165 } 166 167 /* Register handler to avoid interrupt lockup */ 168 rc = register_interrupt_handler(device, irq, handler, &irq_code); 169 if (rc != EOK) { 170 usb_log_error("Failed to register interrupt handler: %s.\n", 171 str_error(rc)); 172 return rc; 173 } 174 175 return EOK; 176 } 177 139 178 /** Announce OHCI root hub to the DDF 140 179 * … … 145 184 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) 146 185 { 186 bool addr_reqd = false; 187 bool ep_added = false; 188 bool fun_bound = false; 189 int rc; 190 147 191 assert(instance); 148 192 assert(hub_fun); … … 150 194 /* Try to get address 1 for root hub. */ 151 195 instance->rh.address = 1; 152 int ret= usb_device_manager_request_address(196 rc = usb_device_manager_request_address( 153 197 &instance->generic.dev_manager, &instance->rh.address, false, 154 198 USB_SPEED_FULL); 155 if (r et!= EOK) {199 if (rc != EOK) { 156 200 usb_log_error("Failed to get OHCI root hub address: %s\n", 157 str_error(ret)); 158 return ret; 159 } 160 161 #define CHECK_RET_UNREG_RETURN(ret, message...) \ 162 if (ret != EOK) { \ 163 usb_log_error(message); \ 164 usb_endpoint_manager_remove_ep( \ 165 &instance->generic.ep_manager, instance->rh.address, 0, \ 166 USB_DIRECTION_BOTH, NULL, NULL); \ 167 usb_device_manager_release_address( \ 168 &instance->generic.dev_manager, instance->rh.address); \ 169 return ret; \ 170 } else (void)0 171 172 ret = usb_endpoint_manager_add_ep( 201 str_error(rc)); 202 goto error; 203 } 204 205 addr_reqd = true; 206 207 rc = usb_endpoint_manager_add_ep( 173 208 &instance->generic.ep_manager, instance->rh.address, 0, 174 209 USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 175 210 0, NULL, NULL); 176 CHECK_RET_UNREG_RETURN(ret, 177 "Failed to register root hub control endpoint: %s.\n", 178 str_error(ret)); 179 180 ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 181 CHECK_RET_UNREG_RETURN(ret, 182 "Failed to add root hub match-id: %s.\n", str_error(ret)); 183 184 ret = ddf_fun_bind(hub_fun); 185 CHECK_RET_UNREG_RETURN(ret, 186 "Failed to bind root hub function: %s.\n", str_error(ret)); 187 188 ret = usb_device_manager_bind_address(&instance->generic.dev_manager, 211 if (rc != EOK) { 212 usb_log_error("Failed to register root hub control endpoint: %s.\n", 213 str_error(rc)); 214 goto error; 215 } 216 217 ep_added = true; 218 219 rc = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 220 if (rc != EOK) { 221 usb_log_error("Failed to add root hub match-id: %s.\n", 222 str_error(rc)); 223 goto error; 224 } 225 226 rc = ddf_fun_bind(hub_fun); 227 if (rc != EOK) { 228 usb_log_error("Failed to bind root hub function: %s.\n", 229 str_error(rc)); 230 goto error; 231 } 232 233 fun_bound = true; 234 235 rc = usb_device_manager_bind_address(&instance->generic.dev_manager, 189 236 instance->rh.address, ddf_fun_get_handle(hub_fun)); 190 if (r et != EOK)237 if (rc != EOK) { 191 238 usb_log_warning("Failed to bind root hub address: %s.\n", 192 str_error(ret)); 193 194 return EOK; 195 #undef CHECK_RET_RELEASE 239 str_error(rc)); 240 } 241 242 return EOK; 243 error: 244 if (fun_bound) 245 ddf_fun_unbind(hub_fun); 246 if (ep_added) { 247 usb_endpoint_manager_remove_ep( 248 &instance->generic.ep_manager, instance->rh.address, 0, 249 USB_DIRECTION_BOTH, NULL, NULL); 250 } 251 if (addr_reqd) { 252 usb_device_manager_release_address( 253 &instance->generic.dev_manager, instance->rh.address); 254 } 255 return rc; 196 256 } 197 257 … … 208 268 assert(instance); 209 269 210 #define CHECK_RET_RETURN(ret, message...) \ 211 if (ret != EOK) { \ 212 usb_log_error(message); \ 213 return ret; \ 214 } else (void)0 215 216 int ret = 270 int rc = 217 271 pio_enable((void*)regs, reg_size, (void**)&instance->registers); 218 CHECK_RET_RETURN(ret, 219 "Failed to gain access to device registers: %s.\n", str_error(ret)); 272 if (rc != EOK) { 273 usb_log_error("Failed to gain access to device registers: %s.\n", 274 str_error(rc)); 275 return rc; 276 } 220 277 221 278 list_initialize(&instance->pending_batches); … … 228 285 instance->generic.ep_remove_hook = ohci_endpoint_fini; 229 286 230 ret = hc_init_memory(instance); 231 CHECK_RET_RETURN(ret, "Failed to create OHCI memory structures: %s.\n", 232 str_error(ret)); 233 #undef CHECK_RET_RETURN 287 rc = hc_init_memory(instance); 288 if (rc != EOK) { 289 usb_log_error("Failed to create OHCI memory structures: %s.\n", 290 str_error(rc)); 291 return rc; 292 } 234 293 235 294 fibril_mutex_initialize(&instance->guard); -
uspace/drv/bus/usb/ohci/hc.h
rf2c19b0 r03c971f 35 35 #define DRV_OHCI_HC_H 36 36 37 #include <ddf/interrupt.h> 37 38 #include <fibril.h> 38 39 #include <fibril_synch.h> … … 74 75 } hc_t; 75 76 76 size_t hc_irq_pio_range_count(void);77 size_t hc_irq_cmd_count(void);78 77 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 79 78 size_t); 79 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t); 80 80 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun); 81 81 int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts); -
uspace/drv/bus/usb/ohci/ohci.c
rf2c19b0 r03c971f 143 143 int device_setup_ohci(ddf_dev_t *device) 144 144 { 145 bool ih_registered = false; 146 bool hc_inited = false; 147 int rc; 148 145 149 if (device == NULL) 146 150 return EBADMEM; … … 152 156 } 153 157 154 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \155 if (ret != EOK) { \156 if (instance->hc_fun) { \157 ddf_fun_destroy(instance->hc_fun); \158 } \159 if (instance->rh_fun) { \160 ddf_fun_destroy(instance->rh_fun); \161 } \162 usb_log_error(message); \163 return ret; \164 } else (void)0165 166 158 instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc"); 167 int ret = instance->hc_fun ? EOK : ENOMEM; 168 CHECK_RET_DEST_FREE_RETURN(ret, 169 "Failed to create OHCI HC function: %s.\n", str_error(ret)); 159 if (instance->hc_fun == NULL) { 160 usb_log_error("Failed to create OHCI HC function: %s.\n", 161 str_error(ENOMEM)); 162 rc = ENOMEM; 163 goto error; 164 } 165 170 166 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 171 167 ddf_fun_data_implant(instance->hc_fun, &instance->hc); 172 168 173 169 instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh"); 174 ret = instance->rh_fun ? EOK : ENOMEM; 175 CHECK_RET_DEST_FREE_RETURN(ret, 176 "Failed to create OHCI RH function: %s.\n", str_error(ret)); 170 if (instance->rh_fun == NULL) { 171 usb_log_error("Failed to create OHCI RH function: %s.\n", 172 str_error(ENOMEM)); 173 rc = ENOMEM; 174 goto error; 175 } 176 177 177 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 178 178 … … 181 181 int irq = 0; 182 182 183 ret = get_my_registers(device, ®_base, ®_size, &irq); 184 CHECK_RET_DEST_FREE_RETURN(ret, 185 "Failed to get register memory addresses for %" PRIun ": %s.\n", 186 ddf_dev_get_handle(device), str_error(ret)); 183 rc = get_my_registers(device, ®_base, ®_size, &irq); 184 if (rc != EOK) { 185 usb_log_error("Failed to get register memory addresses " 186 "for %" PRIun ": %s.\n", ddf_dev_get_handle(device), 187 str_error(rc)); 188 goto error; 189 } 190 187 191 usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n", 188 192 (void *) reg_base, reg_size, irq); 189 193 190 const size_t ranges_count = hc_irq_pio_range_count(); 191 const size_t cmds_count = hc_irq_cmd_count(); 192 irq_pio_range_t irq_ranges[ranges_count]; 193 irq_cmd_t irq_cmds[cmds_count]; 194 irq_code_t irq_code = { 195 .rangecount = ranges_count, 196 .ranges = irq_ranges, 197 .cmdcount = cmds_count, 198 .cmds = irq_cmds 199 }; 200 201 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 202 sizeof(irq_cmds), reg_base, reg_size); 203 CHECK_RET_DEST_FREE_RETURN(ret, 204 "Failed to generate IRQ code: %s.\n", str_error(ret)); 205 206 207 /* Register handler to avoid interrupt lockup */ 208 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 209 CHECK_RET_DEST_FREE_RETURN(ret, 210 "Failed to register interrupt handler: %s.\n", str_error(ret)); 194 rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler); 195 if (rc != EOK) { 196 usb_log_error("Failed to register interrupt handler: %s.\n", 197 str_error(rc)); 198 goto error; 199 } 200 201 ih_registered = true; 211 202 212 203 /* Try to enable interrupts */ 213 204 bool interrupts = false; 214 r et= enable_interrupts(device);215 if (r et!= EOK) {205 rc = enable_interrupts(device); 206 if (rc != EOK) { 216 207 usb_log_warning("Failed to enable interrupts: %s." 217 " Falling back to polling\n", str_error(r et));208 " Falling back to polling\n", str_error(rc)); 218 209 /* We don't need that handler */ 219 210 unregister_interrupt_handler(device, irq); 211 ih_registered = false; 220 212 } else { 221 213 usb_log_debug("Hw interrupts enabled.\n"); … … 223 215 } 224 216 225 ret = hc_init(&instance->hc, reg_base, reg_size, interrupts); 226 CHECK_RET_DEST_FREE_RETURN(ret, 227 "Failed to init ohci_hcd: %s.\n", str_error(ret)); 228 229 #define CHECK_RET_FINI_RETURN(ret, message...) \ 230 if (ret != EOK) { \ 231 hc_fini(&instance->hc); \ 232 unregister_interrupt_handler(device, irq); \ 233 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 234 } else (void)0 235 236 237 ret = ddf_fun_bind(instance->hc_fun); 238 CHECK_RET_FINI_RETURN(ret, 239 "Failed to bind OHCI device function: %s.\n", str_error(ret)); 240 241 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 242 CHECK_RET_FINI_RETURN(ret, 243 "Failed to add OHCI to HC class: %s.\n", str_error(ret)); 244 245 ret = hc_register_hub(&instance->hc, instance->rh_fun); 246 CHECK_RET_FINI_RETURN(ret, 247 "Failed to register OHCI root hub: %s.\n", str_error(ret)); 248 return ret; 249 250 #undef CHECK_RET_FINI_RETURN 217 rc = hc_init(&instance->hc, reg_base, reg_size, interrupts); 218 if (rc != EOK) { 219 usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc)); 220 goto error; 221 } 222 223 hc_inited = true; 224 225 rc = ddf_fun_bind(instance->hc_fun); 226 if (rc != EOK) { 227 usb_log_error("Failed to bind OHCI device function: %s.\n", 228 str_error(rc)); 229 goto error; 230 } 231 232 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 233 if (rc != EOK) { 234 usb_log_error("Failed to add OHCI to HC category: %s.\n", 235 str_error(rc)); 236 goto error; 237 } 238 239 rc = hc_register_hub(&instance->hc, instance->rh_fun); 240 if (rc != EOK) { 241 usb_log_error("Failed to register OHCI root hub: %s.\n", 242 str_error(rc)); 243 goto error; 244 } 245 246 return EOK; 247 248 error: 249 if (hc_inited) 250 hc_fini(&instance->hc); 251 if (ih_registered) 252 unregister_interrupt_handler(device, irq); 253 if (instance->hc_fun != NULL) 254 ddf_fun_destroy(instance->hc_fun); 255 if (instance->rh_fun != NULL) 256 ddf_fun_destroy(instance->rh_fun); 257 return rc; 251 258 } 252 259 /** -
uspace/drv/bus/usb/uhci/hc.c
rf2c19b0 r03c971f 90 90 static int hc_debug_checker(void *arg); 91 91 92 93 /** Get number of PIO ranges used in IRQ code. 94 * @return Number of ranges. 95 */ 96 size_t hc_irq_pio_range_count(void) 97 { 98 return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t); 99 } 100 101 /** Get number of commands used in IRQ code. 102 * @return Number of commands. 103 */ 104 size_t hc_irq_cmd_count(void) 105 { 106 return sizeof(uhci_irq_commands) / sizeof(irq_cmd_t); 107 } 92 enum { 93 /** Number of PIO ranges used in IRQ code */ 94 hc_irq_pio_range_count = 95 sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t), 96 97 /* Number of commands used in IRQ code */ 98 hc_irq_cmd_count = 99 sizeof(uhci_irq_commands) / sizeof(irq_cmd_t) 100 }; 108 101 109 102 /** Generate IRQ code. … … 133 126 cmds[0].addr = ®isters->usbsts; 134 127 cmds[3].addr = ®isters->usbsts; 128 129 return EOK; 130 } 131 132 /** Register interrupt handler. 133 * 134 * @param[in] device Host controller DDF device 135 * @param[in] reg_base Register range base 136 * @param[in] reg_size Register range size 137 * @param[in] irq Interrupt number 138 * @paran[in] handler Interrupt handler 139 * 140 * @return EOK on success or negative error code 141 */ 142 int hc_register_irq_handler(ddf_dev_t *device, uintptr_t reg_base, size_t reg_size, 143 int irq, interrupt_handler_t handler) 144 { 145 int rc; 146 irq_pio_range_t irq_ranges[hc_irq_pio_range_count]; 147 irq_cmd_t irq_cmds[hc_irq_cmd_count]; 148 rc = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 149 sizeof(irq_cmds), reg_base, reg_size); 150 if (rc != EOK) { 151 usb_log_error("Failed to generate IRQ commands: %s.\n", 152 str_error(rc)); 153 return rc; 154 } 155 156 irq_code_t irq_code = { 157 .rangecount = hc_irq_pio_range_count, 158 .ranges = irq_ranges, 159 .cmdcount = hc_irq_cmd_count, 160 .cmds = irq_cmds 161 }; 162 163 /* Register handler to avoid interrupt lockup */ 164 rc = register_interrupt_handler(device, irq, handler, &irq_code); 165 if (rc != EOK) { 166 usb_log_error("Failed to register interrupt handler: %s.\n", 167 str_error(rc)); 168 return rc; 169 } 135 170 136 171 return EOK; … … 209 244 { 210 245 assert(reg_size >= sizeof(uhci_regs_t)); 211 int ret; 212 213 #define CHECK_RET_RETURN(ret, message...) \ 214 if (ret != EOK) { \ 215 usb_log_error(message); \ 216 return ret; \ 217 } else (void) 0 246 int rc; 218 247 219 248 instance->hw_interrupts = interrupts; … … 222 251 /* allow access to hc control registers */ 223 252 uhci_regs_t *io; 224 ret = pio_enable(regs, reg_size, (void **)&io); 225 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p: %s.\n", 226 io, str_error(ret)); 253 rc = pio_enable(regs, reg_size, (void **)&io); 254 if (rc != EOK) { 255 usb_log_error("Failed to gain access to registers at %p: %s.\n", 256 io, str_error(rc)); 257 return rc; 258 } 259 227 260 instance->registers = io; 228 261 usb_log_debug( 229 262 "Device registers at %p (%zuB) accessible.\n", io, reg_size); 230 263 231 r et= hc_init_mem_structures(instance);232 CHECK_RET_RETURN(ret,233 "Failed to initialize UHCI memory structures: %s.\n",234 str_error(ret));235 236 #undef CHECK_RET_RETURN 264 rc = hc_init_mem_structures(instance); 265 if (rc != EOK) { 266 usb_log_error("Failed to initialize UHCI memory structures: %s.\n", 267 str_error(rc)); 268 return rc; 269 } 237 270 238 271 hcd_init(&instance->generic, USB_SPEED_FULL, … … 397 430 398 431 return EOK; 399 #undef CHECK_RET_CLEAR_RETURN400 432 } 401 433 -
uspace/drv/bus/usb/uhci/hc.h
rf2c19b0 r03c971f 36 36 #define DRV_UHCI_HC_H 37 37 38 #include <ddf/interrupt.h> 38 39 #include <fibril.h> 39 40 #include <usb/host/hcd.h> … … 119 120 } hc_t; 120 121 121 size_t hc_irq_pio_range_count(void); 122 size_t hc_irq_cmd_count(void); 122 int hc_register_irq_handler(ddf_dev_t *, uintptr_t, size_t, int, interrupt_handler_t); 123 123 int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t, 124 124 size_t); -
uspace/drv/bus/usb/uhci/uhci.c
rf2c19b0 r03c971f 38 38 39 39 #include <errno.h> 40 #include <stdbool.h> 40 41 #include <str_error.h> 41 42 #include <ddf/interrupt.h> … … 149 150 int device_setup_uhci(ddf_dev_t *device) 150 151 { 152 bool ih_registered = false; 153 bool hc_inited = false; 154 bool fun_bound = false; 155 int rc; 156 151 157 if (!device) 152 158 return EBADMEM; … … 158 164 } 159 165 160 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \161 if (ret != EOK) { \162 if (instance->hc_fun) \163 ddf_fun_destroy(instance->hc_fun); \164 if (instance->rh_fun) {\165 ddf_fun_destroy(instance->rh_fun); \166 } \167 usb_log_error(message); \168 return ret; \169 } else (void)0170 171 instance->rh_fun = NULL;172 166 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci_hc"); 173 int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK; 174 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n"); 167 if (instance->hc_fun == NULL) { 168 usb_log_error("Failed to create UHCI HC function.\n"); 169 rc = ENOMEM; 170 goto error; 171 } 172 175 173 ddf_fun_set_ops(instance->hc_fun, &hc_ops); 176 174 ddf_fun_data_implant(instance->hc_fun, &instance->hc.generic); 177 175 178 176 instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci_rh"); 179 ret = (instance->rh_fun == NULL) ? ENOMEM : EOK; 180 CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n"); 177 if (instance->rh_fun == NULL) { 178 usb_log_error("Failed to create UHCI RH function.\n"); 179 rc = ENOMEM; 180 goto error; 181 } 182 181 183 ddf_fun_set_ops(instance->rh_fun, &rh_ops); 182 184 ddf_fun_data_implant(instance->rh_fun, &instance->rh); … … 186 188 int irq = 0; 187 189 188 ret = get_my_registers(device, ®_base, ®_size, &irq); 189 CHECK_RET_DEST_FREE_RETURN(ret, 190 "Failed to get I/O addresses for %" PRIun ": %s.\n", 191 ddf_dev_get_handle(device), str_error(ret)); 190 rc = get_my_registers(device, ®_base, ®_size, &irq); 191 if (rc != EOK) { 192 usb_log_error("Failed to get I/O addresses for %" PRIun ": %s.\n", 193 ddf_dev_get_handle(device), str_error(rc)); 194 goto error; 195 } 192 196 usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n", 193 197 (void *) reg_base, reg_size, irq); 194 198 195 ret = disable_legacy(device); 196 CHECK_RET_DEST_FREE_RETURN(ret, 197 "Failed to disable legacy USB: %s.\n", str_error(ret)); 198 199 const size_t ranges_count = hc_irq_pio_range_count(); 200 const size_t cmds_count = hc_irq_cmd_count(); 201 irq_pio_range_t irq_ranges[ranges_count]; 202 irq_cmd_t irq_cmds[cmds_count]; 203 ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds, 204 sizeof(irq_cmds), reg_base, reg_size); 205 CHECK_RET_DEST_FREE_RETURN(ret, 206 "Failed to generate IRQ commands: %s.\n", str_error(ret)); 207 208 irq_code_t irq_code = { 209 .rangecount = ranges_count, 210 .ranges = irq_ranges, 211 .cmdcount = cmds_count, 212 .cmds = irq_cmds 213 }; 214 215 /* Register handler to avoid interrupt lockup */ 216 ret = register_interrupt_handler(device, irq, irq_handler, &irq_code); 217 CHECK_RET_DEST_FREE_RETURN(ret, 218 "Failed to register interrupt handler: %s.\n", str_error(ret)); 199 rc = disable_legacy(device); 200 if (rc != EOK) { 201 usb_log_error("Failed to disable legacy USB: %s.\n", 202 str_error(rc)); 203 goto error; 204 } 205 206 rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler); 207 if (rc != EOK) { 208 usb_log_error("Failed to register interrupt handler: %s.\n", 209 str_error(rc)); 210 goto error; 211 } 212 213 ih_registered = true; 219 214 220 215 bool interrupts = false; 221 r et= enable_interrupts(device);222 if (r et!= EOK) {216 rc = enable_interrupts(device); 217 if (rc != EOK) { 223 218 usb_log_warning("Failed to enable interrupts: %s." 224 " Falling back to polling.\n", str_error(r et));219 " Falling back to polling.\n", str_error(rc)); 225 220 } else { 226 221 usb_log_debug("Hw interrupts enabled.\n"); … … 228 223 } 229 224 230 ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 231 CHECK_RET_DEST_FREE_RETURN(ret, 232 "Failed to init uhci_hcd: %s.\n", str_error(ret)); 233 234 #define CHECK_RET_FINI_RETURN(ret, message...) \ 235 if (ret != EOK) { \ 236 hc_fini(&instance->hc); \ 237 CHECK_RET_DEST_FREE_RETURN(ret, message); \ 238 return ret; \ 239 } else (void)0 240 241 ret = ddf_fun_bind(instance->hc_fun); 242 CHECK_RET_FINI_RETURN(ret, "Failed to bind UHCI device function: %s.\n", 243 str_error(ret)); 244 245 ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 246 CHECK_RET_FINI_RETURN(ret, 247 "Failed to add UHCI to HC class: %s.\n", str_error(ret)); 248 249 ret = rh_init(&instance->rh, instance->rh_fun, 225 rc = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts); 226 if (rc != EOK) { 227 usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(rc)); 228 goto error; 229 } 230 231 hc_inited = true; 232 233 rc = ddf_fun_bind(instance->hc_fun); 234 if (rc != EOK) { 235 usb_log_error("Failed to bind UHCI device function: %s.\n", 236 str_error(rc)); 237 goto error; 238 } 239 240 fun_bound = true; 241 242 rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY); 243 if (rc != EOK) { 244 usb_log_error("Failed to add UHCI to HC class: %s.\n", 245 str_error(rc)); 246 goto error; 247 } 248 249 rc = rh_init(&instance->rh, instance->rh_fun, 250 250 (uintptr_t)instance->hc.registers + 0x10, 4); 251 CHECK_RET_FINI_RETURN(ret, 252 "Failed to setup UHCI root hub: %s.\n", str_error(ret)); 253 254 ret = ddf_fun_bind(instance->rh_fun); 255 CHECK_RET_FINI_RETURN(ret, 256 "Failed to register UHCI root hub: %s.\n", str_error(ret)); 251 if (rc != EOK) { 252 usb_log_error("Failed to setup UHCI root hub: %s.\n", 253 str_error(rc)); 254 goto error; 255 } 256 257 rc = ddf_fun_bind(instance->rh_fun); 258 if (rc != EOK) { 259 usb_log_error("Failed to register UHCI root hub: %s.\n", 260 str_error(rc)); 261 goto error; 262 } 257 263 258 264 return EOK; 259 #undef CHECK_RET_FINI_RETURN 265 266 error: 267 if (fun_bound) 268 ddf_fun_unbind(instance->hc_fun); 269 if (hc_inited) 270 hc_fini(&instance->hc); 271 if (ih_registered) 272 unregister_interrupt_handler(device, irq); 273 if (instance->hc_fun != NULL) 274 ddf_fun_destroy(instance->hc_fun); 275 if (instance->rh_fun != NULL) { 276 ddf_fun_destroy(instance->rh_fun); 277 } 278 return rc; 260 279 } 261 280 /** -
uspace/drv/bus/usb/uhcirh/main.c
rf2c19b0 r03c971f 93 93 size_t io_size = 0; 94 94 uhci_root_hub_t *rh = NULL; 95 int r et = EOK;95 int rc; 96 96 97 #define CHECK_RET_FREE_RH_RETURN(ret, message...) \ 98 if (ret != EOK) { \ 99 usb_log_error(message); \ 100 return ret; \ 101 } else (void)0 97 rc = hc_get_my_registers(device, &io_regs, &io_size); 98 if (rc != EOK) { 99 usb_log_error( "Failed to get registers from HC: %s.\n", 100 str_error(rc)); 101 return rc; 102 } 102 103 103 ret = hc_get_my_registers(device, &io_regs, &io_size);104 CHECK_RET_FREE_RH_RETURN(ret,105 "Failed to get registers from HC: %s.\n", str_error(ret));106 104 usb_log_debug("I/O regs at %p (size %zuB).\n", 107 105 (void *) io_regs, io_size); 108 106 109 107 rh = ddf_dev_data_alloc(device, sizeof(uhci_root_hub_t)); 110 ret = (rh == NULL) ? ENOMEM : EOK; 111 CHECK_RET_FREE_RH_RETURN(ret, 112 "Failed to allocate rh driver instance.\n"); 108 if (rh == NULL) { 109 usb_log_error("Failed to allocate rh driver instance.\n"); 110 return ENOMEM; 111 } 113 112 114 ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 115 CHECK_RET_FREE_RH_RETURN(ret, 116 "Failed(%d) to initialize rh driver instance: %s.\n", 117 ret, str_error(ret)); 113 rc = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 114 if (rc != EOK) { 115 usb_log_error("Failed(%d) to initialize rh driver instance: " 116 "%s.\n", rc, str_error(rc)); 117 return rc; 118 } 118 119 119 120 usb_log_info("Controlling root hub '%s' (%" PRIun ").\n", 120 121 ddf_dev_get_name(device), ddf_dev_get_handle(device)); 122 121 123 return EOK; 122 124 } -
uspace/drv/bus/usb/uhcirh/port.c
rf2c19b0 r03c971f 150 150 { 151 151 uhci_port_t *instance = port; 152 int rc; 152 153 assert(instance); 153 154 154 155 unsigned allowed_failures = MAX_ERROR_COUNT; 155 #define CHECK_RET_FAIL(ret, msg...) \156 if (ret != EOK) { \157 usb_log_error(msg); \158 if (!(allowed_failures-- > 0)) { \159 usb_log_fatal( \160 "Maximum number of failures reached, " \161 "bailing out.\n"); \162 return ret; \163 } \164 continue; \165 } else (void)0166 156 167 157 while (1) { … … 182 172 instance->id_string, port_status); 183 173 184 int ret = usb_hc_connection_open(&instance->hc_connection); 185 CHECK_RET_FAIL(ret, "%s: Failed to connect to HC %s.\n", 186 instance->id_string, str_error(ret)); 174 rc = usb_hc_connection_open(&instance->hc_connection); 175 if (rc != EOK) { 176 usb_log_error("%s: Failed to connect to HC %s.\n", 177 instance->id_string, str_error(rc)); 178 if (!(allowed_failures-- > 0)) 179 goto fatal_error; 180 continue; 181 } 187 182 188 183 /* Remove any old device */ … … 204 199 } 205 200 206 ret = usb_hc_connection_close(&instance->hc_connection); 207 CHECK_RET_FAIL(ret, "%s: Failed to disconnect from hc: %s.\n", 208 instance->id_string, str_error(ret)); 209 } 210 return EOK; 201 rc = usb_hc_connection_close(&instance->hc_connection); 202 if (rc != EOK) { 203 usb_log_error("%s: Failed to disconnect from HC %s.\n", 204 instance->id_string, str_error(rc)); 205 if (!(allowed_failures-- > 0)) 206 goto fatal_error; 207 continue; 208 } 209 } 210 211 return EOK; 212 213 fatal_error: 214 usb_log_fatal("Maximum number of failures reached, bailing out.\n"); 215 return rc; 211 216 } 212 217 -
uspace/drv/bus/usb/vhc/hub/virthubops.c
rf2c19b0 r03c971f 299 299 size_t *act_size) 300 300 { 301 int rc ;301 int rc = ENOTSUP; 302 302 size_t port = request->index - 1; 303 303 usb_hub_class_feature_t feature = request->value; -
uspace/drv/char/i8042/i8042.c
rf2c19b0 r03c971f 63 63 #define i8042_AUX_DISABLE 0x20 64 64 #define i8042_KBD_TRANSLATE 0x40 /* Use this to switch to XT scancodes */ 65 66 #define CHECK_RET_DESTROY(ret, msg...) \67 do { \68 if (ret != EOK) { \69 ddf_msg(LVL_ERROR, msg); \70 if (dev->kbd_fun) { \71 dev->kbd_fun->driver_data = NULL; \72 ddf_fun_destroy(dev->kbd_fun); \73 } \74 if (dev->aux_fun) { \75 dev->aux_fun->driver_data = NULL; \76 ddf_fun_destroy(dev->aux_fun); \77 } \78 } \79 } while (0)80 81 #define CHECK_RET_UNBIND_DESTROY(ret, msg...) \82 do { \83 if (ret != EOK) { \84 ddf_msg(LVL_ERROR, msg); \85 if (dev->kbd_fun) { \86 ddf_fun_unbind(dev->kbd_fun); \87 dev->kbd_fun->driver_data = NULL; \88 ddf_fun_destroy(dev->kbd_fun); \89 } \90 if (dev->aux_fun) { \91 ddf_fun_unbind(dev->aux_fun); \92 dev->aux_fun->driver_data = NULL; \93 ddf_fun_destroy(dev->aux_fun); \94 } \95 } \96 } while (0)97 65 98 66 void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); -
uspace/drv/char/i8042/main.c
rf2c19b0 r03c971f 45 45 #include <async.h> 46 46 #include "i8042.h" 47 48 #define CHECK_RET_RETURN(ret, message...) \49 do { \50 if (ret != EOK) { \51 ddf_msg(LVL_ERROR, message); \52 return ret; \53 } \54 } while (0)55 47 56 48 /** Get address of I/O registers. … … 112 104 static int i8042_dev_add(ddf_dev_t *device) 113 105 { 114 if (!device)115 return EINVAL;116 117 106 uintptr_t io_regs = 0; 118 107 size_t io_size = 0; 119 108 int kbd = 0; 120 109 int mouse = 0; 110 int rc; 121 111 122 int ret = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse); 123 CHECK_RET_RETURN(ret, "Failed to get registers: %s.", 124 str_error(ret)); 112 if (!device) 113 return EINVAL; 114 115 rc = get_my_registers(device, &io_regs, &io_size, &kbd, &mouse); 116 if (rc != EOK) { 117 ddf_msg(LVL_ERROR, "Failed to get registers: %s.", 118 str_error(rc)); 119 return rc; 120 } 121 125 122 ddf_msg(LVL_DEBUG, "I/O regs at %p (size %zuB), IRQ kbd %d, IRQ mouse %d.", 126 123 (void *) io_regs, io_size, kbd, mouse); 127 124 128 125 i8042_t *i8042 = ddf_dev_data_alloc(device, sizeof(i8042_t)); 129 ret = (i8042 == NULL) ? ENOMEM : EOK; 130 CHECK_RET_RETURN(ret, "Failed to allocate i8042 driver instance."); 126 if (i8042 == NULL) { 127 ddf_msg(LVL_ERROR, "Out of memory."); 128 return ENOMEM; 129 } 131 130 132 ret = i8042_init(i8042, (void *) io_regs, io_size, kbd, mouse, device); 133 CHECK_RET_RETURN(ret, "Failed to initialize i8042 driver: %s.", 134 str_error(ret)); 131 rc = i8042_init(i8042, (void *) io_regs, io_size, kbd, mouse, device); 132 if (rc != EOK) { 133 ddf_msg(LVL_ERROR, "Failed to initialize i8042 driver: %s.", 134 str_error(rc)); 135 return rc; 136 } 135 137 136 138 ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", -
uspace/drv/char/ns8250/ns8250.c
rf2c19b0 r03c971f 160 160 /** I/O registers **/ 161 161 ns8250_regs_t *regs; 162 /** Is there any clientconnected to the device? */163 bool client_connected;162 /** Are there any clients connected to the device? */ 163 unsigned client_connections; 164 164 /** The irq assigned to this device. */ 165 165 int irq; … … 236 236 * 237 237 * @param fun The serial port function 238 * @param buf The ou put buffer for read data.238 * @param buf The output buffer for read data. 239 239 * @param count The number of bytes to be read. 240 240 * … … 420 420 ns->irq = res->res.interrupt.irq; 421 421 irq = true; 422 ddf_msg(LVL_NOTE, "Device %s was as igned irq = 0x%x.",422 ddf_msg(LVL_NOTE, "Device %s was assigned irq = 0x%x.", 423 423 ddf_dev_get_name(ns->dev), ns->irq); 424 424 break; … … 433 433 } 434 434 ioport = true; 435 ddf_msg(LVL_NOTE, "Device %s was as igned I/O address = "435 ddf_msg(LVL_NOTE, "Device %s was assigned I/O address = " 436 436 "0x%x.", ddf_dev_get_name(ns->dev), ns->io_addr); 437 437 break; … … 753 753 uint8_t val = ns8250_read_8(regs); 754 754 755 if (ns->client_connect ed) {755 if (ns->client_connections > 0) { 756 756 bool buf_was_empty = buf_is_empty(&ns->input_buffer); 757 757 if (!buf_push_back(&ns->input_buffer, val)) { … … 827 827 ddf_fun_t *fun = NULL; 828 828 bool need_cleanup = false; 829 bool need_unreg_intr_handler = false; 829 830 int rc; 830 831 … … 869 870 goto fail; 870 871 } 872 need_unreg_intr_handler = true; 871 873 872 874 /* Enable interrupt. */ … … 903 905 if (fun != NULL) 904 906 ddf_fun_destroy(fun); 907 if (need_unreg_intr_handler) 908 ns8250_unregister_interrupt_handler(ns); 905 909 if (need_cleanup) 906 910 ns8250_dev_cleanup(ns); … … 914 918 915 919 fibril_mutex_lock(&ns->mutex); 916 if (ns->client_connect ed) {920 if (ns->client_connections > 0) { 917 921 fibril_mutex_unlock(&ns->mutex); 918 922 return EBUSY; … … 948 952 949 953 fibril_mutex_lock(&ns->mutex); 950 if (ns->client_connected) { 951 res = ELIMIT; 952 } else if (ns->removed) { 954 if (ns->removed) { 953 955 res = ENXIO; 954 956 } else { 955 957 res = EOK; 956 ns->client_connect ed = true;958 ns->client_connections++; 957 959 } 958 960 fibril_mutex_unlock(&ns->mutex); … … 974 976 fibril_mutex_lock(&data->mutex); 975 977 976 assert(data->client_connect ed);977 978 data->client_connected = false;979 buf_clear(&data->input_buffer);978 assert(data->client_connections > 0); 979 980 if (!(--data->client_connections)) 981 buf_clear(&data->input_buffer); 980 982 981 983 fibril_mutex_unlock(&data->mutex); -
uspace/drv/char/ps2mouse/main.c
rf2c19b0 r03c971f 80 80 static int mouse_add(ddf_dev_t *device) 81 81 { 82 int rc; 83 82 84 if (!device) 83 85 return EINVAL; 84 86 85 #define CHECK_RET_RETURN(ret, message...) \ 86 if (ret != EOK) { \ 87 ddf_msg(LVL_ERROR, message); \88 return ret; \89 } else (void)0 87 ps2_mouse_t *mouse = ddf_dev_data_alloc(device, sizeof(ps2_mouse_t)); 88 if (mouse == NULL) { 89 ddf_msg(LVL_ERROR, "Failed to allocate mouse driver instance."); 90 return ENOMEM; 91 } 90 92 91 ps2_mouse_t *mouse = ddf_dev_data_alloc(device, sizeof(ps2_mouse_t)); 92 int ret = (mouse == NULL) ? ENOMEM : EOK; 93 CHECK_RET_RETURN(ret, "Failed to allocate mouse driver instance."); 94 95 ret = ps2_mouse_init(mouse, device); 96 CHECK_RET_RETURN(ret, 97 "Failed to initialize mouse driver: %s.", str_error(ret)); 93 rc = ps2_mouse_init(mouse, device); 94 if (rc != EOK) { 95 ddf_msg(LVL_ERROR, "Failed to initialize mouse driver: %s.", 96 str_error(rc)); 97 return rc; 98 } 98 99 99 100 ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", -
uspace/drv/char/ps2mouse/ps2mouse.c
rf2c19b0 r03c971f 70 70 #define PS2_BUTTON_MASK(button) (1 << button) 71 71 72 #define MOUSE_READ_BYTE_TEST(sess, value ) \72 #define MOUSE_READ_BYTE_TEST(sess, value_) \ 73 73 do { \ 74 uint8_t value = (value_); \ 74 75 uint8_t data = 0; \ 75 76 const ssize_t size = chardev_read(sess, &data, 1); \ … … 78 79 return size < 0 ? size : EIO; \ 79 80 } \ 80 if (data != (value)) { \81 if (data != value) { \ 81 82 ddf_msg(LVL_DEBUG, "Failed testing byte: got %hhx vs. %hhx)", \ 82 data, (value)); \83 data, value); \ 83 84 return EIO; \ 84 85 } \ 85 86 } while (0) 86 87 87 #define MOUSE_WRITE_BYTE(sess, value ) \88 #define MOUSE_WRITE_BYTE(sess, value_) \ 88 89 do { \ 90 uint8_t value = (value_); \ 89 91 uint8_t data = (value); \ 90 92 const ssize_t size = chardev_write(sess, &data, 1); \ -
uspace/drv/char/xtkbd/main.c
rf2c19b0 r03c971f 80 80 static int xt_kbd_add(ddf_dev_t *device) 81 81 { 82 int rc; 83 82 84 if (!device) 83 85 return EINVAL; 84 86 85 #define CHECK_RET_RETURN(ret, message...) \ 86 if (ret != EOK) { \ 87 ddf_msg(LVL_ERROR, message); \88 return ret; \89 } else (void)0 87 xt_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(xt_kbd_t)); 88 if (kbd == NULL) { 89 ddf_msg(LVL_ERROR, "Failed to allocate XT/KBD driver instance."); 90 return ENOMEM; 91 } 90 92 91 xt_kbd_t *kbd = ddf_dev_data_alloc(device, sizeof(xt_kbd_t)); 92 int ret = (kbd == NULL) ? ENOMEM : EOK; 93 CHECK_RET_RETURN(ret, "Failed to allocate XT/KBD driver instance."); 94 95 ret = xt_kbd_init(kbd, device); 96 CHECK_RET_RETURN(ret, 97 "Failed to initialize XT_KBD driver: %s.", str_error(ret)); 93 rc = xt_kbd_init(kbd, device); 94 if (rc != EOK) { 95 ddf_msg(LVL_ERROR, "Failed to initialize XT_KBD driver: %s.", 96 str_error(rc)); 97 return rc; 98 } 98 99 99 100 ddf_msg(LVL_NOTE, "Controlling '%s' (%" PRIun ").", -
uspace/drv/infrastructure/rootamdm37x/rootamdm37x.c
rf2c19b0 r03c971f 48 48 49 49 typedef struct { 50 const char *name; 51 match_id_t match_id; 50 52 hw_resource_list_t hw_resources; 51 53 } rootamdm37x_fun_t; 52 54 53 /* See amdm37x TRM page. 3316 for these values */ 54 #define OHCI_BASE_ADDRESS 0x48064400 55 #define OHCI_SIZE 1024 56 #define EHCI_BASE_ADDRESS 0x48064800 57 #define EHCI_SIZE 1024 55 /* See amdm37x TRM page 3316 for these values */ 56 #define OHCI_BASE_ADDRESS 0x48064400 57 #define OHCI_SIZE 1024 58 #define EHCI_BASE_ADDRESS 0x48064800 59 #define EHCI_SIZE 1024 60 61 /* See amdm37x TRM page 1813 for these values */ 62 #define DSS_BASE_ADDRESS 0x48050000 63 #define DSS_SIZE 512 64 #define DISPC_BASE_ADDRESS 0x48050400 65 #define DISPC_SIZE 1024 66 #define VIDEO_ENC_BASE_ADDRESS 0x48050C00 67 #define VIDEO_ENC_SIZE 256 68 58 69 59 70 static hw_resource_t ohci_res[] = { … … 88 99 }; 89 100 90 static const rootamdm37x_fun_t ohci = { 91 .hw_resources = { 92 .resources = ohci_res, 93 .count = sizeof(ohci_res)/sizeof(ohci_res[0]), 94 } 95 }; 96 97 static const rootamdm37x_fun_t ehci = { 98 .hw_resources = { 99 .resources = ehci_res, 100 .count = sizeof(ehci_res) / sizeof(ehci_res[0]), 101 } 102 }; 101 static hw_resource_t disp_res[] = { 102 { 103 .type = MEM_RANGE, 104 .res.io_range = { 105 .address = DSS_BASE_ADDRESS, 106 .size = DSS_SIZE, 107 .endianness = LITTLE_ENDIAN 108 }, 109 }, 110 { 111 .type = MEM_RANGE, 112 .res.io_range = { 113 .address = DISPC_BASE_ADDRESS, 114 .size = DISPC_SIZE, 115 .endianness = LITTLE_ENDIAN 116 }, 117 }, 118 { 119 .type = MEM_RANGE, 120 .res.io_range = { 121 .address = VIDEO_ENC_BASE_ADDRESS, 122 .size = VIDEO_ENC_SIZE, 123 .endianness = LITTLE_ENDIAN 124 }, 125 }, 126 { 127 .type = INTERRUPT, 128 .res.interrupt = { .irq = 25 }, 129 }, 130 }; 131 132 static const rootamdm37x_fun_t amdm37x_funcs[] = { 133 { 134 .name = "ohci", 135 .match_id = { .id = "usb/host=ohci", .score = 90 }, 136 .hw_resources = { .resources = ohci_res, .count = ARRAY_SIZE(ohci_res) } 137 }, 138 { 139 .name = "ehci", 140 .match_id = { .id = "usb/host=ehci", .score = 90 }, 141 .hw_resources = { .resources = ehci_res, .count = ARRAY_SIZE(ehci_res) } 142 }, 143 { 144 .name = "fb", 145 .match_id = { .id = "amdm37x&dispc", .score = 90 }, 146 .hw_resources = { .resources = disp_res, .count = ARRAY_SIZE(disp_res) } 147 }, 148 }; 149 103 150 104 151 static hw_resource_list_t *rootamdm37x_get_resources(ddf_fun_t *fnode); … … 114 161 }; 115 162 116 static int rootamdm37x_add_fun(ddf_dev_t *dev, const char *name, 117 const char *str_match_id, const rootamdm37x_fun_t *fun) 118 { 119 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", name); 120 163 static int rootamdm37x_add_fun(ddf_dev_t *dev, const rootamdm37x_fun_t *fun) 164 { 165 assert(dev); 166 assert(fun); 167 168 ddf_msg(LVL_DEBUG, "Adding new function '%s'.", fun->name); 169 121 170 /* Create new device function. */ 122 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, name);171 ddf_fun_t *fnode = ddf_fun_create(dev, fun_inner, fun->name); 123 172 if (fnode == NULL) 124 173 return ENOMEM; 125 174 126 175 /* Add match id */ 127 int ret = ddf_fun_add_match_id(fnode, str_match_id, 100); 176 int ret = ddf_fun_add_match_id(fnode, 177 fun->match_id.id, fun->match_id.score); 128 178 if (ret != EOK) { 129 179 ddf_fun_destroy(fnode); … … 146 196 ret = ddf_fun_bind(fnode); 147 197 if (ret != EOK) { 148 ddf_msg(LVL_ERROR, "Failed binding function %s.", name);198 ddf_msg(LVL_ERROR, "Failed binding function %s.", fun->name); 149 199 ddf_fun_destroy(fnode); 150 200 return ret; … … 189 239 190 240 /* Register functions */ 191 if (rootamdm37x_add_fun(dev, "ohci", "usb/host=ohci", &ohci) != EOK) 192 ddf_msg(LVL_ERROR, "Failed to add OHCI function for " 193 "BeagleBoard-xM platform."); 194 if (rootamdm37x_add_fun(dev, "ehci", "usb/host=ehci", &ehci) != EOK) 195 ddf_msg(LVL_ERROR, "Failed to add EHCI function for " 196 "BeagleBoard-xM platform."); 197 if (rootamdm37x_add_fun(dev, "dispc", "amdm37x&dispc", &ehci) != EOK) 198 ddf_msg(LVL_ERROR, "Failed to add dispc function for " 199 "BeagleBoard-xM platform."); 200 241 for (unsigned i = 0; i < ARRAY_SIZE(amdm37x_funcs); ++i) { 242 if (rootamdm37x_add_fun(dev, &amdm37x_funcs[i]) != EOK) 243 ddf_msg(LVL_ERROR, "Failed to add %s function for " 244 "BeagleBoard-xM platform.", amdm37x_funcs[i].name); 245 } 201 246 return EOK; 202 247 } -
uspace/drv/infrastructure/rootamdm37x/uhh.h
rf2c19b0 r03c971f 85 85 #define UHH_DEBUG_CSR_EHCI_SIMULATION_MODE_FLAG (1 << 6) 86 86 #define UHH_DEBUG_CSR_OHCI_CNTSEL_FLAG (1 << 7) 87 #define UHH_DEBUG_CSR_OHCI_GLOBAL_ sUSPEND_FLAG (1 << 16)87 #define UHH_DEBUG_CSR_OHCI_GLOBAL_SUSPEND_FLAG (1 << 16) 88 88 #define UHH_DEBUG_CSR_OHCI_CCS1_FLAG (1 << 17) 89 89 #define UHH_DEBUG_CSR_OHCI_CCS2_FLAG (1 << 18) -
uspace/drv/nic/rtl8139/driver.c
rf2c19b0 r03c971f 620 620 if (size == 0 || size > RTL8139_FRAME_MAX_LENGTH) { 621 621 ddf_msg(LVL_ERROR, "Receiver error -> receiver reset (size: %4" PRIu16 ", " 622 "header 0x%4" PRIx 16 ". Offset: %d)", size, frame_header,622 "header 0x%4" PRIx32 ". Offset: %" PRIu16 ")", size, frame_header, 623 623 rx_offset); 624 624 goto rx_err;
Note:
See TracChangeset
for help on using the changeset viewer.
