예제 #1
0
파일: amd7930.c 프로젝트: nhanh0/hah
static void
Bchan_rcv_bh(struct BCState *bcs)
{
	struct IsdnCardState *cs = bcs->cs;
	struct amd7930_hw *hw = &bcs->hw.amd7930;
	struct sk_buff *skb;
	int len;

	if (cs->debug & L1_DEB_HSCX) {
		char tmp[1024];

		sprintf(tmp, "amd7930_Bchan_rcv (%d/%d)",
			hw->rv_buff_in, hw->rv_buff_out);
		debugl1(cs, tmp);
		QuickHex(tmp, hw->rv_buff + hw->rv_buff_out,
			 RCV_BUFSIZE/RCV_BUFBLKS);
		debugl1(cs, tmp);
	}

	do {
		if (bcs->mode == L1_MODE_HDLC) {
			while ((len = read_raw_hdlc_data(hw->hdlc_state,
							 hw->rv_buff + hw->rv_buff_out, RCV_BUFSIZE/RCV_BUFBLKS,
							 hw->rv_skb->tail, HSCX_BUFMAX))) {
				if (len > 0 && (cs->debug & L1_DEB_HSCX_FIFO)) {
					char tmp[1024];
					char *t = tmp;

					t += sprintf(t, "amd7930_Bchan_rcv %c cnt %d", bcs->channel ? 'B' : 'A', len);
					QuickHex(t, hw->rv_skb->tail, len);
					debugl1(cs, tmp);
				}

				if (len > HSCX_BUFMAX/2) {
					/* Large packet received */

					if (!(skb = dev_alloc_skb(HSCX_BUFMAX))) {
						printk(KERN_WARNING "amd7930: receive out of memory");
					} else {
						skb_put(hw->rv_skb, len);
						skb_queue_tail(&bcs->rqueue, hw->rv_skb);
						hw->rv_skb = skb;
						bcs->event |= 1 << B_RCVBUFREADY;
						queue_task(&bcs->tqueue, &tq_immediate);
					}
				} else if (len > 0) {
					/* Small packet received */

					if (!(skb = dev_alloc_skb(len))) {
						printk(KERN_WARNING "amd7930: receive out of memory\n");
					} else {
						memcpy(skb_put(skb, len), hw->rv_skb->tail, len);
						skb_queue_tail(&bcs->rqueue, skb);
						bcs->event |= 1 << B_RCVBUFREADY;
						queue_task(&bcs->tqueue, &tq_immediate);
						mark_bh(IMMEDIATE_BH);
					}
				} else {
					/* Reception Error */
					/* printk("amd7930: B channel receive error\n"); */
				}
			}
		} else if (bcs->mode == L1_MODE_TRANS) {
			if (!(skb = dev_alloc_skb(RCV_BUFSIZE/RCV_BUFBLKS))) {
				printk(KERN_WARNING "amd7930: receive out of memory\n");
			} else {
				memcpy(skb_put(skb, RCV_BUFSIZE/RCV_BUFBLKS),
				       hw->rv_buff + hw->rv_buff_out,
				       RCV_BUFSIZE/RCV_BUFBLKS);
				skb_queue_tail(&bcs->rqueue, skb);
				bcs->event |= 1 << B_RCVBUFREADY;
				queue_task(&bcs->tqueue, &tq_immediate);
				mark_bh(IMMEDIATE_BH);
			}
		}

		if (hw->rv_buff_in == hw->rv_buff_out) {
			/* Buffer was filled up - need to restart receiver */
			amd7930_brecv(0, bcs->channel,
				      hw->rv_buff + hw->rv_buff_in,
				      RCV_BUFSIZE/RCV_BUFBLKS,
				      (void *) &Bchan_recv_callback,
				      (void *) bcs);
		}

		hw->rv_buff_out += RCV_BUFSIZE/RCV_BUFBLKS;
		hw->rv_buff_out %= RCV_BUFSIZE;

	} while (hw->rv_buff_in != hw->rv_buff_out);
}
예제 #2
0
파일: elsa.c 프로젝트: 274914765/C
static int
check_arcofi(struct IsdnCardState *cs)
{
    int arcofi_present = 0;
    char tmp[40];
    char *t;
    u_char *p;

    if (!cs->dc.isac.mon_tx)
        if (!(cs->dc.isac.mon_tx=kmalloc(MAX_MON_FRAME, GFP_ATOMIC))) {
            if (cs->debug & L1_DEB_WARN)
                debugl1(cs, "ISAC MON TX out of buffers!");
            return(0);
        }
    cs->dc.isac.arcofi_bc = 0;
    arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION);
    interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
    if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) {
            debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
            p = cs->dc.isac.mon_rx;
            t = tmp;
            t += sprintf(tmp, "Arcofi data");
            QuickHex(t, p, cs->dc.isac.mon_rxp);
            debugl1(cs, tmp);
            if ((cs->dc.isac.mon_rxp == 2) && (cs->dc.isac.mon_rx[0] == 0xa0)) {
                switch(cs->dc.isac.mon_rx[1]) {
                    case 0x80:
                        debugl1(cs, "Arcofi 2160 detected");
                        arcofi_present = 1;
                        break;
                    case 0x82:
                        debugl1(cs, "Arcofi 2165 detected");
                        arcofi_present = 2;
                        break;
                    case 0x84:
                        debugl1(cs, "Arcofi 2163 detected");
                        arcofi_present = 3;
                        break;
                    default:
                        debugl1(cs, "unknown Arcofi response");
                        break;
                }
            } else
                debugl1(cs, "undefined Monitor response");
            cs->dc.isac.mon_rxp = 0;
    } else if (cs->dc.isac.mon_tx) {
        debugl1(cs, "Arcofi not detected");
    }
    if (arcofi_present) {
        if (cs->subtyp==ELSA_QS1000) {
            cs->subtyp = ELSA_QS3000;
            printk(KERN_INFO
                "Elsa: %s detected modem at 0x%lx\n",
                Elsa_Types[cs->subtyp],
                cs->hw.elsa.base+8);
            release_region(cs->hw.elsa.base, 8);
            if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
                printk(KERN_WARNING
                    "HiSax: %s config port %lx-%lx already in use\n",
                    Elsa_Types[cs->subtyp],
                    cs->hw.elsa.base + 8,
                    cs->hw.elsa.base + 16);
            }
        } else if (cs->subtyp==ELSA_PCC16) {
            cs->subtyp = ELSA_PCF;
            printk(KERN_INFO
                "Elsa: %s detected modem at 0x%lx\n",
                Elsa_Types[cs->subtyp],
                cs->hw.elsa.base+8);
            release_region(cs->hw.elsa.base, 8);
            if (!request_region(cs->hw.elsa.base, 16, "elsa isdn modem")) {
                printk(KERN_WARNING
                    "HiSax: %s config port %lx-%lx already in use\n",
                    Elsa_Types[cs->subtyp],
                    cs->hw.elsa.base + 8,
                    cs->hw.elsa.base + 16);
            }
        } else
            printk(KERN_INFO
                "Elsa: %s detected modem at 0x%lx\n",
                Elsa_Types[cs->subtyp],
                cs->hw.elsa.base+8);
        arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0);
        interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
        return(1);
    }
    return(0);
}