/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION 1986,1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */

/* $Header:adunload.c 12.0$ */
/* $ACIS:adunload.c 12.0$ */
/* $Source: /ibm/acis/usr/sys/ca_atr/RCS/adunload.c,v $ */

#if !defined(lint) && !defined(NO_RCS_HDRS)
static char *rcsid = "$Header:adunload.c 12.0$";
#endif

#include "../machine/io.h"
 
int hdprobe(), hdslave(), hdattach(), hdint();

#ifdef ATR
#include "../h/types.h"
#include "../ca_atr/pcif.h"

typedef u_short hd_data_t;  

#define DO_NOTHING_ADDR ((hd_data_t *) -1)  /* insure this is a bad virtual address */
#endif ATR

#ifdef IBMRTPC
typedef int hd_data_t;

#define DO_NOTHING_ADDR ((hd_data_t *) 0)   /* insure this is a bad real address */
#endif IBMRTPC

#ifdef DEBUG
#define HDDEBUG(how,stmt) if (hddebug & (how)) stmt	/* print it etc. */

#define	SHOW_ENQ	0x01
#define SHOW_DEQ	0x02
#define SHOW_INTR	0x04
#define SHOW_INIT	0x08
#define SHOW_XFER	0x10
#define SHOW_WAIT	0x20		  /* show wait */
#define SHOW_REGS	0x40
#define SHOW_ORDWR	0x80
#define SHOW_LED	0x100		  /* show unit in LEDs */
#define SHOW_COUNT	0x200		  /* show the current count information */
#define SHOW_SWITCH	0x400		  /* show switching of controllers */
#define SHOW_BAD	0x800		  /* show bad block forwarding */
#define SHOW_GO		0x1000		  /* show each command data */
#define SHOW_CONFIG	0x2000		  /* show configuration */
#define SHOW_DUMP	0x4000		  /* show dumping */
#define SHOW_DUMPIO	0x8000		  /* show dump I/O */
#define SHOW_RETRY	0x10000		  /* show retries */

extern int hddebug;/* on hd.c */	  /* XXX -- change to 0 when done debugging */

#else !DEBUG
#define HDDEBUG(how,stmt) 	/* do nothing */

#endif

#define HDXFERSIZE (sizeof (hd_data_t))

#define COUNT	12
 /*
  * this block read routine is used to copy data out of the adapter
  * for cases when 'buffaddr' is on a page boundary.
  * since it is on a page boundary it is also on a 32bit and a 16 bit
  * boundary.
  * flag = 0	for write
  * flag != 0 	for read
  */
adunload(buffaddr, adreg, hdcnt, flag)
	register hd_data_t * buffaddr;
	register int hdcnt;
	register hd_data_t * adreg;
	register int flag;
{

	register int ioaddr;  /* XXX GRL */
	register int r1;

  	HDDEBUG(SHOW_COUNT,printf("ADUNLOAD: addr=%x count=%d \n",buffaddr,hdcnt));

/* This is a hack just to find out if the new macros work ... GRL */
/* Insted of trying to unwind the code to figure out who passes us */
/* this address, I am forcint the value to be the data port for the */
/* primary disk controller at 0x1f0.				    */

	ioaddr = 0x1f0 + pcif_io_hw;




	if (flag) {
                  if (buffaddr == DO_NOTHING_ADDR) {
			register int i;
			while ((hdcnt -= HDXFERSIZE) >= 0)
				i = IOINW(ioaddr);
			return;
		}
		for (; (hdcnt -= HDXFERSIZE * COUNT) >= 0;) {
			buffaddr[0] = IOINW(ioaddr);
			buffaddr[1] = IOINW(ioaddr);
			buffaddr[2] = IOINW(ioaddr);
			buffaddr[3] = IOINW(ioaddr);
			buffaddr[4] = IOINW(ioaddr);
			buffaddr[5] = IOINW(ioaddr);
			buffaddr[6] = IOINW(ioaddr);
			buffaddr[7] = IOINW(ioaddr);
			buffaddr[8] = IOINW(ioaddr);
			buffaddr[9] = IOINW(ioaddr);
			buffaddr[10] = IOINW(ioaddr);
			buffaddr[11] = IOINW(ioaddr);
			buffaddr += COUNT;
		}
		hdcnt += HDXFERSIZE * COUNT; /* correct overshoot */
		for (; hdcnt > 0; hdcnt -= HDXFERSIZE)
			*buffaddr++ = IOINW(ioaddr);
	} else {
               if (buffaddr == DO_NOTHING_ADDR){ 
			register int i;
			while ((hdcnt -= HDXFERSIZE) >= 0)
				IOOUTW(ioaddr, 0);
			return;
		}
		for (; (hdcnt -= HDXFERSIZE * COUNT) >= 0;) {
			IOOUTW(ioaddr, buffaddr[0]);
			IOOUTW(ioaddr, buffaddr[1]);
			IOOUTW(ioaddr, buffaddr[2]);
			IOOUTW(ioaddr, buffaddr[3]);
			IOOUTW(ioaddr, buffaddr[4]);
			IOOUTW(ioaddr, buffaddr[5]);
			IOOUTW(ioaddr, buffaddr[6]);
			IOOUTW(ioaddr, buffaddr[7]);
			IOOUTW(ioaddr, buffaddr[8]);
			IOOUTW(ioaddr, buffaddr[9]);
			IOOUTW(ioaddr, buffaddr[10]);
			IOOUTW(ioaddr, buffaddr[11]);
			buffaddr += COUNT;
		}
		hdcnt += HDXFERSIZE * COUNT; /* correct overshoot */
		for (; hdcnt > 0; hdcnt -= HDXFERSIZE)
			IOOUTW(ioaddr, *buffaddr++);
	}
}
