Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'firewire-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394

Pull firewire updates from Takashi Sakamoto:
"This consist of three parts; UAPI update, OHCI driver update, and
several bug fixes.

Firstly, the 1394 OHCI specification defines method to retrieve
hardware time stamps for asynchronous communication, which was
previously unavailable in user space. This adds new events to the
UAPI, allowing applications to retrieve the time when asynchronous
packet are received and sent. The new events are tested in the
bleeding edge of libhinawa and look to work well. The new version of
libhinawa will be released after current merge window is closed:

https://git.kernel.org/pub/scm/libs/ieee1394/libhinawa.git/

Secondly, the FireWire stack includes a PCM device driver for 1394
OHCI hardware, This change modernizes the driver by managed resource
(devres) framework.

Lastly, bug fixes for firewire-net and firewire-core"

* tag 'firewire-6.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394: (25 commits)
firewire: net: fix use after free in fwnet_finish_incoming_packet()
firewire: core: obsolete usage of GFP_ATOMIC at building node tree
firewire: ohci: release buffer for AR req/resp contexts when managed resource is released
firewire: ohci: use devres for content of configuration ROM
firewire: ohci: use devres for IT, IR, AT/receive, and AT/request contexts
firewire: ohci: use devres for list of isochronous contexts
firewire: ohci: use devres for requested IRQ
firewire: ohci: use devres for misc DMA buffer
firewire: ohci: use devres for MMIO region mapping
firewire: ohci: use devres for PCI-related resources
firewire: ohci: use devres for memory object of ohci structure
firewire: fix warnings to generate UAPI documentation
firewire: fix build failure due to missing module license
firewire: cdev: implement new event relevant to phy packet with time stamp
firewire: cdev: add new event to notify phy packet with time stamp
firewire: cdev: code refactoring to dispatch event for phy packet
firewire: cdev: implement new event to notify response subaction with time stamp
firewire: cdev: add new event to notify response subaction with time stamp
firewire: cdev: code refactoring to operate event of response
firewire: core: implement variations to send request and wait for response with time stamp
...

+694 -231
+4
drivers/firewire/.kunitconfig
··· 1 + CONFIG_KUNIT=y 2 + CONFIG_PCI=y 3 + CONFIG_FIREWIRE=y 4 + CONFIG_FIREWIRE_KUNIT_UAPI_TEST=y
+16
drivers/firewire/Kconfig
··· 18 18 To compile this driver as a module, say M here: the module will be 19 19 called firewire-core. 20 20 21 + config FIREWIRE_KUNIT_UAPI_TEST 22 + tristate "KUnit tests for layout of structure in UAPI" if !KUNIT_ALL_TESTS 23 + depends on FIREWIRE && KUNIT 24 + default KUNIT_ALL_TESTS 25 + help 26 + This builds the KUnit tests whether structures exposed to user 27 + space have expected layout. 28 + 29 + KUnit tests run during boot and output the results to the debug 30 + log in TAP format (https://testanything.org/). Only useful for 31 + kernel devs running KUnit test harness and are not for inclusion 32 + into a production build. 33 + 34 + For more information on KUnit and unit tests in general, refer 35 + to the KUnit documentation in Documentation/dev-tools/kunit/. 36 + 21 37 config FIREWIRE_OHCI 22 38 tristate "OHCI-1394 controllers" 23 39 depends on PCI && FIREWIRE && MMU
+3
drivers/firewire/Makefile
··· 15 15 obj-$(CONFIG_FIREWIRE_NET) += firewire-net.o 16 16 obj-$(CONFIG_FIREWIRE_NOSY) += nosy.o 17 17 obj-$(CONFIG_PROVIDE_OHCI1394_DMA_INIT) += init_ohci1394_dma.o 18 + 19 + firewire-uapi-test-objs += uapi-test.o 20 + obj-$(CONFIG_FIREWIRE_KUNIT_UAPI_TEST) += firewire-uapi-test.o
+188 -64
drivers/firewire/core-cdev.c
··· 43 43 #define FW_CDEV_VERSION_EVENT_REQUEST2 4 44 44 #define FW_CDEV_VERSION_ALLOCATE_REGION_END 4 45 45 #define FW_CDEV_VERSION_AUTO_FLUSH_ISO_OVERFLOW 5 46 + #define FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP 6 46 47 47 48 struct client { 48 49 u32 version; ··· 170 169 struct event event; 171 170 struct client *client; 172 171 struct outbound_transaction_resource r; 173 - struct fw_cdev_event_response response; 172 + union { 173 + struct fw_cdev_event_response without_tstamp; 174 + struct fw_cdev_event_response2 with_tstamp; 175 + } rsp; 174 176 }; 175 177 176 178 struct inbound_transaction_event { ··· 181 177 union { 182 178 struct fw_cdev_event_request request; 183 179 struct fw_cdev_event_request2 request2; 180 + struct fw_cdev_event_request3 with_tstamp; 184 181 } req; 185 182 }; 186 183 ··· 204 199 struct event event; 205 200 struct client *client; 206 201 struct fw_packet p; 207 - struct fw_cdev_event_phy_packet phy_packet; 202 + union { 203 + struct fw_cdev_event_phy_packet without_tstamp; 204 + struct fw_cdev_event_phy_packet2 with_tstamp; 205 + } phy_packet; 208 206 }; 209 207 210 208 struct inbound_phy_packet_event { 211 209 struct event event; 212 - struct fw_cdev_event_phy_packet phy_packet; 210 + union { 211 + struct fw_cdev_event_phy_packet without_tstamp; 212 + struct fw_cdev_event_phy_packet2 with_tstamp; 213 + } phy_packet; 213 214 }; 214 215 215 216 #ifdef CONFIG_COMPAT ··· 545 534 { 546 535 } 547 536 548 - static void complete_transaction(struct fw_card *card, int rcode, 549 - void *payload, size_t length, void *data) 537 + static void complete_transaction(struct fw_card *card, int rcode, u32 request_tstamp, 538 + u32 response_tstamp, void *payload, size_t length, void *data) 550 539 { 551 540 struct outbound_transaction_event *e = data; 552 - struct fw_cdev_event_response *rsp = &e->response; 553 541 struct client *client = e->client; 554 542 unsigned long flags; 555 - 556 - if (length < rsp->length) 557 - rsp->length = length; 558 - if (rcode == RCODE_COMPLETE) 559 - memcpy(rsp->data, payload, rsp->length); 560 543 561 544 spin_lock_irqsave(&client->lock, flags); 562 545 idr_remove(&client->resource_idr, e->r.resource.handle); ··· 558 553 wake_up(&client->tx_flush_wait); 559 554 spin_unlock_irqrestore(&client->lock, flags); 560 555 561 - rsp->type = FW_CDEV_EVENT_RESPONSE; 562 - rsp->rcode = rcode; 556 + switch (e->rsp.without_tstamp.type) { 557 + case FW_CDEV_EVENT_RESPONSE: 558 + { 559 + struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; 563 560 564 - /* 565 - * In the case that sizeof(*rsp) doesn't align with the position of the 566 - * data, and the read is short, preserve an extra copy of the data 567 - * to stay compatible with a pre-2.6.27 bug. Since the bug is harmless 568 - * for short reads and some apps depended on it, this is both safe 569 - * and prudent for compatibility. 570 - */ 571 - if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data)) 572 - queue_event(client, &e->event, rsp, sizeof(*rsp), 573 - rsp->data, rsp->length); 574 - else 575 - queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, 576 - NULL, 0); 561 + if (length < rsp->length) 562 + rsp->length = length; 563 + if (rcode == RCODE_COMPLETE) 564 + memcpy(rsp->data, payload, rsp->length); 565 + 566 + rsp->rcode = rcode; 567 + 568 + // In the case that sizeof(*rsp) doesn't align with the position of the 569 + // data, and the read is short, preserve an extra copy of the data 570 + // to stay compatible with a pre-2.6.27 bug. Since the bug is harmless 571 + // for short reads and some apps depended on it, this is both safe 572 + // and prudent for compatibility. 573 + if (rsp->length <= sizeof(*rsp) - offsetof(typeof(*rsp), data)) 574 + queue_event(client, &e->event, rsp, sizeof(*rsp), rsp->data, rsp->length); 575 + else 576 + queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, NULL, 0); 577 + 578 + break; 579 + } 580 + case FW_CDEV_EVENT_RESPONSE2: 581 + { 582 + struct fw_cdev_event_response2 *rsp = &e->rsp.with_tstamp; 583 + 584 + if (length < rsp->length) 585 + rsp->length = length; 586 + if (rcode == RCODE_COMPLETE) 587 + memcpy(rsp->data, payload, rsp->length); 588 + 589 + rsp->rcode = rcode; 590 + rsp->request_tstamp = request_tstamp; 591 + rsp->response_tstamp = response_tstamp; 592 + 593 + queue_event(client, &e->event, rsp, sizeof(*rsp) + rsp->length, NULL, 0); 594 + 595 + break; 596 + default: 597 + WARN_ON(1); 598 + break; 599 + } 600 + } 577 601 578 602 /* Drop the idr's reference */ 579 603 client_put(client); ··· 613 579 int destination_id, int speed) 614 580 { 615 581 struct outbound_transaction_event *e; 582 + void *payload; 616 583 int ret; 617 584 618 585 if (request->tcode != TCODE_STREAM_DATA && ··· 627 592 e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL); 628 593 if (e == NULL) 629 594 return -ENOMEM; 630 - 631 595 e->client = client; 632 - e->response.length = request->length; 633 - e->response.closure = request->closure; 634 596 635 - if (request->data && 636 - copy_from_user(e->response.data, 637 - u64_to_uptr(request->data), request->length)) { 597 + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { 598 + struct fw_cdev_event_response *rsp = &e->rsp.without_tstamp; 599 + 600 + rsp->type = FW_CDEV_EVENT_RESPONSE; 601 + rsp->length = request->length; 602 + rsp->closure = request->closure; 603 + payload = rsp->data; 604 + } else { 605 + struct fw_cdev_event_response2 *rsp = &e->rsp.with_tstamp; 606 + 607 + rsp->type = FW_CDEV_EVENT_RESPONSE2; 608 + rsp->length = request->length; 609 + rsp->closure = request->closure; 610 + payload = rsp->data; 611 + } 612 + 613 + if (request->data && copy_from_user(payload, u64_to_uptr(request->data), request->length)) { 638 614 ret = -EFAULT; 639 615 goto failed; 640 616 } ··· 655 609 if (ret < 0) 656 610 goto failed; 657 611 658 - fw_send_request(client->device->card, &e->r.transaction, 659 - request->tcode, destination_id, request->generation, 660 - speed, request->offset, e->response.data, 661 - request->length, complete_transaction, e); 612 + fw_send_request_with_tstamp(client->device->card, &e->r.transaction, request->tcode, 613 + destination_id, request->generation, speed, request->offset, 614 + payload, request->length, complete_transaction, e); 662 615 return 0; 663 616 664 617 failed: ··· 753 708 req->handle = r->resource.handle; 754 709 req->closure = handler->closure; 755 710 event_size0 = sizeof(*req); 756 - } else { 711 + } else if (handler->client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { 757 712 struct fw_cdev_event_request2 *req = &e->req.request2; 758 713 759 714 req->type = FW_CDEV_EVENT_REQUEST2; ··· 766 721 req->length = length; 767 722 req->handle = r->resource.handle; 768 723 req->closure = handler->closure; 724 + event_size0 = sizeof(*req); 725 + } else { 726 + struct fw_cdev_event_request3 *req = &e->req.with_tstamp; 727 + 728 + req->type = FW_CDEV_EVENT_REQUEST3; 729 + req->tcode = tcode; 730 + req->offset = offset; 731 + req->source_node_id = source; 732 + req->destination_node_id = destination; 733 + req->card = card->index; 734 + req->generation = generation; 735 + req->length = length; 736 + req->handle = r->resource.handle; 737 + req->closure = handler->closure; 738 + req->tstamp = fw_request_get_timestamp(request); 769 739 event_size0 = sizeof(*req); 770 740 } 771 741 ··· 1555 1495 { 1556 1496 struct outbound_phy_packet_event *e = 1557 1497 container_of(packet, struct outbound_phy_packet_event, p); 1558 - struct client *e_client; 1498 + struct client *e_client = e->client; 1499 + u32 rcode; 1559 1500 1560 1501 switch (status) { 1561 - /* expected: */ 1562 - case ACK_COMPLETE: e->phy_packet.rcode = RCODE_COMPLETE; break; 1563 - /* should never happen with PHY packets: */ 1564 - case ACK_PENDING: e->phy_packet.rcode = RCODE_COMPLETE; break; 1502 + // expected: 1503 + case ACK_COMPLETE: 1504 + rcode = RCODE_COMPLETE; 1505 + break; 1506 + // should never happen with PHY packets: 1507 + case ACK_PENDING: 1508 + rcode = RCODE_COMPLETE; 1509 + break; 1565 1510 case ACK_BUSY_X: 1566 1511 case ACK_BUSY_A: 1567 - case ACK_BUSY_B: e->phy_packet.rcode = RCODE_BUSY; break; 1568 - case ACK_DATA_ERROR: e->phy_packet.rcode = RCODE_DATA_ERROR; break; 1569 - case ACK_TYPE_ERROR: e->phy_packet.rcode = RCODE_TYPE_ERROR; break; 1570 - /* stale generation; cancelled; on certain controllers: no ack */ 1571 - default: e->phy_packet.rcode = status; break; 1512 + case ACK_BUSY_B: 1513 + rcode = RCODE_BUSY; 1514 + break; 1515 + case ACK_DATA_ERROR: 1516 + rcode = RCODE_DATA_ERROR; 1517 + break; 1518 + case ACK_TYPE_ERROR: 1519 + rcode = RCODE_TYPE_ERROR; 1520 + break; 1521 + // stale generation; cancelled; on certain controllers: no ack 1522 + default: 1523 + rcode = status; 1524 + break; 1572 1525 } 1573 - e->phy_packet.data[0] = packet->timestamp; 1574 1526 1575 - e_client = e->client; 1576 - queue_event(e->client, &e->event, &e->phy_packet, 1577 - sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0); 1527 + switch (e->phy_packet.without_tstamp.type) { 1528 + case FW_CDEV_EVENT_PHY_PACKET_SENT: 1529 + { 1530 + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; 1531 + 1532 + pp->rcode = rcode; 1533 + pp->data[0] = packet->timestamp; 1534 + queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, 1535 + NULL, 0); 1536 + break; 1537 + } 1538 + case FW_CDEV_EVENT_PHY_PACKET_SENT2: 1539 + { 1540 + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; 1541 + 1542 + pp->rcode = rcode; 1543 + pp->tstamp = packet->timestamp; 1544 + queue_event(e->client, &e->event, &e->phy_packet, sizeof(*pp) + pp->length, 1545 + NULL, 0); 1546 + break; 1547 + } 1548 + default: 1549 + WARN_ON(1); 1550 + break; 1551 + } 1552 + 1578 1553 client_put(e_client); 1579 1554 } 1580 1555 ··· 1623 1528 if (!client->device->is_local) 1624 1529 return -ENOSYS; 1625 1530 1626 - e = kzalloc(sizeof(*e) + 4, GFP_KERNEL); 1531 + e = kzalloc(sizeof(*e) + sizeof(a->data), GFP_KERNEL); 1627 1532 if (e == NULL) 1628 1533 return -ENOMEM; 1629 1534 ··· 1636 1541 e->p.header[2] = a->data[1]; 1637 1542 e->p.header_length = 12; 1638 1543 e->p.callback = outbound_phy_packet_callback; 1639 - e->phy_packet.closure = a->closure; 1640 - e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT; 1641 - if (is_ping_packet(a->data)) 1642 - e->phy_packet.length = 4; 1544 + 1545 + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { 1546 + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; 1547 + 1548 + pp->closure = a->closure; 1549 + pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT; 1550 + if (is_ping_packet(a->data)) 1551 + pp->length = 4; 1552 + } else { 1553 + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; 1554 + 1555 + pp->closure = a->closure; 1556 + pp->type = FW_CDEV_EVENT_PHY_PACKET_SENT2; 1557 + // Keep the data field so that application can match the response event to the 1558 + // request. 1559 + pp->length = sizeof(a->data); 1560 + memcpy(pp->data, a->data, sizeof(a->data)); 1561 + } 1643 1562 1644 1563 card->driver->send_request(card, &e->p); 1645 1564 ··· 1692 1583 if (e == NULL) 1693 1584 break; 1694 1585 1695 - e->phy_packet.closure = client->phy_receiver_closure; 1696 - e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; 1697 - e->phy_packet.rcode = RCODE_COMPLETE; 1698 - e->phy_packet.length = 8; 1699 - e->phy_packet.data[0] = p->header[1]; 1700 - e->phy_packet.data[1] = p->header[2]; 1701 - queue_event(client, &e->event, 1702 - &e->phy_packet, sizeof(e->phy_packet) + 8, NULL, 0); 1586 + if (client->version < FW_CDEV_VERSION_EVENT_ASYNC_TSTAMP) { 1587 + struct fw_cdev_event_phy_packet *pp = &e->phy_packet.without_tstamp; 1588 + 1589 + pp->closure = client->phy_receiver_closure; 1590 + pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED; 1591 + pp->rcode = RCODE_COMPLETE; 1592 + pp->length = 8; 1593 + pp->data[0] = p->header[1]; 1594 + pp->data[1] = p->header[2]; 1595 + queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); 1596 + } else { 1597 + struct fw_cdev_event_phy_packet2 *pp = &e->phy_packet.with_tstamp; 1598 + 1599 + pp = &e->phy_packet.with_tstamp; 1600 + pp->closure = client->phy_receiver_closure; 1601 + pp->type = FW_CDEV_EVENT_PHY_PACKET_RECEIVED2; 1602 + pp->rcode = RCODE_COMPLETE; 1603 + pp->length = 8; 1604 + pp->tstamp = p->timestamp; 1605 + pp->data[0] = p->header[1]; 1606 + pp->data[1] = p->header[2]; 1607 + queue_event(client, &e->event, &e->phy_packet, sizeof(*pp) + 8, NULL, 0); 1608 + } 1703 1609 } 1704 1610 1705 1611 spin_unlock_irqrestore(&card->lock, flags);
+1 -1
drivers/firewire/core-device.c
··· 1211 1211 * without actually having a link. 1212 1212 */ 1213 1213 create: 1214 - device = kzalloc(sizeof(*device), GFP_ATOMIC); 1214 + device = kzalloc(sizeof(*device), GFP_KERNEL); 1215 1215 if (device == NULL) 1216 1216 break; 1217 1217
+1 -1
drivers/firewire/core-topology.c
··· 101 101 { 102 102 struct fw_node *node; 103 103 104 - node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); 104 + node = kzalloc(struct_size(node, ports, port_count), GFP_KERNEL); 105 105 if (node == NULL) 106 106 return NULL; 107 107
+70 -23
drivers/firewire/core-transaction.c
··· 70 70 return 1; 71 71 } 72 72 73 - static int close_transaction(struct fw_transaction *transaction, 74 - struct fw_card *card, int rcode) 73 + static int close_transaction(struct fw_transaction *transaction, struct fw_card *card, int rcode, 74 + u32 response_tstamp) 75 75 { 76 76 struct fw_transaction *t = NULL, *iter; 77 77 unsigned long flags; ··· 92 92 spin_unlock_irqrestore(&card->lock, flags); 93 93 94 94 if (t) { 95 - t->callback(card, rcode, NULL, 0, t->callback_data); 95 + if (!t->with_tstamp) { 96 + t->callback.without_tstamp(card, rcode, NULL, 0, t->callback_data); 97 + } else { 98 + t->callback.with_tstamp(card, rcode, t->packet.timestamp, response_tstamp, 99 + NULL, 0, t->callback_data); 100 + } 96 101 return 0; 97 102 } 98 103 ··· 112 107 int fw_cancel_transaction(struct fw_card *card, 113 108 struct fw_transaction *transaction) 114 109 { 110 + u32 tstamp; 111 + 115 112 /* 116 113 * Cancel the packet transmission if it's still queued. That 117 114 * will call the packet transmission callback which cancels ··· 128 121 * if the transaction is still pending and remove it in that case. 129 122 */ 130 123 131 - return close_transaction(transaction, card, RCODE_CANCELLED); 124 + if (transaction->packet.ack == 0) { 125 + // The timestamp is reused since it was just read now. 126 + tstamp = transaction->packet.timestamp; 127 + } else { 128 + u32 curr_cycle_time = 0; 129 + 130 + (void)fw_card_read_cycle_time(card, &curr_cycle_time); 131 + tstamp = cycle_time_to_ohci_tstamp(curr_cycle_time); 132 + } 133 + 134 + return close_transaction(transaction, card, RCODE_CANCELLED, tstamp); 132 135 } 133 136 EXPORT_SYMBOL(fw_cancel_transaction); 134 137 ··· 157 140 card->tlabel_mask &= ~(1ULL << t->tlabel); 158 141 spin_unlock_irqrestore(&card->lock, flags); 159 142 160 - t->callback(card, RCODE_CANCELLED, NULL, 0, t->callback_data); 143 + if (!t->with_tstamp) { 144 + t->callback.without_tstamp(card, RCODE_CANCELLED, NULL, 0, t->callback_data); 145 + } else { 146 + t->callback.with_tstamp(card, RCODE_CANCELLED, t->packet.timestamp, 147 + t->split_timeout_cycle, NULL, 0, t->callback_data); 148 + } 161 149 } 162 150 163 151 static void start_split_transaction_timeout(struct fw_transaction *t, ··· 184 162 spin_unlock_irqrestore(&card->lock, flags); 185 163 } 186 164 165 + static u32 compute_split_timeout_timestamp(struct fw_card *card, u32 request_timestamp); 166 + 187 167 static void transmit_complete_callback(struct fw_packet *packet, 188 168 struct fw_card *card, int status) 189 169 { ··· 194 170 195 171 switch (status) { 196 172 case ACK_COMPLETE: 197 - close_transaction(t, card, RCODE_COMPLETE); 173 + close_transaction(t, card, RCODE_COMPLETE, packet->timestamp); 198 174 break; 199 175 case ACK_PENDING: 176 + { 177 + t->split_timeout_cycle = 178 + compute_split_timeout_timestamp(card, packet->timestamp) & 0xffff; 200 179 start_split_transaction_timeout(t, card); 201 180 break; 181 + } 202 182 case ACK_BUSY_X: 203 183 case ACK_BUSY_A: 204 184 case ACK_BUSY_B: 205 - close_transaction(t, card, RCODE_BUSY); 185 + close_transaction(t, card, RCODE_BUSY, packet->timestamp); 206 186 break; 207 187 case ACK_DATA_ERROR: 208 - close_transaction(t, card, RCODE_DATA_ERROR); 188 + close_transaction(t, card, RCODE_DATA_ERROR, packet->timestamp); 209 189 break; 210 190 case ACK_TYPE_ERROR: 211 - close_transaction(t, card, RCODE_TYPE_ERROR); 191 + close_transaction(t, card, RCODE_TYPE_ERROR, packet->timestamp); 212 192 break; 213 193 default: 214 194 /* 215 195 * In this case the ack is really a juju specific 216 196 * rcode, so just forward that to the callback. 217 197 */ 218 - close_transaction(t, card, status); 198 + close_transaction(t, card, status, packet->timestamp); 219 199 break; 220 200 } 221 201 } ··· 316 288 } 317 289 318 290 /** 319 - * fw_send_request() - submit a request packet for transmission 291 + * __fw_send_request() - submit a request packet for transmission to generate callback for response 292 + * subaction with or without time stamp. 320 293 * @card: interface to send the request at 321 294 * @t: transaction instance to which the request belongs 322 295 * @tcode: transaction code ··· 327 298 * @offset: 48bit wide offset into destination's address space 328 299 * @payload: data payload for the request subaction 329 300 * @length: length of the payload, in bytes 330 - * @callback: function to be called when the transaction is completed 301 + * @callback: union of two functions whether to receive time stamp or not for response 302 + * subaction. 303 + * @with_tstamp: Whether to receive time stamp or not for response subaction. 331 304 * @callback_data: data to be passed to the transaction completion callback 332 305 * 333 306 * Submit a request packet into the asynchronous request transmission queue. ··· 366 335 * transaction completion and hence execution of @callback may happen even 367 336 * before fw_send_request() returns. 368 337 */ 369 - void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, 370 - int destination_id, int generation, int speed, 371 - unsigned long long offset, void *payload, size_t length, 372 - fw_transaction_callback_t callback, void *callback_data) 338 + void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, 339 + int destination_id, int generation, int speed, unsigned long long offset, 340 + void *payload, size_t length, union fw_transaction_callback callback, 341 + bool with_tstamp, void *callback_data) 373 342 { 374 343 unsigned long flags; 375 344 int tlabel; ··· 384 353 tlabel = allocate_tlabel(card); 385 354 if (tlabel < 0) { 386 355 spin_unlock_irqrestore(&card->lock, flags); 387 - callback(card, RCODE_SEND_ERROR, NULL, 0, callback_data); 356 + if (!with_tstamp) { 357 + callback.without_tstamp(card, RCODE_SEND_ERROR, NULL, 0, callback_data); 358 + } else { 359 + // Timestamping on behalf of hardware. 360 + u32 curr_cycle_time = 0; 361 + u32 tstamp; 362 + 363 + (void)fw_card_read_cycle_time(card, &curr_cycle_time); 364 + tstamp = cycle_time_to_ohci_tstamp(curr_cycle_time); 365 + 366 + callback.with_tstamp(card, RCODE_SEND_ERROR, tstamp, tstamp, NULL, 0, 367 + callback_data); 368 + } 388 369 return; 389 370 } 390 371 ··· 404 361 t->tlabel = tlabel; 405 362 t->card = card; 406 363 t->is_split_transaction = false; 407 - timer_setup(&t->split_timeout_timer, 408 - split_transaction_timeout_callback, 0); 364 + timer_setup(&t->split_timeout_timer, split_transaction_timeout_callback, 0); 409 365 t->callback = callback; 366 + t->with_tstamp = with_tstamp; 410 367 t->callback_data = callback_data; 411 368 412 - fw_fill_request(&t->packet, tcode, t->tlabel, 413 - destination_id, card->node_id, generation, 369 + fw_fill_request(&t->packet, tcode, t->tlabel, destination_id, card->node_id, generation, 414 370 speed, offset, payload, length); 415 371 t->packet.callback = transmit_complete_callback; 416 372 ··· 419 377 420 378 card->driver->send_request(card, &t->packet); 421 379 } 422 - EXPORT_SYMBOL(fw_send_request); 380 + EXPORT_SYMBOL_GPL(__fw_send_request); 423 381 424 382 struct transaction_callback_data { 425 383 struct completion done; ··· 1089 1047 */ 1090 1048 card->driver->cancel_packet(card, &t->packet); 1091 1049 1092 - t->callback(card, rcode, data, data_length, t->callback_data); 1050 + if (!t->with_tstamp) { 1051 + t->callback.without_tstamp(card, rcode, data, data_length, t->callback_data); 1052 + } else { 1053 + t->callback.with_tstamp(card, rcode, t->packet.timestamp, p->timestamp, data, 1054 + data_length, t->callback_data); 1055 + } 1093 1056 } 1094 1057 EXPORT_SYMBOL(fw_core_handle_response); 1095 1058
+7
drivers/firewire/core.h
··· 247 247 void fw_request_get(struct fw_request *request); 248 248 void fw_request_put(struct fw_request *request); 249 249 250 + // Convert the value of IEEE 1394 CYCLE_TIME register to the format of timeStamp field in 251 + // descriptors of 1394 OHCI. 252 + static inline u32 cycle_time_to_ohci_tstamp(u32 tstamp) 253 + { 254 + return (tstamp & 0x0ffff000) >> 12; 255 + } 256 + 250 257 #define FW_PHY_CONFIG_NO_NODE_ID -1 251 258 #define FW_PHY_CONFIG_CURRENT_GAP_COUNT -1 252 259 void fw_send_phy_config(struct fw_card *card,
+4 -2
drivers/firewire/net.c
··· 479 479 struct sk_buff *skb, u16 source_node_id, 480 480 bool is_broadcast, u16 ether_type) 481 481 { 482 - int status; 482 + int status, len; 483 483 484 484 switch (ether_type) { 485 485 case ETH_P_ARP: ··· 533 533 } 534 534 skb->protocol = protocol; 535 535 } 536 + 537 + len = skb->len; 536 538 status = netif_rx(skb); 537 539 if (status == NET_RX_DROP) { 538 540 net->stats.rx_errors++; 539 541 net->stats.rx_dropped++; 540 542 } else { 541 543 net->stats.rx_packets++; 542 - net->stats.rx_bytes += skb->len; 544 + net->stats.rx_bytes += len; 543 545 } 544 546 545 547 return 0;
+77 -112
drivers/firewire/ohci.c
··· 677 677 struct device *dev = ctx->ohci->card.device; 678 678 unsigned int i; 679 679 680 + if (!ctx->buffer) 681 + return; 682 + 680 683 vunmap(ctx->buffer); 681 684 682 685 for (i = 0; i < AR_BUFFERS; i++) { ··· 1108 1105 if (ctx->total_allocation >= 16*1024*1024) 1109 1106 return -ENOMEM; 1110 1107 1111 - desc = dma_alloc_coherent(ctx->ohci->card.device, PAGE_SIZE, 1112 - &bus_addr, GFP_ATOMIC); 1108 + desc = dmam_alloc_coherent(ctx->ohci->card.device, PAGE_SIZE, &bus_addr, GFP_ATOMIC); 1113 1109 if (!desc) 1114 1110 return -ENOMEM; 1115 1111 ··· 1167 1165 struct fw_card *card = &ctx->ohci->card; 1168 1166 struct descriptor_buffer *desc, *tmp; 1169 1167 1170 - list_for_each_entry_safe(desc, tmp, &ctx->buffer_list, list) 1171 - dma_free_coherent(card->device, PAGE_SIZE, desc, 1172 - desc->buffer_bus - 1173 - ((void *)&desc->buffer - (void *)desc)); 1168 + list_for_each_entry_safe(desc, tmp, &ctx->buffer_list, list) { 1169 + dmam_free_coherent(card->device, PAGE_SIZE, desc, 1170 + desc->buffer_bus - ((void *)&desc->buffer - (void *)desc)); 1171 + } 1174 1172 } 1175 1173 1176 1174 /* Must be called with ohci->lock held */ ··· 1625 1623 } 1626 1624 } 1627 1625 1626 + static u32 get_cycle_time(struct fw_ohci *ohci); 1627 + 1628 1628 static void at_context_transmit(struct context *ctx, struct fw_packet *packet) 1629 1629 { 1630 1630 unsigned long flags; ··· 1637 1633 if (HEADER_GET_DESTINATION(packet->header[0]) == ctx->ohci->node_id && 1638 1634 ctx->ohci->generation == packet->generation) { 1639 1635 spin_unlock_irqrestore(&ctx->ohci->lock, flags); 1636 + 1637 + // Timestamping on behalf of the hardware. 1638 + packet->timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ctx->ohci)); 1639 + 1640 1640 handle_local_request(ctx, packet); 1641 1641 return; 1642 1642 } ··· 1648 1640 ret = at_context_queue_packet(ctx, packet); 1649 1641 spin_unlock_irqrestore(&ctx->ohci->lock, flags); 1650 1642 1651 - if (ret < 0) 1652 - packet->callback(packet, &ctx->ohci->card, packet->ack); 1643 + if (ret < 0) { 1644 + // Timestamping on behalf of the hardware. 1645 + packet->timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ctx->ohci)); 1653 1646 1647 + packet->callback(packet, &ctx->ohci->card, packet->ack); 1648 + } 1654 1649 } 1655 1650 1656 1651 static void detect_dead_context(struct fw_ohci *ohci, ··· 2055 2044 spin_unlock_irq(&ohci->lock); 2056 2045 2057 2046 if (free_rom) 2058 - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2059 - free_rom, free_rom_bus); 2047 + dmam_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, free_rom, free_rom_bus); 2060 2048 2061 2049 log_selfids(ohci, generation, self_id_count); 2062 2050 ··· 2387 2377 */ 2388 2378 2389 2379 if (config_rom) { 2390 - ohci->next_config_rom = 2391 - dma_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2392 - &ohci->next_config_rom_bus, 2393 - GFP_KERNEL); 2380 + ohci->next_config_rom = dmam_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2381 + &ohci->next_config_rom_bus, GFP_KERNEL); 2394 2382 if (ohci->next_config_rom == NULL) 2395 2383 return -ENOMEM; 2396 2384 ··· 2480 2472 * ohci->next_config_rom to NULL (see bus_reset_work). 2481 2473 */ 2482 2474 2483 - next_config_rom = 2484 - dma_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2485 - &next_config_rom_bus, GFP_KERNEL); 2475 + next_config_rom = dmam_alloc_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2476 + &next_config_rom_bus, GFP_KERNEL); 2486 2477 if (next_config_rom == NULL) 2487 2478 return -ENOMEM; 2488 2479 ··· 2514 2507 spin_unlock_irq(&ohci->lock); 2515 2508 2516 2509 /* If we didn't use the DMA allocation, delete it. */ 2517 - if (next_config_rom != NULL) 2518 - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 2519 - next_config_rom, next_config_rom_bus); 2510 + if (next_config_rom != NULL) { 2511 + dmam_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, next_config_rom, 2512 + next_config_rom_bus); 2513 + } 2520 2514 2521 2515 /* 2522 2516 * Now initiate a bus reset to have the changes take ··· 2565 2557 log_ar_at_event(ohci, 'T', packet->speed, packet->header, 0x20); 2566 2558 driver_data->packet = NULL; 2567 2559 packet->ack = RCODE_CANCELLED; 2560 + 2561 + // Timestamping on behalf of the hardware. 2562 + packet->timestamp = cycle_time_to_ohci_tstamp(get_cycle_time(ohci)); 2563 + 2568 2564 packet->callback(packet, &ohci->card, packet->ack); 2569 2565 ret = 0; 2570 2566 out: ··· 3556 3544 static inline void pmac_ohci_off(struct pci_dev *dev) {} 3557 3545 #endif /* CONFIG_PPC_PMAC */ 3558 3546 3547 + static void release_ohci(struct device *dev, void *data) 3548 + { 3549 + struct pci_dev *pdev = to_pci_dev(dev); 3550 + struct fw_ohci *ohci = pci_get_drvdata(pdev); 3551 + 3552 + pmac_ohci_off(pdev); 3553 + 3554 + ar_context_release(&ohci->ar_response_ctx); 3555 + ar_context_release(&ohci->ar_request_ctx); 3556 + 3557 + dev_notice(dev, "removed fw-ohci device\n"); 3558 + } 3559 + 3559 3560 static int pci_probe(struct pci_dev *dev, 3560 3561 const struct pci_device_id *ent) 3561 3562 { ··· 3583 3558 return -ENOSYS; 3584 3559 } 3585 3560 3586 - ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); 3587 - if (ohci == NULL) { 3588 - err = -ENOMEM; 3589 - goto fail; 3590 - } 3591 - 3561 + ohci = devres_alloc(release_ohci, sizeof(*ohci), GFP_KERNEL); 3562 + if (ohci == NULL) 3563 + return -ENOMEM; 3592 3564 fw_card_initialize(&ohci->card, &ohci_driver, &dev->dev); 3593 - 3565 + pci_set_drvdata(dev, ohci); 3594 3566 pmac_ohci_on(dev); 3567 + devres_add(&dev->dev, ohci); 3595 3568 3596 - err = pci_enable_device(dev); 3569 + err = pcim_enable_device(dev); 3597 3570 if (err) { 3598 3571 dev_err(&dev->dev, "failed to enable OHCI hardware\n"); 3599 - goto fail_free; 3572 + return err; 3600 3573 } 3601 3574 3602 3575 pci_set_master(dev); 3603 3576 pci_write_config_dword(dev, OHCI1394_PCI_HCI_Control, 0); 3604 - pci_set_drvdata(dev, ohci); 3605 3577 3606 3578 spin_lock_init(&ohci->lock); 3607 3579 mutex_init(&ohci->phy_reg_mutex); ··· 3608 3586 if (!(pci_resource_flags(dev, 0) & IORESOURCE_MEM) || 3609 3587 pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) { 3610 3588 ohci_err(ohci, "invalid MMIO resource\n"); 3611 - err = -ENXIO; 3612 - goto fail_disable; 3589 + return -ENXIO; 3613 3590 } 3614 3591 3615 - err = pci_request_region(dev, 0, ohci_driver_name); 3592 + err = pcim_iomap_regions(dev, 1 << 0, ohci_driver_name); 3616 3593 if (err) { 3617 - ohci_err(ohci, "MMIO resource unavailable\n"); 3618 - goto fail_disable; 3594 + ohci_err(ohci, "request and map MMIO resource unavailable\n"); 3595 + return -ENXIO; 3619 3596 } 3620 - 3621 - ohci->registers = pci_iomap(dev, 0, OHCI1394_REGISTER_SIZE); 3622 - if (ohci->registers == NULL) { 3623 - ohci_err(ohci, "failed to remap registers\n"); 3624 - err = -ENXIO; 3625 - goto fail_iomem; 3626 - } 3597 + ohci->registers = pcim_iomap_table(dev)[0]; 3627 3598 3628 3599 for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) 3629 3600 if ((ohci_quirks[i].vendor == dev->vendor) && ··· 3637 3622 */ 3638 3623 BUILD_BUG_ON(AR_BUFFERS * sizeof(struct descriptor) > PAGE_SIZE/4); 3639 3624 BUILD_BUG_ON(SELF_ID_BUF_SIZE > PAGE_SIZE/2); 3640 - ohci->misc_buffer = dma_alloc_coherent(ohci->card.device, 3641 - PAGE_SIZE, 3642 - &ohci->misc_buffer_bus, 3643 - GFP_KERNEL); 3644 - if (!ohci->misc_buffer) { 3645 - err = -ENOMEM; 3646 - goto fail_iounmap; 3647 - } 3625 + ohci->misc_buffer = dmam_alloc_coherent(&dev->dev, PAGE_SIZE, &ohci->misc_buffer_bus, 3626 + GFP_KERNEL); 3627 + if (!ohci->misc_buffer) 3628 + return -ENOMEM; 3648 3629 3649 3630 err = ar_context_init(&ohci->ar_request_ctx, ohci, 0, 3650 3631 OHCI1394_AsReqRcvContextControlSet); 3651 3632 if (err < 0) 3652 - goto fail_misc_buf; 3633 + return err; 3653 3634 3654 3635 err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4, 3655 3636 OHCI1394_AsRspRcvContextControlSet); 3656 3637 if (err < 0) 3657 - goto fail_arreq_ctx; 3638 + return err; 3658 3639 3659 3640 err = context_init(&ohci->at_request_ctx, ohci, 3660 3641 OHCI1394_AsReqTrContextControlSet, handle_at_packet); 3661 3642 if (err < 0) 3662 - goto fail_arrsp_ctx; 3643 + return err; 3663 3644 3664 3645 err = context_init(&ohci->at_response_ctx, ohci, 3665 3646 OHCI1394_AsRspTrContextControlSet, handle_at_packet); 3666 3647 if (err < 0) 3667 - goto fail_atreq_ctx; 3648 + return err; 3668 3649 3669 3650 reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); 3670 3651 ohci->ir_context_channels = ~0ULL; ··· 3669 3658 ohci->ir_context_mask = ohci->ir_context_support; 3670 3659 ohci->n_ir = hweight32(ohci->ir_context_mask); 3671 3660 size = sizeof(struct iso_context) * ohci->n_ir; 3672 - ohci->ir_context_list = kzalloc(size, GFP_KERNEL); 3661 + ohci->ir_context_list = devm_kzalloc(&dev->dev, size, GFP_KERNEL); 3662 + if (!ohci->ir_context_list) 3663 + return -ENOMEM; 3673 3664 3674 3665 reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); 3675 3666 ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); ··· 3684 3671 ohci->it_context_mask = ohci->it_context_support; 3685 3672 ohci->n_it = hweight32(ohci->it_context_mask); 3686 3673 size = sizeof(struct iso_context) * ohci->n_it; 3687 - ohci->it_context_list = kzalloc(size, GFP_KERNEL); 3688 - 3689 - if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { 3690 - err = -ENOMEM; 3691 - goto fail_contexts; 3692 - } 3674 + ohci->it_context_list = devm_kzalloc(&dev->dev, size, GFP_KERNEL); 3675 + if (!ohci->it_context_list) 3676 + return -ENOMEM; 3693 3677 3694 3678 ohci->self_id = ohci->misc_buffer + PAGE_SIZE/2; 3695 3679 ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2; ··· 3699 3689 3700 3690 if (!(ohci->quirks & QUIRK_NO_MSI)) 3701 3691 pci_enable_msi(dev); 3702 - if (request_irq(dev->irq, irq_handler, 3703 - pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED, 3704 - ohci_driver_name, ohci)) { 3692 + err = devm_request_irq(&dev->dev, dev->irq, irq_handler, 3693 + pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED, ohci_driver_name, ohci); 3694 + if (err < 0) { 3705 3695 ohci_err(ohci, "failed to allocate interrupt %d\n", dev->irq); 3706 - err = -EIO; 3707 3696 goto fail_msi; 3708 3697 } 3709 3698 3710 3699 err = fw_card_add(&ohci->card, max_receive, link_speed, guid); 3711 3700 if (err) 3712 - goto fail_irq; 3701 + goto fail_msi; 3713 3702 3714 3703 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; 3715 3704 ohci_notice(ohci, ··· 3721 3712 3722 3713 return 0; 3723 3714 3724 - fail_irq: 3725 - free_irq(dev->irq, ohci); 3726 3715 fail_msi: 3727 3716 pci_disable_msi(dev); 3728 - fail_contexts: 3729 - kfree(ohci->ir_context_list); 3730 - kfree(ohci->it_context_list); 3731 - context_release(&ohci->at_response_ctx); 3732 - fail_atreq_ctx: 3733 - context_release(&ohci->at_request_ctx); 3734 - fail_arrsp_ctx: 3735 - ar_context_release(&ohci->ar_response_ctx); 3736 - fail_arreq_ctx: 3737 - ar_context_release(&ohci->ar_request_ctx); 3738 - fail_misc_buf: 3739 - dma_free_coherent(ohci->card.device, PAGE_SIZE, 3740 - ohci->misc_buffer, ohci->misc_buffer_bus); 3741 - fail_iounmap: 3742 - pci_iounmap(dev, ohci->registers); 3743 - fail_iomem: 3744 - pci_release_region(dev, 0); 3745 - fail_disable: 3746 - pci_disable_device(dev); 3747 - fail_free: 3748 - kfree(ohci); 3749 - pmac_ohci_off(dev); 3750 - fail: 3717 + 3751 3718 return err; 3752 3719 } 3753 3720 ··· 3748 3763 */ 3749 3764 3750 3765 software_reset(ohci); 3751 - free_irq(dev->irq, ohci); 3752 3766 3753 - if (ohci->next_config_rom && ohci->next_config_rom != ohci->config_rom) 3754 - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 3755 - ohci->next_config_rom, ohci->next_config_rom_bus); 3756 - if (ohci->config_rom) 3757 - dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, 3758 - ohci->config_rom, ohci->config_rom_bus); 3759 - ar_context_release(&ohci->ar_request_ctx); 3760 - ar_context_release(&ohci->ar_response_ctx); 3761 - dma_free_coherent(ohci->card.device, PAGE_SIZE, 3762 - ohci->misc_buffer, ohci->misc_buffer_bus); 3763 - context_release(&ohci->at_request_ctx); 3764 - context_release(&ohci->at_response_ctx); 3765 - kfree(ohci->it_context_list); 3766 - kfree(ohci->ir_context_list); 3767 3767 pci_disable_msi(dev); 3768 - pci_iounmap(dev, ohci->registers); 3769 - pci_release_region(dev, 0); 3770 - pci_disable_device(dev); 3771 - kfree(ohci); 3772 - pmac_ohci_off(dev); 3773 3768 3774 - dev_notice(&dev->dev, "removed fw-ohci device\n"); 3769 + dev_notice(&dev->dev, "removing fw-ohci device\n"); 3775 3770 } 3776 3771 3777 3772 #ifdef CONFIG_PM
+89
drivers/firewire/uapi-test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + // 3 + // uapi_test.c - An application of Kunit to check layout of structures exposed to user space for 4 + // FireWire subsystem. 5 + // 6 + // Copyright (c) 2023 Takashi Sakamoto 7 + 8 + #include <kunit/test.h> 9 + #include <linux/firewire-cdev.h> 10 + 11 + // Known issue added at v2.6.27 kernel. 12 + static void structure_layout_event_response(struct kunit *test) 13 + { 14 + #if defined(CONFIG_X86_32) 15 + // 4 bytes alignment for aggregate type including 8 bytes storage types. 16 + KUNIT_EXPECT_EQ(test, 20, sizeof(struct fw_cdev_event_response)); 17 + #else 18 + // 8 bytes alignment for aggregate type including 8 bytes storage types. 19 + KUNIT_EXPECT_EQ(test, 24, sizeof(struct fw_cdev_event_response)); 20 + #endif 21 + 22 + KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_response, closure)); 23 + KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_response, type)); 24 + KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_response, rcode)); 25 + KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_response, length)); 26 + KUNIT_EXPECT_EQ(test, 20, offsetof(struct fw_cdev_event_response, data)); 27 + } 28 + 29 + // Added at v6.5. 30 + static void structure_layout_event_request3(struct kunit *test) 31 + { 32 + KUNIT_EXPECT_EQ(test, 56, sizeof(struct fw_cdev_event_request3)); 33 + 34 + KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_request3, closure)); 35 + KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_request3, type)); 36 + KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_request3, tcode)); 37 + KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_request3, offset)); 38 + KUNIT_EXPECT_EQ(test, 24, offsetof(struct fw_cdev_event_request3, source_node_id)); 39 + KUNIT_EXPECT_EQ(test, 28, offsetof(struct fw_cdev_event_request3, destination_node_id)); 40 + KUNIT_EXPECT_EQ(test, 32, offsetof(struct fw_cdev_event_request3, card)); 41 + KUNIT_EXPECT_EQ(test, 36, offsetof(struct fw_cdev_event_request3, generation)); 42 + KUNIT_EXPECT_EQ(test, 40, offsetof(struct fw_cdev_event_request3, handle)); 43 + KUNIT_EXPECT_EQ(test, 44, offsetof(struct fw_cdev_event_request3, length)); 44 + KUNIT_EXPECT_EQ(test, 48, offsetof(struct fw_cdev_event_request3, tstamp)); 45 + KUNIT_EXPECT_EQ(test, 56, offsetof(struct fw_cdev_event_request3, data)); 46 + } 47 + 48 + // Added at v6.5. 49 + static void structure_layout_event_response2(struct kunit *test) 50 + { 51 + KUNIT_EXPECT_EQ(test, 32, sizeof(struct fw_cdev_event_response2)); 52 + 53 + KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_response2, closure)); 54 + KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_response2, type)); 55 + KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_response2, rcode)); 56 + KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_response2, length)); 57 + KUNIT_EXPECT_EQ(test, 20, offsetof(struct fw_cdev_event_response2, request_tstamp)); 58 + KUNIT_EXPECT_EQ(test, 24, offsetof(struct fw_cdev_event_response2, response_tstamp)); 59 + KUNIT_EXPECT_EQ(test, 32, offsetof(struct fw_cdev_event_response2, data)); 60 + } 61 + 62 + // Added at v6.5. 63 + static void structure_layout_event_phy_packet2(struct kunit *test) 64 + { 65 + KUNIT_EXPECT_EQ(test, 24, sizeof(struct fw_cdev_event_phy_packet2)); 66 + 67 + KUNIT_EXPECT_EQ(test, 0, offsetof(struct fw_cdev_event_phy_packet2, closure)); 68 + KUNIT_EXPECT_EQ(test, 8, offsetof(struct fw_cdev_event_phy_packet2, type)); 69 + KUNIT_EXPECT_EQ(test, 12, offsetof(struct fw_cdev_event_phy_packet2, rcode)); 70 + KUNIT_EXPECT_EQ(test, 16, offsetof(struct fw_cdev_event_phy_packet2, length)); 71 + KUNIT_EXPECT_EQ(test, 20, offsetof(struct fw_cdev_event_phy_packet2, tstamp)); 72 + KUNIT_EXPECT_EQ(test, 24, offsetof(struct fw_cdev_event_phy_packet2, data)); 73 + } 74 + 75 + static struct kunit_case structure_layout_test_cases[] = { 76 + KUNIT_CASE(structure_layout_event_response), 77 + KUNIT_CASE(structure_layout_event_request3), 78 + KUNIT_CASE(structure_layout_event_response2), 79 + KUNIT_CASE(structure_layout_event_phy_packet2), 80 + {} 81 + }; 82 + 83 + static struct kunit_suite structure_layout_test_suite = { 84 + .name = "firewire-uapi-structure-layout", 85 + .test_cases = structure_layout_test_cases, 86 + }; 87 + kunit_test_suite(structure_layout_test_suite); 88 + 89 + MODULE_LICENSE("GPL");
+77 -5
include/linux/firewire.h
··· 261 261 typedef void (*fw_transaction_callback_t)(struct fw_card *card, int rcode, 262 262 void *data, size_t length, 263 263 void *callback_data); 264 + typedef void (*fw_transaction_callback_with_tstamp_t)(struct fw_card *card, int rcode, 265 + u32 request_tstamp, u32 response_tstamp, void *data, 266 + size_t length, void *callback_data); 267 + 268 + union fw_transaction_callback { 269 + fw_transaction_callback_t without_tstamp; 270 + fw_transaction_callback_with_tstamp_t with_tstamp; 271 + }; 272 + 264 273 /* 265 274 * This callback handles an inbound request subaction. It is called in 266 275 * RCU read-side context, therefore must not sleep. ··· 321 312 struct fw_card *card; 322 313 bool is_split_transaction; 323 314 struct timer_list split_timeout_timer; 315 + u32 split_timeout_cycle; 324 316 325 317 struct fw_packet packet; 326 318 ··· 329 319 * The data passed to the callback is valid only during the 330 320 * callback. 331 321 */ 332 - fw_transaction_callback_t callback; 322 + union fw_transaction_callback callback; 323 + bool with_tstamp; 333 324 void *callback_data; 334 325 }; 335 326 ··· 356 345 struct fw_request *request, int rcode); 357 346 int fw_get_request_speed(struct fw_request *request); 358 347 u32 fw_request_get_timestamp(const struct fw_request *request); 359 - void fw_send_request(struct fw_card *card, struct fw_transaction *t, 360 - int tcode, int destination_id, int generation, int speed, 361 - unsigned long long offset, void *payload, size_t length, 362 - fw_transaction_callback_t callback, void *callback_data); 348 + 349 + void __fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, 350 + int destination_id, int generation, int speed, unsigned long long offset, 351 + void *payload, size_t length, union fw_transaction_callback callback, 352 + bool with_tstamp, void *callback_data); 353 + 354 + /** 355 + * fw_send_request() - submit a request packet for transmission to generate callback for response 356 + * subaction without time stamp. 357 + * @card: interface to send the request at 358 + * @t: transaction instance to which the request belongs 359 + * @tcode: transaction code 360 + * @destination_id: destination node ID, consisting of bus_ID and phy_ID 361 + * @generation: bus generation in which request and response are valid 362 + * @speed: transmission speed 363 + * @offset: 48bit wide offset into destination's address space 364 + * @payload: data payload for the request subaction 365 + * @length: length of the payload, in bytes 366 + * @callback: function to be called when the transaction is completed 367 + * @callback_data: data to be passed to the transaction completion callback 368 + * 369 + * A variation of __fw_send_request() to generate callback for response subaction without time 370 + * stamp. 371 + */ 372 + static inline void fw_send_request(struct fw_card *card, struct fw_transaction *t, int tcode, 373 + int destination_id, int generation, int speed, 374 + unsigned long long offset, void *payload, size_t length, 375 + fw_transaction_callback_t callback, void *callback_data) 376 + { 377 + union fw_transaction_callback cb = { 378 + .without_tstamp = callback, 379 + }; 380 + __fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload, 381 + length, cb, false, callback_data); 382 + } 383 + 384 + /** 385 + * fw_send_request_with_tstamp() - submit a request packet for transmission to generate callback for 386 + * response with time stamp. 387 + * @card: interface to send the request at 388 + * @t: transaction instance to which the request belongs 389 + * @tcode: transaction code 390 + * @destination_id: destination node ID, consisting of bus_ID and phy_ID 391 + * @generation: bus generation in which request and response are valid 392 + * @speed: transmission speed 393 + * @offset: 48bit wide offset into destination's address space 394 + * @payload: data payload for the request subaction 395 + * @length: length of the payload, in bytes 396 + * @callback: function to be called when the transaction is completed 397 + * @callback_data: data to be passed to the transaction completion callback 398 + * 399 + * A variation of __fw_send_request() to generate callback for response subaction with time stamp. 400 + */ 401 + static inline void fw_send_request_with_tstamp(struct fw_card *card, struct fw_transaction *t, 402 + int tcode, int destination_id, int generation, int speed, unsigned long long offset, 403 + void *payload, size_t length, fw_transaction_callback_with_tstamp_t callback, 404 + void *callback_data) 405 + { 406 + union fw_transaction_callback cb = { 407 + .with_tstamp = callback, 408 + }; 409 + __fw_send_request(card, t, tcode, destination_id, generation, speed, offset, payload, 410 + length, cb, true, callback_data); 411 + } 412 + 363 413 int fw_cancel_transaction(struct fw_card *card, 364 414 struct fw_transaction *transaction); 365 415 int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
+157 -23
include/uapi/linux/firewire-cdev.h
··· 46 46 #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED 0x08 47 47 #define FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL 0x09 48 48 49 + /* available since kernel version 6.5 */ 50 + #define FW_CDEV_EVENT_REQUEST3 0x0a 51 + #define FW_CDEV_EVENT_RESPONSE2 0x0b 52 + #define FW_CDEV_EVENT_PHY_PACKET_SENT2 0x0c 53 + #define FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 0x0d 54 + 49 55 /** 50 56 * struct fw_cdev_event_common - Common part of all fw_cdev_event_* types 51 57 * @closure: For arbitrary use by userspace ··· 109 103 * @length: Data length, i.e. the response's payload size in bytes 110 104 * @data: Payload data, if any 111 105 * 106 + * This event is sent instead of &fw_cdev_event_response if the kernel or the client implements 107 + * ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_response2. 108 + */ 109 + struct fw_cdev_event_response { 110 + __u64 closure; 111 + __u32 type; 112 + __u32 rcode; 113 + __u32 length; 114 + __u32 data[]; 115 + }; 116 + 117 + /** 118 + * struct fw_cdev_event_response2 - Sent when a response packet was received 119 + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_SEND_REQUEST 120 + * or %FW_CDEV_IOC_SEND_BROADCAST_REQUEST 121 + * or %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl 122 + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_RESPONSE 123 + * @rcode: Response code returned by the remote node 124 + * @length: Data length, i.e. the response's payload size in bytes 125 + * @request_tstamp: The time stamp of isochronous cycle at which the request was sent. 126 + * @response_tstamp: The time stamp of isochronous cycle at which the response was sent. 127 + * @padding: Padding to keep the size of structure as multiples of 8 in various architectures 128 + * since 4 byte alignment is used for 8 byte of object type in System V ABI for i386 129 + * architecture. 130 + * @data: Payload data, if any 131 + * 112 132 * This event is sent when the stack receives a response to an outgoing request 113 133 * sent by %FW_CDEV_IOC_SEND_REQUEST ioctl. The payload data for responses 114 134 * carrying data (read and lock responses) follows immediately and can be ··· 144 112 * involve response packets. This includes unified write transactions, 145 113 * broadcast write transactions, and transmission of asynchronous stream 146 114 * packets. @rcode indicates success or failure of such transmissions. 115 + * 116 + * The value of @request_tstamp expresses the isochronous cycle at which the request was sent to 117 + * initiate the transaction. The value of @response_tstamp expresses the isochronous cycle at which 118 + * the response arrived to complete the transaction. Each value is unsigned 16 bit integer 119 + * containing three low order bits of second field and all 13 bits of cycle field in format of 120 + * CYCLE_TIMER register. 147 121 */ 148 - struct fw_cdev_event_response { 122 + struct fw_cdev_event_response2 { 149 123 __u64 closure; 150 124 __u32 type; 151 125 __u32 rcode; 152 126 __u32 length; 127 + __u32 request_tstamp; 128 + __u32 response_tstamp; 129 + __u32 padding; 153 130 __u32 data[]; 154 131 }; 155 132 ··· 200 159 * @length: Data length, i.e. the request's payload size in bytes 201 160 * @data: Incoming data, if any 202 161 * 162 + * This event is sent instead of &fw_cdev_event_request3 if the kernel or the client implements 163 + * ABI version <= 5. It has the lack of time stamp field comparing to &fw_cdev_event_request3. 164 + */ 165 + struct fw_cdev_event_request2 { 166 + __u64 closure; 167 + __u32 type; 168 + __u32 tcode; 169 + __u64 offset; 170 + __u32 source_node_id; 171 + __u32 destination_node_id; 172 + __u32 card; 173 + __u32 generation; 174 + __u32 handle; 175 + __u32 length; 176 + __u32 data[]; 177 + }; 178 + 179 + /** 180 + * struct fw_cdev_event_request3 - Sent on incoming request to an address region 181 + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_ALLOCATE ioctl 182 + * @type: See &fw_cdev_event_common; always %FW_CDEV_EVENT_REQUEST2 183 + * @tcode: Transaction code of the incoming request 184 + * @offset: The offset into the 48-bit per-node address space 185 + * @source_node_id: Sender node ID 186 + * @destination_node_id: Destination node ID 187 + * @card: The index of the card from which the request came 188 + * @generation: Bus generation in which the request is valid 189 + * @handle: Reference to the kernel-side pending request 190 + * @length: Data length, i.e. the request's payload size in bytes 191 + * @tstamp: The time stamp of isochronous cycle at which the request arrived. 192 + * @padding: Padding to keep the size of structure as multiples of 8 in various architectures 193 + * since 4 byte alignment is used for 8 byte of object type in System V ABI for i386 194 + * architecture. 195 + * @data: Incoming data, if any 196 + * 203 197 * This event is sent when the stack receives an incoming request to an address 204 198 * region registered using the %FW_CDEV_IOC_ALLOCATE ioctl. The request is 205 199 * guaranteed to be completely contained in the specified region. Userspace is ··· 267 191 * sent. 268 192 * 269 193 * If the client subsequently needs to initiate requests to the sender node of 270 - * an &fw_cdev_event_request2, it needs to use a device file with matching 194 + * an &fw_cdev_event_request3, it needs to use a device file with matching 271 195 * card index, node ID, and generation for outbound requests. 196 + * 197 + * @tstamp is isochronous cycle at which the request arrived. It is 16 bit integer value and the 198 + * higher 3 bits expresses three low order bits of second field in the format of CYCLE_TIME 199 + * register and the rest 13 bits expresses cycle field. 272 200 */ 273 - struct fw_cdev_event_request2 { 201 + struct fw_cdev_event_request3 { 274 202 __u64 closure; 275 203 __u32 type; 276 204 __u32 tcode; ··· 285 205 __u32 generation; 286 206 __u32 handle; 287 207 __u32 length; 208 + __u32 tstamp; 209 + __u32 padding; 288 210 __u32 data[]; 289 211 }; 290 212 ··· 423 341 * @type: %FW_CDEV_EVENT_PHY_PACKET_SENT or %..._RECEIVED 424 342 * @rcode: %RCODE_..., indicates success or failure of transmission 425 343 * @length: Data length in bytes 426 - * @data: Incoming data 344 + * @data: Incoming data for %FW_CDEV_IOC_RECEIVE_PHY_PACKETS. For %FW_CDEV_IOC_SEND_PHY_PACKET 345 + * the field has the same data in the request, thus the length of 8 bytes. 427 346 * 428 - * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty, 429 - * except in case of a ping packet: Then, @length is 4, and @data[0] is the 430 - * ping time in 49.152MHz clocks if @rcode is %RCODE_COMPLETE. 431 - * 432 - * If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED, @length is 8 and @data 433 - * consists of the two PHY packet quadlets, in host byte order. 347 + * This event is sent instead of &fw_cdev_event_phy_packet2 if the kernel or 348 + * the client implements ABI version <= 5. It has the lack of time stamp field comparing to 349 + * &fw_cdev_event_phy_packet2. 434 350 */ 435 351 struct fw_cdev_event_phy_packet { 436 352 __u64 closure; 437 353 __u32 type; 438 354 __u32 rcode; 439 355 __u32 length; 356 + __u32 data[]; 357 + }; 358 + 359 + /** 360 + * struct fw_cdev_event_phy_packet2 - A PHY packet was transmitted or received with time stamp. 361 + * @closure: See &fw_cdev_event_common; set by %FW_CDEV_IOC_SEND_PHY_PACKET 362 + * or %FW_CDEV_IOC_RECEIVE_PHY_PACKETS ioctl 363 + * @type: %FW_CDEV_EVENT_PHY_PACKET_SENT2 or %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 364 + * @rcode: %RCODE_..., indicates success or failure of transmission 365 + * @length: Data length in bytes 366 + * @tstamp: For %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, the time stamp of isochronous cycle at 367 + * which the packet arrived. For %FW_CDEV_EVENT_PHY_PACKET_SENT2 and non-ping packet, 368 + * the time stamp of isochronous cycle at which the packet was sent. For ping packet, 369 + * the tick count for round-trip time measured by 1394 OHCI controller. 370 + * The time stamp of isochronous cycle at which either the response was sent for 371 + * %FW_CDEV_EVENT_PHY_PACKET_SENT2 or the request arrived for 372 + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2. 373 + * @data: Incoming data 374 + * 375 + * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT2, @length is 8 and @data consists of the two PHY 376 + * packet quadlets to be sent, in host byte order, 377 + * 378 + * If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, @length is 8 and @data consists of the two PHY 379 + * packet quadlets, in host byte order. 380 + * 381 + * For %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2, the @tstamp is the isochronous cycle at which the 382 + * packet arrived. It is 16 bit integer value and the higher 3 bits expresses three low order bits 383 + * of second field and the rest 13 bits expresses cycle field in the format of CYCLE_TIME register. 384 + * 385 + * For %FW_CDEV_EVENT_PHY_PACKET_SENT2, the @tstamp has different meanings whether to sent the 386 + * packet for ping or not. If it's not for ping, the @tstamp is the isochronous cycle at which the 387 + * packet was sent, and use the same format as the case of %FW_CDEV_EVENT_PHY_PACKET_SENT2. If it's 388 + * for ping, the @tstamp is for round-trip time measured by 1394 OHCI controller with 42.195 MHz 389 + * resolution. 390 + */ 391 + struct fw_cdev_event_phy_packet2 { 392 + __u64 closure; 393 + __u32 type; 394 + __u32 rcode; 395 + __u32 length; 396 + __u32 tstamp; 440 397 __u32 data[]; 441 398 }; 442 399 ··· 496 375 * %FW_CDEV_EVENT_PHY_PACKET_SENT or 497 376 * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED 498 377 * 378 + * @request3: Valid if @common.type == %FW_CDEV_EVENT_REQUEST3 379 + * @response2: Valid if @common.type == %FW_CDEV_EVENT_RESPONSE2 380 + * @phy_packet2: Valid if @common.type == %FW_CDEV_EVENT_PHY_PACKET_SENT2 or 381 + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 382 + * 499 383 * Convenience union for userspace use. Events could be read(2) into an 500 384 * appropriately aligned char buffer and then cast to this union for further 501 385 * processing. Note that for a request, response or iso_interrupt event, ··· 519 393 struct fw_cdev_event_iso_interrupt_mc iso_interrupt_mc; /* added in 2.6.36 */ 520 394 struct fw_cdev_event_iso_resource iso_resource; /* added in 2.6.30 */ 521 395 struct fw_cdev_event_phy_packet phy_packet; /* added in 2.6.36 */ 396 + struct fw_cdev_event_request3 request3; /* added in 6.5 */ 397 + struct fw_cdev_event_response2 response2; /* added in 6.5 */ 398 + struct fw_cdev_event_phy_packet2 phy_packet2; /* added in 6.5 */ 522 399 }; 523 400 524 401 /* available since kernel version 2.6.22 */ ··· 586 457 * 5 (3.4) - send %FW_CDEV_EVENT_ISO_INTERRUPT events when needed to 587 458 * avoid dropping data 588 459 * - added %FW_CDEV_IOC_FLUSH_ISO 460 + * 6 (6.5) - added some event for subactions of asynchronous transaction with time stamp 461 + * - %FW_CDEV_EVENT_REQUEST3 462 + * - %FW_CDEV_EVENT_RESPONSE2 463 + * - %FW_CDEV_EVENT_PHY_PACKET_SENT2 464 + * - %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 589 465 */ 590 466 591 467 /** ··· 636 502 * @data: Userspace pointer to payload 637 503 * @generation: The bus generation where packet is valid 638 504 * 639 - * Send a request to the device. This ioctl implements all outgoing requests. 640 - * Both quadlet and block request specify the payload as a pointer to the data 641 - * in the @data field. Once the transaction completes, the kernel writes an 642 - * &fw_cdev_event_response event back. The @closure field is passed back to 643 - * user space in the response event. 505 + * Send a request to the device. This ioctl implements all outgoing requests. Both quadlet and 506 + * block request specify the payload as a pointer to the data in the @data field. Once the 507 + * transaction completes, the kernel writes either &fw_cdev_event_response event or 508 + * &fw_cdev_event_response event back. The @closure field is passed back to user space in the 509 + * response event. 644 510 */ 645 511 struct fw_cdev_send_request { 646 512 __u32 tcode; ··· 1123 989 * @generation: The bus generation where packet is valid 1124 990 * @speed: Speed to transmit at 1125 991 * 1126 - * The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet 1127 - * to every device which is listening to the specified channel. The kernel 1128 - * writes an &fw_cdev_event_response event which indicates success or failure of 1129 - * the transmission. 992 + * The %FW_CDEV_IOC_SEND_STREAM_PACKET ioctl sends an asynchronous stream packet to every device 993 + * which is listening to the specified channel. The kernel writes either &fw_cdev_event_response 994 + * event or &fw_cdev_event_response2 event which indicates success or failure of the transmission. 1130 995 */ 1131 996 struct fw_cdev_send_stream_packet { 1132 997 __u32 length; ··· 1144 1011 * @data: First and second quadlet of the PHY packet 1145 1012 * @generation: The bus generation where packet is valid 1146 1013 * 1147 - * The %FW_CDEV_IOC_SEND_PHY_PACKET ioctl sends a PHY packet to all nodes 1148 - * on the same card as this device. After transmission, an 1014 + * The %FW_CDEV_IOC_SEND_PHY_PACKET ioctl sends a PHY packet to all nodes on the same card as this 1015 + * device. After transmission, either %FW_CDEV_EVENT_PHY_PACKET_SENT event or 1149 1016 * %FW_CDEV_EVENT_PHY_PACKET_SENT event is generated. 1150 1017 * 1151 1018 * The payload @data\[\] shall be specified in host byte order. Usually, ··· 1164 1031 * struct fw_cdev_receive_phy_packets - start reception of PHY packets 1165 1032 * @closure: Passed back to userspace in phy packet events 1166 1033 * 1167 - * This ioctl activates issuing of %FW_CDEV_EVENT_PHY_PACKET_RECEIVED due to 1168 - * incoming PHY packets from any node on the same bus as the device. 1034 + * This ioctl activates issuing of either %FW_CDEV_EVENT_PHY_PACKET_RECEIVED or 1035 + * %FW_CDEV_EVENT_PHY_PACKET_RECEIVED2 due to incoming PHY packets from any node on the same bus 1036 + * as the device. 1169 1037 * 1170 1038 * The ioctl is only permitted on device files which represent a local node. 1171 1039 */