aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aic7xxx/aic7xxx_osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aic7xxx/aic7xxx_osm.c')
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c97
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
126static struct scsi_transport_template *ahc_linux_transport_template = NULL; 126static 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 *);
393static void ahc_linux_setup_tag_info_global(char *p); 387static void ahc_linux_setup_tag_info_global(char *p);
394static aic_option_callback_t ahc_linux_setup_tag_info;
395static int aic7xxx_setup(char *s); 388static int aic7xxx_setup(char *s);
396 389
397static int ahc_linux_unit; 390static 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
916static char *
917ahc_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
2332static void ahc_linux_exit(void);
2333
2334static void ahc_linux_set_width(struct scsi_target *starget, int width) 2407static 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);