Exemple #1
0
static inline void kill_queue(struct isi_port *port, short queue)
{
	struct isi_board *card = port->card;
	unsigned long base = card->base;
	u16 channel = port->channel;

	if (!lock_card(card))
		return;

	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
	outw((queue << 8) | 0x06, base);
	InterruptTheCard(base);
	unlock_card(card);
}
Exemple #2
0
/* card->lock MUST NOT be held */
static inline void raise_dtr_rts(struct isi_port *port)
{
	struct isi_board *card = port->card;
	unsigned long base = card->base;
	u16 channel = port->channel;

	if (!lock_card(card))
		return;

	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
	outw(0x0f04, base);
	InterruptTheCard(base);
	port->status |= (ISI_DTR | ISI_RTS);
	unlock_card(card);
}
Exemple #3
0
static inline void drop_dtr(struct isi_port *port)
{
	struct isi_board *card = port->card;
	unsigned long base = card->base;
	u16 channel = port->channel;

	if (!lock_card(card))
		return;

	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
	outw(0x0404, base);
	InterruptTheCard(base);
	port->status &= ~ISI_DTR;
	unlock_card(card);
}
Exemple #4
0
static bool check_magic()
{
  bool     bFailure = false;
  int      uid_data;

  for (uint32_t page = 0; page <= 1; page++) {
    // Show if the readout went well
    if (bFailure) {
      // When a failure occured we need to redo the anti-collision
      if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
        ERR("tag was removed");
        return false;
      }
      bFailure = false;
    }

    uid_data = 0x00000000;

    memcpy(mp.mpd.abtData, &uid_data, sizeof uid_data);
    memset(mp.mpd.abtData + 4, 0, 12);

    //Force the write without checking for errors - otherwise the writes to the sector 0 seem to complain
    nfc_initiator_mifare_cmd(pnd, MC_WRITE, page, &mp);
  }

  //Check that the ID is now set to 0x000000000000
  if (nfc_initiator_mifare_cmd(pnd, MC_READ, 0, &mp)) {
    //printf("%u", mp.mpd.abtData);
    bool result = true;
    for (int i = 0; i <= 7; i++) {
      if (mp.mpd.abtData[i] != 0x00) result = false;
    }

    if (result) {
      return true;
    }

  }

  //Initially check if we can unlock via the MF method
  if (unlock_card()) {
    return true;
  } else {
    return false;
  }

}
static void isicom_dtr_rts(struct tty_port *port, int on)
{
	struct isi_port *ip = container_of(port, struct isi_port, port);
	struct isi_board *card = ip->card;
	unsigned long base = card->base;
	u16 channel = ip->channel;

	if (!lock_card(card))
		return;

	if (on) {
		outw(0x8000 | (channel << card->shift_count) | 0x02, base);
		outw(0x0f04, base);
		InterruptTheCard(base);
		ip->status |= (ISI_DTR | ISI_RTS);
	} else {
		outw(0x8000 | (channel << card->shift_count) | 0x02, base);
		outw(0x0C04, base);
		InterruptTheCard(base);
		ip->status &= ~(ISI_DTR | ISI_RTS);
	}
	unlock_card(card);
}
Exemple #6
0
static void isicom_tx(unsigned long _data)
{
	short count = (BOARD_COUNT-1), card, base;
	short txcount, wrd, residue, word_count, cnt;
	struct isi_port *port;
	struct tty_struct *tty;

	/*	find next active board	*/
	card = (prev_card + 1) & 0x0003;
	while(count-- > 0) {
		if (isi_card[card].status & BOARD_ACTIVE)
			break;
		card = (card + 1) & 0x0003;
	}
	if (!(isi_card[card].status & BOARD_ACTIVE))
		goto sched_again;

	prev_card = card;

	count = isi_card[card].port_count;
	port = isi_card[card].ports;
	base = isi_card[card].base;
	for (;count > 0;count--, port++) {
		if (!lock_card_at_interrupt(&isi_card[card]))
			continue;
		/* port not active or tx disabled to force flow control */
		if (!(port->flags & ASYNC_INITIALIZED) ||
				!(port->status & ISI_TXOK))
			unlock_card(&isi_card[card]);
			continue;

		tty = port->tty;


		if (tty == NULL) {
			unlock_card(&isi_card[card]);
			continue;
		}

		txcount = min_t(short, TX_SIZE, port->xmit_cnt);
		if (txcount <= 0 || tty->stopped || tty->hw_stopped) {
			unlock_card(&isi_card[card]);
			continue;
		}
		if (!(inw(base + 0x02) & (1 << port->channel))) {
			unlock_card(&isi_card[card]);
			continue;
		}
		pr_dbg("txing %d bytes, port%d.\n", txcount,
			port->channel + 1);
		outw((port->channel << isi_card[card].shift_count) | txcount,
			base);
		residue = NO;
		wrd = 0;
		while (1) {
			cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
					- port->xmit_tail));
			if (residue == YES) {
				residue = NO;
				if (cnt > 0) {
					wrd |= (port->xmit_buf[port->xmit_tail]
									<< 8);
					port->xmit_tail = (port->xmit_tail + 1)
						& (SERIAL_XMIT_SIZE - 1);
					port->xmit_cnt--;
					txcount--;
					cnt--;
					outw(wrd, base);
				} else {
					outw(wrd, base);
					break;
				}
			}
			if (cnt <= 0) break;
			word_count = cnt >> 1;
			outsw(base, port->xmit_buf+port->xmit_tail,word_count);
			port->xmit_tail = (port->xmit_tail
				+ (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
			txcount -= (word_count << 1);
			port->xmit_cnt -= (word_count << 1);
			if (cnt & 0x0001) {
				residue = YES;
				wrd = port->xmit_buf[port->xmit_tail];
				port->xmit_tail = (port->xmit_tail + 1)
					& (SERIAL_XMIT_SIZE - 1);
				port->xmit_cnt--;
				txcount--;
			}
		}

		InterruptTheCard(base);
		if (port->xmit_cnt <= 0)
			port->status &= ~ISI_TXOK;
		if (port->xmit_cnt <= WAKEUP_CHARS)
			schedule_work(&port->bh_tqueue);
		unlock_card(&isi_card[card]);
	}

	/*	schedule another tx for hopefully in about 10ms	*/
sched_again:
	if (!re_schedule) {
		re_schedule = 2;
 		return;
	}

	init_timer(&tx);
	tx.expires = jiffies + HZ/100;
	tx.data = 0;
	tx.function = isicom_tx;
	add_timer(&tx);

	return;
}
bool write_card(int write_block_zero)
{
    uint32_t uiBlock;
    bool    bFailure = false;
    uint32_t uiWriteBlocks = 0;
    if (write_block_zero)
    {
        if (!unlock_card())
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Writing %d blocks |", uiBlocks + 1);
    #endif
    //! Write the card from begin to end;
    for (uiBlock = 0; uiBlock <= uiBlocks; uiBlock++)
    {
        //! Authenticate everytime we reach the first sector of a new block
        if (is_first_block(uiBlock))
        {
            if (bFailure)
            {
                //! When a failure occured we need to redo the anti-collision
                if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: tag was removed\n");
                    #endif
                    sprintf(message_erreur,"Error: tag was removed !");
                    return false;
                }
                bFailure = false;
            }
            fflush(stdout);
            //! Try to authenticate for the current sector
            if (!write_block_zero && !authenticate(uiBlock))
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nError: authentication failed for block %02x\n", uiBlock);
                #endif
                sprintf(message_erreur,"Error: authentication failed for block %02x !", uiBlock);
                return false;
            }
        }
        if (is_trailer_block(uiBlock))
        {
            //! Copy the keys over from our key dump and store the retrieved access bits
            memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6);
            memcpy(mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4);
            memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6);
            //! Try to write the trailer
            if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false)
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"failed to write trailer block %d \n", uiBlock);
                #endif
                bFailure = true;
            }
        }
        else
        {
            //! The first block 0x00 is read only, skip this
            if (uiBlock == 0 && ! write_block_zero && ! magic2)
                continue;
    
            //! Make sure a earlier write did not fail
            if (!bFailure)
            {
                //! Try to write the data block
                memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16);
                //! do not write a block 0 with incorrect BCC - card will be made invalid!
                if (uiBlock == 0)
                {
                    if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2)
                    {
                        #ifdef DEBUG_PRINTF
                        fprintf(stderr,"!\nError: incorrect BCC in MFD file!\n");
                        fprintf(stderr,"Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]);
                        #endif
                        sprintf(message_erreur,"Error: incorrect BCC in MFD file! ");
                        return false;
                    }
                }
                if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp))
                {
                    bFailure = true;
                }
            }
        }
        //! Show if the write went well for each block
        print_success_or_failure(bFailure, &uiWriteBlocks);
        if ((! bTolerateFailures) && bFailure)
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1);
    #endif
    fflush(stdout);
    return true;
}
bool read_card(int read_unlocked)
{
    int32_t iBlock;
    bool    bFailure = false;
    uint32_t uiReadBlocks = 0;
    if (read_unlocked)
    {
        if (!unlock_card())
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Reading out %d blocks |\n", uiBlocks + 1);
    #endif
    //! Read the card from end to begin
    for (iBlock = uiBlocks; iBlock >= 0; iBlock--)
    {
        //! Authenticate everytime we reach a trailer block
        if (is_trailer_block(iBlock))
        {
            if (bFailure)
            {
                //! When a failure occured we need to redo the anti-collision
                if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: tag was removed\n");
                    #endif
                    sprintf(message_erreur,"Error: tag was removed !");
                    return false;
                }
                bFailure = false;
            }
            fflush(stdout);
            //! Try to authenticate for the current sector
            if (!read_unlocked && !authenticate(iBlock))
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nError: authentication failed for block 0x%02x\n", iBlock);
                #endif
                sprintf(message_erreur,"Error: authentication failed for block 0x%02x !", iBlock);
                return false;
            }
            //! Try to read out the trailer
            if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp))
            {
                if (read_unlocked)
                {
                    memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
                }
                else
                {
                    //! Copy the keys over from our key dump and store the retrieved access bits
                    memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, 6);
                    memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4);
                    memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6);
                }
            }
            else
            {
                #ifdef DEBUG_PRINTF
                fprintf(stderr,"!\nfailed to read trailer block 0x%02x\n", iBlock);
                #endif
                bFailure = true;
            }
        }
        else
        {
            //! Make sure a earlier readout did not fail
            if (!bFailure)
            {
                //! Try to read out the data block
                if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp))
                {
                    memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16);
                }
                else
                {
                    #ifdef DEBUG_PRINTF
                    fprintf(stderr,"!\nError: unable to read block 0x%02x\n", iBlock);
                    #endif
                    bFailure = true;
                }
            }
        }
        //! Show if the readout went well for each block
        print_success_or_failure(bFailure, &uiReadBlocks);
        if ((! bTolerateFailures) && bFailure)
        {
            return false;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"|\n");
    fprintf(stderr,"Done : %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1);
    #endif
    fflush(stdout);
    return true;
}