📄 ieee1394_core.c
字号:
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,flags); 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, flags); 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, flags); 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, flags); fill_async_lock_resp(packet, rcode, extcode, 8); break; default: rcode = RCODE_TYPE_ERROR; fill_async_lock_resp(packet, rcode, extcode, 0); } if (rcode >= 0) { send_packet_nocare(packet); } else { hpsb_free_packet(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; } dump_packet("received packet", data, size, -1); 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; }}static void abort_requests(struct hpsb_host *host){ struct hpsb_packet *packet; struct sk_buff *skb; host->driver->devctl(host, CANCEL_REQUESTS, 0); while ((skb = skb_dequeue(&host->pending_packet_queue)) != NULL) { packet = (struct hpsb_packet *)skb->data; packet->state = hpsb_complete; packet->ack_code = ACKX_ABORTED; queue_packet_complete(packet); }}void abort_timedouts(unsigned long __opaque){ struct hpsb_host *host = (struct hpsb_host *)__opaque; unsigned long flags; struct hpsb_packet *packet; struct sk_buff *skb; unsigned long expire; spin_lock_irqsave(&host->csr.lock, flags); expire = host->csr.expire; spin_unlock_irqrestore(&host->csr.lock, flags); /* Hold the lock around this, since we aren't dequeuing all * packets, just ones we need. */ spin_lock_irqsave(&host->pending_packet_queue.lock, flags); while (!skb_queue_empty(&host->pending_packet_queue)) { skb = skb_peek(&host->pending_packet_queue); packet = (struct hpsb_packet *)skb->data; if (time_before(packet->sendtime + expire, jiffies)) { __skb_unlink(skb, &host->pending_packet_queue); packet->state = hpsb_complete; packet->ack_code = ACKX_TIMEOUT; queue_packet_complete(packet); } else { /* Since packets are added to the tail, the oldest * ones are first, always. When we get to one that * isn't timed out, the rest aren't either. */ break; } } if (!skb_queue_empty(&host->pending_packet_queue)) mod_timer(&host->timeout, jiffies + host->timeout_interval); spin_unlock_irqrestore(&host->pending_packet_queue.lock, flags);}/* Kernel thread and vars, which handles packets that are completed. Only * packets that have a "complete" function are sent here. This way, the * completion is run out of kernel context, and doesn't block the rest of * the stack. */static struct task_struct *khpsbpkt_thread;static struct sk_buff_head hpsbpkt_queue;static void queue_packet_complete(struct hpsb_packet *packet){ if (packet->no_waiter) { hpsb_free_packet(packet); return; } if (packet->complete_routine != NULL) { skb_queue_tail(&hpsbpkt_queue, packet->skb); wake_up_process(khpsbpkt_thread); } return;}static int hpsbpkt_thread(void *__hi){ struct sk_buff *skb; struct hpsb_packet *packet; void (*complete_routine)(void*); void *complete_data; current->flags |= PF_NOFREEZE; while (!kthread_should_stop()) { while ((skb = skb_dequeue(&hpsbpkt_queue)) != NULL) { packet = (struct hpsb_packet *)skb->data; complete_routine = packet->complete_routine; complete_data = packet->complete_data; packet->complete_routine = packet->complete_data = NULL; complete_routine(complete_data); } set_current_state(TASK_INTERRUPTIBLE); if (!skb_peek(&hpsbpkt_queue)) schedule(); __set_current_state(TASK_RUNNING); } return 0;}static int __init ieee1394_init(void){ int i, ret; skb_queue_head_init(&hpsbpkt_queue); /* non-fatal error */ if (hpsb_init_config_roms()) { HPSB_ERR("Failed to initialize some config rom entries.\n"); HPSB_ERR("Some features may not be available\n"); } khpsbpkt_thread = kthread_run(hpsbpkt_thread, NULL, "khpsbpkt"); if (IS_ERR(khpsbpkt_thread)) { HPSB_ERR("Failed to start hpsbpkt thread!\n"); ret = PTR_ERR(khpsbpkt_thread); goto exit_cleanup_config_roms; } if (register_chrdev_region(IEEE1394_CORE_DEV, 256, "ieee1394")) { HPSB_ERR("unable to register character device major %d!\n", IEEE1394_MAJOR); ret = -ENODEV; goto exit_release_kernel_thread; } ret = bus_register(&ieee1394_bus_type); if (ret < 0) { HPSB_INFO("bus register failed"); goto release_chrdev; } for (i = 0; fw_bus_attrs[i]; i++) { ret = bus_create_file(&ieee1394_bus_type, fw_bus_attrs[i]); if (ret < 0) { while (i >= 0) { bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i--]); } bus_unregister(&ieee1394_bus_type); goto release_chrdev; } } ret = class_register(&hpsb_host_class); if (ret < 0) goto release_all_bus; hpsb_protocol_class = class_create(THIS_MODULE, "ieee1394_protocol"); if (IS_ERR(hpsb_protocol_class)) { ret = PTR_ERR(hpsb_protocol_class); goto release_class_host; } ret = init_csr(); if (ret) { HPSB_INFO("init csr failed"); ret = -ENOMEM; goto release_class_protocol; } if (disable_nodemgr) { HPSB_INFO("nodemgr and IRM functionality disabled"); /* We shouldn't contend for IRM with nodemgr disabled, since nodemgr implements functionality required of ieee1394a-2000 IRMs */ hpsb_disable_irm = 1; return 0; } if (hpsb_disable_irm) { HPSB_INFO("IRM functionality disabled"); } ret = init_ieee1394_nodemgr(); if (ret < 0) { HPSB_INFO("init nodemgr failed"); goto cleanup_csr; } return 0;cleanup_csr: cleanup_csr();release_class_protocol: class_destroy(hpsb_protocol_class);release_class_host: class_unregister(&hpsb_host_class);release_all_bus: for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type);release_chrdev: unregister_chrdev_region(IEEE1394_CORE_DEV, 256);exit_release_kernel_thread: kthread_stop(khpsbpkt_thread);exit_cleanup_config_roms: hpsb_cleanup_config_roms(); return ret;}static void __exit ieee1394_cleanup(void){ int i; if (!disable_nodemgr) cleanup_ieee1394_nodemgr(); cleanup_csr(); class_destroy(hpsb_protocol_class); class_unregister(&hpsb_host_class); for (i = 0; fw_bus_attrs[i]; i++) bus_remove_file(&ieee1394_bus_type, fw_bus_attrs[i]); bus_unregister(&ieee1394_bus_type); kthread_stop(khpsbpkt_thread); hpsb_cleanup_config_roms(); unregister_chrdev_region(IEEE1394_CORE_DEV, 256);}fs_initcall(ieee1394_init); /* same as ohci1394 */module_exit(ieee1394_cleanup);/* Exported symbols *//** hosts.c **/EXPORT_SYMBOL(hpsb_alloc_host);EXPORT_SYMBOL(hpsb_add_host);EXPORT_SYMBOL(hpsb_resume_host);EXPORT_SYMBOL(hpsb_remove_host);EXPORT_SYMBOL(hpsb_update_config_rom_image);/** ieee1394_core.c **/EXPORT_SYMBOL(hpsb_speedto_str);EXPORT_SYMBOL(hpsb_protocol_class);EXPORT_SYMBOL(hpsb_set_packet_complete_task);EXPORT_SYMBOL(hpsb_alloc_packet);EXPORT_SYMBOL(hpsb_free_packet);EXPORT_SYMBOL(hpsb_send_packet);EXPORT_SYMBOL(hpsb_reset_bus);EXPORT_SYMBOL(hpsb_read_cycle_timer);EXPORT_SYMBOL(hpsb_bus_reset);EXPORT_SYMBOL(hpsb_selfid_received);EXPORT_SYMBOL(hpsb_selfid_complete);EXPORT_SYMBOL(hpsb_packet_sent);EXPORT_SYMBOL(hpsb_packet_received);EXPORT_SYMBOL_GPL(hpsb_disable_irm);/** ieee1394_transactions.c **/EXPORT_SYMBOL(hpsb_get_tlabel);EXPORT_SYMBOL(hpsb_free_tlabel);EXPORT_SYMBOL(hpsb_make_readpacket);EXPORT_SYMBOL(hpsb_make_writepacket);EXPORT_SYMBOL(hpsb_make_streampacket);EXPORT_SYMBOL(hpsb_make_lockpacket);EXPORT_SYMBOL(hpsb_make_lock64packet);EXPORT_SYMBOL(hpsb_make_phypacket);EXPORT_SYMBOL(hpsb_make_isopacket);EXPORT_SYMBOL(hpsb_read);EXPORT_SYMBOL(hpsb_write);EXPORT_SYMBOL(hpsb_packet_success);/** highlevel.c **/EXPORT_SYMBOL(hpsb_register_highlevel);EXPORT_SYMBOL(hpsb_unregister_highlevel);EXPORT_SYMBOL(hpsb_register_addrspace);EXPORT_SYMBOL(hpsb_unregister_addrspace);EXPORT_SYMBOL(hpsb_allocate_and_register_addrspace);EXPORT_SYMBOL(hpsb_listen_channel);EXPORT_SYMBOL(hpsb_unlisten_channel);EXPORT_SYMBOL(hpsb_get_hostinfo);EXPORT_SYMBOL(hpsb_create_hostinfo);EXPORT_SYMBOL(hpsb_destroy_hostinfo);EXPORT_SYMBOL(hpsb_set_hostinfo_key);EXPORT_SYMBOL(hpsb_get_hostinfo_bykey);EXPORT_SYMBOL(hpsb_set_hostinfo);EXPORT_SYMBOL(highlevel_host_reset);/** nodemgr.c **/EXPORT_SYMBOL(hpsb_node_fill_packet);EXPORT_SYMBOL(hpsb_node_write);EXPORT_SYMBOL(__hpsb_register_protocol);EXPORT_SYMBOL(hpsb_unregister_protocol);/** csr.c **/EXPORT_SYMBOL(hpsb_update_config_rom);/** dma.c **/EXPORT_SYMBOL(dma_prog_region_init);EXPORT_SYMBOL(dma_prog_region_alloc);EXPORT_SYMBOL(dma_prog_region_free);EXPORT_SYMBOL(dma_region_init);EXPORT_SYMBOL(dma_region_alloc);EXPORT_SYMBOL(dma_region_free);EXPORT_SYMBOL(dma_region_sync_for_cpu);EXPORT_SYMBOL(dma_region_sync_for_device);EXPORT_SYMBOL(dma_region_mmap);EXPORT_SYMBOL(dma_region_offset_to_bus);/** iso.c **/EXPORT_SYMBOL(hpsb_iso_xmit_init);EXPORT_SYMBOL(hpsb_iso_recv_init);EXPORT_SYMBOL(hpsb_iso_xmit_start);EXPORT_SYMBOL(hpsb_iso_recv_start);EXPORT_SYMBOL(hpsb_iso_recv_listen_channel);EXPORT_SYMBOL(hpsb_iso_recv_unlisten_channel);EXPORT_SYMBOL(hpsb_iso_recv_set_channel_mask);EXPORT_SYMBOL(hpsb_iso_stop);EXPORT_SYMBOL(hpsb_iso_shutdown);EXPORT_SYMBOL(hpsb_iso_xmit_queue_packet);EXPORT_SYMBOL(hpsb_iso_xmit_sync);EXPORT_SYMBOL(hpsb_iso_recv_release_packets);EXPORT_SYMBOL(hpsb_iso_n_ready);EXPORT_SYMBOL(hpsb_iso_packet_sent);EXPORT_SYMBOL(hpsb_iso_packet_received);EXPORT_SYMBOL(hpsb_iso_wake);EXPORT_SYMBOL(hpsb_iso_recv_flush);/** csr1212.c **/EXPORT_SYMBOL(csr1212_new_directory);EXPORT_SYMBOL(csr1212_attach_keyval_to_directory);EXPORT_SYMBOL(csr1212_detach_keyval_from_directory);EXPORT_SYMBOL(csr1212_release_keyval);EXPORT_SYMBOL(csr1212_read);EXPORT_SYMBOL(csr1212_parse_keyval);EXPORT_SYMBOL(_csr1212_read_keyval);EXPORT_SYMBOL(_csr1212_destroy_keyval);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -