Deleted Added
full compact
vpoio.c (184130) vpoio.c (185003)
1/*-
2 * Copyright (c) 1998, 1999 Nicolas Souchu
3 * Copyright (c) 2000 Alcove - Nicolas Souchu
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1998, 1999 Nicolas Souchu
3 * Copyright (c) 2000 Alcove - Nicolas Souchu
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/ppbus/vpoio.c 184130 2008-10-21 18:30:10Z jhb $");
31__FBSDID("$FreeBSD: head/sys/dev/ppbus/vpoio.c 185003 2008-11-16 17:42:02Z jhb $");
32
33#ifdef _KERNEL
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/malloc.h>
39

--- 173 unchanged lines hidden (view full) ---

213};
214
215/*
216 * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes
217 */
218static struct ppb_microseq spp_outbyte_submicroseq[] = {
219
220/* loop: */
32
33#ifdef _KERNEL
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/module.h>
37#include <sys/bus.h>
38#include <sys/malloc.h>
39

--- 173 unchanged lines hidden (view full) ---

213};
214
215/*
216 * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes
217 */
218static struct ppb_microseq spp_outbyte_submicroseq[] = {
219
220/* loop: */
221 MS_RASSERT_P(1, MS_REG_DTR),
221 MS_RASSERT_P(1, MS_REG_DTR),
222 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE),
223 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE),
224 MS_DELAY(VP0_PULSE),
225 MS_DBRA(-5 /* loop */),
226
227 /* return from the put call */
228 MS_RET(0)
229};
230
231/* EPP 1.7 microsequences, ptr and len set at runtime */
232static struct ppb_microseq epp17_outstr_body[] = {
233 MS_CASS(H_AUTO | H_SELIN | H_INIT | H_STROBE),
234
235/* loop: */
222 MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE),
223 MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE),
224 MS_DELAY(VP0_PULSE),
225 MS_DBRA(-5 /* loop */),
226
227 /* return from the put call */
228 MS_RET(0)
229};
230
231/* EPP 1.7 microsequences, ptr and len set at runtime */
232static struct ppb_microseq epp17_outstr_body[] = {
233 MS_CASS(H_AUTO | H_SELIN | H_INIT | H_STROBE),
234
235/* loop: */
236 MS_RASSERT_P(1, MS_REG_EPP_D),
236 MS_RASSERT_P(1, MS_REG_EPP_D),
237 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */
238 MS_DBRA(-3 /* loop */),
239
240 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
241 MS_RET(0),
242/* error: */
243 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
244 MS_RET(1)
245};
246
247static struct ppb_microseq epp17_instr_body[] = {
248 MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_STROBE),
249
250/* loop: */
237 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */
238 MS_DBRA(-3 /* loop */),
239
240 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
241 MS_RET(0),
242/* error: */
243 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
244 MS_RET(1)
245};
246
247static struct ppb_microseq epp17_instr_body[] = {
248 MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_STROBE),
249
250/* loop: */
251 MS_RFETCH_P(1, MS_REG_EPP_D, MS_FETCH_ALL),
251 MS_RFETCH_P(1, MS_REG_EPP_D, MS_FETCH_ALL),
252 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */
253 MS_DBRA(-3 /* loop */),
254
255 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE),
256 MS_RET(0),
257/* error: */
258 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE),
259 MS_RET(1)

--- 32 unchanged lines hidden (view full) ---

292 int error;
293 int ret;
294
295 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) {
296
297#ifdef VP0_DEBUG
298 printf("%s: can't request bus!\n", __func__);
299#endif
252 MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */
253 MS_DBRA(-3 /* loop */),
254
255 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE),
256 MS_RET(0),
257/* error: */
258 MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE),
259 MS_RET(1)

--- 32 unchanged lines hidden (view full) ---

292 int error;
293 int ret;
294
295 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) {
296
297#ifdef VP0_DEBUG
298 printf("%s: can't request bus!\n", __func__);
299#endif
300 return error;
300 return (error);
301 }
302
303 if (PPB_IN_EPP_MODE(ppbus))
304 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
305 else
306 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
307
308 return (0);
309}
310
311/*
312 * vpoio_reset()
313 *
314 * SCSI reset signal, the drive must be in disk mode
315 */
316static void
301 }
302
303 if (PPB_IN_EPP_MODE(ppbus))
304 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
305 else
306 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
307
308 return (0);
309}
310
311/*
312 * vpoio_reset()
313 *
314 * SCSI reset signal, the drive must be in disk mode
315 */
316static void
317vpoio_reset (struct vpoio_data *vpo)
317vpoio_reset(struct vpoio_data *vpo)
318{
319 device_t ppbus = device_get_parent(vpo->vpo_dev);
320 int ret;
321
322 struct ppb_microseq reset_microseq[] = {
323
324 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT)
325

--- 32 unchanged lines hidden (view full) ---

358static int
359vpoio_detect(struct vpoio_data *vpo)
360{
361 device_t ppbus = device_get_parent(vpo->vpo_dev);
362 int error, ret;
363
364 /* allocate the bus, then apply microsequences */
365 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
318{
319 device_t ppbus = device_get_parent(vpo->vpo_dev);
320 int ret;
321
322 struct ppb_microseq reset_microseq[] = {
323
324 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT)
325

--- 32 unchanged lines hidden (view full) ---

358static int
359vpoio_detect(struct vpoio_data *vpo)
360{
361 device_t ppbus = device_get_parent(vpo->vpo_dev);
362 int error, ret;
363
364 /* allocate the bus, then apply microsequences */
365 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
366 return (error);
366 return (error);
367
368 /* Force disconnection */
369 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
370
371 /* Try to enter EPP mode, then connect to the drive in EPP mode */
372 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
373 /* call manually the microseq instead of using the appropriate function
374 * since we already requested the ppbus */

--- 36 unchanged lines hidden (view full) ---

411 vpo->vpo_mode_found = VP0_MODE_EPP;
412 }
413
414 /* send SCSI reset signal */
415 vpoio_reset(vpo);
416
417 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
418
367
368 /* Force disconnection */
369 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
370
371 /* Try to enter EPP mode, then connect to the drive in EPP mode */
372 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
373 /* call manually the microseq instead of using the appropriate function
374 * since we already requested the ppbus */

--- 36 unchanged lines hidden (view full) ---

411 vpo->vpo_mode_found = VP0_MODE_EPP;
412 }
413
414 /* send SCSI reset signal */
415 vpoio_reset(vpo);
416
417 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
418
419 /* ensure we are disconnected or daisy chained peripheral
419 /* ensure we are disconnected or daisy chained peripheral
420 * may cause serious problem to the disk */
421 if (vpoio_in_disk_mode(vpo)) {
422 if (bootverbose)
423 device_printf(vpo->vpo_dev,
424 "can't disconnect from the drive\n");
425 goto error;
426 }
427

--- 66 unchanged lines hidden (view full) ---

494/* error: */ MS_RET(1),
495/* ready: */ MS_RET(0)
496 };
497
498 /* initialize the select microsequence */
499 ppb_MS_init_msq(select_microseq, 2,
500 SELECT_TARGET, 1 << target,
501 SELECT_INITIATOR, 1 << initiator);
420 * may cause serious problem to the disk */
421 if (vpoio_in_disk_mode(vpo)) {
422 if (bootverbose)
423 device_printf(vpo->vpo_dev,
424 "can't disconnect from the drive\n");
425 goto error;
426 }
427

--- 66 unchanged lines hidden (view full) ---

494/* error: */ MS_RET(1),
495/* ready: */ MS_RET(0)
496 };
497
498 /* initialize the select microsequence */
499 ppb_MS_init_msq(select_microseq, 2,
500 SELECT_TARGET, 1 << target,
501 SELECT_INITIATOR, 1 << initiator);
502
502
503 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
504
505 if (ret)
506 return (VP0_ESELECT_TIMEOUT);
507
508 return (0);
509}
510

--- 29 unchanged lines hidden (view full) ---

540
541 ppb_MS_init_msq(wait_microseq, 2,
542 WAIT_RET, (void *)&ret,
543 WAIT_TMO, tmo);
544
545 ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err);
546
547 if (err)
503 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
504
505 if (ret)
506 return (VP0_ESELECT_TIMEOUT);
507
508 return (0);
509}
510

--- 29 unchanged lines hidden (view full) ---

540
541 ppb_MS_init_msq(wait_microseq, 2,
542 WAIT_RET, (void *)&ret,
543 WAIT_TMO, tmo);
544
545 ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err);
546
547 if (err)
548 return (0); /* command timed out */
548 return (0); /* command timed out */
549
550 return(ret);
551}
552
553/*
554 * vpoio_probe()
555 *
556 * Low level probe of vpo device

--- 24 unchanged lines hidden (view full) ---

581 * vpoio_attach()
582 *
583 * Low level attachment of vpo device
584 *
585 */
586int
587vpoio_attach(struct vpoio_data *vpo)
588{
549
550 return(ret);
551}
552
553/*
554 * vpoio_probe()
555 *
556 * Low level probe of vpo device

--- 24 unchanged lines hidden (view full) ---

581 * vpoio_attach()
582 *
583 * Low level attachment of vpo device
584 *
585 */
586int
587vpoio_attach(struct vpoio_data *vpo)
588{
589 DECLARE_NIBBLE_INBYTE_SUBMICROSEQ;
589 DECLARE_NIBBLE_INBYTE_SUBMICROSEQ;
590 device_t ppbus = device_get_parent(vpo->vpo_dev);
591 int error = 0;
592
593 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
594 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
595
596 if (!vpo->vpo_nibble_inbyte_msq)
597 return (ENXIO);
598
599 bcopy((void *)nibble_inbyte_submicroseq,
600 (void *)vpo->vpo_nibble_inbyte_msq,
601 sizeof(nibble_inbyte_submicroseq));
602
603 ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4,
604 INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h,
605 INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l,
606 INB_NIBBLE_F, nibble_inbyte_hook,
590 device_t ppbus = device_get_parent(vpo->vpo_dev);
591 int error = 0;
592
593 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
594 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
595
596 if (!vpo->vpo_nibble_inbyte_msq)
597 return (ENXIO);
598
599 bcopy((void *)nibble_inbyte_submicroseq,
600 (void *)vpo->vpo_nibble_inbyte_msq,
601 sizeof(nibble_inbyte_submicroseq));
602
603 ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4,
604 INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h,
605 INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l,
606 INB_NIBBLE_F, nibble_inbyte_hook,
607 INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble);
607 INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble);
608
609 /*
610 * Initialize mode dependent in/out microsequences
611 */
612 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT)))
613 goto error;
614
615 /* ppbus sets automatically the last mode entered during detection */

--- 51 unchanged lines hidden (view full) ---

667}
668
669/*
670 * vpoio_do_scsi()
671 *
672 * Send an SCSI command
673 *
674 */
608
609 /*
610 * Initialize mode dependent in/out microsequences
611 */
612 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT)))
613 goto error;
614
615 /* ppbus sets automatically the last mode entered during detection */

--- 51 unchanged lines hidden (view full) ---

667}
668
669/*
670 * vpoio_do_scsi()
671 *
672 * Send an SCSI command
673 *
674 */
675int
675int
676vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
677 int clen, char *buffer, int blen, int *result, int *count,
678 int *ret)
679{
680 device_t ppbus = device_get_parent(vpo->vpo_dev);
681 register char r;
682 char l, h = 0;
683 int len, error = 0;

--- 6 unchanged lines hidden (view full) ---

690 * Should we allow this call to be interruptible?
691 * The only way to report the interruption is to return
692 * EIO do upper SCSI code :^(
693 */
694 if ((error = vpoio_connect(vpo, PPB_WAIT|PPB_INTR)))
695 return (error);
696
697 if (!vpoio_in_disk_mode(vpo)) {
676vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
677 int clen, char *buffer, int blen, int *result, int *count,
678 int *ret)
679{
680 device_t ppbus = device_get_parent(vpo->vpo_dev);
681 register char r;
682 char l, h = 0;
683 int len, error = 0;

--- 6 unchanged lines hidden (view full) ---

690 * Should we allow this call to be interruptible?
691 * The only way to report the interruption is to return
692 * EIO do upper SCSI code :^(
693 */
694 if ((error = vpoio_connect(vpo, PPB_WAIT|PPB_INTR)))
695 return (error);
696
697 if (!vpoio_in_disk_mode(vpo)) {
698 *ret = VP0_ECONNECT; goto error;
698 *ret = VP0_ECONNECT;
699 goto error;
699 }
700
701 if ((*ret = vpoio_select(vpo,host,target)))
702 goto error;
703
704 /*
705 * Send the command ...
706 *

--- 7 unchanged lines hidden (view full) ---

714 goto error;
715 }
716 if (vpoio_outstr(vpo, &command[k], 1)) {
717 *ret = VP0_EPPDATA_TIMEOUT;
718 goto error;
719 }
720 }
721
700 }
701
702 if ((*ret = vpoio_select(vpo,host,target)))
703 goto error;
704
705 /*
706 * Send the command ...
707 *

--- 7 unchanged lines hidden (view full) ---

715 goto error;
716 }
717 if (vpoio_outstr(vpo, &command[k], 1)) {
718 *ret = VP0_EPPDATA_TIMEOUT;
719 goto error;
720 }
721 }
722
722 /*
723 * Completion ...
723 /*
724 * Completion ...
724 */
725
726 *count = 0;
727 for (;;) {
728
729 if (!(r = vpoio_wait(vpo, VP0_LOW_SPINTMO))) {
725 */
726
727 *count = 0;
728 for (;;) {
729
730 if (!(r = vpoio_wait(vpo, VP0_LOW_SPINTMO))) {
730 *ret = VP0_ESTATUS_TIMEOUT; goto error;
731 *ret = VP0_ESTATUS_TIMEOUT;
732 goto error;
731 }
732
733 /* stop when the ZIP wants to send status */
734 if (r == (char)0xf0)
735 break;
736
737 if (*count >= blen) {
738 *ret = VP0_EDATA_OVERFLOW;

--- 19 unchanged lines hidden (view full) ---

758 *ret = error;
759 goto error;
760 }
761
762 *count += len;
763 }
764
765 if (vpoio_instr(vpo, &l, 1)) {
733 }
734
735 /* stop when the ZIP wants to send status */
736 if (r == (char)0xf0)
737 break;
738
739 if (*count >= blen) {
740 *ret = VP0_EDATA_OVERFLOW;

--- 19 unchanged lines hidden (view full) ---

760 *ret = error;
761 goto error;
762 }
763
764 *count += len;
765 }
766
767 if (vpoio_instr(vpo, &l, 1)) {
766 *ret = VP0_EOTHER; goto error;
768 *ret = VP0_EOTHER;
769 goto error;
767 }
768
769 /* check if the ZIP wants to send more status */
770 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) == (char)0xf0)
771 if (vpoio_instr(vpo, &h, 1)) {
770 }
771
772 /* check if the ZIP wants to send more status */
773 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) == (char)0xf0)
774 if (vpoio_instr(vpo, &h, 1)) {
772 *ret = VP0_EOTHER+2; goto error;
775 *ret = VP0_EOTHER + 2;
776 goto error;
773 }
774
775 *result = ((int) h << 8) | ((int) l & 0xff);
776
777error:
778 /* return to printer state, release the ppbus */
779 vpoio_disconnect(vpo);
780 return (0);
781}
777 }
778
779 *result = ((int) h << 8) | ((int) l & 0xff);
780
781error:
782 /* return to printer state, release the ppbus */
783 vpoio_disconnect(vpo);
784 return (0);
785}