static void mipsnet_interrupt( void *_dev ) { phantom_device_t * dev = _dev; struct mipsnet *pvt = dev->drv_private; (void) pvt; u_int32_t status = BUSRD( dev->iobase + MIPSNET_INT_CTL ); if( status & MIPSNET_INTCTL_TESTBIT ) { pvt->test_interrupt++; BUSWR( dev->iobase + MIPSNET_INT_CTL, 0 ); // ack test interrupt } // ack rx/tx interrupts BUSWR( dev->iobase + MIPSNET_INT_CTL, status & (MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TXDONE) ); SHOW_FLOW( 6, "Interrupt status %b", status, "\020\1TXDONE\2RXDONE\32TEST" ); if( status & MIPSNET_INTCTL_RXDONE ) hal_sem_release( &(pvt->recv_interrupt_sem) ); if( status & MIPSNET_INTCTL_TXDONE ) hal_sem_release( &(pvt->send_interrupt_sem) ); //if( status & (D8390_ISR_RXE|D8390_ISR_TXE) ) hal_sem_release( &(pvt->reset_sem) ); }
void scr_repaint_all(void) { CHECK_START(); paint_all++; paint_request++; // TODO need atomic hal_sem_release( &paint_sem ); }
static int rtl8169_txint(rtl8169 *r, uint16 int_status) { //uint32 txstat; //int i; int rc = INT_NO_RESCHEDULE; if (int_status & (IMR_TOK|IMR_TER)) { int i; /* see how many frames were transmitted */ i = 0; while ((r->txdesc[r->tx_idx_full].flags & RTL_DESC_OWN) == 0) { i++; inc_tx_idx_full(r); if (r->tx_idx_full == r->tx_idx_free) { break; } } SHOW_FLOW(3, "txint: sent %d frames, idx_full = %d, idx_free = %d\n", i, r->tx_idx_full, r->tx_idx_free); if (i > 0) { //TODO #warning SEM_FLAG_NO_RESCHED //hal_sem_release_etc(r->tx_sem, 1, SEM_FLAG_NO_RESCHED); hal_sem_release(&r->tx_sem); rc = INT_RESCHEDULE; } } return rc; }
static int rtl8169_rxint(rtl8169 *r, uint16 int_status) { int rc = INT_NO_RESCHEDULE; if (int_status & (IMR_ROK|IMR_RER)) { int i; /* see how many frames we got, adjust our index */ i = 0; while ((r->rxdesc[r->rx_idx_full].flags & RTL_DESC_OWN) == 0) { i++; inc_rx_idx_full(r); if (r->rx_idx_full == r->rx_idx_free) { /* we just used up the last descriptor */ SHOW_ERROR0(1, "rtl8169_rxint: used up last descriptor, chip is gonna blow.\n"); /* XXX deal with this somehow */ break; // no more frames left on the ring } } SHOW_FLOW(3, "rxint: got %d frames, idx_full = %d, idx_free = %d\n", i, r->rx_idx_full, r->rx_idx_free); if (i > 0) { //TODO #warning SEM_FLAG_NO_RESCHED //hal_sem_release_etc( &r->rx_sem, 1, SEM_FLAG_NO_RESCHED); hal_sem_release( &r->rx_sem ); rc = INT_RESCHEDULE; } } return rc; }
void ps2_insert_mouse_event( int x, int y, int buttons ) { if(NULL == video_drv) return; video_drv->mouse_x = x; video_drv->mouse_y = y; struct ui_event e; ev_make_mouse_event( &e, x, y, buttons ); /* memset( &e, 0, sizeof(e) ); e.type = UI_EVENT_TYPE_MOUSE; e.time = fast_time(); e.focus= 0; e.m.buttons = buttons; e.abs_x = x; e.abs_y = y; e.extra = 0; */ put_buf(&e); hal_sem_release( &mouse_sem ); }
static void sem_softirq(void *a) { (void) a; printf("sema softirq\n"); //hal_sleep_msec( 10 ); sem_released = 1; hal_sem_release( &test_sem_0 ); }
/************************************************************************** NE_RESET - Reset adapter **************************************************************************/ static void mipsnet_reset(phantom_device_t * dev) { struct mipsnet *pvt = dev->drv_private; // Release send sema once so that we'll xmit first packet without a problem hal_sem_release( &(pvt->send_interrupt_sem) ); BUSWR( dev->iobase + MIPSNET_RX_DATA_COUNT, 0 ); BUSWR( dev->iobase + MIPSNET_TX_DATA_COUNT, 0 ); BUSWR( dev->iobase + MIPSNET_INT_CTL, MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT ); }
void w_request_async_repaint( rect_t *r ) { CHECK_START(); rect_t old_total = total; int old_pq = paint_request; rect_add( &total, &old_total, r ); // Other thread changed something, we have collision. // For now just repaint all the screen. if(old_pq != paint_request) paint_all++; paint_request++; // TODO need atomic hal_sem_release( &paint_sem ); }
static void sem_rel(void *a) { (void) a; hal_sleep_msec( 300 ); printf("sema release 1 (direct)\n"); sem_released = 1; hal_sem_release( &test_sem_0 ); #if TEST_SOFTIRQ hal_sleep_msec( 300 ); printf("sema release 2 (softirq %d)\n", softirq ); sem_released = 1; hal_request_softirq( softirq ); #endif /* while(!stop_sem_test) { hal_sleep_msec( 500 ); } */ }
void paint_q_add( rect_t *r ) { hal_mutex_lock( &rect_list_lock ); pqel_t *new_el = mkel( r ); // Don't die, just let some garbage onscreen? if(0 == new_el) return; hal_sem_release( &painter_sem ); if(paint_q_empty()) { queue_enter(&rect_list, new_el, pqel_t *, chain); goto finish; } pqel_t *pqel; again: queue_iterate( &rect_list, pqel, pqel_t *, chain ) { // r includes qe - delete qe if( rect_includes( r, &pqel->r ) ) { queue_remove( &rect_list, pqel, pqel_t *, chain ); goto again; } // qe includes r - skip addition if( rect_includes( &pqel->r, r ) ) { free( new_el ); goto finish; } }
void w_event_deliver_thread(void) { hal_sem_init( &we_sem, "wevent" ); we_inited = 1; hal_set_thread_name("WEvent"); hal_set_current_thread_priority(PHANTOM_SYS_THREAD_PRIO+1); while(1) { hal_sem_acquire( &we_sem ); // TODO need some 'acquire_all' method to eat all releases restart: w_lock(); window_handle_t w; queue_iterate_back(&allwindows, w, drv_video_window_t *, chain) { if( w->events_count ) { if(w->eventDeliverSema) hal_sem_release(w->eventDeliverSema); if(w->inKernelEventProcess) { w_unlock(); w_do_deliver_event(w); goto restart; } } } w_unlock(); } }
ssize_t rtl8169_rx(rtl8169 *r, char *buf, ssize_t buf_len) { //uint32 tail; ssize_t len; int rc; bool release_sem = false; SHOW_FLOW0(3, "rtl8169_rx: entry\n"); if(buf_len < 1500) return -1; restart: hal_sem_acquire(&r->rx_sem); mutex_lock(&r->lock); int_disable_interrupts(); acquire_spinlock(&r->reg_spinlock); /* look at the descriptor pointed to by rx_idx_free */ if (r->rxdesc[r->rx_idx_free].flags & RTL_DESC_OWN) { /* for some reason it's owned by the card, wait for more packets */ release_spinlock(&r->reg_spinlock); int_restore_interrupts(); mutex_unlock(&r->lock); goto restart; } /* process this packet */ len = r->rxdesc[r->rx_idx_free].frame_len & 0x3fff; SHOW_FLOW(3, "rtl8169_rx: desc idx %d: len %d\n", r->rx_idx_free, len); if (len > buf_len) { rc = ERR_TOO_BIG; release_sem = true; goto out; } memcpy(buf, RXBUF(r, r->rx_idx_free), len); rc = len; #if debug_level_flow >= 3 hexdump(RXBUF(r, r->rx_idx_free), len, 0, 0); #endif /* stick it back in the free list */ r->rxdesc[r->rx_idx_free].buffer_size = BUFSIZE_PER_FRAME; r->rxdesc[r->rx_idx_free].flags = (r->rxdesc[r->rx_idx_free].flags & RTL_DESC_EOR) | RTL_DESC_OWN; inc_rx_idx_free(r); /* see if there are more packets pending */ if ((r->rxdesc[r->rx_idx_free].flags & RTL_DESC_OWN) == 0) release_sem = true; // if so, release the rx sem so the next reader gets a shot out: release_spinlock(&r->reg_spinlock); int_restore_interrupts(); if(release_sem) hal_sem_release(&r->rx_sem); mutex_unlock(&r->lock); return rc; }
static void ps2ms_int_handler( void *arg ) { (void) arg; static int inbytepos = 0; signed char mousedata = inb( PS2_DATA_ADDR ); SHOW_FLOW( 10 ,"%2X ", mousedata & 0xFFu ); switch(inbytepos) { case 0: // first byte has one in this pos if(1 && ! (0x8 & mousedata) ) { //inbytepos = -1; break; inbytepos = 0; return; } ps2ms_state_buttons = 0x7 & mousedata; xsign = 0x10 & mousedata; ysign = 0x20 & mousedata; break; case 1: xval = mousedata; break; case 2: yval = mousedata; break; case 3: break; case 4: break; } inbytepos++; inbytepos %= 3; //inbytepos %= 4; if(inbytepos != 0) return; xval = insert_bit9( xval, xsign ); yval = insert_bit9( yval, ysign ); ps2ms_state_xpos += xval; ps2ms_state_ypos += yval; if( ps2ms_state_xpos < 0 ) ps2ms_state_xpos = 0; if( ps2ms_state_ypos < 0 ) ps2ms_state_ypos = 0; if( ps2ms_state_xpos > video_drv->xsize ) ps2ms_state_xpos = video_drv->xsize; if( ps2ms_state_ypos > video_drv->ysize ) ps2ms_state_ypos = video_drv->ysize; //printf("ms %d %d %x\n", ps2ms_state_xpos, ps2ms_state_ypos, ps2ms_state_buttons ); if(NULL != video_drv) { video_drv->mouse_x = ps2ms_state_xpos; video_drv->mouse_y = ps2ms_state_ypos; struct ui_event e; e.type = UI_EVENT_TYPE_MOUSE; e.time = fast_time(); e.focus= 0; e.m.buttons = ps2ms_state_buttons; e.abs_x = ps2ms_state_xpos; e.abs_y = ps2ms_state_ypos; put_buf(&e); hal_sem_release( &mouse_sem ); } }
static void com_interrupt( void *_dev ) { phantom_device_t * dev = _dev; int unit = dev->seq_number; int addr = dev->iobase; com_port_t *cp = dev->drv_private; (void) unit; SHOW_FLOW( 9, "com port %d interrupt", unit ); //register struct tty *tp = &com_tty[unit]; //static char comoverrun = 0; //char c, line, intr_id; char intr_id; //int modem_stat; int line_stat; while (! ((intr_id=(inb(INTR_ID(addr))&MASKi)) & 1)) { switch (intr_id) { case MODi: /* modem change */ //int ms = inb(MODEM_STAT(addr)); //commodem_intr(unit, ms)); break; case TRAi: hal_sem_release( &(cp->wsem) ); //comtimer_state[unit] = 0; //tp->t_state &= ~(TS_BUSY|TS_FLUSH); //tt_write_wakeup(tp); //(void) comstart(tp); break; case RECi: case CTIi: /* Character timeout indication */ hal_sem_release( &(cp->rsem) ); break; case LINi: line_stat = inb(LINE_STAT(addr)); (void) line_stat; #if 0 if ((line_stat & iPE) && ((tp->t_flags&(EVENP|ODDP)) == EVENP || (tp->t_flags&(EVENP|ODDP)) == ODDP)) { /* parity error */; } else if (line&iOR && !comoverrun) { printf("com%d: overrun\n", unit); comoverrun = 1; } else if (line_stat & (iFE | iBRKINTR)) { /* framing error or break */ ttyinput(tp->t_breakc, tp); } #endif break; } } }