diff options
Diffstat (limited to 'drivers/scsi/sym53c8xx_2/sym_glue.c')
-rw-r--r-- | drivers/scsi/sym53c8xx_2/sym_glue.c | 117 |
1 files changed, 82 insertions, 35 deletions
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 7fc0b97173e1..1fffd2b3c654 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -514,9 +514,10 @@ static inline int sym_setup_cdb(struct sym_hcb *np, struct scsi_cmnd *cmd, struc | |||
514 | */ | 514 | */ |
515 | int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) | 515 | int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct sym_ccb *cp) |
516 | { | 516 | { |
517 | int dir; | ||
518 | struct sym_tcb *tp = &np->target[cp->target]; | 517 | struct sym_tcb *tp = &np->target[cp->target]; |
519 | struct sym_lcb *lp = sym_lp(tp, cp->lun); | 518 | struct sym_lcb *lp = sym_lp(tp, cp->lun); |
519 | u32 lastp, goalp; | ||
520 | int dir; | ||
520 | 521 | ||
521 | /* | 522 | /* |
522 | * Build the CDB. | 523 | * Build the CDB. |
@@ -534,15 +535,47 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
534 | sym_set_cam_status(cmd, DID_ERROR); | 535 | sym_set_cam_status(cmd, DID_ERROR); |
535 | goto out_abort; | 536 | goto out_abort; |
536 | } | 537 | } |
538 | |||
539 | /* | ||
540 | * No segments means no data. | ||
541 | */ | ||
542 | if (!cp->segments) | ||
543 | dir = DMA_NONE; | ||
537 | } else { | 544 | } else { |
538 | cp->data_len = 0; | 545 | cp->data_len = 0; |
539 | cp->segments = 0; | 546 | cp->segments = 0; |
540 | } | 547 | } |
541 | 548 | ||
542 | /* | 549 | /* |
543 | * Set data pointers. | 550 | * Set the data pointer. |
544 | */ | 551 | */ |
545 | sym_setup_data_pointers(np, cp, dir); | 552 | switch (dir) { |
553 | case DMA_BIDIRECTIONAL: | ||
554 | printk("%s: got DMA_BIDIRECTIONAL command", sym_name(np)); | ||
555 | sym_set_cam_status(cmd, DID_ERROR); | ||
556 | goto out_abort; | ||
557 | case DMA_TO_DEVICE: | ||
558 | goalp = SCRIPTA_BA(np, data_out2) + 8; | ||
559 | lastp = goalp - 8 - (cp->segments * (2*4)); | ||
560 | break; | ||
561 | case DMA_FROM_DEVICE: | ||
562 | cp->host_flags |= HF_DATA_IN; | ||
563 | goalp = SCRIPTA_BA(np, data_in2) + 8; | ||
564 | lastp = goalp - 8 - (cp->segments * (2*4)); | ||
565 | break; | ||
566 | case DMA_NONE: | ||
567 | default: | ||
568 | lastp = goalp = SCRIPTB_BA(np, no_data); | ||
569 | break; | ||
570 | } | ||
571 | |||
572 | /* | ||
573 | * Set all pointers values needed by SCRIPTS. | ||
574 | */ | ||
575 | cp->phys.head.lastp = cpu_to_scr(lastp); | ||
576 | cp->phys.head.savep = cpu_to_scr(lastp); | ||
577 | cp->startp = cp->phys.head.savep; | ||
578 | cp->goalp = cpu_to_scr(goalp); | ||
546 | 579 | ||
547 | /* | 580 | /* |
548 | * When `#ifed 1', the code below makes the driver | 581 | * When `#ifed 1', the code below makes the driver |
@@ -563,10 +596,7 @@ int sym_setup_data_and_start(struct sym_hcb *np, struct scsi_cmnd *cmd, struct s | |||
563 | /* | 596 | /* |
564 | * activate this job. | 597 | * activate this job. |
565 | */ | 598 | */ |
566 | if (lp) | 599 | sym_start_next_ccbs(np, lp, 2); |
567 | sym_start_next_ccbs(np, lp, 2); | ||
568 | else | ||
569 | sym_put_start_queue(np, cp); | ||
570 | return 0; | 600 | return 0; |
571 | 601 | ||
572 | out_abort: | 602 | out_abort: |
@@ -981,15 +1011,14 @@ static int device_queue_depth(struct sym_hcb *np, int target, int lun) | |||
981 | 1011 | ||
982 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) | 1012 | static int sym53c8xx_slave_alloc(struct scsi_device *sdev) |
983 | { | 1013 | { |
984 | struct sym_hcb *np; | 1014 | struct sym_hcb *np = sym_get_hcb(sdev->host); |
985 | struct sym_tcb *tp; | 1015 | struct sym_tcb *tp = &np->target[sdev->id]; |
1016 | struct sym_lcb *lp; | ||
986 | 1017 | ||
987 | if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) | 1018 | if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) |
988 | return -ENXIO; | 1019 | return -ENXIO; |
989 | 1020 | ||
990 | np = sym_get_hcb(sdev->host); | 1021 | tp->starget = sdev->sdev_target; |
991 | tp = &np->target[sdev->id]; | ||
992 | |||
993 | /* | 1022 | /* |
994 | * Fail the device init if the device is flagged NOSCAN at BOOT in | 1023 | * Fail the device init if the device is flagged NOSCAN at BOOT in |
995 | * the NVRAM. This may speed up boot and maintain coherency with | 1024 | * the NVRAM. This may speed up boot and maintain coherency with |
@@ -999,35 +1028,41 @@ static int sym53c8xx_slave_alloc(struct scsi_device *sdev) | |||
999 | * lun devices behave badly when asked for a non zero LUN. | 1028 | * lun devices behave badly when asked for a non zero LUN. |
1000 | */ | 1029 | */ |
1001 | 1030 | ||
1002 | if ((tp->usrflags & SYM_SCAN_BOOT_DISABLED) || | 1031 | if (tp->usrflags & SYM_SCAN_BOOT_DISABLED) { |
1003 | ((tp->usrflags & SYM_SCAN_LUNS_DISABLED) && sdev->lun != 0)) { | ||
1004 | tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; | 1032 | tp->usrflags &= ~SYM_SCAN_BOOT_DISABLED; |
1033 | starget_printk(KERN_INFO, tp->starget, | ||
1034 | "Scan at boot disabled in NVRAM\n"); | ||
1005 | return -ENXIO; | 1035 | return -ENXIO; |
1006 | } | 1036 | } |
1007 | 1037 | ||
1008 | tp->starget = sdev->sdev_target; | 1038 | if (tp->usrflags & SYM_SCAN_LUNS_DISABLED) { |
1039 | if (sdev->lun != 0) | ||
1040 | return -ENXIO; | ||
1041 | starget_printk(KERN_INFO, tp->starget, | ||
1042 | "Multiple LUNs disabled in NVRAM\n"); | ||
1043 | } | ||
1044 | |||
1045 | lp = sym_alloc_lcb(np, sdev->id, sdev->lun); | ||
1046 | if (!lp) | ||
1047 | return -ENOMEM; | ||
1048 | |||
1049 | spi_min_period(tp->starget) = tp->usr_period; | ||
1050 | spi_max_width(tp->starget) = tp->usr_width; | ||
1051 | |||
1009 | return 0; | 1052 | return 0; |
1010 | } | 1053 | } |
1011 | 1054 | ||
1012 | /* | 1055 | /* |
1013 | * Linux entry point for device queue sizing. | 1056 | * Linux entry point for device queue sizing. |
1014 | */ | 1057 | */ |
1015 | static int sym53c8xx_slave_configure(struct scsi_device *device) | 1058 | static int sym53c8xx_slave_configure(struct scsi_device *sdev) |
1016 | { | 1059 | { |
1017 | struct sym_hcb *np = sym_get_hcb(device->host); | 1060 | struct sym_hcb *np = sym_get_hcb(sdev->host); |
1018 | struct sym_tcb *tp = &np->target[device->id]; | 1061 | struct sym_tcb *tp = &np->target[sdev->id]; |
1019 | struct sym_lcb *lp; | 1062 | struct sym_lcb *lp = sym_lp(tp, sdev->lun); |
1020 | int reqtags, depth_to_use; | 1063 | int reqtags, depth_to_use; |
1021 | 1064 | ||
1022 | /* | 1065 | /* |
1023 | * Allocate the LCB if not yet. | ||
1024 | * If it fail, we may well be in the sh*t. :) | ||
1025 | */ | ||
1026 | lp = sym_alloc_lcb(np, device->id, device->lun); | ||
1027 | if (!lp) | ||
1028 | return -ENOMEM; | ||
1029 | |||
1030 | /* | ||
1031 | * Get user flags. | 1066 | * Get user flags. |
1032 | */ | 1067 | */ |
1033 | lp->curr_flags = lp->user_flags; | 1068 | lp->curr_flags = lp->user_flags; |
@@ -1038,10 +1073,10 @@ static int sym53c8xx_slave_configure(struct scsi_device *device) | |||
1038 | * Use at least 2. | 1073 | * Use at least 2. |
1039 | * Donnot use more than our maximum. | 1074 | * Donnot use more than our maximum. |
1040 | */ | 1075 | */ |
1041 | reqtags = device_queue_depth(np, device->id, device->lun); | 1076 | reqtags = device_queue_depth(np, sdev->id, sdev->lun); |
1042 | if (reqtags > tp->usrtags) | 1077 | if (reqtags > tp->usrtags) |
1043 | reqtags = tp->usrtags; | 1078 | reqtags = tp->usrtags; |
1044 | if (!device->tagged_supported) | 1079 | if (!sdev->tagged_supported) |
1045 | reqtags = 0; | 1080 | reqtags = 0; |
1046 | #if 1 /* Avoid to locally queue commands for no good reasons */ | 1081 | #if 1 /* Avoid to locally queue commands for no good reasons */ |
1047 | if (reqtags > SYM_CONF_MAX_TAG) | 1082 | if (reqtags > SYM_CONF_MAX_TAG) |
@@ -1050,19 +1085,30 @@ static int sym53c8xx_slave_configure(struct scsi_device *device) | |||
1050 | #else | 1085 | #else |
1051 | depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); | 1086 | depth_to_use = (reqtags ? SYM_CONF_MAX_TAG : 2); |
1052 | #endif | 1087 | #endif |
1053 | scsi_adjust_queue_depth(device, | 1088 | scsi_adjust_queue_depth(sdev, |
1054 | (device->tagged_supported ? | 1089 | (sdev->tagged_supported ? |
1055 | MSG_SIMPLE_TAG : 0), | 1090 | MSG_SIMPLE_TAG : 0), |
1056 | depth_to_use); | 1091 | depth_to_use); |
1057 | lp->s.scdev_depth = depth_to_use; | 1092 | lp->s.scdev_depth = depth_to_use; |
1058 | sym_tune_dev_queuing(tp, device->lun, reqtags); | 1093 | sym_tune_dev_queuing(tp, sdev->lun, reqtags); |
1059 | 1094 | ||
1060 | if (!spi_initial_dv(device->sdev_target)) | 1095 | if (!spi_initial_dv(sdev->sdev_target)) |
1061 | spi_dv_device(device); | 1096 | spi_dv_device(sdev); |
1062 | 1097 | ||
1063 | return 0; | 1098 | return 0; |
1064 | } | 1099 | } |
1065 | 1100 | ||
1101 | static void sym53c8xx_slave_destroy(struct scsi_device *sdev) | ||
1102 | { | ||
1103 | struct sym_hcb *np = sym_get_hcb(sdev->host); | ||
1104 | struct sym_lcb *lp = sym_lp(&np->target[sdev->id], sdev->lun); | ||
1105 | |||
1106 | if (lp->itlq_tbl) | ||
1107 | sym_mfree_dma(lp->itlq_tbl, SYM_CONF_MAX_TASK * 4, "ITLQ_TBL"); | ||
1108 | kfree(lp->cb_tags); | ||
1109 | sym_mfree_dma(lp, sizeof(*lp), "LCB"); | ||
1110 | } | ||
1111 | |||
1066 | /* | 1112 | /* |
1067 | * Linux entry point for info() function | 1113 | * Linux entry point for info() function |
1068 | */ | 1114 | */ |
@@ -1497,7 +1543,7 @@ static int sym_setup_bus_dma_mask(struct sym_hcb *np) | |||
1497 | { | 1543 | { |
1498 | #if SYM_CONF_DMA_ADDRESSING_MODE > 0 | 1544 | #if SYM_CONF_DMA_ADDRESSING_MODE > 0 |
1499 | #if SYM_CONF_DMA_ADDRESSING_MODE == 1 | 1545 | #if SYM_CONF_DMA_ADDRESSING_MODE == 1 |
1500 | #define DMA_DAC_MASK 0x000000ffffffffffULL /* 40-bit */ | 1546 | #define DMA_DAC_MASK DMA_40BIT_MASK |
1501 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 | 1547 | #elif SYM_CONF_DMA_ADDRESSING_MODE == 2 |
1502 | #define DMA_DAC_MASK DMA_64BIT_MASK | 1548 | #define DMA_DAC_MASK DMA_64BIT_MASK |
1503 | #endif | 1549 | #endif |
@@ -1926,6 +1972,7 @@ static struct scsi_host_template sym2_template = { | |||
1926 | .queuecommand = sym53c8xx_queue_command, | 1972 | .queuecommand = sym53c8xx_queue_command, |
1927 | .slave_alloc = sym53c8xx_slave_alloc, | 1973 | .slave_alloc = sym53c8xx_slave_alloc, |
1928 | .slave_configure = sym53c8xx_slave_configure, | 1974 | .slave_configure = sym53c8xx_slave_configure, |
1975 | .slave_destroy = sym53c8xx_slave_destroy, | ||
1929 | .eh_abort_handler = sym53c8xx_eh_abort_handler, | 1976 | .eh_abort_handler = sym53c8xx_eh_abort_handler, |
1930 | .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, | 1977 | .eh_device_reset_handler = sym53c8xx_eh_device_reset_handler, |
1931 | .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, | 1978 | .eh_bus_reset_handler = sym53c8xx_eh_bus_reset_handler, |