diff options
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 284 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 268 |
2 files changed, 267 insertions, 285 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index ce58431bee8e..d5877316cbea 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -99,9 +99,6 @@ static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, | |||
99 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 99 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
100 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | 100 | int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); |
101 | 101 | ||
102 | static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
103 | static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev); | ||
104 | static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id); | ||
105 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 102 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
106 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 103 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
107 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); | 104 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
@@ -2286,7 +2283,6 @@ mptscsih_slave_configure(struct scsi_device *sdev) | |||
2286 | } | 2283 | } |
2287 | 2284 | ||
2288 | vdevice->configured_lun = 1; | 2285 | vdevice->configured_lun = 1; |
2289 | mptscsih_initTarget(hd, vtarget, sdev); | ||
2290 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); | 2286 | mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); |
2291 | 2287 | ||
2292 | dsprintk((MYIOC_s_INFO_FMT | 2288 | dsprintk((MYIOC_s_INFO_FMT |
@@ -2550,286 +2546,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2550 | 2546 | ||
2551 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2547 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2552 | /* | 2548 | /* |
2553 | * mptscsih_initTarget - Target, LUN alloc/free functionality. | ||
2554 | * @hd: Pointer to MPT_SCSI_HOST structure | ||
2555 | * @vtarget: per target private data | ||
2556 | * @sdev: SCSI device | ||
2557 | * | ||
2558 | * NOTE: It's only SAFE to call this routine if data points to | ||
2559 | * sane & valid STANDARD INQUIRY data! | ||
2560 | * | ||
2561 | * Allocate and initialize memory for this target. | ||
2562 | * Save inquiry data. | ||
2563 | * | ||
2564 | */ | ||
2565 | static void | ||
2566 | mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | ||
2567 | struct scsi_device *sdev) | ||
2568 | { | ||
2569 | dinitprintk((MYIOC_s_INFO_FMT "initTarget channel=%d id=%d lun=%d hd=%p\n", | ||
2570 | hd->ioc->name, vtarget->channel, vtarget->id, | ||
2571 | sdev->lun, hd)); | ||
2572 | |||
2573 | /* Is LUN supported? If so, upper 2 bits will be 0 | ||
2574 | * in first byte of inquiry data. | ||
2575 | */ | ||
2576 | if (sdev->inq_periph_qual != 0) | ||
2577 | return; | ||
2578 | |||
2579 | if (vtarget == NULL) | ||
2580 | return; | ||
2581 | |||
2582 | vtarget->type = sdev->type; | ||
2583 | |||
2584 | if (hd->ioc->bus_type != SPI) | ||
2585 | return; | ||
2586 | |||
2587 | if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | ||
2588 | /* Treat all Processors as SAF-TE if | ||
2589 | * command line option is set */ | ||
2590 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2591 | mptscsih_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
2592 | }else if ((sdev->type == TYPE_PROCESSOR) && | ||
2593 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | ||
2594 | if (sdev->inquiry_len > 49 ) { | ||
2595 | if (sdev->inquiry[44] == 'S' && | ||
2596 | sdev->inquiry[45] == 'A' && | ||
2597 | sdev->inquiry[46] == 'F' && | ||
2598 | sdev->inquiry[47] == '-' && | ||
2599 | sdev->inquiry[48] == 'T' && | ||
2600 | sdev->inquiry[49] == 'E' ) { | ||
2601 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
2602 | mptscsih_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
2603 | } | ||
2604 | } | ||
2605 | } | ||
2606 | mptscsih_setTargetNegoParms(hd, vtarget, sdev); | ||
2607 | } | ||
2608 | |||
2609 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2610 | /* | ||
2611 | * Update the target negotiation parameters based on the | ||
2612 | * the Inquiry data, adapter capabilities, and NVRAM settings. | ||
2613 | * | ||
2614 | */ | ||
2615 | static void | ||
2616 | mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | ||
2617 | struct scsi_device *sdev) | ||
2618 | { | ||
2619 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | ||
2620 | int id = (int) target->id; | ||
2621 | int nvram; | ||
2622 | u8 width = MPT_NARROW; | ||
2623 | u8 factor = MPT_ASYNC; | ||
2624 | u8 offset = 0; | ||
2625 | u8 nfactor; | ||
2626 | u8 noQas = 1; | ||
2627 | |||
2628 | target->negoFlags = pspi_data->noQas; | ||
2629 | |||
2630 | /* noQas == 0 => device supports QAS. */ | ||
2631 | |||
2632 | if (sdev->scsi_level < SCSI_2) { | ||
2633 | width = 0; | ||
2634 | factor = MPT_ULTRA2; | ||
2635 | offset = pspi_data->maxSyncOffset; | ||
2636 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2637 | } else { | ||
2638 | if (scsi_device_wide(sdev)) { | ||
2639 | width = 1; | ||
2640 | } | ||
2641 | |||
2642 | if (scsi_device_sync(sdev)) { | ||
2643 | factor = pspi_data->minSyncFactor; | ||
2644 | if (!scsi_device_dt(sdev)) | ||
2645 | factor = MPT_ULTRA2; | ||
2646 | else { | ||
2647 | if (!scsi_device_ius(sdev) && | ||
2648 | !scsi_device_qas(sdev)) | ||
2649 | factor = MPT_ULTRA160; | ||
2650 | else { | ||
2651 | factor = MPT_ULTRA320; | ||
2652 | if (scsi_device_qas(sdev)) { | ||
2653 | ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); | ||
2654 | noQas = 0; | ||
2655 | } | ||
2656 | if (sdev->type == TYPE_TAPE && | ||
2657 | scsi_device_ius(sdev)) | ||
2658 | target->negoFlags |= MPT_TAPE_NEGO_IDP; | ||
2659 | } | ||
2660 | } | ||
2661 | offset = pspi_data->maxSyncOffset; | ||
2662 | |||
2663 | /* If RAID, never disable QAS | ||
2664 | * else if non RAID, do not disable | ||
2665 | * QAS if bit 1 is set | ||
2666 | * bit 1 QAS support, non-raid only | ||
2667 | * bit 0 IU support | ||
2668 | */ | ||
2669 | if (target->raidVolume == 1) { | ||
2670 | noQas = 0; | ||
2671 | } | ||
2672 | } else { | ||
2673 | factor = MPT_ASYNC; | ||
2674 | offset = 0; | ||
2675 | } | ||
2676 | } | ||
2677 | |||
2678 | if (!sdev->tagged_supported) { | ||
2679 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
2680 | } | ||
2681 | |||
2682 | /* Update tflags based on NVRAM settings. (SCSI only) | ||
2683 | */ | ||
2684 | if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
2685 | nvram = pspi_data->nvram[id]; | ||
2686 | nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; | ||
2687 | |||
2688 | if (width) | ||
2689 | width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; | ||
2690 | |||
2691 | if (offset > 0) { | ||
2692 | /* Ensure factor is set to the | ||
2693 | * maximum of: adapter, nvram, inquiry | ||
2694 | */ | ||
2695 | if (nfactor) { | ||
2696 | if (nfactor < pspi_data->minSyncFactor ) | ||
2697 | nfactor = pspi_data->minSyncFactor; | ||
2698 | |||
2699 | factor = max(factor, nfactor); | ||
2700 | if (factor == MPT_ASYNC) | ||
2701 | offset = 0; | ||
2702 | } else { | ||
2703 | offset = 0; | ||
2704 | factor = MPT_ASYNC; | ||
2705 | } | ||
2706 | } else { | ||
2707 | factor = MPT_ASYNC; | ||
2708 | } | ||
2709 | } | ||
2710 | |||
2711 | /* Make sure data is consistent | ||
2712 | */ | ||
2713 | if ((!width) && (factor < MPT_ULTRA2)) { | ||
2714 | factor = MPT_ULTRA2; | ||
2715 | } | ||
2716 | |||
2717 | /* Save the data to the target structure. | ||
2718 | */ | ||
2719 | target->minSyncFactor = factor; | ||
2720 | target->maxOffset = offset; | ||
2721 | target->maxWidth = width; | ||
2722 | |||
2723 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | ||
2724 | |||
2725 | /* Disable unused features. | ||
2726 | */ | ||
2727 | if (!width) | ||
2728 | target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; | ||
2729 | |||
2730 | if (!offset) | ||
2731 | target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; | ||
2732 | |||
2733 | if ( factor > MPT_ULTRA320 ) | ||
2734 | noQas = 0; | ||
2735 | |||
2736 | if (noQas && (pspi_data->noQas == 0)) { | ||
2737 | pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; | ||
2738 | target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | ||
2739 | |||
2740 | /* Disable QAS in a mixed configuration case | ||
2741 | */ | ||
2742 | |||
2743 | ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | ||
2744 | } | ||
2745 | } | ||
2746 | |||
2747 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2748 | |||
2749 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2750 | /* | ||
2751 | * SCSI Config Page functionality ... | ||
2752 | */ | ||
2753 | |||
2754 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2755 | /* mptscsih_writeIOCPage4 - write IOC Page 4 | ||
2756 | * @hd: Pointer to a SCSI Host Structure | ||
2757 | * @channel: write IOC Page4 for this Bus | ||
2758 | * @id: write IOC Page4 for this ID | ||
2759 | * | ||
2760 | * Return: -EAGAIN if unable to obtain a Message Frame | ||
2761 | * or 0 if success. | ||
2762 | * | ||
2763 | * Remark: We do not wait for a return, write pages sequentially. | ||
2764 | */ | ||
2765 | static int | ||
2766 | mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id) | ||
2767 | { | ||
2768 | MPT_ADAPTER *ioc = hd->ioc; | ||
2769 | Config_t *pReq; | ||
2770 | IOCPage4_t *IOCPage4Ptr; | ||
2771 | MPT_FRAME_HDR *mf; | ||
2772 | dma_addr_t dataDma; | ||
2773 | u16 req_idx; | ||
2774 | u32 frameOffset; | ||
2775 | u32 flagsLength; | ||
2776 | int ii; | ||
2777 | |||
2778 | /* Get a MF for this command. | ||
2779 | */ | ||
2780 | if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { | ||
2781 | dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", | ||
2782 | ioc->name)); | ||
2783 | return -EAGAIN; | ||
2784 | } | ||
2785 | |||
2786 | /* Set the request and the data pointers. | ||
2787 | * Place data at end of MF. | ||
2788 | */ | ||
2789 | pReq = (Config_t *)mf; | ||
2790 | |||
2791 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
2792 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
2793 | |||
2794 | /* Complete the request frame (same for all requests). | ||
2795 | */ | ||
2796 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
2797 | pReq->Reserved = 0; | ||
2798 | pReq->ChainOffset = 0; | ||
2799 | pReq->Function = MPI_FUNCTION_CONFIG; | ||
2800 | pReq->ExtPageLength = 0; | ||
2801 | pReq->ExtPageType = 0; | ||
2802 | pReq->MsgFlags = 0; | ||
2803 | for (ii=0; ii < 8; ii++) { | ||
2804 | pReq->Reserved2[ii] = 0; | ||
2805 | } | ||
2806 | |||
2807 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | ||
2808 | dataDma = ioc->spi_data.IocPg4_dma; | ||
2809 | ii = IOCPage4Ptr->ActiveSEP++; | ||
2810 | IOCPage4Ptr->SEP[ii].SEPTargetID = id; | ||
2811 | IOCPage4Ptr->SEP[ii].SEPBus = channel; | ||
2812 | pReq->Header = IOCPage4Ptr->Header; | ||
2813 | pReq->PageAddress = cpu_to_le32(id | (channel << 8 )); | ||
2814 | |||
2815 | /* Add a SGE to the config request. | ||
2816 | */ | ||
2817 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | | ||
2818 | (IOCPage4Ptr->Header.PageLength + ii) * 4; | ||
2819 | |||
2820 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | ||
2821 | |||
2822 | dinitprintk((MYIOC_s_INFO_FMT | ||
2823 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d channel=%d id=%d \n", | ||
2824 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, channel, id)); | ||
2825 | |||
2826 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
2827 | |||
2828 | return 0; | ||
2829 | } | ||
2830 | |||
2831 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2832 | /* | ||
2833 | * Bus Scan and Domain Validation functionality ... | 2549 | * Bus Scan and Domain Validation functionality ... |
2834 | */ | 2550 | */ |
2835 | 2551 | ||
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index aec0c2fe221f..4896d7cc681a 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -95,6 +95,269 @@ static int mptspiDoneCtx = -1; | |||
95 | static int mptspiTaskCtx = -1; | 95 | static int mptspiTaskCtx = -1; |
96 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ | 96 | static int mptspiInternalCtx = -1; /* Used only for internal commands */ |
97 | 97 | ||
98 | /** | ||
99 | * mptspi_setTargetNegoParms - Update the target negotiation | ||
100 | * parameters based on the the Inquiry data, adapter capabilities, | ||
101 | * and NVRAM settings | ||
102 | * | ||
103 | * @hd: Pointer to a SCSI Host Structure | ||
104 | * @vtarget: per target private data | ||
105 | * @sdev: SCSI device | ||
106 | * | ||
107 | **/ | ||
108 | static void | ||
109 | mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, | ||
110 | struct scsi_device *sdev) | ||
111 | { | ||
112 | SpiCfgData *pspi_data = &hd->ioc->spi_data; | ||
113 | int id = (int) target->id; | ||
114 | int nvram; | ||
115 | u8 width = MPT_NARROW; | ||
116 | u8 factor = MPT_ASYNC; | ||
117 | u8 offset = 0; | ||
118 | u8 nfactor; | ||
119 | u8 noQas = 1; | ||
120 | |||
121 | target->negoFlags = pspi_data->noQas; | ||
122 | |||
123 | if (sdev->scsi_level < SCSI_2) { | ||
124 | width = 0; | ||
125 | factor = MPT_ULTRA2; | ||
126 | offset = pspi_data->maxSyncOffset; | ||
127 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
128 | } else { | ||
129 | if (scsi_device_wide(sdev)) | ||
130 | width = 1; | ||
131 | |||
132 | if (scsi_device_sync(sdev)) { | ||
133 | factor = pspi_data->minSyncFactor; | ||
134 | if (!scsi_device_dt(sdev)) | ||
135 | factor = MPT_ULTRA2; | ||
136 | else { | ||
137 | if (!scsi_device_ius(sdev) && | ||
138 | !scsi_device_qas(sdev)) | ||
139 | factor = MPT_ULTRA160; | ||
140 | else { | ||
141 | factor = MPT_ULTRA320; | ||
142 | if (scsi_device_qas(sdev)) { | ||
143 | ddvprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", scsi_device_qas(sdev), id)); | ||
144 | noQas = 0; | ||
145 | } | ||
146 | if (sdev->type == TYPE_TAPE && | ||
147 | scsi_device_ius(sdev)) | ||
148 | target->negoFlags |= MPT_TAPE_NEGO_IDP; | ||
149 | } | ||
150 | } | ||
151 | offset = pspi_data->maxSyncOffset; | ||
152 | |||
153 | /* If RAID, never disable QAS | ||
154 | * else if non RAID, do not disable | ||
155 | * QAS if bit 1 is set | ||
156 | * bit 1 QAS support, non-raid only | ||
157 | * bit 0 IU support | ||
158 | */ | ||
159 | if (target->raidVolume == 1) | ||
160 | noQas = 0; | ||
161 | } else { | ||
162 | factor = MPT_ASYNC; | ||
163 | offset = 0; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | if (!sdev->tagged_supported) | ||
168 | target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; | ||
169 | |||
170 | /* Update tflags based on NVRAM settings. (SCSI only) | ||
171 | */ | ||
172 | if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { | ||
173 | nvram = pspi_data->nvram[id]; | ||
174 | nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; | ||
175 | |||
176 | if (width) | ||
177 | width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; | ||
178 | |||
179 | if (offset > 0) { | ||
180 | /* Ensure factor is set to the | ||
181 | * maximum of: adapter, nvram, inquiry | ||
182 | */ | ||
183 | if (nfactor) { | ||
184 | if (nfactor < pspi_data->minSyncFactor ) | ||
185 | nfactor = pspi_data->minSyncFactor; | ||
186 | |||
187 | factor = max(factor, nfactor); | ||
188 | if (factor == MPT_ASYNC) | ||
189 | offset = 0; | ||
190 | } else { | ||
191 | offset = 0; | ||
192 | factor = MPT_ASYNC; | ||
193 | } | ||
194 | } else { | ||
195 | factor = MPT_ASYNC; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | /* Make sure data is consistent | ||
200 | */ | ||
201 | if ((!width) && (factor < MPT_ULTRA2)) | ||
202 | factor = MPT_ULTRA2; | ||
203 | |||
204 | /* Save the data to the target structure. | ||
205 | */ | ||
206 | target->minSyncFactor = factor; | ||
207 | target->maxOffset = offset; | ||
208 | target->maxWidth = width; | ||
209 | |||
210 | target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; | ||
211 | |||
212 | /* Disable unused features. | ||
213 | */ | ||
214 | if (!width) | ||
215 | target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; | ||
216 | |||
217 | if (!offset) | ||
218 | target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; | ||
219 | |||
220 | if ( factor > MPT_ULTRA320 ) | ||
221 | noQas = 0; | ||
222 | |||
223 | if (noQas && (pspi_data->noQas == 0)) { | ||
224 | pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; | ||
225 | target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; | ||
226 | |||
227 | /* Disable QAS in a mixed configuration case | ||
228 | */ | ||
229 | |||
230 | ddvprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); | ||
231 | } | ||
232 | } | ||
233 | |||
234 | /** | ||
235 | * mptspi_writeIOCPage4 - write IOC Page 4 | ||
236 | * @hd: Pointer to a SCSI Host Structure | ||
237 | * @channel: | ||
238 | * @id: write IOC Page4 for this ID & Bus | ||
239 | * | ||
240 | * Return: -EAGAIN if unable to obtain a Message Frame | ||
241 | * or 0 if success. | ||
242 | * | ||
243 | * Remark: We do not wait for a return, write pages sequentially. | ||
244 | **/ | ||
245 | static int | ||
246 | mptspi_writeIOCPage4(MPT_SCSI_HOST *hd, u8 channel , u8 id) | ||
247 | { | ||
248 | MPT_ADAPTER *ioc = hd->ioc; | ||
249 | Config_t *pReq; | ||
250 | IOCPage4_t *IOCPage4Ptr; | ||
251 | MPT_FRAME_HDR *mf; | ||
252 | dma_addr_t dataDma; | ||
253 | u16 req_idx; | ||
254 | u32 frameOffset; | ||
255 | u32 flagsLength; | ||
256 | int ii; | ||
257 | |||
258 | /* Get a MF for this command. | ||
259 | */ | ||
260 | if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { | ||
261 | dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", | ||
262 | ioc->name)); | ||
263 | return -EAGAIN; | ||
264 | } | ||
265 | |||
266 | /* Set the request and the data pointers. | ||
267 | * Place data at end of MF. | ||
268 | */ | ||
269 | pReq = (Config_t *)mf; | ||
270 | |||
271 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | ||
272 | frameOffset = ioc->req_sz - sizeof(IOCPage4_t); | ||
273 | |||
274 | /* Complete the request frame (same for all requests). | ||
275 | */ | ||
276 | pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; | ||
277 | pReq->Reserved = 0; | ||
278 | pReq->ChainOffset = 0; | ||
279 | pReq->Function = MPI_FUNCTION_CONFIG; | ||
280 | pReq->ExtPageLength = 0; | ||
281 | pReq->ExtPageType = 0; | ||
282 | pReq->MsgFlags = 0; | ||
283 | for (ii=0; ii < 8; ii++) { | ||
284 | pReq->Reserved2[ii] = 0; | ||
285 | } | ||
286 | |||
287 | IOCPage4Ptr = ioc->spi_data.pIocPg4; | ||
288 | dataDma = ioc->spi_data.IocPg4_dma; | ||
289 | ii = IOCPage4Ptr->ActiveSEP++; | ||
290 | IOCPage4Ptr->SEP[ii].SEPTargetID = id; | ||
291 | IOCPage4Ptr->SEP[ii].SEPBus = channel; | ||
292 | pReq->Header = IOCPage4Ptr->Header; | ||
293 | pReq->PageAddress = cpu_to_le32(id | (channel << 8 )); | ||
294 | |||
295 | /* Add a SGE to the config request. | ||
296 | */ | ||
297 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | | ||
298 | (IOCPage4Ptr->Header.PageLength + ii) * 4; | ||
299 | |||
300 | mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); | ||
301 | |||
302 | ddvprintk((MYIOC_s_INFO_FMT | ||
303 | "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", | ||
304 | ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, id, channel)); | ||
305 | |||
306 | mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); | ||
307 | |||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * mptspi_initTarget - Target, LUN alloc/free functionality. | ||
313 | * @hd: Pointer to MPT_SCSI_HOST structure | ||
314 | * @vtarget: per target private data | ||
315 | * @sdev: SCSI device | ||
316 | * | ||
317 | * NOTE: It's only SAFE to call this routine if data points to | ||
318 | * sane & valid STANDARD INQUIRY data! | ||
319 | * | ||
320 | * Allocate and initialize memory for this target. | ||
321 | * Save inquiry data. | ||
322 | * | ||
323 | **/ | ||
324 | static void | ||
325 | mptspi_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, | ||
326 | struct scsi_device *sdev) | ||
327 | { | ||
328 | |||
329 | /* Is LUN supported? If so, upper 2 bits will be 0 | ||
330 | * in first byte of inquiry data. | ||
331 | */ | ||
332 | if (sdev->inq_periph_qual != 0) | ||
333 | return; | ||
334 | |||
335 | if (vtarget == NULL) | ||
336 | return; | ||
337 | |||
338 | vtarget->type = sdev->type; | ||
339 | |||
340 | if ((sdev->type == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { | ||
341 | /* Treat all Processors as SAF-TE if | ||
342 | * command line option is set */ | ||
343 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
344 | mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
345 | }else if ((sdev->type == TYPE_PROCESSOR) && | ||
346 | !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { | ||
347 | if (sdev->inquiry_len > 49 ) { | ||
348 | if (sdev->inquiry[44] == 'S' && | ||
349 | sdev->inquiry[45] == 'A' && | ||
350 | sdev->inquiry[46] == 'F' && | ||
351 | sdev->inquiry[47] == '-' && | ||
352 | sdev->inquiry[48] == 'T' && | ||
353 | sdev->inquiry[49] == 'E' ) { | ||
354 | vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; | ||
355 | mptspi_writeIOCPage4(hd, vtarget->channel, vtarget->id); | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | mptspi_setTargetNegoParms(hd, vtarget, sdev); | ||
360 | } | ||
98 | 361 | ||
99 | /** | 362 | /** |
100 | * mptspi_is_raid - Determines whether target is belonging to volume | 363 | * mptspi_is_raid - Determines whether target is belonging to volume |
@@ -408,13 +671,16 @@ static int mptspi_slave_alloc(struct scsi_device *sdev) | |||
408 | 671 | ||
409 | static int mptspi_slave_configure(struct scsi_device *sdev) | 672 | static int mptspi_slave_configure(struct scsi_device *sdev) |
410 | { | 673 | { |
411 | int ret = mptscsih_slave_configure(sdev); | ||
412 | struct _MPT_SCSI_HOST *hd = | 674 | struct _MPT_SCSI_HOST *hd = |
413 | (struct _MPT_SCSI_HOST *)sdev->host->hostdata; | 675 | (struct _MPT_SCSI_HOST *)sdev->host->hostdata; |
676 | VirtTarget *vtarget = scsi_target(sdev)->hostdata; | ||
677 | int ret = mptscsih_slave_configure(sdev); | ||
414 | 678 | ||
415 | if (ret) | 679 | if (ret) |
416 | return ret; | 680 | return ret; |
417 | 681 | ||
682 | mptspi_initTarget(hd, vtarget, sdev); | ||
683 | |||
418 | if ((sdev->channel == 1 || | 684 | if ((sdev->channel == 1 || |
419 | !(mptspi_is_raid(hd, sdev->id))) && | 685 | !(mptspi_is_raid(hd, sdev->id))) && |
420 | !spi_initial_dv(sdev->sdev_target)) | 686 | !spi_initial_dv(sdev->sdev_target)) |