aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic79xx_osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx/aic79xx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c96
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
49static struct scsi_transport_template *ahd_linux_transport_template = NULL; 49static 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 *);
374static void ahd_linux_setup_tag_info_global(char *p); 368static void ahd_linux_setup_tag_info_global(char *p);
375static aic_option_callback_t ahd_linux_setup_tag_info;
376static aic_option_callback_t ahd_linux_setup_iocell_info;
377static int aic79xx_setup(char *c); 369static int aic79xx_setup(char *c);
378 370
379static int ahd_linux_unit; 371static 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
902static char *
903ahd_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] == ':') {