aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
authorEric Moore <eric.moore@lsi.com>2007-01-29 11:43:17 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-02-02 21:49:42 -0500
commit5a9c47b1344b514758d5d7f193c672850390cc36 (patch)
treee51ee96d7984203a8990109d0c3c825668074e56 /drivers/message/fusion
parent793955f549c710a1b0c18f823d5d710840747b15 (diff)
[SCSI] fusion - move SPI API over to mptspi.c
Move some functions that only apply to the mptspi module over from mptscsih.c Signed-off-by: Eric Moore <Eric.Moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptscsih.c284
-rw-r--r--drivers/message/fusion/mptspi.c268
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,
99int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 99int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
100int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 100int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
101 101
102static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
103static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
104static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int channel, int id);
105int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 102int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
106static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 103static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
107static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); 104static 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 */
2565static void
2566mptscsih_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 */
2615static void
2616mptscsih_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 */
2765static int
2766mptscsih_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;
95static int mptspiTaskCtx = -1; 95static int mptspiTaskCtx = -1;
96static int mptspiInternalCtx = -1; /* Used only for internal commands */ 96static 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 **/
108static void
109mptspi_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 **/
245static int
246mptspi_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 **/
324static void
325mptspi_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
409static int mptspi_slave_configure(struct scsi_device *sdev) 672static 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))