diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_osm.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.c | 96 |
1 files changed, 84 insertions, 12 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 3feb739cd554..6b6d4e287793 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c | |||
@@ -48,12 +48,6 @@ | |||
48 | 48 | ||
49 | static struct scsi_transport_template *ahd_linux_transport_template = NULL; | 49 | static struct scsi_transport_template *ahd_linux_transport_template = NULL; |
50 | 50 | ||
51 | /* | ||
52 | * Include aiclib.c as part of our | ||
53 | * "module dependencies are hard" work around. | ||
54 | */ | ||
55 | #include "aiclib.c" | ||
56 | |||
57 | #include <linux/init.h> /* __setup */ | 51 | #include <linux/init.h> /* __setup */ |
58 | #include <linux/mm.h> /* For fetching system memory size */ | 52 | #include <linux/mm.h> /* For fetching system memory size */ |
59 | #include <linux/blkdev.h> /* For block_size() */ | 53 | #include <linux/blkdev.h> /* For block_size() */ |
@@ -372,8 +366,6 @@ static int ahd_linux_run_command(struct ahd_softc*, | |||
372 | struct ahd_linux_device *, | 366 | struct ahd_linux_device *, |
373 | struct scsi_cmnd *); | 367 | struct scsi_cmnd *); |
374 | static void ahd_linux_setup_tag_info_global(char *p); | 368 | static void ahd_linux_setup_tag_info_global(char *p); |
375 | static aic_option_callback_t ahd_linux_setup_tag_info; | ||
376 | static aic_option_callback_t ahd_linux_setup_iocell_info; | ||
377 | static int aic79xx_setup(char *c); | 369 | static int aic79xx_setup(char *c); |
378 | 370 | ||
379 | static int ahd_linux_unit; | 371 | static int ahd_linux_unit; |
@@ -907,6 +899,86 @@ ahd_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) | |||
907 | } | 899 | } |
908 | } | 900 | } |
909 | 901 | ||
902 | static char * | ||
903 | ahd_parse_brace_option(char *opt_name, char *opt_arg, char *end, int depth, | ||
904 | void (*callback)(u_long, int, int, int32_t), | ||
905 | u_long callback_arg) | ||
906 | { | ||
907 | char *tok_end; | ||
908 | char *tok_end2; | ||
909 | int i; | ||
910 | int instance; | ||
911 | int targ; | ||
912 | int done; | ||
913 | char tok_list[] = {'.', ',', '{', '}', '\0'}; | ||
914 | |||
915 | /* All options use a ':' name/arg separator */ | ||
916 | if (*opt_arg != ':') | ||
917 | return (opt_arg); | ||
918 | opt_arg++; | ||
919 | instance = -1; | ||
920 | targ = -1; | ||
921 | done = FALSE; | ||
922 | /* | ||
923 | * Restore separator that may be in | ||
924 | * the middle of our option argument. | ||
925 | */ | ||
926 | tok_end = strchr(opt_arg, '\0'); | ||
927 | if (tok_end < end) | ||
928 | *tok_end = ','; | ||
929 | while (!done) { | ||
930 | switch (*opt_arg) { | ||
931 | case '{': | ||
932 | if (instance == -1) { | ||
933 | instance = 0; | ||
934 | } else { | ||
935 | if (depth > 1) { | ||
936 | if (targ == -1) | ||
937 | targ = 0; | ||
938 | } else { | ||
939 | printf("Malformed Option %s\n", | ||
940 | opt_name); | ||
941 | done = TRUE; | ||
942 | } | ||
943 | } | ||
944 | opt_arg++; | ||
945 | break; | ||
946 | case '}': | ||
947 | if (targ != -1) | ||
948 | targ = -1; | ||
949 | else if (instance != -1) | ||
950 | instance = -1; | ||
951 | opt_arg++; | ||
952 | break; | ||
953 | case ',': | ||
954 | case '.': | ||
955 | if (instance == -1) | ||
956 | done = TRUE; | ||
957 | else if (targ >= 0) | ||
958 | targ++; | ||
959 | else if (instance >= 0) | ||
960 | instance++; | ||
961 | opt_arg++; | ||
962 | break; | ||
963 | case '\0': | ||
964 | done = TRUE; | ||
965 | break; | ||
966 | default: | ||
967 | tok_end = end; | ||
968 | for (i = 0; tok_list[i]; i++) { | ||
969 | tok_end2 = strchr(opt_arg, tok_list[i]); | ||
970 | if ((tok_end2) && (tok_end2 < tok_end)) | ||
971 | tok_end = tok_end2; | ||
972 | } | ||
973 | callback(callback_arg, instance, targ, | ||
974 | simple_strtol(opt_arg, NULL, 0)); | ||
975 | opt_arg = tok_end; | ||
976 | break; | ||
977 | } | ||
978 | } | ||
979 | return (opt_arg); | ||
980 | } | ||
981 | |||
910 | /* | 982 | /* |
911 | * Handle Linux boot parameters. This routine allows for assigning a value | 983 | * Handle Linux boot parameters. This routine allows for assigning a value |
912 | * to a parameter with a ':' between the parameter and the value. | 984 | * to a parameter with a ':' between the parameter and the value. |
@@ -964,18 +1036,18 @@ aic79xx_setup(char *s) | |||
964 | if (strncmp(p, "global_tag_depth", n) == 0) { | 1036 | if (strncmp(p, "global_tag_depth", n) == 0) { |
965 | ahd_linux_setup_tag_info_global(p + n); | 1037 | ahd_linux_setup_tag_info_global(p + n); |
966 | } else if (strncmp(p, "tag_info", n) == 0) { | 1038 | } else if (strncmp(p, "tag_info", n) == 0) { |
967 | s = aic_parse_brace_option("tag_info", p + n, end, | 1039 | s = ahd_parse_brace_option("tag_info", p + n, end, |
968 | 2, ahd_linux_setup_tag_info, 0); | 1040 | 2, ahd_linux_setup_tag_info, 0); |
969 | } else if (strncmp(p, "slewrate", n) == 0) { | 1041 | } else if (strncmp(p, "slewrate", n) == 0) { |
970 | s = aic_parse_brace_option("slewrate", | 1042 | s = ahd_parse_brace_option("slewrate", |
971 | p + n, end, 1, ahd_linux_setup_iocell_info, | 1043 | p + n, end, 1, ahd_linux_setup_iocell_info, |
972 | AIC79XX_SLEWRATE_INDEX); | 1044 | AIC79XX_SLEWRATE_INDEX); |
973 | } else if (strncmp(p, "precomp", n) == 0) { | 1045 | } else if (strncmp(p, "precomp", n) == 0) { |
974 | s = aic_parse_brace_option("precomp", | 1046 | s = ahd_parse_brace_option("precomp", |
975 | p + n, end, 1, ahd_linux_setup_iocell_info, | 1047 | p + n, end, 1, ahd_linux_setup_iocell_info, |
976 | AIC79XX_PRECOMP_INDEX); | 1048 | AIC79XX_PRECOMP_INDEX); |
977 | } else if (strncmp(p, "amplitude", n) == 0) { | 1049 | } else if (strncmp(p, "amplitude", n) == 0) { |
978 | s = aic_parse_brace_option("amplitude", | 1050 | s = ahd_parse_brace_option("amplitude", |
979 | p + n, end, 1, ahd_linux_setup_iocell_info, | 1051 | p + n, end, 1, ahd_linux_setup_iocell_info, |
980 | AIC79XX_AMPLITUDE_INDEX); | 1052 | AIC79XX_AMPLITUDE_INDEX); |
981 | } else if (p[n] == ':') { | 1053 | } else if (p[n] == ':') { |