⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee1394_core.c

📁 这个是uClinux下的ieee1394驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (isroot) {		host->driver->devctl(host, ACT_CYCLE_MASTER, 1);		host->is_cycmst = 1;	}	atomic_inc(&host->generation);	host->in_bus_reset = 0;        highlevel_host_reset(host);}void hpsb_packet_sent(struct hpsb_host *host, struct hpsb_packet *packet,                       int ackcode){        unsigned long flags;        packet->ack_code = ackcode;        if (packet->no_waiter) {                /* must not have a tlabel allocated */                free_hpsb_packet(packet);                return;        }        if (ackcode != ACK_PENDING || !packet->expect_response) {                packet->state = hpsb_complete;                up(&packet->state_change);                up(&packet->state_change);                process_complete_tasks(packet);                return;        }        packet->state = hpsb_pending;        packet->sendtime = jiffies;        spin_lock_irqsave(&host->pending_pkt_lock, flags);        list_add_tail(&packet->list, &host->pending_packets);        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);        up(&packet->state_change);        schedule_task(&host->timeout_tq);}/** * hpsb_send_packet - transmit a packet on the bus * @packet: packet to send * * The packet is sent through the host specified in the packet->host field. * Before sending, the packet's transmit speed is automatically determined using * the local speed map when it is an async, non-broadcast packet. * * Possibilities for failure are that host is either not initialized, in bus * reset, the packet's generation number doesn't match the current generation * number or the host reports a transmit error. * * Return value: False (0) on failure, true (1) otherwise. */int hpsb_send_packet(struct hpsb_packet *packet){        struct hpsb_host *host = packet->host;        if (host->is_shutdown || host->in_bus_reset            || (packet->generation != get_hpsb_generation(host))) {                return 0;        }        packet->state = hpsb_queued;        if (packet->type == hpsb_async && packet->node_id != ALL_NODES) {                packet->speed_code =                        host->speed_map[(host->node_id & NODE_MASK) * 64                                       + (packet->node_id & NODE_MASK)];        }#ifdef CONFIG_IEEE1394_VERBOSEDEBUG        switch (packet->speed_code) {        case 2:                dump_packet("send packet 400:", packet->header,                            packet->header_size);                break;        case 1:                dump_packet("send packet 200:", packet->header,                            packet->header_size);                break;        default:                dump_packet("send packet 100:", packet->header,                            packet->header_size);        }#endif        return host->driver->transmit_packet(host, packet);}static void send_packet_nocare(struct hpsb_packet *packet){        if (!hpsb_send_packet(packet)) {                free_hpsb_packet(packet);        }}void handle_packet_response(struct hpsb_host *host, int tcode, quadlet_t *data,                            size_t size){        struct hpsb_packet *packet = NULL;        struct list_head *lh;        int tcode_match = 0;        int tlabel;        unsigned long flags;        tlabel = (data[0] >> 10) & 0x3f;        spin_lock_irqsave(&host->pending_pkt_lock, flags);        list_for_each(lh, &host->pending_packets) {                packet = list_entry(lh, struct hpsb_packet, list);                if ((packet->tlabel == tlabel)                    && (packet->node_id == (data[1] >> 16))){                        break;                }        }        if (lh == &host->pending_packets) {                HPSB_DEBUG("unsolicited response packet received - np");                dump_packet("contents:", data, 16);                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);                return;        }        switch (packet->tcode) {        case TCODE_WRITEQ:        case TCODE_WRITEB:                if (tcode == TCODE_WRITE_RESPONSE) tcode_match = 1;                break;        case TCODE_READQ:                if (tcode == TCODE_READQ_RESPONSE) tcode_match = 1;                break;        case TCODE_READB:                if (tcode == TCODE_READB_RESPONSE) tcode_match = 1;                break;        case TCODE_LOCK_REQUEST:                if (tcode == TCODE_LOCK_RESPONSE) tcode_match = 1;                break;        }        if (!tcode_match || (packet->tlabel != tlabel)            || (packet->node_id != (data[1] >> 16))) {                HPSB_INFO("unsolicited response packet received");                dump_packet("contents:", data, 16);                spin_unlock_irqrestore(&host->pending_pkt_lock, flags);                return;        }        list_del(&packet->list);        spin_unlock_irqrestore(&host->pending_pkt_lock, flags);        /* FIXME - update size fields? */        switch (tcode) {        case TCODE_WRITE_RESPONSE:                memcpy(packet->header, data, 12);                break;        case TCODE_READQ_RESPONSE:                memcpy(packet->header, data, 16);                break;        case TCODE_READB_RESPONSE:                memcpy(packet->header, data, 16);                memcpy(packet->data, data + 4, size - 16);                break;        case TCODE_LOCK_RESPONSE:                memcpy(packet->header, data, 16);                memcpy(packet->data, data + 4, (size - 16) > 8 ? 8 : size - 16);                break;        }        packet->state = hpsb_complete;        up(&packet->state_change);	process_complete_tasks(packet);}static struct hpsb_packet *create_reply_packet(struct hpsb_host *host,					       quadlet_t *data, size_t dsize){        struct hpsb_packet *p;        dsize += (dsize % 4 ? 4 - (dsize % 4) : 0);        p = alloc_hpsb_packet(dsize);        if (p == NULL) {                /* FIXME - send data_error response */                return NULL;        }        p->type = hpsb_async;        p->state = hpsb_unused;        p->host = host;        p->node_id = data[1] >> 16;        p->tlabel = (data[0] >> 10) & 0x3f;        p->no_waiter = 1;	p->generation = get_hpsb_generation(host);        if (dsize % 4) {                p->data[dsize / 4] = 0;        }        return p;}#define PREP_REPLY_PACKET(length) \                packet = create_reply_packet(host, data, length); \                if (packet == NULL) breakstatic void handle_incoming_packet(struct hpsb_host *host, int tcode,				   quadlet_t *data, size_t size, int write_acked){        struct hpsb_packet *packet;        int length, rcode, extcode;        nodeid_t source = data[1] >> 16;	nodeid_t dest = data[0] >> 16;        u64 addr;        /* big FIXME - no error checking is done for an out of bounds length */        switch (tcode) {        case TCODE_WRITEQ:                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_write(host, source, dest, data+3,					addr, 4);                if (!write_acked                    && ((data[0] >> 16) & NODE_MASK) != NODE_MASK) {                        /* not a broadcast write, reply */                        PREP_REPLY_PACKET(0);                        fill_async_write_resp(packet, rcode);                        send_packet_nocare(packet);                }                break;        case TCODE_WRITEB:                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_write(host, source, dest, data+4,					addr, data[3]>>16);                if (!write_acked                    && ((data[0] >> 16) & NODE_MASK) != NODE_MASK) {                        /* not a broadcast write, reply */                        PREP_REPLY_PACKET(0);                        fill_async_write_resp(packet, rcode);                        send_packet_nocare(packet);                }                break;        case TCODE_READQ:                PREP_REPLY_PACKET(0);                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_read(host, source, data, addr, 4);                fill_async_readquad_resp(packet, rcode, *data);                send_packet_nocare(packet);                break;        case TCODE_READB:                length = data[3] >> 16;                PREP_REPLY_PACKET(length);                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                rcode = highlevel_read(host, source, packet->data, addr,                                       length);                fill_async_readblock_resp(packet, rcode, length);                send_packet_nocare(packet);                break;        case TCODE_LOCK_REQUEST:                length = data[3] >> 16;                extcode = data[3] & 0xffff;                addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];                PREP_REPLY_PACKET(8);                if ((extcode == 0) || (extcode >= 7)) {                        /* let switch default handle error */                        length = 0;                }                switch (length) {                case 4:                        rcode = highlevel_lock(host, source, packet->data, addr,                                               data[4], 0, extcode);                        fill_async_lock_resp(packet, rcode, extcode, 4);                        break;                case 8:                        if ((extcode != EXTCODE_FETCH_ADD)                             && (extcode != EXTCODE_LITTLE_ADD)) {                                rcode = highlevel_lock(host, source,                                                       packet->data, addr,                                                       data[5], data[4],                                                        extcode);                                fill_async_lock_resp(packet, rcode, extcode, 4);                        } else {                                rcode = highlevel_lock64(host, source,                                             (octlet_t *)packet->data, addr,                                             *(octlet_t *)(data + 4), 0ULL,                                             extcode);                                fill_async_lock_resp(packet, rcode, extcode, 8);                        }                        break;                case 16:                        rcode = highlevel_lock64(host, source,                                                 (octlet_t *)packet->data, addr,                                                 *(octlet_t *)(data + 6),                                                 *(octlet_t *)(data + 4),                                                  extcode);                        fill_async_lock_resp(packet, rcode, extcode, 8);                        break;                default:                        fill_async_lock_resp(packet, RCODE_TYPE_ERROR,                                             extcode, 0);                }                send_packet_nocare(packet);                break;        }}#undef PREP_REPLY_PACKETvoid hpsb_packet_received(struct hpsb_host *host, quadlet_t *data, size_t size,                          int write_acked){        int tcode;        if (host->in_bus_reset) {                HPSB_INFO("received packet during reset; ignoring");                return;        }#ifdef CONFIG_IEEE1394_VERBOSEDEBUG        dump_packet("received packet:", data, size);#endif        tcode = (data[0] >> 4) & 0xf;        switch (tcode) {        case TCODE_WRITE_RESPONSE:        case TCODE_READQ_RESPONSE:        case TCODE_READB_RESPONSE:        case TCODE_LOCK_RESPONSE:                handle_packet_response(host, tcode, data, size);                break;        case TCODE_WRITEQ:        case TCODE_WRITEB:        case TCODE_READQ:        case TCODE_READB:        case TCODE_LOCK_REQUEST:                handle_incoming_packet(host, tcode, data, size, write_acked);                break;        case TCODE_ISO_DATA:                highlevel_iso_receive(host, data, size);                break;        case TCODE_CYCLE_START:                /* simply ignore this packet if it is passed on */                break;        default:                HPSB_NOTICE("received packet with bogus transaction code %d",                             tcode);                break;        }}void abort_requests(struct hpsb_host *host){        unsigned long flags;        struct hpsb_packet *packet;        struct list_head *lh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -