/* Output the buffer that out_char() has been storing into. * We have our own output function, so that we never block on a write * to the printer. Each time we output our buffer to the printer, * we also see if the printer has something to send us. If so, * we call proc_input_char() to process each character. */ static void out_buf(void) { char *wptr, *rptr, ibuf[IBSIZE]; int wcnt, nread, nwritten; fd_set rfds, wfds; FD_ZERO(&wfds); FD_ZERO(&rfds); set_nonblock(); /* don't want the write() to block */ wptr = outbuf; /* ptr to first char to output */ wcnt = outptr - wptr; /* #bytes to output */ while (wcnt > 0) { FD_SET(psfd, &wfds); FD_SET(psfd, &rfds); if (intr_flag) handle_intr(); while (select(psfd + 1, &rfds, &wfds, NULL, NULL) < 0) { if (errno == EINTR) { if (intr_flag) handle_intr(); /* no return */ } else log_sys("out_buf: select error"); } if (FD_ISSET(psfd, &rfds)) { /* printer is readable */ if ( (nread = read(psfd, ibuf, IBSIZE)) < 0) log_sys("out_buf: read error"); rptr = ibuf; while (--nread >= 0) proc_input_char(*rptr++); } if (FD_ISSET(psfd, &wfds)) { /* printer is writeable */ if ( (nwritten = write(psfd, wptr, wcnt)) < 0) log_sys("out_buf: write error"); wcnt -= nwritten; wptr += nwritten; } } outptr = outbuf; /* reset buffer pointer and count */ outcnt = OBSIZE; }
static int w89c840_poll(struct nic *nic) { int packet_received = 0; u32 intr_status = readl(ioaddr + IntrStatus); do { int entry = w840private.cur_rx % RX_RING_SIZE; struct w840_rx_desc *desc = w840private.rx_head_desc; s32 status = desc->status; if (status & DescOwn) { packet_received = 0; break; } if ((status & 0x38008300) != 0x0300) { if ((status & 0x38000300) != 0x0300) { if ((status & 0xffff) != 0x7fff) { printf("winbond-840 : Oversized Ethernet frame spanned " "multiple buffers, entry %d status %X !\n", w840private.cur_rx, status); } } else if (status & 0x8000) { #if defined(W89C840_DEBUG) printf("winbond-840 : Receive error, Rx status %X :", status); if (status & 0x0890) { printf(" RXLEN_ERROR"); } if (status & 0x004C) { printf(", FRAME_ERROR"); } if (status & 0x0002) { printf(", CRC_ERROR"); } printf("\n"); #endif w89c840_reset(nic); packet_received = 0; break; } } else { int pkt_len = ((status >> 16) & 0x7ff) - 4; #if defined(W89C840_DEBUG) printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status); #endif nic->packetlen = pkt_len; memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len); packet_received = 1; w840private.rx_ring[entry].status = DescOwn; #if defined(W89C840_DEBUG) printf(" Rx data %hhX:%hhX:%hhX:%hhX:%hhX:" "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX " "%hhX.%hhX.%hhX.%hhX.\n", nic->packet[0], nic->packet[1], nic->packet[2], nic->packet[3], nic->packet[4], nic->packet[5], nic->packet[6], nic->packet[7], nic->packet[8], nic->packet[9], nic->packet[10], nic->packet[11], nic->packet[12], nic->packet[13], nic->packet[14], nic->packet[15], nic->packet[16], nic->packet[17]); #endif } entry = (++w840private.cur_rx) % RX_RING_SIZE; w840private.rx_head_desc = &w840private.rx_ring[entry]; } while (0); if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) { handle_intr(intr_status); } return packet_received; }