Deleted Added
full compact
immio.c (55205) immio.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/immio.c 55205 1999-12-29 04:46:21Z peter $
26 * $FreeBSD: head/sys/dev/ppbus/immio.c 55939 2000-01-14 00:18:06Z nsouch $
27 *
28 */
29
30/*
31 * Iomega ZIP+ Matchmaker Parallel Port Interface driver
32 *
33 * Thanks to David Campbell work on the Linux driver and the Iomega specs
34 * Thanks to Thiebault Moeglin for the drive
35 */
36#ifdef _KERNEL
37#include <sys/param.h>
38#include <sys/systm.h>
27 *
28 */
29
30/*
31 * Iomega ZIP+ Matchmaker Parallel Port Interface driver
32 *
33 * Thanks to David Campbell work on the Linux driver and the Iomega specs
34 * Thanks to Thiebault Moeglin for the drive
35 */
36#ifdef _KERNEL
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/module.h>
40#include <sys/bus.h>
39#include <sys/malloc.h>
40#include <sys/buf.h>
41
42#include <machine/clock.h>
43
44#endif /* _KERNEL */
45
46#ifdef _KERNEL
47#include <sys/kernel.h>
48#endif /* _KERNEL */
49
50#include "opt_vpo.h"
51
41#include <sys/malloc.h>
42#include <sys/buf.h>
43
44#include <machine/clock.h>
45
46#endif /* _KERNEL */
47
48#ifdef _KERNEL
49#include <sys/kernel.h>
50#endif /* _KERNEL */
51
52#include "opt_vpo.h"
53
54#include <dev/ppbus/ppbio.h>
52#include <dev/ppbus/ppbconf.h>
53#include <dev/ppbus/ppb_msq.h>
54#include <dev/ppbus/vpoio.h>
55#include <dev/ppbus/ppb_1284.h>
56
55#include <dev/ppbus/ppbconf.h>
56#include <dev/ppbus/ppb_msq.h>
57#include <dev/ppbus/vpoio.h>
58#include <dev/ppbus/ppb_1284.h>
59
60#include "ppbus_if.h"
61
57#define VP0_SELTMO 5000 /* select timeout */
58#define VP0_FAST_SPINTMO 500000 /* wait status timeout */
59#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */
60
61#define VP0_SECTOR_SIZE 512
62
63/*
64 * Microcode to execute very fast I/O sequences at the lowest bus level.

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

270 MS_RET(0),
271};
272
273static int
274imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus)
275{
276 DECLARE_CPP_MICROSEQ;
277
62#define VP0_SELTMO 5000 /* select timeout */
63#define VP0_FAST_SPINTMO 500000 /* wait status timeout */
64#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */
65
66#define VP0_SECTOR_SIZE 512
67
68/*
69 * Microcode to execute very fast I/O sequences at the lowest bus level.

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

275 MS_RET(0),
276};
277
278static int
279imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus)
280{
281 DECLARE_CPP_MICROSEQ;
282
283 device_t ppbus = device_get_parent(vpo->vpo_dev);
278 char s1, s2, s3;
279 int ret;
280
281 /* all should be ok */
282 if (connected)
283 *connected = 0;
284
285 ppb_MS_init_msq(cpp_microseq, 4, CPP_S1, (void *)&s1,
286 CPP_S2, (void *)&s2, CPP_S3, (void *)&s3,
287 CPP_PARAM, 0x30);
288
284 char s1, s2, s3;
285 int ret;
286
287 /* all should be ok */
288 if (connected)
289 *connected = 0;
290
291 ppb_MS_init_msq(cpp_microseq, 4, CPP_S1, (void *)&s1,
292 CPP_S2, (void *)&s2, CPP_S3, (void *)&s3,
293 CPP_PARAM, 0x30);
294
289 ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
295 ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
290
291 if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x38)) {
292 if (bootverbose)
293 printf("imm%d: (disconnect) s1=0x%x s2=0x%x, s3=0x%x\n",
294 vpo->vpo_unit, s1 & 0xff, s2 & 0xff, s3 & 0xff);
295 if (connected)
296 *connected = VP0_ECONNECT;
297 }
298
299 if (release_bus)
296
297 if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x38)) {
298 if (bootverbose)
299 printf("imm%d: (disconnect) s1=0x%x s2=0x%x, s3=0x%x\n",
300 vpo->vpo_unit, s1 & 0xff, s2 & 0xff, s3 & 0xff);
301 if (connected)
302 *connected = VP0_ECONNECT;
303 }
304
305 if (release_bus)
300 return (ppb_release_bus(&vpo->vpo_dev));
306 return (ppb_release_bus(ppbus, vpo->vpo_dev));
301 else
302 return (0);
303}
304
305/*
306 * how : PPB_WAIT or PPB_DONTWAIT
307 */
308static int
309imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
310{
311 DECLARE_CPP_MICROSEQ;
312
307 else
308 return (0);
309}
310
311/*
312 * how : PPB_WAIT or PPB_DONTWAIT
313 */
314static int
315imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus)
316{
317 DECLARE_CPP_MICROSEQ;
318
319 device_t ppbus = device_get_parent(vpo->vpo_dev);
313 char s1, s2, s3;
314 int error;
315 int ret;
316
317 /* all should be ok */
318 if (disconnected)
319 *disconnected = 0;
320
321 if (request_bus)
320 char s1, s2, s3;
321 int error;
322 int ret;
323
324 /* all should be ok */
325 if (disconnected)
326 *disconnected = 0;
327
328 if (request_bus)
322 if ((error = ppb_request_bus(&vpo->vpo_dev, how)))
329 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how)))
323 return (error);
324
325 ppb_MS_init_msq(cpp_microseq, 3, CPP_S1, (void *)&s1,
326 CPP_S2, (void *)&s2, CPP_S3, (void *)&s3);
327
328 /* select device 0 in compatible mode */
329 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
330 return (error);
331
332 ppb_MS_init_msq(cpp_microseq, 3, CPP_S1, (void *)&s1,
333 CPP_S2, (void *)&s2, CPP_S3, (void *)&s3);
334
335 /* select device 0 in compatible mode */
336 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
330 ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
337 ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
331
332 /* disconnect all devices */
333 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x30);
338
339 /* disconnect all devices */
340 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x30);
334 ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
341 ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
335
342
336 if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
343 if (PPB_IN_EPP_MODE(ppbus))
337 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x28);
338 else
339 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
340
344 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x28);
345 else
346 ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0);
347
341 ppb_MS_microseq(&vpo->vpo_dev, cpp_microseq, &ret);
348 ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret);
342
343 if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x30)) {
344 if (bootverbose)
345 printf("imm%d: (connect) s1=0x%x s2=0x%x, s3=0x%x\n",
346 vpo->vpo_unit, s1 & 0xff, s2 & 0xff, s3 & 0xff);
347 if (disconnected)
348 *disconnected = VP0_ECONNECT;
349 }

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

354/*
355 * imm_detect()
356 *
357 * Detect and initialise the VP0 adapter.
358 */
359static int
360imm_detect(struct vpoio_data *vpo)
361{
349
350 if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x30)) {
351 if (bootverbose)
352 printf("imm%d: (connect) s1=0x%x s2=0x%x, s3=0x%x\n",
353 vpo->vpo_unit, s1 & 0xff, s2 & 0xff, s3 & 0xff);
354 if (disconnected)
355 *disconnected = VP0_ECONNECT;
356 }

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

361/*
362 * imm_detect()
363 *
364 * Detect and initialise the VP0 adapter.
365 */
366static int
367imm_detect(struct vpoio_data *vpo)
368{
369 device_t ppbus = device_get_parent(vpo->vpo_dev);
362 int error;
363
370 int error;
371
364 if ((error = ppb_request_bus(&vpo->vpo_dev, PPB_DONTWAIT)))
372 if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT)))
365 return (error);
366
367 /* disconnect the drive, keep the bus */
368 imm_disconnect(vpo, NULL, 0);
369
370 /* we already have the bus, just connect */
371 imm_connect(vpo, PPB_DONTWAIT, &error, 0);
372
373 if (error) {
374 if (bootverbose)
375 printf("imm%d: can't connect to the drive\n",
376 vpo->vpo_unit);
377 goto error;
378 }
379
380 /* send SCSI reset signal */
373 return (error);
374
375 /* disconnect the drive, keep the bus */
376 imm_disconnect(vpo, NULL, 0);
377
378 /* we already have the bus, just connect */
379 imm_connect(vpo, PPB_DONTWAIT, &error, 0);
380
381 if (error) {
382 if (bootverbose)
383 printf("imm%d: can't connect to the drive\n",
384 vpo->vpo_unit);
385 goto error;
386 }
387
388 /* send SCSI reset signal */
381 ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, NULL);
389 ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL);
382
383 /* release the bus now */
384 imm_disconnect(vpo, &error, 1);
385
386 /* ensure we are disconnected or daisy chained peripheral
387 * may cause serious problem to the disk */
388
389 if (error) {
390 if (bootverbose)
391 printf("imm%d: can't disconnect from the drive\n",
392 vpo->vpo_unit);
393 goto error;
394 }
395
396 return (0);
397
398error:
390
391 /* release the bus now */
392 imm_disconnect(vpo, &error, 1);
393
394 /* ensure we are disconnected or daisy chained peripheral
395 * may cause serious problem to the disk */
396
397 if (error) {
398 if (bootverbose)
399 printf("imm%d: can't disconnect from the drive\n",
400 vpo->vpo_unit);
401 goto error;
402 }
403
404 return (0);
405
406error:
399 ppb_release_bus(&vpo->vpo_dev);
407 ppb_release_bus(ppbus, vpo->vpo_dev);
400 return (VP0_EINITFAILED);
401}
402
403/*
404 * imm_outstr()
405 */
406static int
407imm_outstr(struct vpoio_data *vpo, char *buffer, int size)
408{
408 return (VP0_EINITFAILED);
409}
410
411/*
412 * imm_outstr()
413 */
414static int
415imm_outstr(struct vpoio_data *vpo, char *buffer, int size)
416{
417 device_t ppbus = device_get_parent(vpo->vpo_dev);
409 int error = 0;
410
418 int error = 0;
419
411 if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
412 ppb_reset_epp_timeout(&vpo->vpo_dev);
420 if (PPB_IN_EPP_MODE(ppbus))
421 ppb_reset_epp_timeout(ppbus);
413
422
414 ppb_MS_exec(&vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
423 ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer,
415 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
416
417 return (error);
418}
419
420/*
421 * imm_instr()
422 */
423static int
424imm_instr(struct vpoio_data *vpo, char *buffer, int size)
425{
424 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
425
426 return (error);
427}
428
429/*
430 * imm_instr()
431 */
432static int
433imm_instr(struct vpoio_data *vpo, char *buffer, int size)
434{
435 device_t ppbus = device_get_parent(vpo->vpo_dev);
426 int error = 0;
427
436 int error = 0;
437
428 if (PPB_IN_EPP_MODE(&vpo->vpo_dev))
429 ppb_reset_epp_timeout(&vpo->vpo_dev);
438 if (PPB_IN_EPP_MODE(ppbus))
439 ppb_reset_epp_timeout(ppbus);
430
440
431 ppb_MS_exec(&vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
441 ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer,
432 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
433
434 return (error);
435}
436
437static char
438imm_select(struct vpoio_data *vpo, int initiator, int target)
439{
440 DECLARE_SELECT_MICROSEQUENCE;
442 (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error);
443
444 return (error);
445}
446
447static char
448imm_select(struct vpoio_data *vpo, int initiator, int target)
449{
450 DECLARE_SELECT_MICROSEQUENCE;
451 device_t ppbus = device_get_parent(vpo->vpo_dev);
441 int ret;
442
443 /* initialize the select microsequence */
444 ppb_MS_init_msq(select_microseq, 1,
445 SELECT_TARGET, 1 << initiator | 1 << target);
446
452 int ret;
453
454 /* initialize the select microsequence */
455 ppb_MS_init_msq(select_microseq, 1,
456 SELECT_TARGET, 1 << initiator | 1 << target);
457
447 ppb_MS_microseq(&vpo->vpo_dev, select_microseq, &ret);
458 ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);
448
449 return (ret);
450}
451
452/*
453 * imm_wait()
454 *
455 * H_SELIN must be low.
456 *
457 * XXX should be ported to microseq
458 */
459static char
460imm_wait(struct vpoio_data *vpo, int tmo)
461{
459
460 return (ret);
461}
462
463/*
464 * imm_wait()
465 *
466 * H_SELIN must be low.
467 *
468 * XXX should be ported to microseq
469 */
470static char
471imm_wait(struct vpoio_data *vpo, int tmo)
472{
462
473 device_t ppbus = device_get_parent(vpo->vpo_dev);
463 register int k;
464 register char r;
465
474 register int k;
475 register char r;
476
466 ppb_wctr(&vpo->vpo_dev, 0xc);
477 ppb_wctr(ppbus, 0xc);
467
468 /* XXX should be ported to microseq */
469 k = 0;
478
479 /* XXX should be ported to microseq */
480 k = 0;
470 while (!((r = ppb_rstr(&vpo->vpo_dev)) & 0x80) && (k++ < tmo))
481 while (!((r = ppb_rstr(ppbus)) & 0x80) && (k++ < tmo))
471 DELAY(1);
472
473 /*
474 * Return some status information.
475 * Semantics : 0x88 = ZIP+ wants more data
476 * 0x98 = ZIP+ wants to send more data
477 * 0xa8 = ZIP+ wants command
478 * 0xb8 = end of transfer, ZIP+ is sending status
479 */
482 DELAY(1);
483
484 /*
485 * Return some status information.
486 * Semantics : 0x88 = ZIP+ wants more data
487 * 0x98 = ZIP+ wants to send more data
488 * 0xa8 = ZIP+ wants command
489 * 0xb8 = end of transfer, ZIP+ is sending status
490 */
480 ppb_wctr(&vpo->vpo_dev, 0x4);
491 ppb_wctr(ppbus, 0x4);
481 if (k < tmo)
482 return (r & 0xb8);
483
484 return (0); /* command timed out */
485}
486
487static int
488imm_negociate(struct vpoio_data *vpo)
489{
490 DECLARE_NEGOCIATE_MICROSEQ;
492 if (k < tmo)
493 return (r & 0xb8);
494
495 return (0); /* command timed out */
496}
497
498static int
499imm_negociate(struct vpoio_data *vpo)
500{
501 DECLARE_NEGOCIATE_MICROSEQ;
502 device_t ppbus = device_get_parent(vpo->vpo_dev);
491 int negociate_mode;
492 int ret;
493
503 int negociate_mode;
504 int ret;
505
494 if (PPB_IN_NIBBLE_MODE(&vpo->vpo_dev))
506 if (PPB_IN_NIBBLE_MODE(ppbus))
495 negociate_mode = 0;
507 negociate_mode = 0;
496 else if (PPB_IN_PS2_MODE(&vpo->vpo_dev))
508 else if (PPB_IN_PS2_MODE(ppbus))
497 negociate_mode = 1;
498 else
499 return (0);
500
501#if 0 /* XXX use standalone code not to depend on ppb_1284 code yet */
509 negociate_mode = 1;
510 else
511 return (0);
512
513#if 0 /* XXX use standalone code not to depend on ppb_1284 code yet */
502 ret = ppb_1284_negociate(&vpo->vpo_dev, negociate_mode);
514 ret = ppb_1284_negociate(ppbus, negociate_mode);
503
504 if (ret)
505 return (VP0_ENEGOCIATE);
506#endif
507
515
516 if (ret)
517 return (VP0_ENEGOCIATE);
518#endif
519
508 ppb_MS_init_msq(negociate_microseq, 1, NEGOCIATED_MODE, negociate_mode);
520 ppb_MS_init_msq(negociate_microseq, 1,
521 NEGOCIATED_MODE, negociate_mode);
509
522
510 ppb_MS_microseq(&vpo->vpo_dev, negociate_microseq, &ret);
523 ppb_MS_microseq(ppbus, vpo->vpo_dev, negociate_microseq, &ret);
511
512 return (ret);
513}
514
515/*
516 * imm_probe()
517 *
518 * Low level probe of vpo device
519 *
520 */
524
525 return (ret);
526}
527
528/*
529 * imm_probe()
530 *
531 * Low level probe of vpo device
532 *
533 */
521struct ppb_device *
522imm_probe(struct ppb_data *ppb, struct vpoio_data *vpo)
534int
535imm_probe(device_t dev, struct vpoio_data *vpo)
523{
536{
537 int error;
524
525 /* ppbus dependent initialisation */
538
539 /* ppbus dependent initialisation */
526 vpo->vpo_dev.id_unit = vpo->vpo_unit;
527 vpo->vpo_dev.name = "vpo";
528 vpo->vpo_dev.ppb = ppb;
540 vpo->vpo_dev = dev;
529
530 /* now, try to initialise the drive */
541
542 /* now, try to initialise the drive */
531 if (imm_detect(vpo)) {
532 return (NULL);
543 if ((error = imm_detect(vpo))) {
544 return (error);
533 }
534
545 }
546
535 return (&vpo->vpo_dev);
547 return (0);
536}
537
538/*
539 * imm_attach()
540 *
541 * Low level attachment of vpo device
542 *
543 */
544int
545imm_attach(struct vpoio_data *vpo)
546{
548}
549
550/*
551 * imm_attach()
552 *
553 * Low level attachment of vpo device
554 *
555 */
556int
557imm_attach(struct vpoio_data *vpo)
558{
559 device_t ppbus = device_get_parent(vpo->vpo_dev);
547 int epp;
548
549 /*
560 int epp;
561
562 /*
550 * Report ourselves
551 */
552 printf("imm%d: <Iomega Matchmaker Parallel to SCSI interface> on ppbus %d\n",
553 vpo->vpo_dev.id_unit, vpo->vpo_dev.ppb->ppb_link->adapter_unit);
554
555 /*
556 * Initialize microsequence code
557 */
558 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
559 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
560
561 if (!vpo->vpo_nibble_inbyte_msq)
563 * Initialize microsequence code
564 */
565 vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc(
566 sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT);
567
568 if (!vpo->vpo_nibble_inbyte_msq)
562 return (0);
569 return (ENXIO);
563
564 bcopy((void *)nibble_inbyte_submicroseq,
565 (void *)vpo->vpo_nibble_inbyte_msq,
566 sizeof(nibble_inbyte_submicroseq));
567
568 INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo);
569
570 /*
571 * Initialize mode dependent in/out microsequences
572 */
570
571 bcopy((void *)nibble_inbyte_submicroseq,
572 (void *)vpo->vpo_nibble_inbyte_msq,
573 sizeof(nibble_inbyte_submicroseq));
574
575 INIT_NIBBLE_INBYTE_SUBMICROSEQ(vpo);
576
577 /*
578 * Initialize mode dependent in/out microsequences
579 */
573 ppb_request_bus(&vpo->vpo_dev, PPB_WAIT);
580 ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT);
574
575 /* enter NIBBLE mode to configure submsq */
581
582 /* enter NIBBLE mode to configure submsq */
576 if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1) {
583 if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1) {
577
584
578 ppb_MS_GET_init(&vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
579 ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
585 ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq);
586 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
580 }
581
582 /* enter PS2 mode to configure submsq */
587 }
588
589 /* enter PS2 mode to configure submsq */
583 if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1) {
590 if (ppb_set_mode(ppbus, PPB_PS2) != -1) {
584
591
585 ppb_MS_GET_init(&vpo->vpo_dev, ps2_inbyte_submicroseq);
586 ppb_MS_PUT_init(&vpo->vpo_dev, spp_outbyte_submicroseq);
592 ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq);
593 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq);
587 }
588
594 }
595
589 epp = ppb_get_epp_protocol(&vpo->vpo_dev);
596 epp = ppb_get_epp_protocol(ppbus);
590
591 /* enter EPP mode to configure submsq */
597
598 /* enter EPP mode to configure submsq */
592 if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
599 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
593
594 switch (epp) {
595 case EPP_1_9:
596 case EPP_1_7:
600
601 switch (epp) {
602 case EPP_1_9:
603 case EPP_1_7:
597 ppb_MS_GET_init(&vpo->vpo_dev, epp17_instr);
598 ppb_MS_PUT_init(&vpo->vpo_dev, epp17_outstr);
604 ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr);
605 ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr);
599 break;
600 default:
601 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
602 epp);
603 }
604 }
605
606 /* try to enter EPP or PS/2 mode, NIBBLE otherwise */
606 break;
607 default:
608 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
609 epp);
610 }
611 }
612
613 /* try to enter EPP or PS/2 mode, NIBBLE otherwise */
607 if (ppb_set_mode(&vpo->vpo_dev, PPB_EPP) != -1) {
614 if (ppb_set_mode(ppbus, PPB_EPP) != -1) {
608 switch (epp) {
609 case EPP_1_9:
610 printf("imm%d: EPP 1.9 mode\n", vpo->vpo_unit);
611 break;
612 case EPP_1_7:
613 printf("imm%d: EPP 1.7 mode\n", vpo->vpo_unit);
614 break;
615 default:
616 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
617 epp);
618 }
615 switch (epp) {
616 case EPP_1_9:
617 printf("imm%d: EPP 1.9 mode\n", vpo->vpo_unit);
618 break;
619 case EPP_1_7:
620 printf("imm%d: EPP 1.7 mode\n", vpo->vpo_unit);
621 break;
622 default:
623 panic("%s: unknown EPP protocol (0x%x)", __FUNCTION__,
624 epp);
625 }
619 } else if (ppb_set_mode(&vpo->vpo_dev, PPB_PS2) != -1)
626 } else if (ppb_set_mode(ppbus, PPB_PS2) != -1)
620 printf("imm%d: PS2 mode\n", vpo->vpo_unit);
621
627 printf("imm%d: PS2 mode\n", vpo->vpo_unit);
628
622 else if (ppb_set_mode(&vpo->vpo_dev, PPB_NIBBLE) != -1)
629 else if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1)
623 printf("imm%d: NIBBLE mode\n", vpo->vpo_unit);
624
625 else {
626 printf("imm%d: can't enter NIBBLE, PS2 or EPP mode\n",
627 vpo->vpo_unit);
628
630 printf("imm%d: NIBBLE mode\n", vpo->vpo_unit);
631
632 else {
633 printf("imm%d: can't enter NIBBLE, PS2 or EPP mode\n",
634 vpo->vpo_unit);
635
629 ppb_release_bus(&vpo->vpo_dev);
636 ppb_release_bus(ppbus, vpo->vpo_dev);
630
631 free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
637
638 free(vpo->vpo_nibble_inbyte_msq, M_DEVBUF);
632 return (0);
639 return (ENXIO);
633 }
634
640 }
641
635 ppb_release_bus(&vpo->vpo_dev);
642 ppb_release_bus(ppbus, vpo->vpo_dev);
636
643
637 return (1);
644 return (0);
638}
639
640/*
641 * imm_reset_bus()
642 *
643 */
644int
645imm_reset_bus(struct vpoio_data *vpo)
646{
645}
646
647/*
648 * imm_reset_bus()
649 *
650 */
651int
652imm_reset_bus(struct vpoio_data *vpo)
653{
654 device_t ppbus = device_get_parent(vpo->vpo_dev);
647 int disconnected;
648
649 /* first, connect to the drive and request the bus */
650 imm_connect(vpo, PPB_WAIT|PPB_INTR, &disconnected, 1);
651
652 if (!disconnected) {
653
654 /* reset the SCSI bus */
655 int disconnected;
656
657 /* first, connect to the drive and request the bus */
658 imm_connect(vpo, PPB_WAIT|PPB_INTR, &disconnected, 1);
659
660 if (!disconnected) {
661
662 /* reset the SCSI bus */
655 ppb_MS_microseq(&vpo->vpo_dev, reset_microseq, NULL);
663 ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL);
656
657 /* then disconnect */
658 imm_disconnect(vpo, NULL, 1);
659 }
660
661 return (0);
662}
663
664/*
665 * imm_do_scsi()
666 *
667 * Send an SCSI command
668 *
669 */
670int
671imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
672 int clen, char *buffer, int blen, int *result, int *count,
673 int *ret)
674{
664
665 /* then disconnect */
666 imm_disconnect(vpo, NULL, 1);
667 }
668
669 return (0);
670}
671
672/*
673 * imm_do_scsi()
674 *
675 * Send an SCSI command
676 *
677 */
678int
679imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command,
680 int clen, char *buffer, int blen, int *result, int *count,
681 int *ret)
682{
675
683 device_t ppbus = device_get_parent(vpo->vpo_dev);
676 register char r;
677 char l, h = 0;
678 int len, error = 0, not_connected = 0;
679 register int k;
680 int negociated = 0;
681
682 /*
683 * enter disk state, allocate the ppbus

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

747
748 /* ZIP+ wants to send data? */
749 if (r == (char)0x88) {
750 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
751 VP0_SECTOR_SIZE : 2;
752
753 error = imm_outstr(vpo, &buffer[*count], len);
754 } else {
684 register char r;
685 char l, h = 0;
686 int len, error = 0, not_connected = 0;
687 register int k;
688 int negociated = 0;
689
690 /*
691 * enter disk state, allocate the ppbus

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

755
756 /* ZIP+ wants to send data? */
757 if (r == (char)0x88) {
758 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
759 VP0_SECTOR_SIZE : 2;
760
761 error = imm_outstr(vpo, &buffer[*count], len);
762 } else {
755 if (!PPB_IN_EPP_MODE(&vpo->vpo_dev))
763 if (!PPB_IN_EPP_MODE(ppbus))
756 len = 1;
757 else
758 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
759 VP0_SECTOR_SIZE : 1;
760
761 error = imm_instr(vpo, &buffer[*count], len);
762 }
763
764 if (error) {
765 *ret = error;
766 goto error;
767 }
768
769 *count += len;
770 }
771
764 len = 1;
765 else
766 len = (((blen - *count) >= VP0_SECTOR_SIZE)) ?
767 VP0_SECTOR_SIZE : 1;
768
769 error = imm_instr(vpo, &buffer[*count], len);
770 }
771
772 if (error) {
773 *ret = error;
774 goto error;
775 }
776
777 *count += len;
778 }
779
772 if ((PPB_IN_NIBBLE_MODE(&vpo->vpo_dev) ||
773 PPB_IN_PS2_MODE(&vpo->vpo_dev)) && negociated)
774 ppb_MS_microseq(&vpo->vpo_dev, transfer_epilog, NULL);
780 if ((PPB_IN_NIBBLE_MODE(ppbus) ||
781 PPB_IN_PS2_MODE(ppbus)) && negociated)
782 ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL);
775
776 /*
777 * Retrieve status ...
778 */
779 if (imm_negociate(vpo)) {
780 *ret = VP0_ENEGOCIATE;
781 goto error;
782 } else

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

790 if (imm_wait(vpo, VP0_FAST_SPINTMO) == (char)0xb8)
791 if (imm_instr(vpo, &h, 1)) {
792 *ret = VP0_EOTHER+2; goto error;
793 }
794
795 *result = ((int) h << 8) | ((int) l & 0xff);
796
797error:
783
784 /*
785 * Retrieve status ...
786 */
787 if (imm_negociate(vpo)) {
788 *ret = VP0_ENEGOCIATE;
789 goto error;
790 } else

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

798 if (imm_wait(vpo, VP0_FAST_SPINTMO) == (char)0xb8)
799 if (imm_instr(vpo, &h, 1)) {
800 *ret = VP0_EOTHER+2; goto error;
801 }
802
803 *result = ((int) h << 8) | ((int) l & 0xff);
804
805error:
798 if ((PPB_IN_NIBBLE_MODE(&vpo->vpo_dev) ||
799 PPB_IN_PS2_MODE(&vpo->vpo_dev)) && negociated)
800 ppb_MS_microseq(&vpo->vpo_dev, transfer_epilog, NULL);
806 if ((PPB_IN_NIBBLE_MODE(ppbus) ||
807 PPB_IN_PS2_MODE(ppbus)) && negociated)
808 ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL);
801
802 /* return to printer state, release the ppbus */
803 imm_disconnect(vpo, NULL, 1);
804
805 return (0);
806}
809
810 /* return to printer state, release the ppbus */
811 imm_disconnect(vpo, NULL, 1);
812
813 return (0);
814}