Deleted Added
full compact
vpoio.c (55205) vpoio.c (55939)
1/*-
1/*-
2 * Copyright (c) 1998 Nicolas Souchu
2 * Copyright (c) 1998, 1999 Nicolas Souchu
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

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

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

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

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/ppbus/vpoio.c 55205 1999-12-29 04:46:21Z peter $
26 * $FreeBSD: head/sys/dev/ppbus/vpoio.c 55939 2000-01-14 00:18:06Z nsouch $
27 *
28 */
29
30#ifdef _KERNEL
31#include <sys/param.h>
32#include <sys/systm.h>
27 *
28 */
29
30#ifdef _KERNEL
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/module.h>
34#include <sys/bus.h>
33#include <sys/malloc.h>
34#include <sys/buf.h>
35
36#include <machine/clock.h>
37
38#endif
39
40#ifdef _KERNEL
41#include <sys/kernel.h>
42#endif
43
44#include "opt_vpo.h"
45
35#include <sys/malloc.h>
36#include <sys/buf.h>
37
38#include <machine/clock.h>
39
40#endif
41
42#ifdef _KERNEL
43#include <sys/kernel.h>
44#endif
45
46#include "opt_vpo.h"
47
48#include <dev/ppbus/ppbio.h>
46#include <dev/ppbus/ppbconf.h>
47#include <dev/ppbus/ppb_msq.h>
48#include <dev/ppbus/vpoio.h>
49
49#include <dev/ppbus/ppbconf.h>
50#include <dev/ppbus/ppb_msq.h>
51#include <dev/ppbus/vpoio.h>
52
53#include "ppbus_if.h"
54
50/*
51 * The driver pools the drive. We may add a timeout queue to avoid
52 * active polling on nACK. I've tried this but it leads to unreliable
53 * transfers
54 */
55#define VP0_SELTMO 5000 /* select timeout */
56#define VP0_FAST_SPINTMO 500000 /* wait status timeout */
57#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */

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

266 MS_RET(1),
267/* error: */
268 MS_RET(0)
269};
270
271static int
272vpoio_disconnect(struct vpoio_data *vpo)
273{
55/*
56 * The driver pools the drive. We may add a timeout queue to avoid
57 * active polling on nACK. I've tried this but it leads to unreliable
58 * transfers
59 */
60#define VP0_SELTMO 5000 /* select timeout */
61#define VP0_FAST_SPINTMO 500000 /* wait status timeout */
62#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */

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

271 MS_RET(1),
272/* error: */
273 MS_RET(0)
274};
275
276static int
277vpoio_disconnect(struct vpoio_data *vpo)
278{
279 device_t ppbus = device_get_parent(vpo->vpo_dev);
274 int ret;
275
280 int ret;
281
276 ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
277 return (ppb_release_bus(&vpo->vpo_dev));
282 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
283 return (ppb_release_bus(ppbus, vpo->vpo_dev));
278}
279
280/*
281 * how : PPB_WAIT or PPB_DONTWAIT
282 */
283static int
284vpoio_connect(struct vpoio_data *vpo, int how)
285{
284}
285
286/*
287 * how : PPB_WAIT or PPB_DONTWAIT
288 */
289static int
290vpoio_connect(struct vpoio_data *vpo, int how)
291{
292 device_t ppbus = device_get_parent(vpo->vpo_dev);
286 int error;
287 int ret;
288
293 int error;
294 int ret;
295
289 if ((error = ppb_request_bus(&vpo->vpo_dev, how))) {
296 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) {
290
291#ifdef VP0_DEBUG
292 printf("%s: can't request bus!\n", __FUNCTION__);
293#endif
294 return error;
295 }
296
297
298#ifdef VP0_DEBUG
299 printf("%s: can't request bus!\n", __FUNCTION__);
300#endif
301 return error;
302 }
303
297 if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
298 ppb_MS_microseq(&vpo->vpo_dev, connect_epp_microseq, &ret);
304 if (PPB_IN_EPP_MODE(ppbus))
305 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
299 else
306 else
300 ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
307 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
301
302 return (0);
303}
304
305/*
306 * vpoio_reset()
307 *
308 * SCSI reset signal, the drive must be in disk mode
309 */
310static void
311vpoio_reset (struct vpoio_data *vpo)
312{
308
309 return (0);
310}
311
312/*
313 * vpoio_reset()
314 *
315 * SCSI reset signal, the drive must be in disk mode
316 */
317static void
318vpoio_reset (struct vpoio_data *vpo)
319{
320 device_t ppbus = device_get_parent(vpo->vpo_dev);
313 int ret;
314
315 struct ppb_microseq reset_microseq[] = {
316
317 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT)
318
319 MS_DASS(MS_UNKNOWN),
320 MS_CASS(H_AUTO | H_nSELIN | H_nINIT | H_STROBE),
321 MS_DELAY(25),
322 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
323 MS_RET(0)
324 };
325
326 ppb_MS_init_msq(reset_microseq, 1, INITIATOR, 1 << VP0_INITIATOR);
321 int ret;
322
323 struct ppb_microseq reset_microseq[] = {
324
325 #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT)
326
327 MS_DASS(MS_UNKNOWN),
328 MS_CASS(H_AUTO | H_nSELIN | H_nINIT | H_STROBE),
329 MS_DELAY(25),
330 MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE),
331 MS_RET(0)
332 };
333
334 ppb_MS_init_msq(reset_microseq, 1, INITIATOR, 1 << VP0_INITIATOR);
327 ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, &ret);
335 ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, &ret);
328
329 return;
330}
331
332/*
333 * vpoio_in_disk_mode()
334 */
335static int
336vpoio_in_disk_mode(struct vpoio_data *vpo)
337{
336
337 return;
338}
339
340/*
341 * vpoio_in_disk_mode()
342 */
343static int
344vpoio_in_disk_mode(struct vpoio_data *vpo)
345{
346 device_t ppbus = device_get_parent(vpo->vpo_dev);
338 int ret;
339
347 int ret;
348
340 ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
349 ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
341
342 return (ret);
343}
344
345/*
346 * vpoio_detect()
347 *
348 * Detect and initialise the VP0 adapter.
349 */
350static int
351vpoio_detect(struct vpoio_data *vpo)
352{
350
351 return (ret);
352}
353
354/*
355 * vpoio_detect()
356 *
357 * Detect and initialise the VP0 adapter.
358 */
359static int
360vpoio_detect(struct vpoio_data *vpo)
361{
362 device_t ppbus = device_get_parent(vpo->vpo_dev);
353 int error, ret;
354
355 /* allocate the bus, then apply microsequences */
363 int error, ret;
364
365 /* allocate the bus, then apply microsequences */
356 if ((error = ppb_request_bus(&vpo->vpo_dev, PPB_DONTWAIT)))
366 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
357 return (error);
358
367 return (error);
368
359 ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
369 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
360
370
361 if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
362 ppb_MS_microseq(&vpo->vpo_dev, connect_epp_microseq, &ret);
371 if (PPB_IN_EPP_MODE(ppbus))
372 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret);
363 else
373 else
364 ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
374 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
365
375
366 ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
376 ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
367 if (!ret) {
368
369 /* try spp mode (maybe twice or because previous mode was PS2)
370 * NIBBLE mode will be restored on next transfers if detection
371 * succeed
372 */
377 if (!ret) {
378
379 /* try spp mode (maybe twice or because previous mode was PS2)
380 * NIBBLE mode will be restored on next transfers if detection
381 * succeed
382 */
373 ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE);
374 ppb_MS_microseq(&vpo->vpo_dev, connect_spp_microseq, &ret);
383 ppb_set_mode(ppbus, PPB_NIBBLE);
384 ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret);
375
385
376 ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
386 ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
377 if (!ret) {
378 if (bootverbose)
379 printf("vpo%d: can't connect to the drive\n",
380 vpo->vpo_unit);
381
382 /* disconnect and release the bus */
387 if (!ret) {
388 if (bootverbose)
389 printf("vpo%d: can't connect to the drive\n",
390 vpo->vpo_unit);
391
392 /* disconnect and release the bus */
383 ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq,
393 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq,
384 &ret);
385 goto error;
386 }
387 }
388
389 /* send SCSI reset signal */
390 vpoio_reset(vpo);
391
394 &ret);
395 goto error;
396 }
397 }
398
399 /* send SCSI reset signal */
400 vpoio_reset(vpo);
401
392 ppb_MS_microseq(&vpo->vpo_dev, disconnect_microseq, &ret);
402 ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret);
393
394 /* ensure we are disconnected or daisy chained peripheral
395 * may cause serious problem to the disk */
396
403
404 /* ensure we are disconnected or daisy chained peripheral
405 * may cause serious problem to the disk */
406
397 ppb_MS_microseq(&vpo->vpo_dev, in_disk_mode, &ret);
407 ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret);
398 if (ret) {
399 if (bootverbose)
400 printf("vpo%d: can't disconnect from the drive\n",
401 vpo->vpo_unit);
402 goto error;
403 }
404
408 if (ret) {
409 if (bootverbose)
410 printf("vpo%d: can't disconnect from the drive\n",
411 vpo->vpo_unit);
412 goto error;
413 }
414
405 ppb_release_bus(&vpo->vpo_dev);
415 ppb_release_bus(ppbus, vpo->vpo_dev);
406 return (0);
407
408error:
416 return (0);
417
418error:
409 ppb_release_bus(&vpo->vpo_dev);
419 ppb_release_bus(ppbus, vpo->vpo_dev);
410 return (VP0_EINITFAILED);
411}
412
413/*
414 * vpoio_outstr()
415 */
416static int
417vpoio_outstr(struct vpoio_data *vpo, char *buffer, int size)
418{
420 return (VP0_EINITFAILED);
421}
422
423/*
424 * vpoio_outstr()
425 */
426static int
427vpoio_outstr(struct vpoio_data *vpo, char *buffer, int size)
428{
419
429 device_t ppbus = device_get_parent(vpo->vpo_dev);
420 int error = 0;
421
430 int error = 0;
431
422 ppb_MS_exec(&vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
432 ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
423 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
424
425#if 0
426 /* XXX EPP 1.9 not implemented with microsequences */
427 else {
428
433 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
434
435#if 0
436 /* XXX EPP 1.9 not implemented with microsequences */
437 else {
438
429 ppb_reset_epp_timeout(&vpo->vpo_dev);
430 ppb_wctr(&vpo->vpo_dev,
431 H_AUTO | H_SELIN | H_INIT | H_STROBE);
439 ppb_reset_epp_timeout(ppbus);
440 ppb_wctr(ppbus, H_AUTO | H_SELIN | H_INIT | H_STROBE);
432
433 if (((long) buffer | size) & 0x03)
441
442 if (((long) buffer | size) & 0x03)
434 ppb_outsb_epp(&vpo->vpo_dev,
443 ppb_outsb_epp(ppbus,
435 buffer, size);
436 else
444 buffer, size);
445 else
437 ppb_outsl_epp(&vpo->vpo_dev,
446 ppb_outsl_epp(ppbus,
438 buffer, size/4);
439
447 buffer, size/4);
448
440 if ((ppb_rstr(&vpo->vpo_dev) & TIMEOUT)) {
449 if ((ppb_rstr(ppbus) & TIMEOUT)) {
441 error = VP0_EPPDATA_TIMEOUT;
442 goto error;
443 }
444
450 error = VP0_EPPDATA_TIMEOUT;
451 goto error;
452 }
453
445 ppb_wctr(&vpo->vpo_dev,
446 H_AUTO | H_nSELIN | H_INIT | H_STROBE);
454 ppb_wctr(ppbus, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
447 }
448#endif
455 }
456#endif
449 ppb_ecp_sync(&vpo->vpo_dev);
457 ppb_ecp_sync(ppbus);
450
451 return (error);
452}
453
454/*
455 * vpoio_instr()
456 */
457static int
458vpoio_instr(struct vpoio_data *vpo, char *buffer, int size)
459{
458
459 return (error);
460}
461
462/*
463 * vpoio_instr()
464 */
465static int
466vpoio_instr(struct vpoio_data *vpo, char *buffer, int size)
467{
468 device_t ppbus = device_get_parent(vpo->vpo_dev);
460 int error = 0;
461
469 int error = 0;
470
462 ppb_MS_exec(&vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
471 ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
463 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
464
465#if 0
466 /* XXX EPP 1.9 not implemented with microsequences */
467 else {
468
472 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
473
474#if 0
475 /* XXX EPP 1.9 not implemented with microsequences */
476 else {
477
469 ppb_reset_epp_timeout(&vpo->vpo_dev);
470 ppb_wctr(&vpo->vpo_dev, PCD |
478 ppb_reset_epp_timeout(ppbus);
479 ppb_wctr(ppbus, PCD |
471 H_AUTO | H_SELIN | H_INIT | H_STROBE);
472
473 if (((long) buffer | size) & 0x03)
480 H_AUTO | H_SELIN | H_INIT | H_STROBE);
481
482 if (((long) buffer | size) & 0x03)
474 ppb_insb_epp(&vpo->vpo_dev,
483 ppb_insb_epp(ppbus,
475 buffer, size);
476 else
484 buffer, size);
485 else
477 ppb_insl_epp(&vpo->vpo_dev,
486 ppb_insl_epp(ppbus,
478 buffer, size/4);
479
487 buffer, size/4);
488
480 if ((ppb_rstr(&vpo->vpo_dev) & TIMEOUT)) {
489 if ((ppb_rstr(ppbus) & TIMEOUT)) {
481 error = VP0_EPPDATA_TIMEOUT;
482 goto error;
483 }
484
490 error = VP0_EPPDATA_TIMEOUT;
491 goto error;
492 }
493
485 ppb_wctr(&vpo->vpo_dev, PCD |
494 ppb_wctr(ppbus, PCD |
486 H_AUTO | H_nSELIN | H_INIT | H_STROBE);
487 }
488#endif
495 H_AUTO | H_nSELIN | H_INIT | H_STROBE);
496 }
497#endif
489 ppb_ecp_sync(&vpo->vpo_dev);
498 ppb_ecp_sync(ppbus);
490
491 return (error);
492}
493
494static char
495vpoio_select(struct vpoio_data *vpo, int initiator, int target)
496{
499
500 return (error);
501}
502
503static char
504vpoio_select(struct vpoio_data *vpo, int initiator, int target)
505{
506 device_t ppbus = device_get_parent(vpo->vpo_dev);
497 int ret;
498
499 struct ppb_microseq select_microseq[] = {
500
501 /* parameter list
502 */
503 #define SELECT_TARGET MS_PARAM(0, 1, MS_TYP_INT)
504 #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT)

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

518/* ready: */ MS_RET(0)
519 };
520
521 /* initialize the select microsequence */
522 ppb_MS_init_msq(select_microseq, 2,
523 SELECT_TARGET, 1 << target,
524 SELECT_INITIATOR, 1 << initiator);
525
507 int ret;
508
509 struct ppb_microseq select_microseq[] = {
510
511 /* parameter list
512 */
513 #define SELECT_TARGET MS_PARAM(0, 1, MS_TYP_INT)
514 #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT)

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

528/* ready: */ MS_RET(0)
529 };
530
531 /* initialize the select microsequence */
532 ppb_MS_init_msq(select_microseq, 2,
533 SELECT_TARGET, 1 << target,
534 SELECT_INITIATOR, 1 << initiator);
535
526 ppb_MS_microseq(&vpo->vpo_dev, select_microseq, &ret);
536 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
527
528 if (ret)
529 return (VP0_ESELECT_TIMEOUT);
530
531 return (0);
532}
533
534/*
535 * vpoio_wait()
536 *
537 * H_SELIN must be low.
538 *
539 * XXX should be ported to microseq
540 */
541static char
542vpoio_wait(struct vpoio_data *vpo, int tmo)
543{
537
538 if (ret)
539 return (VP0_ESELECT_TIMEOUT);
540
541 return (0);
542}
543
544/*
545 * vpoio_wait()
546 *
547 * H_SELIN must be low.
548 *
549 * XXX should be ported to microseq
550 */
551static char
552vpoio_wait(struct vpoio_data *vpo, int tmo)
553{
544
554 device_t ppbus = device_get_parent(vpo->vpo_dev);
545 register int k;
546 register char r;
547
548#if 0 /* broken */
555 register int k;
556 register char r;
557
558#if 0 /* broken */
549 if (ppb_poll_device(&vpo->vpo_dev, 150, nBUSY, nBUSY, PPB_INTR))
559 if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR))
550 return (0);
551
560 return (0);
561
552 return (ppb_rstr(&vpo->vpo_dev) & 0xf0);
562 return (ppb_rstr(ppbus) & 0xf0);
553#endif
554
555 /* XXX should be ported to microseq */
556 k = 0;
563#endif
564
565 /* XXX should be ported to microseq */
566 k = 0;
557 while (!((r = ppb_rstr(&vpo->vpo_dev)) & nBUSY) && (k++ < tmo))
567 while (!((r = ppb_rstr(ppbus)) & nBUSY) && (k++ < tmo))
558 ;
559
560 /*
561 * Return some status information.
562 * Semantics : 0xc0 = ZIP wants more data
563 * 0xd0 = ZIP wants to send more data
564 * 0xe0 = ZIP wants command
565 * 0xf0 = end of transfer, ZIP is sending status

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

571}
572
573/*
574 * vpoio_probe()
575 *
576 * Low level probe of vpo device
577 *
578 */
568 ;
569
570 /*
571 * Return some status information.
572 * Semantics : 0xc0 = ZIP wants more data
573 * 0xd0 = ZIP wants to send more data
574 * 0xe0 = ZIP wants command
575 * 0xf0 = end of transfer, ZIP is sending status

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

581}
582
583/*
584 * vpoio_probe()
585 *
586 * Low level probe of vpo device
587 *
588 */
579struct ppb_device *
580vpoio_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
589int
590vpoio_probe(device_t dev, struct vpoio_data *vpo)
581{
591{
592 int error;
582
583 /* ppbus dependent initialisation */
593
594 /* ppbus dependent initialisation */
584 vpo->vpo_dev.id_unit = vpo->vpo_unit;
585 vpo->vpo_dev.name = "vpo";
586 vpo->vpo_dev.ppb = ppb;
595 vpo->vpo_dev = dev;
587
588 /*
589 * Initialize microsequence code
590 */
591 INIT_TRIG_MICROSEQ;
592
593 /* now, try to initialise the drive */
596
597 /*
598 * Initialize microsequence code
599 */
600 INIT_TRIG_MICROSEQ;
601
602 /* now, try to initialise the drive */
594 if (vpoio_detect(vpo)) {
595 return (NULL);
603 if ((error = vpoio_detect(vpo))) {
604 return (error);
596 }
597
605 }
606
598 return (&vpo->vpo_dev);
607 return (0);
599}
600
601/*
602 * vpoio_attach()
603 *
604 * Low level attachment of vpo device
605 *
606 */
607int
608vpoio_attach(struct vpoio_data *vpo)
609{
608}
609
610/*
611 * vpoio_attach()
612 *
613 * Low level attachment of vpo device
614 *
615 */
616int
617vpoio_attach(struct vpoio_data *vpo)
618{
619 device_t ppbus = device_get_parent(vpo->vpo_dev);
610 int epp;
611
620 int epp;
621
612 /*
613 * Report ourselves
614 */
615 printf("vpo%d: <Iomega VPI0 Parallel to SCSI interface> on ppbus %d\n",
616 vpo->vpo_dev.id_unit, vpo->vpo_dev.ppb->ppb_link->adapter_unit);
617
618 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
619 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
620
621 if (!vpo->vpo_nibble_inbyte_msq)
622 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
623 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
624
625 if (!vpo->vpo_nibble_inbyte_msq)
622 return (0);
626 return (ENXIO);
623
624 bcopy((void *)nibble_inbyte_submicroseq,
625 (void *)vpo->vpo_nibble_inbyte_msq,
626 sizeof(nibble_inbyte_submicroseq));
627
628 INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo);
629
630 /*
631 * Initialize mode dependent in/out microsequences
632 */
627
628 bcopy((void *)nibble_inbyte_submicroseq,
629 (void *)vpo->vpo_nibble_inbyte_msq,
630 sizeof(nibble_inbyte_submicroseq));
631
632 INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo);
633
634 /*
635 * Initialize mode dependent in/out microsequences
636 */
633 ppb_request_bus(&vpo->vpo_dev, PPB_WAIT);
637 ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT);
634
635 /* enter NIBBLE mode to configure submsq */
638
639 /* enter NIBBLE mode to configure submsq */
636 if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1) {
640 if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1) {
637
641
638 ppb_MS_GET_init(&vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
642 ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
639
643
640 ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
644 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
641 }
642
643 /* enter PS2 mode to configure submsq */
645 }
646
647 /* enter PS2 mode to configure submsq */
644 if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1) {
648 if (ppb_set_mode(ppbus, PPB_PS2) != -1) {
645
649
646 ppb_MS_GET_init(&vpo->vpo_dev, ps2_inbyte_submicroseq);
650 ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq);
647
651
648 ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
652 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
649 }
650
653 }
654
651 epp = ppb_get_epp_protocol(&vpo->vpo_dev);
655 epp = ppb_get_epp_protocol(ppbus);
652
653 /* enter EPP mode to configure submsq */
656
657 /* enter EPP mode to configure submsq */
654 if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
658 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
655
656 switch (epp) {
657 case EPP_1_9:
658 /* XXX EPP 1.9 support should be improved */
659 case EPP_1_7:
659
660 switch (epp) {
661 case EPP_1_9:
662 /* XXX EPP 1.9 support should be improved */
663 case EPP_1_7:
660 ppb_MS_GET_init(&vpo->vpo_dev, epp17_instr_body);
664 ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr_body);
661
665
662 ppb_MS_PUT_init(&vpo->vpo_dev, epp17_outstr_body);
666 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr_body);
663 break;
664 default:
665 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
666 epp);
667 }
668 }
669
670 /* try to enter EPP or PS/2 mode, NIBBLE otherwise */
667 break;
668 default:
669 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
670 epp);
671 }
672 }
673
674 /* try to enter EPP or PS/2 mode, NIBBLE otherwise */
671 if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
675 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
672 switch (epp) {
673 case EPP_1_9:
674 printf("vpo%d: EPP 1.9 mode\n", vpo->vpo_unit);
675 break;
676 case EPP_1_7:
677 printf("vpo%d: EPP 1.7 mode\n", vpo->vpo_unit);
678 break;
679 default:
680 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
681 epp);
682 }
676 switch (epp) {
677 case EPP_1_9:
678 printf("vpo%d: EPP 1.9 mode\n", vpo->vpo_unit);
679 break;
680 case EPP_1_7:
681 printf("vpo%d: EPP 1.7 mode\n", vpo->vpo_unit);
682 break;
683 default:
684 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
685 epp);
686 }
683 } else if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1)
687 } else if (ppb_set_mode(ppbus, PPB_PS2) != -1)
684 printf("vpo%d: PS2 mode\n", vpo->vpo_unit);
685
688 printf("vpo%d: PS2 mode\n", vpo->vpo_unit);
689
686 else if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1)
690 else if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1)
687 printf("vpo%d: NIBBLE mode\n", vpo->vpo_unit);
688
689 else {
690 printf("vpo%d: can't enter NIBBLE, PS2 or EPP mode\n",
691 vpo->vpo_unit);
692
691 printf("vpo%d: NIBBLE mode\n", vpo->vpo_unit);
692
693 else {
694 printf("vpo%d: can't enter NIBBLE, PS2 or EPP mode\n",
695 vpo->vpo_unit);
696
693 ppb_release_bus(&vpo->vpo_dev);
697 ppb_release_bus(ppbus, vpo->vpo_dev);
694
695 free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
698
699 free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
696 return (0);
700 return (ENXIO);
697 }
698
701 }
702
699 ppb_release_bus(&vpo->vpo_dev);
703 ppb_release_bus(ppbus, vpo->vpo_dev);
700
704
701 return (1);
705 return (0);
702}
703
704/*
705 * vpoio_reset_bus()
706 *
707 */
708int
709vpoio_reset_bus(struct vpoio_data *vpo)

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

734 * Send an SCSI command
735 *
736 */
737int
738vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
739 int clen, char *buffer, int blen, int *result, int *count,
740 int *ret)
741{
706}
707
708/*
709 * vpoio_reset_bus()
710 *
711 */
712int
713vpoio_reset_bus(struct vpoio_data *vpo)

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

738 * Send an SCSI command
739 *
740 */
741int
742vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
743 int clen, char *buffer, int blen, int *result, int *count,
744 int *ret)
745{
742
746 device_t ppbus = device_get_parent(vpo->vpo_dev);
743 register char r;
744 char l, h = 0;
745 int len, error = 0;
746 register int k;
747
748 /*
749 * enter disk state, allocate the ppbus
750 *

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

763 if ((*ret = vpoio_select(vpo,host,target)))
764 goto error;
765
766 /*
767 * Send the command ...
768 *
769 * set H_SELIN low for vpoio_wait().
770 */
747 register char r;
748 char l, h = 0;
749 int len, error = 0;
750 register int k;
751
752 /*
753 * enter disk state, allocate the ppbus
754 *

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

767 if ((*ret = vpoio_select(vpo,host,target)))
768 goto error;
769
770 /*
771 * Send the command ...
772 *
773 * set H_SELIN low for vpoio_wait().
774 */
771 ppb_wctr(&vpo->vpo_dev, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
775 ppb_wctr(ppbus, H_AUTO | H_nSELIN | H_INIT | H_STROBE);
772
773 for (k = 0; k < clen; k++) {
774 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) != (char)0xe0) {
775 *ret = VP0_ECMD_TIMEOUT;
776 goto error;
777 }
778 if (vpoio_outstr(vpo, &command[k], 1)) {
779 *ret = VP0_EPPDATA_TIMEOUT;

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

799 if (*count >= blen) {
800 *ret = VP0_EDATA_OVERFLOW;
801 goto error;
802 }
803
804 /* if in EPP mode or writing bytes, try to transfer a sector
805 * otherwise, just send one byte
806 */
776
777 for (k = 0; k < clen; k++) {
778 if (vpoio_wait(vpo, VP0_FAST_SPINTMO) != (char)0xe0) {
779 *ret = VP0_ECMD_TIMEOUT;
780 goto error;
781 }
782 if (vpoio_outstr(vpo, &command[k], 1)) {
783 *ret = VP0_EPPDATA_TIMEOUT;

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

803 if (*count >= blen) {
804 *ret = VP0_EDATA_OVERFLOW;
805 goto error;
806 }
807
808 /* if in EPP mode or writing bytes, try to transfer a sector
809 * otherwise, just send one byte
810 */
807 if (PPB_IN_EPP_MODE(&vpo->vpo_dev) || r == (char)0xc0)
811 if (PPB_IN_EPP_MODE(ppbus) || r == (char)0xc0)
808 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
809 VP0_SECTOR_SIZE : 1;
810 else
811 len = 1;
812
813 /* ZIP wants to send data? */
814 if (r == (char)0xc0)
815 error = vpoio_outstr(vpo, &buffer[*count], len);

--- 28 unchanged lines hidden ---
812 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
813 VP0_SECTOR_SIZE : 1;
814 else
815 len = 1;
816
817 /* ZIP wants to send data? */
818 if (r == (char)0xc0)
819 error = vpoio_outstr(vpo, &buffer[*count], len);

--- 28 unchanged lines hidden ---