コード例 #1
0
ファイル: hermes.c プロジェクト: CesarBallardini/minix3
/*****************************************************************************
 *            hermes_cor_reset                                               *
 *                                                                           *
 * This is the first step in initializing the card's firmware and hardware:  *
 * write HERMES_PCI_COR_MASK to the Configuration Option Register            *
 *****************************************************************************/
int hermes_cor_reset (hermes_t *hw) {
	int k;
	u16_t reg;

	/* Assert the reset until the card notice */
	hermes_write_reg (hw, HERMES_PCI_COR, HERMES_PCI_COR_MASK);

	milli_delay (HERMES_PCI_COR_ONT);

	/* Give time for the card to recover from this hard effort */
	hermes_write_reg (hw, HERMES_PCI_COR, 0x0000);

	milli_delay (HERMES_PCI_COR_OFFT);

	/* The card is ready when it's no longer busy */
	k = HERMES_PCI_COR_BUSYT;
	reg = hermes_read_reg (hw, HERMES_CMD);
	while (k && (reg & HERMES_CMD_BUSY)) {
		k--;
		milli_delay (1);
		reg = hermes_read_reg (hw, HERMES_CMD);
	}

	/* Did we timeout ? */
	if (reg & HERMES_CMD_BUSY) {
		printf ("Busy timeout after resetting the COR\n");
		return -1;
	}

	return (0);
}
コード例 #2
0
ファイル: hermes.c プロジェクト: 0xffea/gnumach
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
		     u16 length, const void *value)
{
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	int err = 0;
	unsigned count;

	if (length == 0)
		return -EINVAL;

	err = hermes_bap_seek(hw, bap, rid, 0);
	if (err)
		return err;

	hermes_write_reg(hw, dreg, length);
	hermes_write_reg(hw, dreg, rid);

	count = length - 1;

	hermes_write_words(hw, dreg, value, count);

	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 
				rid, NULL);

	return err;
}
コード例 #3
0
ファイル: hermes.c プロジェクト: hugh712/Jollen
int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 
		     u16 length, const void *value)
{
	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
	int err = 0;
	hermes_response_t resp;
	int count;
	
	DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
	      bap, rid, length, * ((u16 *)value));

	err = hermes_bap_seek(hw, bap, rid, 0);
	if (err)
		goto out;

	hermes_write_reg(hw, dreg, length);
	hermes_write_reg(hw, dreg, rid);

	count = length - 1;

	hermes_write_words(hw, dreg, value, count);

	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 
				rid, &resp);

 out:
	return err;
}
コード例 #4
0
ファイル: hermes.c プロジェクト: 0xffea/gnumach
/* Set up a BAP to read a particular chunk of data from card's internal buffer.
 *
 * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
 * from firmware
 *
 * Callable from any context */
static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
{
	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
	int k;
	u16 reg;

	/* Paranoia.. */
	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
		return -EINVAL;

	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ((reg & HERMES_OFFSET_BUSY) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

#ifdef HERMES_DEBUG_BUFFER
	hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;

	if (k < HERMES_BAP_BUSY_TIMEOUT) {
		struct hermes_debug_entry *e = 
			&hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
		e->bap = bap;
		e->id = id;
		e->offset = offset;
		e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
	}
#endif

	if (reg & HERMES_OFFSET_BUSY)
		return -ETIMEDOUT;

	/* Now we actually set up the transfer */
	hermes_write_reg(hw, sreg, id);
	hermes_write_reg(hw, oreg, offset);

	/* Wait for the BAP to be ready */
	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg & HERMES_OFFSET_BUSY) {
		return -ETIMEDOUT;
	}

	if (reg & HERMES_OFFSET_ERR) {
		return -EIO;
	}


	return 0;
}
コード例 #5
0
ファイル: hermes.c プロジェクト: johnny/CobraDroidBeta
/* Set up a BAP to read a particular chunk of data from card's internal buffer.
 *
 * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
 * from firmware
 *
 * Callable from any context */
static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
{
	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
	int k;
	u16 reg;

	/* Paranoia.. */
	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
		return -EINVAL;

	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ((reg & HERMES_OFFSET_BUSY) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg & HERMES_OFFSET_BUSY)
		return -ETIMEDOUT;

	/* Now we actually set up the transfer */
	hermes_write_reg(hw, sreg, id);
	hermes_write_reg(hw, oreg, offset);

	/* Wait for the BAP to be ready */
	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg != offset) {
		printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
		       "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
		       (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
		       reg, id, offset);

		if (reg & HERMES_OFFSET_BUSY) {
			return -ETIMEDOUT;
		}

		return -EIO;		/* error or wrong offset */
	}

	return 0;
}
コード例 #6
0
static int hermes_bap_seek(struct hermes *hw, int bap, u16 id, u16 offset)
{
	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
	int k;
	u16 reg;

	
	if ((offset > HERMES_BAP_OFFSET_MAX) || (offset % 2))
		return -EINVAL;

	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ((reg & HERMES_OFFSET_BUSY) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg & HERMES_OFFSET_BUSY)
		return -ETIMEDOUT;

	
	hermes_write_reg(hw, sreg, id);
	hermes_write_reg(hw, oreg, offset);

	
	k = HERMES_BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ((reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg != offset) {
		printk(KERN_ERR "hermes @ %p: BAP%d offset %s: "
		       "reg=0x%x id=0x%x offset=0x%x\n", hw->iobase, bap,
		       (reg & HERMES_OFFSET_BUSY) ? "timeout" : "error",
		       reg, id, offset);

		if (reg & HERMES_OFFSET_BUSY)
			return -ETIMEDOUT;

		return -EIO;		
	}

	return 0;
}
コード例 #7
0
ファイル: hermes.c プロジェクト: hugh712/Jollen
/* Set up a BAP to read a particular chunk of data from card's internal buffer.
 *
 * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
 * from firmware
 *
 * Callable from any context */
int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
{
	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
	int k;
	u16 reg;

	/* Paranoia.. */
	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
		return -EINVAL;

	k = BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ((reg & HERMES_OFFSET_BUSY) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg & HERMES_OFFSET_BUSY)
		return -ETIMEDOUT;

	/* Now we actually set up the transfer */
	hermes_write_reg(hw, sreg, id);
	hermes_write_reg(hw, oreg, offset);

	/* Wait for the BAP to be ready */
	k = BAP_BUSY_TIMEOUT;
	reg = hermes_read_reg(hw, oreg);
	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
		k--;
		udelay(1);
		reg = hermes_read_reg(hw, oreg);
	}

	if (reg & HERMES_OFFSET_BUSY) {
		DEBUG(1,"hermes_bap_seek: timeout\n");
		return -ETIMEDOUT;
	}

	if (reg & HERMES_OFFSET_ERR) {
		DEBUG(1,"hermes_bap_seek: BAP error\n");
		return -EIO;
	}


	return 0;
}
コード例 #8
0
ファイル: hermes.c プロジェクト: CesarBallardini/minix3
/*****************************************************************************
 *            hermes_issue_cmd                                               *
 *                                                                           *
 * Issue a command to the chip. Waiting for it to complete is the caller's   *
 * problem. The only thing we have to do first is to see whether we can      *
 * actually write something in the CMD register: is it unbusy?               *
 * Returns -EBUSY if the command register is busy, 0 on success.             *
 *****************************************************************************/
static int hermes_issue_cmd (hermes_t * hw, u16_t cmd, u16_t param0) {
	int k = HERMES_CMD_BUSY_TIMEOUT;
	u16_t reg;

	/* First wait for the command register to unbusy */
	reg = hermes_read_reg (hw, HERMES_CMD);
	while ((reg & HERMES_CMD_BUSY) && k) {
		k--;
		micro_delay (1);
		reg = hermes_read_reg (hw, HERMES_CMD);
	}
	/* it takes too long. Bailing out */
	if (reg & HERMES_CMD_BUSY) {
		printf("Hermes: HERMES_CMD_BUSY timeout\n");
		return -EBUSY;
	}

	/* write the values to the right registers */
	hermes_write_reg (hw, HERMES_PARAM2, 0);
	hermes_write_reg (hw, HERMES_PARAM1, 0);
	hermes_write_reg (hw, HERMES_PARAM0, param0);
	hermes_write_reg (hw, HERMES_CMD, cmd);
	return 0;
}
コード例 #9
0
ファイル: hermes.c プロジェクト: CesarBallardini/minix3
/*****************************************************************************
 *            hermes_init                                                    *
 *                                                                           *
 * Initialize the card                                                       *
 *****************************************************************************/
int hermes_init (hermes_t * hw)
{
	u32_t status, reg, resp0;
	int err = 0;
	int k;

	/* We don't want to be interrupted while resetting the chipset. By 
	 * setting the control mask for hardware interrupt generation to 0,
	 * we won't be disturbed*/
	hw->inten = 0x0;
	hermes_write_reg (hw, HERMES_INTEN, 0);

	/* Acknowledge any pending events waiting for acknowledgement. We 
	 * assume there won't be any important to take care off */
	hermes_write_reg (hw, HERMES_EVACK, 0xffff);

	/* Normally it's a "can't happen" for the command register to
	 * be busy when we go to issue a command because we are
	 * serializing all commands.  However we want to have some
	 * chance of resetting the card even if it gets into a stupid
	 * state, so we actually wait to see if the command register
	 * will unbusy itself here. */
	k = HERMES_CMD_BUSY_TIMEOUT;
	reg = hermes_read_reg (hw, HERMES_CMD);
	while (k && (reg & HERMES_CMD_BUSY)) {
		if (reg == 0xffff) {
			/* Special case - the card has probably 
			 *  been removed, so don't wait for the 
			 *  timeout */
			printf("Hermes: Card removed?\n");
			return -ENODEV;
		}

		k--;
		micro_delay (1);
		reg = hermes_read_reg (hw, HERMES_CMD);
	}

	/* No need to explicitly handle the timeout - if we've timed
	 * out hermes_issue_cmd() will probably return -EBUSY below.
	 * But i check to be sure :-) */
	if (reg & HERMES_CMD_BUSY) {
		printf("Hermes: Timeout waiting for the CMD_BUSY to unset\n");
		return -EBUSY;
	}

	/* According to the documentation, EVSTAT may contain
	 * obsolete event occurrence information.  We have to acknowledge
	 * it by writing EVACK. */
	reg = hermes_read_reg (hw, HERMES_EVSTAT);
	hermes_write_reg (hw, HERMES_EVACK, reg);

	err = hermes_issue_cmd (hw, HERMES_CMD_INIT, 0);
	if (err){
		printf("Hermes: errornr: 0x%x issueing HERMES_CMD_INIT\n",
			 err);
		return err;
	}

	/* here we start waiting for the above command,CMD_INIT, to complete.
	 * Completion is noticeable when the HERMES_EV_CMD bit in the 
	 * HERMES_EVSTAT register is set to 1 */
	reg = hermes_read_reg (hw, HERMES_EVSTAT);
	k = HERMES_CMD_INIT_TIMEOUT;
	while ((!(reg & HERMES_EV_CMD)) && k) {
		k--;
		micro_delay (10);
		reg = hermes_read_reg (hw, HERMES_EVSTAT);
	}


	/* the software support register 0 (there are 3) is filled with a 
	 * magic number. With this one can test the availability of the card */
	hermes_write_reg (hw, HERMES_SWSUPPORT0, HERMES_MAGIC);

	if (!hermes_present (hw)) {
		printf("Hermes: Card not present?: got mag. nr.0x%x\n",
			 hermes_read_reg (hw, HERMES_SWSUPPORT0));
	}

	if (!(reg & HERMES_EV_CMD)) {
		printf("hermes @ %x: Timeout waiting for card to reset\n",
			hw->iobase);
		return -ETIMEDOUT;
	}

	status = hermes_read_reg (hw, HERMES_STATUS);
	resp0 = hermes_read_reg (hw, HERMES_RESP0);

	/* after having issued the command above, the completion set a bit in 
	 * the EVSTAT register. This has to be acknowledged, as follows */
	hermes_write_reg (hw, HERMES_EVACK, HERMES_EV_CMD);

	/* Was the status, the result of the issued command, ok? */
	/* The expression below should be zero. Non-zero means an error */
	if (status & HERMES_STATUS_RESULT) {
		printf("Hermes:Result of INIT_CMD wrong.error value: 0x%x\n",
			(status & HERMES_STATUS_RESULT) >> 8);
		err = -EIO;
	}