···487487};488488489489static int490490+handle_request_packet(uint32_t *data, size_t length)491491+{492492+ struct link_packet *p = (struct link_packet *) data;493493+ struct subaction *sa, *prev;494494+ struct link_transaction *t;495495+496496+ t = link_transaction_lookup(p->common.source, p->common.destination,497497+ p->common.tlabel);498498+ sa = subaction_create(data, length);499499+ t->request = sa;500500+501501+ if (!list_empty(&t->request_list)) {502502+ prev = list_tail(&t->request_list,503503+ struct subaction, link);504504+505505+ if (!ACK_BUSY(prev->ack)) {506506+ /*507507+ * error, we should only see ack_busy_* before the508508+ * ack_pending/ack_complete -- this is an ack_pending509509+ * instead (ack_complete would have finished the510510+ * transaction).511511+ */512512+ }513513+514514+ if (prev->packet.common.tcode != sa->packet.common.tcode ||515515+ prev->packet.common.tlabel != sa->packet.common.tlabel) {516516+ /* memcmp() ? */517517+ /* error, these should match for retries. */518518+ }519519+ }520520+521521+ list_append(&t->request_list, &sa->link);522522+523523+ switch (sa->ack) {524524+ case ACK_COMPLETE:525525+ if (p->common.tcode != TCODE_WRITE_QUADLET &&526526+ p->common.tcode != TCODE_WRITE_BLOCK)527527+ /* error, unified transactions only allowed for write */;528528+ list_remove(&t->link);529529+ handle_transaction(t);530530+ break;531531+532532+ case ACK_NO_ACK:533533+ case ACK_DATA_ERROR:534534+ case ACK_TYPE_ERROR:535535+ list_remove(&t->link);536536+ handle_transaction(t);537537+ break;538538+539539+ case ACK_PENDING:540540+ /* request subaction phase over, wait for response. */541541+ break;542542+543543+ case ACK_BUSY_X:544544+ case ACK_BUSY_A:545545+ case ACK_BUSY_B:546546+ /* ok, wait for retry. */547547+ /* check that retry protocol is respected. */548548+ break;549549+ }550550+551551+ return 1;552552+}553553+554554+static int555555+handle_response_packet(uint32_t *data, size_t length)556556+{557557+ struct link_packet *p = (struct link_packet *) data;558558+ struct subaction *sa, *prev;559559+ struct link_transaction *t;560560+561561+ t = link_transaction_lookup(p->common.destination, p->common.source,562562+ p->common.tlabel);563563+ if (list_empty(&t->request_list)) {564564+ /* unsolicited response */565565+ }566566+567567+ sa = subaction_create(data, length);568568+ t->response = sa;569569+570570+ if (!list_empty(&t->response_list)) {571571+ prev = list_tail(&t->response_list, struct subaction, link);572572+573573+ if (!ACK_BUSY(prev->ack)) {574574+ /*575575+ * error, we should only see ack_busy_* before the576576+ * ack_pending/ack_complete577577+ */578578+ }579579+580580+ if (prev->packet.common.tcode != sa->packet.common.tcode ||581581+ prev->packet.common.tlabel != sa->packet.common.tlabel) {582582+ /* use memcmp() instead? */583583+ /* error, these should match for retries. */584584+ }585585+ } else {586586+ prev = list_tail(&t->request_list, struct subaction, link);587587+ if (prev->ack != ACK_PENDING) {588588+ /*589589+ * error, should not get response unless last request got590590+ * ack_pending.591591+ */592592+ }593593+594594+ if (packet_info[prev->packet.common.tcode].response_tcode !=595595+ sa->packet.common.tcode) {596596+ /* error, tcode mismatch */597597+ }598598+ }599599+600600+ list_append(&t->response_list, &sa->link);601601+602602+ switch (sa->ack) {603603+ case ACK_COMPLETE:604604+ case ACK_NO_ACK:605605+ case ACK_DATA_ERROR:606606+ case ACK_TYPE_ERROR:607607+ list_remove(&t->link);608608+ handle_transaction(t);609609+ /* transaction complete, remove t from pending list. */610610+ break;611611+612612+ case ACK_PENDING:613613+ /* error for responses. */614614+ break;615615+616616+ case ACK_BUSY_X:617617+ case ACK_BUSY_A:618618+ case ACK_BUSY_B:619619+ /* no problem, wait for next retry */620620+ break;621621+ }622622+623623+ return 1;624624+}625625+626626+static int490627handle_packet(uint32_t *data, size_t length)491628{492629 if (length == 0) {···631494 clear_pending_transaction_list();632495 } else if (length > sizeof(struct phy_packet)) {633496 struct link_packet *p = (struct link_packet *) data;634634- struct subaction *sa, *prev;635635- struct link_transaction *t;636497637498 switch (packet_info[p->common.tcode].type) {638499 case PACKET_REQUEST:639639- t = link_transaction_lookup(p->common.source, p->common.destination,640640- p->common.tlabel);641641- sa = subaction_create(data, length);642642- t->request = sa;643643-644644- if (!list_empty(&t->request_list)) {645645- prev = list_tail(&t->request_list,646646- struct subaction, link);647647-648648- if (!ACK_BUSY(prev->ack)) {649649- /*650650- * error, we should only see ack_busy_* before the651651- * ack_pending/ack_complete -- this is an ack_pending652652- * instead (ack_complete would have finished the653653- * transaction).654654- */655655- }656656-657657- if (prev->packet.common.tcode != sa->packet.common.tcode ||658658- prev->packet.common.tlabel != sa->packet.common.tlabel) {659659- /* memcmp() ? */660660- /* error, these should match for retries. */661661- }662662- }663663-664664- list_append(&t->request_list, &sa->link);665665-666666- switch (sa->ack) {667667- case ACK_COMPLETE:668668- if (p->common.tcode != TCODE_WRITE_QUADLET &&669669- p->common.tcode != TCODE_WRITE_BLOCK)670670- /* error, unified transactions only allowed for write */;671671- list_remove(&t->link);672672- handle_transaction(t);673673- break;674674-675675- case ACK_NO_ACK:676676- case ACK_DATA_ERROR:677677- case ACK_TYPE_ERROR:678678- list_remove(&t->link);679679- handle_transaction(t);680680- break;681681-682682- case ACK_PENDING:683683- /* request subaction phase over, wait for response. */684684- break;685685-686686- case ACK_BUSY_X:687687- case ACK_BUSY_A:688688- case ACK_BUSY_B:689689- /* ok, wait for retry. */690690- /* check that retry protocol is respected. */691691- break;692692- }693693- break;500500+ return handle_request_packet(data, length);694501695502 case PACKET_RESPONSE:696696- t = link_transaction_lookup(p->common.destination, p->common.source,697697- p->common.tlabel);698698- if (list_empty(&t->request_list)) {699699- /* unsolicited response */700700- }701701-702702- sa = subaction_create(data, length);703703- t->response = sa;704704-705705- if (!list_empty(&t->response_list)) {706706- prev = list_tail(&t->response_list, struct subaction, link);707707-708708- if (!ACK_BUSY(prev->ack)) {709709- /*710710- * error, we should only see ack_busy_* before the711711- * ack_pending/ack_complete712712- */713713- }714714-715715- if (prev->packet.common.tcode != sa->packet.common.tcode ||716716- prev->packet.common.tlabel != sa->packet.common.tlabel) {717717- /* use memcmp() instead? */718718- /* error, these should match for retries. */719719- }720720- } else {721721- prev = list_tail(&t->request_list, struct subaction, link);722722- if (prev->ack != ACK_PENDING) {723723- /*724724- * error, should not get response unless last request got725725- * ack_pending.726726- */727727- }728728-729729- if (packet_info[prev->packet.common.tcode].response_tcode !=730730- sa->packet.common.tcode) {731731- /* error, tcode mismatch */732732- }733733- }734734-735735- list_append(&t->response_list, &sa->link);736736-737737- switch (sa->ack) {738738- case ACK_COMPLETE:739739- case ACK_NO_ACK:740740- case ACK_DATA_ERROR:741741- case ACK_TYPE_ERROR:742742- list_remove(&t->link);743743- handle_transaction(t);744744- /* transaction complete, remove t from pending list. */745745- break;746746-747747- case ACK_PENDING:748748- /* error for responses. */749749- break;750750-751751- case ACK_BUSY_X:752752- case ACK_BUSY_A:753753- case ACK_BUSY_B:754754- /* no problem, wait for next retry */755755- break;756756- }757757-758758- break;503503+ return handle_response_packet(data, length);759504760505 case PACKET_OTHER:761506 case PACKET_RESERVED: