diff options
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
-rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 97 |
1 files changed, 85 insertions, 12 deletions
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 687f19e9cf03..c932b3b94490 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; |
@@ -635,6 +628,8 @@ ahc_linux_slave_alloc(struct scsi_device *sdev) | |||
635 | 628 | ||
636 | targ->sdev[sdev->lun] = sdev; | 629 | targ->sdev[sdev->lun] = sdev; |
637 | 630 | ||
631 | spi_period(starget) = 0; | ||
632 | |||
638 | return 0; | 633 | return 0; |
639 | } | 634 | } |
640 | 635 | ||
@@ -918,6 +913,86 @@ ahc_linux_setup_tag_info(u_long arg, int instance, int targ, int32_t value) | |||
918 | } | 913 | } |
919 | } | 914 | } |
920 | 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 | |||
921 | /* | 996 | /* |
922 | * Handle Linux boot parameters. This routine allows for assigning a value | 997 | * Handle Linux boot parameters. This routine allows for assigning a value |
923 | * to a parameter with a ':' between the parameter and the value. | 998 | * to a parameter with a ':' between the parameter and the value. |
@@ -972,7 +1047,7 @@ aic7xxx_setup(char *s) | |||
972 | if (strncmp(p, "global_tag_depth", n) == 0) { | 1047 | if (strncmp(p, "global_tag_depth", n) == 0) { |
973 | ahc_linux_setup_tag_info_global(p + n); | 1048 | ahc_linux_setup_tag_info_global(p + n); |
974 | } else if (strncmp(p, "tag_info", n) == 0) { | 1049 | } else if (strncmp(p, "tag_info", n) == 0) { |
975 | s = aic_parse_brace_option("tag_info", p + n, end, | 1050 | s = ahc_parse_brace_option("tag_info", p + n, end, |
976 | 2, ahc_linux_setup_tag_info, 0); | 1051 | 2, ahc_linux_setup_tag_info, 0); |
977 | } else if (p[n] == ':') { | 1052 | } else if (p[n] == ':') { |
978 | *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); | 1053 | *(options[i].flag) = simple_strtoul(p + n + 1, NULL, 0); |
@@ -1612,9 +1687,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel, | |||
1612 | if (channel == 'B') | 1687 | if (channel == 'B') |
1613 | target_offset += 8; | 1688 | target_offset += 8; |
1614 | starget = ahc->platform_data->starget[target_offset]; | 1689 | starget = ahc->platform_data->starget[target_offset]; |
1615 | targ = scsi_transport_target_data(starget); | 1690 | if (starget == NULL) |
1616 | if (targ == NULL) | ||
1617 | break; | 1691 | break; |
1692 | targ = scsi_transport_target_data(starget); | ||
1618 | 1693 | ||
1619 | target_ppr_options = | 1694 | target_ppr_options = |
1620 | (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0) | 1695 | (spi_dt(starget) ? MSG_EXT_PPR_DT_REQ : 0) |
@@ -2329,8 +2404,6 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc) | |||
2329 | { | 2404 | { |
2330 | } | 2405 | } |
2331 | 2406 | ||
2332 | static void ahc_linux_exit(void); | ||
2333 | |||
2334 | static void ahc_linux_set_width(struct scsi_target *starget, int width) | 2407 | static void ahc_linux_set_width(struct scsi_target *starget, int width) |
2335 | { | 2408 | { |
2336 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 2409 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |