···487};488489static int00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000490handle_packet(uint32_t *data, size_t length)491{492 if (length == 0) {···631 clear_pending_transaction_list();632 } else if (length > sizeof(struct phy_packet)) {633 struct link_packet *p = (struct link_packet *) data;634- struct subaction *sa, *prev;635- struct link_transaction *t;636637 switch (packet_info[p->common.tcode].type) {638 case PACKET_REQUEST:639- t = link_transaction_lookup(p->common.source, p->common.destination,640- p->common.tlabel);641- sa = subaction_create(data, length);642- t->request = sa;643-644- if (!list_empty(&t->request_list)) {645- prev = list_tail(&t->request_list,646- struct subaction, link);647-648- if (!ACK_BUSY(prev->ack)) {649- /*650- * error, we should only see ack_busy_* before the651- * ack_pending/ack_complete -- this is an ack_pending652- * instead (ack_complete would have finished the653- * transaction).654- */655- }656-657- if (prev->packet.common.tcode != sa->packet.common.tcode ||658- prev->packet.common.tlabel != sa->packet.common.tlabel) {659- /* memcmp() ? */660- /* error, these should match for retries. */661- }662- }663-664- list_append(&t->request_list, &sa->link);665-666- switch (sa->ack) {667- case ACK_COMPLETE:668- if (p->common.tcode != TCODE_WRITE_QUADLET &&669- p->common.tcode != TCODE_WRITE_BLOCK)670- /* error, unified transactions only allowed for write */;671- list_remove(&t->link);672- handle_transaction(t);673- break;674-675- case ACK_NO_ACK:676- case ACK_DATA_ERROR:677- case ACK_TYPE_ERROR:678- list_remove(&t->link);679- handle_transaction(t);680- break;681-682- case ACK_PENDING:683- /* request subaction phase over, wait for response. */684- break;685-686- case ACK_BUSY_X:687- case ACK_BUSY_A:688- case ACK_BUSY_B:689- /* ok, wait for retry. */690- /* check that retry protocol is respected. */691- break;692- }693- break;694695 case PACKET_RESPONSE:696- t = link_transaction_lookup(p->common.destination, p->common.source,697- p->common.tlabel);698- if (list_empty(&t->request_list)) {699- /* unsolicited response */700- }701-702- sa = subaction_create(data, length);703- t->response = sa;704-705- if (!list_empty(&t->response_list)) {706- prev = list_tail(&t->response_list, struct subaction, link);707-708- if (!ACK_BUSY(prev->ack)) {709- /*710- * error, we should only see ack_busy_* before the711- * ack_pending/ack_complete712- */713- }714-715- if (prev->packet.common.tcode != sa->packet.common.tcode ||716- prev->packet.common.tlabel != sa->packet.common.tlabel) {717- /* use memcmp() instead? */718- /* error, these should match for retries. */719- }720- } else {721- prev = list_tail(&t->request_list, struct subaction, link);722- if (prev->ack != ACK_PENDING) {723- /*724- * error, should not get response unless last request got725- * ack_pending.726- */727- }728-729- if (packet_info[prev->packet.common.tcode].response_tcode !=730- sa->packet.common.tcode) {731- /* error, tcode mismatch */732- }733- }734-735- list_append(&t->response_list, &sa->link);736-737- switch (sa->ack) {738- case ACK_COMPLETE:739- case ACK_NO_ACK:740- case ACK_DATA_ERROR:741- case ACK_TYPE_ERROR:742- list_remove(&t->link);743- handle_transaction(t);744- /* transaction complete, remove t from pending list. */745- break;746-747- case ACK_PENDING:748- /* error for responses. */749- break;750-751- case ACK_BUSY_X:752- case ACK_BUSY_A:753- case ACK_BUSY_B:754- /* no problem, wait for next retry */755- break;756- }757-758- break;759760 case PACKET_OTHER:761 case PACKET_RESERVED:
···487};488489static int490+handle_request_packet(uint32_t *data, size_t length)491+{492+ struct link_packet *p = (struct link_packet *) data;493+ struct subaction *sa, *prev;494+ struct link_transaction *t;495+496+ t = link_transaction_lookup(p->common.source, p->common.destination,497+ p->common.tlabel);498+ sa = subaction_create(data, length);499+ t->request = sa;500+501+ if (!list_empty(&t->request_list)) {502+ prev = list_tail(&t->request_list,503+ struct subaction, link);504+505+ if (!ACK_BUSY(prev->ack)) {506+ /*507+ * error, we should only see ack_busy_* before the508+ * ack_pending/ack_complete -- this is an ack_pending509+ * instead (ack_complete would have finished the510+ * transaction).511+ */512+ }513+514+ if (prev->packet.common.tcode != sa->packet.common.tcode ||515+ prev->packet.common.tlabel != sa->packet.common.tlabel) {516+ /* memcmp() ? */517+ /* error, these should match for retries. */518+ }519+ }520+521+ list_append(&t->request_list, &sa->link);522+523+ switch (sa->ack) {524+ case ACK_COMPLETE:525+ if (p->common.tcode != TCODE_WRITE_QUADLET &&526+ p->common.tcode != TCODE_WRITE_BLOCK)527+ /* error, unified transactions only allowed for write */;528+ list_remove(&t->link);529+ handle_transaction(t);530+ break;531+532+ case ACK_NO_ACK:533+ case ACK_DATA_ERROR:534+ case ACK_TYPE_ERROR:535+ list_remove(&t->link);536+ handle_transaction(t);537+ break;538+539+ case ACK_PENDING:540+ /* request subaction phase over, wait for response. */541+ break;542+543+ case ACK_BUSY_X:544+ case ACK_BUSY_A:545+ case ACK_BUSY_B:546+ /* ok, wait for retry. */547+ /* check that retry protocol is respected. */548+ break;549+ }550+551+ return 1;552+}553+554+static int555+handle_response_packet(uint32_t *data, size_t length)556+{557+ struct link_packet *p = (struct link_packet *) data;558+ struct subaction *sa, *prev;559+ struct link_transaction *t;560+561+ t = link_transaction_lookup(p->common.destination, p->common.source,562+ p->common.tlabel);563+ if (list_empty(&t->request_list)) {564+ /* unsolicited response */565+ }566+567+ sa = subaction_create(data, length);568+ t->response = sa;569+570+ if (!list_empty(&t->response_list)) {571+ prev = list_tail(&t->response_list, struct subaction, link);572+573+ if (!ACK_BUSY(prev->ack)) {574+ /*575+ * error, we should only see ack_busy_* before the576+ * ack_pending/ack_complete577+ */578+ }579+580+ if (prev->packet.common.tcode != sa->packet.common.tcode ||581+ prev->packet.common.tlabel != sa->packet.common.tlabel) {582+ /* use memcmp() instead? */583+ /* error, these should match for retries. */584+ }585+ } else {586+ prev = list_tail(&t->request_list, struct subaction, link);587+ if (prev->ack != ACK_PENDING) {588+ /*589+ * error, should not get response unless last request got590+ * ack_pending.591+ */592+ }593+594+ if (packet_info[prev->packet.common.tcode].response_tcode !=595+ sa->packet.common.tcode) {596+ /* error, tcode mismatch */597+ }598+ }599+600+ list_append(&t->response_list, &sa->link);601+602+ switch (sa->ack) {603+ case ACK_COMPLETE:604+ case ACK_NO_ACK:605+ case ACK_DATA_ERROR:606+ case ACK_TYPE_ERROR:607+ list_remove(&t->link);608+ handle_transaction(t);609+ /* transaction complete, remove t from pending list. */610+ break;611+612+ case ACK_PENDING:613+ /* error for responses. */614+ break;615+616+ case ACK_BUSY_X:617+ case ACK_BUSY_A:618+ case ACK_BUSY_B:619+ /* no problem, wait for next retry */620+ break;621+ }622+623+ return 1;624+}625+626+static int627handle_packet(uint32_t *data, size_t length)628{629 if (length == 0) {···494 clear_pending_transaction_list();495 } else if (length > sizeof(struct phy_packet)) {496 struct link_packet *p = (struct link_packet *) data;00497498 switch (packet_info[p->common.tcode].type) {499 case PACKET_REQUEST:500+ return handle_request_packet(data, length);000000000000000000000000000000000000000000000000000000501502 case PACKET_RESPONSE:503+ return handle_response_packet(data, length);00000000000000000000000000000000000000000000000000000000000000504505 case PACKET_OTHER:506 case PACKET_RESERVED: