/* * vpoio_wait() * * H_SELIN must be low. * * XXX should be ported to microseq */ static char vpoio_wait(struct vpoio_data *vpo, int tmo) { DECLARE_WAIT_MICROSEQUENCE; device_t ppbus = device_get_parent(vpo->vpo_dev); int ret, err; #if 0 /* broken */ if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR)) return (0); return (ppb_rstr(ppbus) & 0xf0); #endif /* * Return some status information. * Semantics : 0xc0 = ZIP wants more data * 0xd0 = ZIP wants to send more data * 0xe0 = ZIP wants command * 0xf0 = end of transfer, ZIP is sending status */ ppb_MS_init_msq(wait_microseq, 2, WAIT_RET, (void *)&ret, WAIT_TMO, tmo); ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); if (err) return (0); /* command timed out */ return(ret); }
/* * byte_peripheral_write() * * Write n bytes in BYTE mode */ int byte_peripheral_write(struct ppb_device *dev, char *buffer, int len, int *sent) { int error = 0, i; char r; ppb_1284_set_state(dev, PPB_PERIPHERAL_TRANSFER); /* wait forever, the remote host is master and should initiate * termination */ for (i=0; i<len; i++) { /* force remote nFAULT low to release the remote waiting * process, if any */ r = ppb_rctr(dev); ppb_wctr(dev, r & ~nINIT); #ifdef DEBUG_1284 printf("y"); #endif /* Event 7 */ error = ppb_poll_device(dev, PPB_FOREVER, nBUSY, nBUSY, PPB_INTR); if (error && error != EWOULDBLOCK) goto error; #ifdef DEBUG_1284 printf("b"); #endif if ((error = byte_peripheral_outbyte(dev, buffer+i, (i == len-1)))) goto error; } error: if (!error) ppb_1284_set_state(dev, PPB_PERIPHERAL_IDLE); *sent = i; return (error); }
/* * ppb_1284_negociate() * * IEEE1284 negociation phase * * Normal nibble mode or request device id mode (see ppb_1284.h) * * After negociation, nFAULT is low if data is available */ int ppb_1284_negociate(struct ppb_device *dev, int mode, int options) { int error; int request_mode; #ifdef DEBUG_1284 printf("n"); #endif if (ppb_1284_get_state(dev) >= PPB_PERIPHERAL_NEGOCIATION) ppb_peripheral_terminate(dev, PPB_WAIT); if (ppb_1284_get_state(dev) != PPB_FORWARD_IDLE) ppb_1284_terminate(dev); #ifdef DEBUG_1284 printf("%d", mode); #endif /* ensure the host is in compatible mode */ ppb_set_mode(dev, PPB_COMPATIBLE); /* reset error to catch the actual negociation error */ ppb_1284_reset_error(dev, PPB_FORWARD_IDLE); /* calculate ext. value */ request_mode = ppb_request_mode(mode, options); /* default state */ ppb_wctr(dev, (nINIT | SELECTIN) & ~(STROBE | AUTOFEED)); DELAY(1); /* enter negociation phase */ ppb_1284_set_state(dev, PPB_NEGOCIATION); /* Event 0 - put the exten. value on the data lines */ ppb_wdtr(dev, request_mode); #ifdef PERIPH_1284 /* request remote host attention */ ppb_wctr(dev, (nINIT | STROBE) & ~(AUTOFEED | SELECTIN)); DELAY(1); ppb_wctr(dev, (nINIT) & ~(STROBE | AUTOFEED | SELECTIN)); #else DELAY(1); #endif /* !PERIPH_1284 */ /* Event 1 - enter IEEE1284 mode */ ppb_wctr(dev, (nINIT | AUTOFEED) & ~(STROBE | SELECTIN)); #ifdef PERIPH_1284 /* ignore the PError line, wait a bit more, remote host's * interrupts don't respond fast enough */ if (ppb_poll_device(dev, 40, nACK | SELECT | nFAULT, SELECT | nFAULT, PPB_NOINTR | PPB_POLL)) { ppb_1284_set_error(dev, PPB_NOT_IEEE1284, 2); error = ENODEV; goto error; } #else /* Event 2 - trying IEEE1284 dialog */ if (do_1284_wait(dev, nACK | PERROR | SELECT | nFAULT, PERROR | SELECT | nFAULT)) { ppb_1284_set_error(dev, PPB_NOT_IEEE1284, 2); error = ENODEV; goto error; } #endif /* !PERIPH_1284 */ /* Event 3 - latch the ext. value to the peripheral */ ppb_wctr(dev, (nINIT | STROBE | AUTOFEED) & ~SELECTIN); DELAY(1); /* Event 4 - IEEE1284 device recognized */ ppb_wctr(dev, nINIT & ~(SELECTIN | AUTOFEED | STROBE)); /* Event 6 - waiting for status lines */ if (do_1284_wait(dev, nACK, nACK)) { ppb_1284_set_error(dev, PPB_TIMEOUT, 6); error = EBUSY; goto error; } /* Event 7 - quering result consider nACK not to misunderstand * a remote computer terminate sequence */ if (options & PPB_EXTENSIBILITY_LINK) { /* XXX not fully supported yet */ ppb_1284_terminate(dev); return (0); } if (request_mode == NIBBLE_1284_NORMAL) { if (do_1284_wait(dev, nACK | SELECT, nACK)) { ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 7); error = ENODEV; goto error; } } else { if (do_1284_wait(dev, nACK | SELECT, SELECT | nACK)) { ppb_1284_set_error(dev, PPB_MODE_UNSUPPORTED, 7); error = ENODEV; goto error; } } switch (mode) { case PPB_NIBBLE: case PPB_PS2: /* enter reverse idle phase */ ppb_1284_set_state(dev, PPB_REVERSE_IDLE); break; case PPB_ECP: /* negociation ok, now setup the communication */ ppb_1284_set_state(dev, PPB_SETUP); ppb_wctr(dev, (nINIT | AUTOFEED) & ~(SELECTIN | STROBE)); #ifdef PERIPH_1284 /* ignore PError line */ if (do_1284_wait(dev, nACK | SELECT | nBUSY, nACK | SELECT | nBUSY)) { ppb_1284_set_error(dev, PPB_TIMEOUT, 30); error = ENODEV; goto error; } #else if (do_1284_wait(dev, nACK | SELECT | PERROR | nBUSY, nACK | SELECT | PERROR | nBUSY)) { ppb_1284_set_error(dev, PPB_TIMEOUT, 30); error = ENODEV; goto error; } #endif /* !PERIPH_1284 */ /* ok, the host enters the ForwardIdle state */ ppb_1284_set_state(dev, PPB_ECP_FORWARD_IDLE); break; case PPB_EPP: ppb_1284_set_state(dev, PPB_EPP_IDLE); break; default: panic("%s: unknown mode (%d)!", __FUNCTION__, mode); } ppb_set_mode(dev, mode); return (0); error: ppb_1284_terminate(dev); return (error); }
static int do_peripheral_wait(struct ppb_device *dev, char mask, char status) { return (ppb_poll_device(dev, 100, mask, status, PPB_NOINTR | PPB_POLL)); }
/* * do_1284_wait() * * Wait for the peripherial up to 40ms */ static int do_1284_wait(struct ppb_device *dev, char mask, char status) { return (ppb_poll_device(dev, 4, mask, status, PPB_NOINTR | PPB_POLL)); }