diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 89 |
1 files changed, 81 insertions, 8 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 22434849de48..4096d523d08d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -125,12 +125,6 @@ | |||
125 | 125 | ||
126 | static struct scsi_transport_template *ahc_linux_transport_template = NULL; | 126 | static struct scsi_transport_template *ahc_linux_transport_template = NULL; |
127 | 127 | ||
128 | /* | ||
129 | * Include aiclib.c as part of our | ||
130 | * "module dependencies are hard" work around. | ||
131 | */ | ||
132 | #include "aiclib.c" | ||
133 | |||
134 | #include <linux/init.h> /* __setup */ | 128 | #include <linux/init.h> /* __setup */ |
135 | #include <linux/mm.h> /* For fetching system memory size */ | 129 | #include <linux/mm.h> /* For fetching system memory size */ |
136 | #include <linux/blkdev.h> /* For block_size() */ | 130 | #include <linux/blkdev.h> /* For block_size() */ |
@@ -391,7 +385,6 @@ static int ahc_linux_run_command(struct ahc_softc*, | |||
391 | struct ahc_linux_device *, | 385 | struct ahc_linux_device *, |
392 | struct scsi_cmnd *); | 386 | struct scsi_cmnd *); |
393 | static void ahc_linux_setup_tag_info_global(char *p); | 387 | static void ahc_linux_setup_tag_info_global(char *p); |
394 | static aic_option_callback_t ahc_linux_setup_tag_info; | ||
395 | static int aic7xxx_setup(char *s); | 388 | static int aic7xxx_setup(char *s); |
396 | 389 | ||
397 | static int ahc_linux_unit; | 390 | static int ahc_linux_unit; |
@@ -920,6 +913,86 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) | |||
920 | } | 913 | } |
921 | } | 914 | } |
922 | 915 | ||
916 | static char * | ||
917 | ahc_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, | ||
918 | void (*callback)(u_long, int, int, int32_t), | ||
919 | u_long callback_arg) | ||
920 | { | ||
921 | char *tok_end; | ||
922 | char *tok_end2; | ||
923 | int i; | ||
924 | int instance; | ||
925 | int targ; | ||
926 | int done; | ||
927 | char tok_list[] = {'.', ',', '{', '}', '\0'}; | ||
928 | |||
929 | /* All options use a ':' name/arg separator */ | ||
930 | if (*opt_arg != ':') | ||
931 | return (opt_arg); | ||
932 | opt_arg++; | ||
933 | instance = -1; | ||
934 | targ = -1; | ||
935 | done = FALSE; | ||
936 | /* | ||
937 | * Restore separator that may be in | ||
938 | * the middle of our option argument. | ||
939 | */ | ||
940 | tok_end = strchr(opt_arg, '\0'); | ||
941 | if (tok_end < end) | ||
942 | *tok_end = ','; | ||
943 | while (!done) { | ||
944 | switch (*opt_arg) { | ||
945 | case '{': | ||
946 | if (instance == -1) { | ||
947 | instance = 0; | ||
948 | } else { | ||
949 | if (depth > 1) { | ||
950 | if (targ == -1) | ||
951 | targ = 0; | ||
952 | } else { | ||
953 | printf("Malformed Option %s\n", | ||
954 | opt_name); | ||
955 | done = TRUE; | ||
956 | } | ||
957 | } | ||
958 | opt_arg++; | ||
959 | break; | ||
960 | case '}': | ||
961 | if (targ != -1) | ||
962 | targ = -1; | ||
963 | else if (instance != -1) | ||
964 | instance = -1; | ||
965 | opt_arg++; | ||
966 | break; | ||
967 | case ',': | ||
968 | case '.': | ||
969 | if (instance == -1) | ||
970 | done = TRUE; | ||
971 | else if (targ >= 0) | ||
972 | targ++; | ||
973 | else if (instance >= 0) | ||
974 | instance++; | ||
975 | opt_arg++; | ||
976 | break; | ||
977 | case '\0': | ||
978 | done = TRUE; | ||
979 | break; | ||
980 | default: | ||
981 | tok_end = end; | ||
982 | for (i = 0; tok_list[i]; i++) { | ||
983 | tok_end2 = strchr(opt_arg, tok_list[i]); | ||
984 | if ((tok_end2) && (tok_end2 < tok_end)) | ||
985 | tok_end = tok_end2; | ||
986 | } | ||
987 | callback(callback_arg, instance, targ, | ||
988 | simple_strtol(opt_arg, NULL, 0)); | ||
989 | opt_arg = tok_end; | ||
990 | break; | ||
991 | } | ||
992 | } | ||
993 | return (opt_arg); | ||
994 | } | ||
995 | |||
923 | /* | 996 | /* |
924 | * Handle Linux boot parameters. This routine allows for assigning a value | 997 | * Handle Linux boot parameters. This routine allows for assigning a value |
925 | * to a parameter with a ':' between the parameter and the value. | 998 | * to a parameter with a ':' between the parameter and the value. |
@@ -974,7 +1047,7 @@ aic7xxx_setup(char *s) | |||
974 | if (strncmp(p, "global_tag_depth", n) == 0) { | 1047 | if (strncmp(p, "global_tag_depth", n) == 0) { |
975 | ahc_linux_setup_tag_info_global(p + n); | 1048 | ahc_linux_setup_tag_info_global(p + n); |
976 | } else if (strncmp(p, "tag_info", n) == 0) { | 1049 | } else if (strncmp(p, "tag_info", n) == 0) { |
977 | s = aic_parse_brace_option("tag_info", p + n, end, | 1050 | s = ahc_parse_brace_option("tag_info", p + n, end, |
978 | 2, ahc_linux_setup_tag_info, 0); | 1051 | 2, ahc_linux_setup_tag_info, 0); |
979 | } else if (p[n] == ':') { | 1052 | } else if (p[n] == ':') { |
980 | *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); | 1053 | *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); |