|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved. ! 25: * ! 26: * dma.m - kern_dev stub for IODevice testing. ! 27: * ! 28: * HISTORY ! 29: * 08-Apr-91 Doug Mitchell at NeXT ! 30: * Created. ! 31: */ ! 32: ! 33: #import <objc/objc.h> ! 34: #import <driverkit/driverServer.h> ! 35: #import <driverkit/return.h> ! 36: #import <driverkit/Device_ddm.h> ! 37: #import <architecture/nrw/io.h> ! 38: #import <driverkit/generalFuncs.h> ! 39: #import <driverkit/interruptMsg.h> ! 40: #import <machkit/NXLock.h> ! 41: #import <bsd/sys/printf.h> ! 42: #import <driverkit/IODeviceParams.h> ! 43: #import <libc.h> ! 44: ! 45: #ifndef KERNEL ! 46: #define vm_map_t vm_task_t ! 47: #endif KERNEL ! 48: ! 49: /* ! 50: * Struct for "enqueueing" dma requests. ! 51: */ ! 52: typedef struct { ! 53: unsigned dma_id; ! 54: vm_offset_t address; ! 55: unsigned byte_count; ! 56: unsigned completed:1; ! 57: queue_chain_t link; ! 58: } dma_frame_t; ! 59: ! 60: /* ! 61: * Info for one mapped dma channel. ! 62: */ ! 63: typedef struct { ! 64: queue_head_t frame_list; // queue of dma frames ! 65: id channel_lock; ! 66: unsigned mapped:1, // true if channel is mapped ! 67: running:1; ! 68: IODmaDirection dir; ! 69: } dma_chan_t; ! 70: ! 71: /* ! 72: * Static variables for "registering" one (and only one) device. ! 73: * If we want to get fancy, we can make these one-per-dev_port. ! 74: */ ! 75: BOOL dev_port_exists = NO; // dev_port_create() called ! 76: BOOL dev_is_mapped = NO; // dev_reg_mapped() called ! 77: port_t interrupt_port = PORT_NULL; ! 78: BOOL streamMode; ! 79: dma_chan_t channel[CHAN_PER_DEV]; ! 80: IODevicePage *dev_page = NULL; ! 81: BOOL int_enabled; ! 82: BOOL int_pending; ! 83: ! 84: static dma_frame_t *dma_frame_alloc(); ! 85: static void dma_frame_free(dma_frame_t *frame); ! 86: static void set_eor(int channel); ! 87: static void set_error_int(int channel); ! 88: ! 89: IOReturn _IOLookupByObjectNumber( ! 90: port_t device_master, ! 91: IODeviceNumber dev_number, ! 92: IOSlotId *slot_id, // returned ! 93: IODeviceType *dev_type, ! 94: BOOL *in_use) ! 95: { ! 96: xpr_dma("dev_get_type\n", 1,2,3,4,5); ! 97: return(IO_R_SUCCESS); ! 98: } ! 99: ! 100: IOReturn _IOLookupByObjectNumberFromPort( ! 101: port_t dev_port, ! 102: IOSlotId *slot_id, // returned ! 103: IODeviceType *dev_type) // returned ! 104: { ! 105: xpr_dma("dev_port_to_type\n", 1,2,3,4,5); ! 106: return(IO_R_SUCCESS); ! 107: } ! 108: ! 109: IOReturn _IOCreateDevicePort( ! 110: port_t device_master, ! 111: task_t target_task, ! 112: IODeviceNumber dev_num, ! 113: port_name_t *dev_port) ! 114: { ! 115: xpr_dma("dev_port_create\n", 1,2,3,4,5); ! 116: dev_port_exists = YES; ! 117: return(IO_R_SUCCESS); ! 118: } ! 119: ! 120: IOReturn _IODestroyDevicePort( ! 121: port_t device_master, ! 122: port_t dev_port) ! 123: { ! 124: xpr_dma("dev_port_destroy\n", 1,2,3,4,5); ! 125: dev_port_exists = NO; ! 126: return(IO_R_SUCCESS); ! 127: } ! 128: ! 129: IOReturn _IOAttachInterrupt( ! 130: port_t dev_port, ! 131: port_t intr_port) ! 132: { ! 133: xpr_dma("dev_intr_attach\n", 1,2,3,4,5); ! 134: if(!dev_port_exists) { ! 135: IOLog("dev_intr_attach: no dev_port\n"); ! 136: return IO_R_PRIVILEGE; ! 137: } ! 138: interrupt_port = intr_port; ! 139: int_enabled = NO; ! 140: return(IO_R_SUCCESS); ! 141: } ! 142: ! 143: IOReturn _IODetachInterrupt( ! 144: port_t dev_port, ! 145: port_t intr_port) ! 146: { ! 147: xpr_dma("dev_intr_detach\n", 1,2,3,4,5); ! 148: if(!dev_port_exists) { ! 149: IOLog("dev_intr_detach: no dev_port\n"); ! 150: return IO_R_PRIVILEGE; ! 151: } ! 152: if(interrupt_port == PORT_NULL) { ! 153: IOLog("dev_intr_detach: no interrupt port\n"); ! 154: return IO_R_NOT_ATTACHED; ! 155: } ! 156: interrupt_port = PORT_NULL; ! 157: return(IO_R_SUCCESS); ! 158: } ! 159: IOReturn _IOAttachChannel( ! 160: port_t dev_port, ! 161: int chan_num, ! 162: BOOL stream_mode, ! 163: int buffer_size) ! 164: { ! 165: dma_chan_t *chan; ! 166: ! 167: xpr_dma("dev_chan_attach\n", 1,2,3,4,5); ! 168: if(!dev_port_exists) { ! 169: IOLog("dev_chan_attach: no dev_port\n"); ! 170: return IO_R_PRIVILEGE; ! 171: } ! 172: if(channel[chan_num].mapped) { ! 173: IOLog("dev_chan_attach: chan already mapped\n"); ! 174: return IO_R_BUSY; ! 175: } ! 176: if(chan_num > CHAN_PER_DEV) { ! 177: IOLog("dev_chan_attach: bogus channel number (%d)\n", ! 178: chan_num); ! 179: return(IO_R_INVALID_ARG); ! 180: } ! 181: chan = &channel[chan_num]; ! 182: chan->mapped = 1; ! 183: int_pending = 0; ! 184: queue_init(&chan->frame_list); ! 185: streamMode = stream_mode; ! 186: chan->channel_lock = [NXSpinLock new]; ! 187: return(IO_R_SUCCESS); ! 188: } ! 189: ! 190: IOReturn _IODetachChannel( ! 191: port_t dev_port, ! 192: int chan_num) ! 193: { ! 194: dma_chan_t *chan = &channel[chan_num]; ! 195: IOReturn rtn = IO_R_SUCCESS; ! 196: ! 197: xpr_dma("dev_chan_detach\n", 1,2,3,4,5); ! 198: if(!dev_port_exists) { ! 199: IOLog("dev_chan_detach: no dev_port\n"); ! 200: return IO_R_PRIVILEGE; ! 201: } ! 202: [chan->channel_lock lock]; ! 203: if(!channel[chan_num].mapped) { ! 204: IOLog("dev_chan_detach: chan not mapped\n"); ! 205: rtn = IO_R_NOT_ATTACHED; ! 206: goto done; ! 207: } ! 208: channel[chan_num].mapped = 0; ! 209: done: ! 210: [chan->channel_lock unlock]; ! 211: return rtn; ! 212: } ! 213: ! 214: IOReturn _IOMapDevicePage( ! 215: IODevicePort dev_port, ! 216: task_t target_task, ! 217: vm_offset_t *addr, /* in/out */ ! 218: BOOL anywhere, ! 219: IOCache cache) ! 220: { ! 221: xpr_dma("dev_reg_map\n", 1,2,3,4,5); ! 222: if(!dev_port_exists) { ! 223: IOLog("dev_reg_map: no dev_port\n"); ! 224: return IO_R_PRIVILEGE; ! 225: } ! 226: dev_page = IOMalloc(sizeof(IODevicePage)); ! 227: bzero(dev_page, sizeof(*dev_page)); ! 228: *addr = (vm_offset_t)dev_page; ! 229: dev_is_mapped = YES; ! 230: return(IO_R_SUCCESS); ! 231: } ! 232: ! 233: IOReturn _IOUnmapDevicePage( ! 234: port_t dev_port, ! 235: task_t target_task, ! 236: vm_offset_t addr) ! 237: { ! 238: xpr_dma("dev_reg_unmap\n", 1,2,3,4,5); ! 239: if(!dev_port_exists) { ! 240: IOLog("dev_reg_unmap: no dev_port\n"); ! 241: return IO_R_PRIVILEGE; ! 242: } ! 243: if(!dev_is_mapped) { ! 244: IOLog("dev_reg_unmap: dev not mapped\n"); ! 245: return(IO_R_NOT_ATTACHED); ! 246: } ! 247: if(addr != (vm_offset_t)dev_page) { ! 248: IOLog("dev_reg_unmap: bad address\n"); ! 249: return IO_R_PRIVILEGE; ! 250: } ! 251: IOFree(dev_page, sizeof(IODevicePage)); ! 252: dev_is_mapped = NO; ! 253: return(IO_R_SUCCESS); ! 254: } ! 255: ! 256: IOReturn _IOMapSlotSpace( ! 257: port_t dev_port, ! 258: task_t target_task, ! 259: vm_offset_t slot_offset, ! 260: vm_size_t length, ! 261: vm_offset_t *addr, // in/out ! 262: BOOL anywhere, ! 263: IOCache cache) ! 264: { ! 265: xpr_dma("dev_slot_map\n", 1,2,3,4,5); ! 266: if(!dev_port_exists) ! 267: return IO_R_PRIVILEGE; ! 268: return(IO_R_SUCCESS); ! 269: } ! 270: ! 271: IOReturn _IOUnmapSlotSpace(port_t dev_port, ! 272: task_t target_task, ! 273: vm_offset_t addr, ! 274: vm_size_t len) ! 275: { ! 276: xpr_dma("dev_slot_unmap\n", 1,2,3,4,5); ! 277: if(!dev_port_exists) ! 278: return IO_R_PRIVILEGE; ! 279: return(IO_R_SUCCESS); ! 280: } ! 281: ! 282: IOReturn _IOSendChannelCommand(port_t dev_port, ! 283: int chan_num, ! 284: IOChannelCommand command) ! 285: { ! 286: xpr_dma("chan_command cmd = 0x%x\n", command,2,3,4,5); ! 287: if(!dev_port_exists) { ! 288: IOLog("chan_command: no dev_port\n"); ! 289: return IO_R_PRIVILEGE; ! 290: } ! 291: if(command & IO_CC_ENABLE_INTERRUPTS) ! 292: int_enabled = 1; ! 293: else if(command & IO_CC_ENABLE_INTERRUPTS) ! 294: int_enabled = 0; ! 295: else { ! 296: IOLog("chan_command: BOGUS COMMAND (0x%x)\n", command); ! 297: return IO_R_INVALID_ARG; ! 298: } ! 299: return(IO_R_SUCCESS); ! 300: } ! 301: ! 302: IOReturn _IOEnqueueDMA(port_t dev_port, ! 303: int chan_num, ! 304: vm_task_t task_id, ! 305: vm_offset_t addr, ! 306: vm_size_t len, ! 307: IODmaDirection rw, ! 308: IODescriptorCommand cmd, ! 309: u_char index, ! 310: IOChannelEnqueueOption opts, ! 311: unsigned dma_id, ! 312: BOOL *running) ! 313: { ! 314: IOReturn rtn = IO_R_SUCCESS; ! 315: dma_chan_t *chan; ! 316: dma_frame_t *frame; ! 317: ! 318: xpr_dma("chan_dma_enqueue dma_id 0x%x len %d chan %d\n", ! 319: dma_id, len, chan_num, 4,5); ! 320: if(!dev_port_exists) { ! 321: IOLog("chan_dma_enqueue: no dev_port\n"); ! 322: return IO_R_PRIVILEGE; ! 323: } ! 324: if(!dev_is_mapped) { ! 325: IOLog("chan_dma_enqueue: no dev_page\n"); ! 326: return IO_R_PRIVILEGE; ! 327: } ! 328: chan = &channel[chan_num]; ! 329: [chan->channel_lock lock]; ! 330: if(!chan->mapped) { ! 331: IOLog("chan_dma_enqueue: channel not mapped\n"); ! 332: rtn = IO_R_NOT_ATTACHED; ! 333: goto done; ! 334: } ! 335: ! 336: /* ! 337: * Take care of enabling interrupts now to simpify notification... ! 338: */ ! 339: if(opts & IO_CEO_ENABLE_INTERRUPTS) ! 340: int_enabled = YES; ! 341: ! 342: /* ! 343: * Enqueue this on the end of this channel's pending DMAs. ! 344: */ ! 345: frame = dma_frame_alloc(); ! 346: frame->dma_id = dma_id; ! 347: frame->address = addr; ! 348: frame->byte_count = len; ! 349: frame->completed = 0; ! 350: if(!queue_empty(&chan->frame_list)) { ! 351: ! 352: /* ! 353: * Make sure we're not changing direction. ! 354: */ ! 355: if(chan->dir != rw) { ! 356: IOLog("chan_dma_enqueue: DMA DIRECTION CHANGE\n"); ! 357: rtn = IO_R_INVALID_ARG; ! 358: goto done; ! 359: } ! 360: } ! 361: else { ! 362: chan->dir = rw; ! 363: } ! 364: queue_enter(&chan->frame_list, ! 365: frame, ! 366: dma_frame_t *, ! 367: link); ! 368: ! 369: /* ! 370: * Block devices: ! 371: * Mark this frame as done. Block devices do their own interrupt ! 372: * simulation for testing. ! 373: * ! 374: * Stream devices: ! 375: * Mark this frame as done for outbound frames only. ! 376: * If this is a IO_DMAWrite and there exists a IO_DMARead ! 377: * channel on this device, mark the first non-complete frame ! 378: * on the read channel's queue as done, copy the data we just enqueued ! 379: * to that (DMA read) frame, and send an interrupt message to the ! 380: * driver. (Intended for ethernet debug). ! 381: */ ! 382: if(!streamMode) { ! 383: frame->completed = 1; ! 384: set_eor(chan_num); ! 385: } ! 386: else if(rw == IO_DMAWrite) { ! 387: ! 388: int read_chan_num; ! 389: dma_chan_t *read_chan = &channel[0]; ! 390: dma_frame_t *read_frame; ! 391: BOOL found = NO; ! 392: IOInterruptMsg int_msg; ! 393: kern_return_t krtn; ! 394: ! 395: frame->completed = 1; ! 396: set_eor(chan_num); ! 397: for(read_chan_num=0; ! 398: read_chan_num<CHAN_PER_DEV; ! 399: read_chan_num++) { ! 400: if(read_chan->dir == IO_DMARead) ! 401: break; ! 402: chan++; ! 403: } ! 404: if(read_chan_num == CHAN_PER_DEV) { ! 405: xpr_dma("chan_dma_enqueue: NO READ CHANNEL\n", ! 406: 1,2,3,4,5); ! 407: ! 408: /* ! 409: * for int_pending.... ! 410: */ ! 411: read_chan = chan; ! 412: goto send_intr; ! 413: } ! 414: ! 415: /* ! 416: * OK, look for an uncompleted DMA frame on the Read channel ! 417: * queue. ! 418: */ ! 419: read_frame = (dma_frame_t *) ! 420: queue_first(&read_chan->frame_list); ! 421: while(!queue_end(&read_chan->frame_list, ! 422: (queue_t)read_frame)) { ! 423: if(!read_frame->completed) { ! 424: found = YES; ! 425: break; ! 426: } ! 427: read_frame = (dma_frame_t *)read_frame->link.next; ! 428: } ! 429: if(!found) { ! 430: /* ! 431: * DMA overrun! Let's call this a "channel error" ! 432: * interrupt. ! 433: */ ! 434: xpr_dma("chan_dma_enqueue: DMA Overrun on Read\n ", ! 435: 1,2,3,4,5); ! 436: if(queue_empty(&read_chan->frame_list)) { ! 437: xpr_dma(" (no frames)\n", 1,2,3,4,5); ! 438: } ! 439: else { ! 440: xpr_dma(" (no incompl frames)\n", 1,2,3,4,5); ! 441: } ! 442: set_error_int(read_chan_num); ! 443: goto send_intr; ! 444: } ! 445: ! 446: /* ! 447: * Found an incomplete Read frame. Copy data over to it ! 448: * and make it complete. ! 449: */ ! 450: bcopy((void *)frame->address, (void *)read_frame->address, ! 451: frame->byte_count); ! 452: read_frame->completed = 1; ! 453: read_frame->byte_count = frame->byte_count; ! 454: set_eor(read_chan_num); ! 455: ! 456: /* ! 457: * Finally, send an interrupt message to the device if ! 458: * we haven't already done so since the last "enable ! 459: * interrupts". ! 460: */ ! 461: send_intr: ! 462: if(int_enabled && !int_pending) { ! 463: bzero(&int_msg, sizeof(int_msg)); ! 464: int_msg.header.msg_size = sizeof(int_msg); ! 465: int_msg.header.msg_id = IO_DMA_INTERRUPT_MSG; ! 466: int_msg.header.msg_remote_port = interrupt_port; ! 467: int_msg.header.msg_local_port = PORT_NULL; ! 468: ! 469: /* ! 470: * Timeout is to handle port queue full. If that ! 471: * happens, it's a bug in this weird test simulation, ! 472: * not the driver. That can never happen on the ! 473: * NRW. ! 474: */ ! 475: krtn = msg_send(&int_msg.header, SEND_TIMEOUT, 1); ! 476: if(krtn) { ! 477: IOLog("chan_dma_enqueue: msg_send returned " ! 478: "%d\n", krtn); ! 479: } ! 480: int_pending = 1; ! 481: int_enabled = 0; ! 482: } ! 483: } ! 484: *running = NO; // right??? ! 485: done: ! 486: [chan->channel_lock unlock]; ! 487: return rtn; ! 488: } ! 489: ! 490: IOReturn _IOEnqueueDMAInt( ! 491: IODevicePort dev_port, ! 492: int chan_num, ! 493: vm_map_t task_id, ! 494: vm_offset_t addr, ! 495: vm_size_t len, ! 496: IODmaDirection rw, ! 497: IODescriptorCommand cmd, // descriptor command - m88k only ! 498: u_char index, ! 499: IOChannelEnqueueOption opts, ! 500: unsigned dma_id, // must be non-zero ! 501: BOOL *running) // returned - m88k only ! 502: { ! 503: return _IOEnqueueDMA(dev_port, ! 504: chan_num, ! 505: task_id, ! 506: addr, ! 507: len, ! 508: rw, ! 509: cmd, ! 510: index, ! 511: opts, ! 512: dma_id, ! 513: running); ! 514: } ! 515: ! 516: IOReturn _IODequeueDMA(port_t dev_port, ! 517: int chan_num, ! 518: IOChannelDequeueOption opts, ! 519: vm_size_t *bcount, // RETURNED ! 520: IOUserStatus *userStatus, // RETURNED, m88k only ! 521: IODmaStatus *dmaStatus, // RETURNED ! 522: BOOL *eor, // RETURNED ! 523: unsigned *dma_id) // RETURNED ! 524: { ! 525: dma_frame_t *frame = NULL; ! 526: dma_chan_t *chan; ! 527: IOReturn rtn = IO_R_SUCCESS; ! 528: BOOL found = NO; ! 529: unsigned summary_bit = 1 << chan_num; ! 530: ! 531: if(!dev_port_exists) ! 532: return IO_R_PRIVILEGE; ! 533: chan = &channel[chan_num]; ! 534: [chan->channel_lock lock]; ! 535: if(!chan->mapped) { ! 536: IOLog("chan_dma_dequeue: channel not mapped\n"); ! 537: rtn = IO_R_NOT_ATTACHED; ! 538: goto done; ! 539: } ! 540: ! 541: /* ! 542: * See if we have a frame to dequeue. We can't tell if a channel ! 543: * is running; this'll be crude. ! 544: */ ! 545: if(!queue_empty(&chan->frame_list)) { ! 546: frame = (dma_frame_t *)queue_first(&chan->frame_list); ! 547: if(frame->completed || (opts & IO_CDO_ALL)) ! 548: found = YES; ! 549: } ! 550: if(found) { ! 551: queue_remove(&chan->frame_list, ! 552: frame, ! 553: dma_frame_t *, ! 554: link); ! 555: *dma_id = frame->dma_id; ! 556: *bcount = frame->byte_count; ! 557: *dma_status = IO_Complete; ! 558: *user_status = 0; ! 559: *eor = frame->completed ? YES : NO; ! 560: dma_frame_free(frame); ! 561: } ! 562: else ! 563: *dma_id = IO_NULL_DMA_ID; ! 564: ! 565: /* ! 566: * Clear this channel's interrupt bit in the summary register. ! 567: */ ! 568: dev_page->int_dev.intr_summ.is_u.is_int &= ~summary_bit; ! 569: int_pending = 0; ! 570: ! 571: /* ! 572: * Re-enable interrupts if appropriate. ! 573: */ ! 574: if((opts & IO_CDO_ENABLE_INTERRUPTS) || ! 575: ((opts & IO_CDO_ENABLE_INTERRUPTS_IF_EMPTY) && (*dma_id == IO_NULL_DMA_ID))) { ! 576: int_enabled = 1; ! 577: } ! 578: ! 579: done: ! 580: xpr_dma("chan_dma_dequeue dma_id 0x%x bcount %d chan %d\n", ! 581: *dma_id, *bcount ,chan_num, 4,5); ! 582: [chan->channel_lock unlock]; ! 583: return rtn; ! 584: } ! 585: ! 586: /* ! 587: * Determine deviceType and name of specified unit. ! 588: */ ! 589: IOReturn _IOLookupByObjectNumber( ! 590: port_t deviceMaster, ! 591: IOObjectNumber unit, ! 592: IOString *deviceType, // returned ! 593: IOString *name) // returned ! 594: { ! 595: return IODoInquire(unit, ! 596: deviceType, ! 597: name); ! 598: } ! 599: ! 600: /* ! 601: * Get/set parameter RPCs. ! 602: */ ! 603: ! 604: IOReturn _IOGetParameterInIntArray( ! 605: port_t device_master, ! 606: IOObjectNumber unit, ! 607: IOParameterName parameterName, ! 608: unsigned int maxCount, // 0 means "as much as ! 609: // possible" ! 610: unsigned int *parameterArray, // data returned here ! 611: unsigned int *returnedCount) // size returned here ! 612: { ! 613: return IODoGetParameterInt(unit, ! 614: parameterName, ! 615: maxCount, ! 616: parameterArray, ! 617: returnedCount); ! 618: } ! 619: ! 620: IOReturn _IOGetParameterInCharArray( ! 621: port_t device_master, ! 622: IOObjectNumber unit, ! 623: IOParameterName parameterName, ! 624: unsigned int maxCount, // 0 means "as much as ! 625: // possible" ! 626: unsigned char *parameterArray, // data returned here ! 627: unsigned int *returnedCount) // size returned here ! 628: { ! 629: return IODoGetParameterChar(unit, ! 630: parameterName, ! 631: maxCount, ! 632: parameterArray, ! 633: returnedCount); ! 634: } ! 635: ! 636: IOReturn _IOSetParameterFromIntArray( ! 637: port_t device_master, ! 638: IOObjectNumber unit, ! 639: IOParameterName parameterName, ! 640: unsigned int count, // size of parameterArray ! 641: unsigned int *parameterArray) ! 642: { ! 643: return IODoSetParameterInt(unit, ! 644: parameterName, ! 645: count, ! 646: parameterArray); ! 647: } ! 648: ! 649: IOReturn _IOSetParameterFromCharArray( ! 650: port_t device_master, ! 651: IOObjectNumber unit, ! 652: IOParameterName parameterName, ! 653: unsigned int count, // size of parameterArray ! 654: unsigned char *parameterArray) ! 655: { ! 656: return IODoSetParameterChar(unit, ! 657: parameterName, ! 658: count, ! 659: parameterArray); ! 660: } ! 661: ! 662: ! 663: static dma_frame_t *dma_frame_alloc() ! 664: { ! 665: return(IOMalloc(sizeof(dma_frame_t))); ! 666: } ! 667: ! 668: static void dma_frame_free(dma_frame_t *frame) ! 669: { ! 670: IOFree(frame, sizeof(dma_frame_t)); ! 671: } ! 672: ! 673: /* ! 674: * Set channel's EOR and descriptor interrupt bits in channel interrupt cause. ! 675: * Also set the channel interrupt bit in the device interrupt summary ! 676: * register. ! 677: */ ! 678: static void set_eor(int channel) ! 679: { ! 680: chan_t *io_chan = &dev_page->chan_regs[channel]; ! 681: unsigned summary_bit = 1 << channel; ! 682: ! 683: io_chan->chan_intr_cause.ci_u.ci_int |= (CI_DESC | CI_EIO); ! 684: dev_page->int_dev.intr_summ.is_u.is_int |= summary_bit; ! 685: } ! 686: ! 687: /* ! 688: * Set channel's error interrupt. ! 689: */ ! 690: static void set_error_int(int channel) ! 691: { ! 692: chan_t *io_chan = &dev_page->chan_regs[channel]; ! 693: unsigned summary_bit = 1 << channel; ! 694: ! 695: io_chan->chan_intr_cause.ci_u.ci_int |= CI_ERROR; ! 696: dev_page->int_dev.intr_summ.is_u.is_int |= summary_bit; ! 697: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.