aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ieee1394/ieee1394_core.c91
1 files changed, 41 insertions, 50 deletions
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index d2240a4a1c22..b368958dc06c 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -859,12 +859,9 @@ static void fill_async_lock_resp(struct hpsb_packet *packet, int rcode, int extc
859 packet->data_size = length; 859 packet->data_size = length;
860} 860}
861 861
862#define PREP_REPLY_PACKET(length) \
863 packet = create_reply_packet(host, data, length); \
864 if (packet == NULL) break
865
866static void handle_incoming_packet(struct hpsb_host *host, int tcode, 862static void handle_incoming_packet(struct hpsb_host *host, int tcode,
867 quadlet_t *data, size_t size, int write_acked) 863 quadlet_t *data, size_t size,
864 int write_acked)
868{ 865{
869 struct hpsb_packet *packet; 866 struct hpsb_packet *packet;
870 int length, rcode, extcode; 867 int length, rcode, extcode;
@@ -874,74 +871,72 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
874 u16 flags = (u16) data[0]; 871 u16 flags = (u16) data[0];
875 u64 addr; 872 u64 addr;
876 873
877 /* big FIXME - no error checking is done for an out of bounds length */ 874 /* FIXME?
875 * Out-of-bounds lengths are left for highlevel_read|write to cap. */
878 876
879 switch (tcode) { 877 switch (tcode) {
880 case TCODE_WRITEQ: 878 case TCODE_WRITEQ:
881 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; 879 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
882 rcode = highlevel_write(host, source, dest, data+3, 880 rcode = highlevel_write(host, source, dest, data + 3,
883 addr, 4, flags); 881 addr, 4, flags);
884 882 goto handle_write_request;
885 if (!write_acked
886 && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK)
887 && (rcode >= 0)) {
888 /* not a broadcast write, reply */
889 PREP_REPLY_PACKET(0);
890 fill_async_write_resp(packet, rcode);
891 send_packet_nocare(packet);
892 }
893 break;
894 883
895 case TCODE_WRITEB: 884 case TCODE_WRITEB:
896 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; 885 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
897 rcode = highlevel_write(host, source, dest, data+4, 886 rcode = highlevel_write(host, source, dest, data + 4,
898 addr, data[3]>>16, flags); 887 addr, data[3] >> 16, flags);
899 888handle_write_request:
900 if (!write_acked 889 if (rcode < 0 || write_acked ||
901 && (NODEID_TO_NODE(data[0] >> 16) != NODE_MASK) 890 NODEID_TO_NODE(data[0] >> 16) == NODE_MASK)
902 && (rcode >= 0)) { 891 return;
903 /* not a broadcast write, reply */ 892 /* not a broadcast write, reply */
904 PREP_REPLY_PACKET(0); 893 packet = create_reply_packet(host, data, 0);
894 if (packet) {
905 fill_async_write_resp(packet, rcode); 895 fill_async_write_resp(packet, rcode);
906 send_packet_nocare(packet); 896 send_packet_nocare(packet);
907 } 897 }
908 break; 898 return;
909 899
910 case TCODE_READQ: 900 case TCODE_READQ:
911 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; 901 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
912 rcode = highlevel_read(host, source, &buffer, addr, 4, flags); 902 rcode = highlevel_read(host, source, &buffer, addr, 4, flags);
903 if (rcode < 0)
904 return;
913 905
914 if (rcode >= 0) { 906 packet = create_reply_packet(host, data, 0);
915 PREP_REPLY_PACKET(0); 907 if (packet) {
916 fill_async_readquad_resp(packet, rcode, buffer); 908 fill_async_readquad_resp(packet, rcode, buffer);
917 send_packet_nocare(packet); 909 send_packet_nocare(packet);
918 } 910 }
919 break; 911 return;
920 912
921 case TCODE_READB: 913 case TCODE_READB:
922 length = data[3] >> 16; 914 length = data[3] >> 16;
923 PREP_REPLY_PACKET(length); 915 packet = create_reply_packet(host, data, length);
916 if (!packet)
917 return;
924 918
925 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; 919 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
926 rcode = highlevel_read(host, source, packet->data, addr, 920 rcode = highlevel_read(host, source, packet->data, addr,
927 length, flags); 921 length, flags);
928 922 if (rcode < 0) {
929 if (rcode >= 0) {
930 fill_async_readblock_resp(packet, rcode, length);
931 send_packet_nocare(packet);
932 } else {
933 hpsb_free_packet(packet); 923 hpsb_free_packet(packet);
924 return;
934 } 925 }
935 break; 926 fill_async_readblock_resp(packet, rcode, length);
927 send_packet_nocare(packet);
928 return;
936 929
937 case TCODE_LOCK_REQUEST: 930 case TCODE_LOCK_REQUEST:
938 length = data[3] >> 16; 931 length = data[3] >> 16;
939 extcode = data[3] & 0xffff; 932 extcode = data[3] & 0xffff;
940 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2]; 933 addr = (((u64)(data[1] & 0xffff)) << 32) | data[2];
941 934
942 PREP_REPLY_PACKET(8); 935 packet = create_reply_packet(host, data, 8);
936 if (!packet)
937 return;
943 938
944 if ((extcode == 0) || (extcode >= 7)) { 939 if (extcode == 0 || extcode >= 7) {
945 /* let switch default handle error */ 940 /* let switch default handle error */
946 length = 0; 941 length = 0;
947 } 942 }
@@ -949,12 +944,12 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
949 switch (length) { 944 switch (length) {
950 case 4: 945 case 4:
951 rcode = highlevel_lock(host, source, packet->data, addr, 946 rcode = highlevel_lock(host, source, packet->data, addr,
952 data[4], 0, extcode,flags); 947 data[4], 0, extcode, flags);
953 fill_async_lock_resp(packet, rcode, extcode, 4); 948 fill_async_lock_resp(packet, rcode, extcode, 4);
954 break; 949 break;
955 case 8: 950 case 8:
956 if ((extcode != EXTCODE_FETCH_ADD) 951 if (extcode != EXTCODE_FETCH_ADD &&
957 && (extcode != EXTCODE_LITTLE_ADD)) { 952 extcode != EXTCODE_LITTLE_ADD) {
958 rcode = highlevel_lock(host, source, 953 rcode = highlevel_lock(host, source,
959 packet->data, addr, 954 packet->data, addr,
960 data[5], data[4], 955 data[5], data[4],
@@ -978,20 +973,16 @@ static void handle_incoming_packet(struct hpsb_host *host, int tcode,
978 break; 973 break;
979 default: 974 default:
980 rcode = RCODE_TYPE_ERROR; 975 rcode = RCODE_TYPE_ERROR;
981 fill_async_lock_resp(packet, rcode, 976 fill_async_lock_resp(packet, rcode, extcode, 0);
982 extcode, 0);
983 } 977 }
984 978
985 if (rcode >= 0) { 979 if (rcode < 0)
986 send_packet_nocare(packet);
987 } else {
988 hpsb_free_packet(packet); 980 hpsb_free_packet(packet);
989 } 981 else
990 break; 982 send_packet_nocare(packet);
983 return;
991 } 984 }
992
993} 985}
994#undef PREP_REPLY_PACKET
995 986
996/** 987/**
997 * hpsb_packet_received - hand over received packet to the core 988 * hpsb_packet_received - hand over received packet to the core